diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/actions.c | 113 | ||||
-rw-r--r-- | src/actions.h | 1 | ||||
-rw-r--r-- | src/data.h | 4 | ||||
-rw-r--r-- | src/main.c | 5 | ||||
-rw-r--r-- | src/split.c | 26 | ||||
-rw-r--r-- | src/split.h | 1 |
6 files changed, 148 insertions, 2 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; +} diff --git a/src/actions.h b/src/actions.h index 643bec5..70a23f4 100644 --- a/src/actions.h +++ b/src/actions.h @@ -116,6 +116,7 @@ char *cmd_nextscreen (int interactive, void *data); char *cmd_unalias (int interactive, void *data); char *cmd_warp(int interactive, void *data); char *cmd_tmpwm (int interactive, void *data); +char *cmd_fselect (int interactive, void *data); void initialize_default_keybindings (void); void free_keybindings (); @@ -23,6 +23,7 @@ #define _RATPOISON_DATA_H #include "linkedlist.h" +#include "number.h" #include <X11/X.h> #include <X11/Xlib.h> @@ -109,6 +110,9 @@ struct screen_info always be one in the list. */ struct list_head rp_window_frames; + /* Keep track of which numbers have been given to frames. */ + struct numset *frames_numset; + /* Pointer to the currently focused frame. One for each screen so when you switch screens the focus doesn't get frobbed. */ rp_window_frame *rp_current_frame; @@ -632,6 +632,9 @@ init_screen (screen_info *s, int screen_num) | SubstructureRedirectMask | SubstructureNotifyMask ); XSync (dpy, False); + /* Create the numset for the frames. */ + s->frames_numset = numset_new (); + /* Build the display string for each screen */ s->display_string = xmalloc (strlen(DisplayString (dpy)) + 21); sprintf (s->display_string, "DISPLAY=%s", DisplayString (dpy)); @@ -720,6 +723,8 @@ free_screen (screen_info *s) XFreeGC (dpy, s->normal_gc); free (s->display_string); + + numset_free (s->frames_numset); } void diff --git a/src/split.c b/src/split.c index e52fd94..c110001 100644 --- a/src/split.c +++ b/src/split.c @@ -148,7 +148,9 @@ create_initial_frame (screen_info *screen) list_add_tail (&screen->rp_current_frame->node, &screen->rp_window_frames); + screen->rp_current_frame->number = numset_request (screen->frames_numset); update_last_access (screen->rp_current_frame); + maximize_frame (screen->rp_current_frame); set_frames_window (screen->rp_current_frame, NULL); } @@ -284,6 +286,9 @@ split_frame (rp_window_frame *frame, int way, int pixels) new_frame = xmalloc (sizeof (rp_window_frame)); + /* Give the frame a unique number. */ + new_frame->number = numset_request (s->frames_numset); + /* It seems intuitive to make the last frame the newly created frame. */ update_last_access (new_frame); @@ -291,7 +296,7 @@ split_frame (rp_window_frame *frame, int way, int pixels) /* TODO: don't put the new frame at the end of the list, put it after the existing frame. Then cycling frames cycles in the order they were created. */ - list_add_tail (&new_frame->node, &s->rp_window_frames); + list_add (&new_frame->node, &s->rp_current_frame->node); set_frames_window (new_frame, NULL); @@ -379,6 +384,8 @@ remove_all_splits () if (frame != s->rp_current_frame) { list_del (&frame->node); + + numset_release (s->frames_numset, frame->number); free (frame); } } @@ -520,7 +527,7 @@ resize_frame_horizontally (rp_window_frame *frame, int diff) list_for_each_entry (cur, &s->rp_window_frames, node) { if (cur->x == (frame->x + frame->width) - && (cur->y + cur->height) > frame->y + && (cur->y + cur->height) > frame->y && cur->y < (frame->y + frame->height)) { cur->width -= diff; @@ -687,6 +694,7 @@ remove_frame (rp_window_frame *frame) area = total_frame_area(s); PRINT_DEBUG (("Total Area: %d\n", area)); + numset_release (s->frames_numset, frame->number); list_del (&frame->node); hide_window (frame->win); hide_others (frame->win); @@ -940,3 +948,17 @@ find_frame_right (rp_window_frame *frame) return NULL; } + +rp_window_frame * +find_frame_number (screen_info *s, int num) +{ + rp_window_frame *cur; + + list_for_each_entry (cur, &s->rp_window_frames, node) + { + if (cur->number == num) + return cur; + } + + return NULL; +} diff --git a/src/split.h b/src/split.h index 7bf56d3..79667cc 100644 --- a/src/split.h +++ b/src/split.h @@ -50,5 +50,6 @@ rp_window_frame *find_frame_left (rp_window_frame *frame); rp_window_frame *find_frame_down (rp_window_frame *frame); rp_window_frame *find_frame_up (rp_window_frame *frame); rp_window_frame *find_last_frame (screen_info *s); +rp_window_frame *find_frame_number (screen_info *s, int num); #endif |