summaryrefslogtreecommitdiff
path: root/src/actions.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/actions.c')
-rw-r--r--src/actions.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/src/actions.c b/src/actions.c
index e655341..cfce0aa 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -92,6 +92,7 @@ static user_command user_commands[] =
{"resize", cmd_resize, arg_STRING},
{"shrink", cmd_shrink, arg_VOID},
{"tmpwm", cmd_tmpwm, arg_STRING},
+ {"fselect", cmd_fselect, arg_VOID},
/*@end (tag required for genrpbindings) */
/* Commands to set default behavior. */
@@ -2825,3 +2826,115 @@ cmd_tmpwm (int interactive, void *data)
/* And we're back in ratpoison. */
return NULL;
}
+
+/* Select a frame by number. */
+char *
+cmd_fselect (int interactive, void *data)
+{
+ rp_window_frame *frame;
+ screen_info *s = current_screen();
+ int fnum = -1;
+
+ /* If the command was specified on the command line or an argument
+ was supplied to it, then try to read that argument. */
+ if (!interactive || data != NULL)
+ {
+ if (data == NULL)
+ {
+ /* The command was from the command line, but they didn't
+ specify an argument. FIXME: give some indication of
+ failure. */
+ return NULL;
+ }
+
+ /* Attempt to read the argument. */
+ if (sscanf (data, "%d", &fnum) < 1)
+ {
+ message (" fselect: numerical argument required ");
+ return NULL;
+ }
+ }
+ /* The command was called interactively and no argument was
+ supplied, so we show the frames' numbers and read a number from
+ the keyboard. */
+ else
+ {
+ KeySym c;
+ unsigned int mod;
+ Window fwin;
+ int revert;
+ Window *wins;
+ XSetWindowAttributes attr;
+ int i;
+ rp_window_frame *cur;
+
+ /* Set up the window attributes to be used in the loop. */
+ attr.border_pixel = s->fg_color;
+ attr.background_pixel = s->bg_color;
+ attr.override_redirect = True;
+
+ wins = xmalloc (sizeof (Window) * num_frames (s));
+
+ /* Loop through each frame and display its number in it's top
+ left corner. */
+ i = 0;
+ list_for_each_entry (cur, &s->rp_window_frames, node)
+ {
+ int width, height;
+ char *num;
+
+ /* Create the string to be displayed in the window and
+ determine the height and width of the window. */
+ num = xsprintf (" %d ", cur->number);
+ width = defaults.bar_x_padding * 2 + XTextWidth (defaults.font, num, strlen (num));
+ height = (FONT_HEIGHT (defaults.font) + defaults.bar_y_padding * 2);
+
+ /* Create and map the window. */
+ wins[i] = XCreateWindow (dpy, s->root, cur->x, cur->y, width, height, 1,
+ CopyFromParent, CopyFromParent, CopyFromParent,
+ CWOverrideRedirect | CWBorderPixel | CWBackPixel,
+ &attr);
+ XMapWindow (dpy, wins[i]);
+ XClearWindow (dpy, wins[i]);
+
+ /* Display the frame's number inside the window. */
+ XDrawString (dpy, wins[i], s->normal_gc,
+ defaults.bar_x_padding,
+ defaults.bar_y_padding + defaults.font->max_bounds.ascent,
+ num, strlen (num));
+
+ free (num);
+ i++;
+ }
+ XSync (dpy, False);
+
+ /* Read a key. */
+ XGetInputFocus (dpy, &fwin, &revert);
+ XSetInputFocus (dpy, s->key_window, RevertToPointerRoot, CurrentTime);
+ read_key (&c, &mod, NULL, 0);
+ XSetInputFocus (dpy, fwin, RevertToPointerRoot, CurrentTime);
+
+ /* Destroy our number windows and free the array. */
+ for (i=0; i<num_frames (s); i++)
+ XDestroyWindow (dpy, wins[i]);
+
+ free (wins);
+
+ /* FIXME: big assumption here. We don't know for sure if all the
+ number keys are between XK_0 and XK_9. */
+ if (c >= XK_0 && c <= XK_9)
+ fnum = c - XK_0;
+ else
+ return NULL;
+ }
+
+ /* Now that we have a frame number to go to, let's try to jump to
+ it. */
+ frame = find_frame_number (s, fnum);
+ if (frame)
+ set_active_frame (frame);
+ else
+ marked_message_printf (0, 0, " fselect: No such frame (%d) ", fnum);
+
+ return NULL;
+}