From 8b6f270c70d8fa6898e7d6c3b9533026c757f48c Mon Sep 17 00:00:00 2001 From: sabetts Date: Sat, 7 Apr 2001 05:17:34 +0000 Subject: * src/split.h (hide_frame_indicator): new prototype (show_frame_indicator): likewise * src/split.c: include (split_frame): set the new_frame's window to NULL (split_frame): calls show_frame_indicator once the split is done. (set_active_frame): only call show_frame_indicator if the frame has no window or if we switched to a different frame. (update_frame_indicator): prints FRAME_STRING in the frame indicator window. (hide_frame_indicator): new function (show_frame_indicator): likewise * src/main.c (rp_rat_bits): new variable (rp_rat_mask_bits): likewise (alrm_handler): calls hide_frame_indicator (init_rat_cursor): new function (init_screen): calls init_rat_cursor * src/events.c (unmap_notify): calls set_active_frame if the window being unmapped was in the current frame (destroy_window): calls set_active_frame if the window being destroyed was in the current frame (grab_rat): new function (grab_rat): likewise (handle_key): calls grab_rat and ungrab_rat * src/data.h (struct screen_info): new variable rat * src/conf.h (FRAME_INDICATOR_TIMEOUT): new #define (FRAME_STRING): likewise (RAT_HEIGHT): likewise (RAT_WIDTH): likewise (RAT_HOT_X): likewise (RAT_HOT_Y): likewise * src/actions.h (cmd_curframe): new prototype * src/actions.c (initialize_default_keybindings): new key binds for "curframe" (user_commands): new command "curframe" (cmd_curframe): new function * src/split.c (remove_all_splits): only maximize the current window if there is one. (maximize_frame): remove unused code to retrieve the current screen_info. * src/actions.c (cmd_h_split): calls h_split_frame on the current frame. (cmd_v_split): likewise (cmd_only): even if the current frame is empty, call remove_all_splits. * src/split.c (maximize_frame): new function (create_initial_frame): calls maximize_frame to fill in the initial frame's fields. (num_frames): comment out (remove_frame): remove special case when there is only 1 frame left. * src/split.h (h_split_frame): renamed frome h_split_window (v_split_frame): renamed frome v_split_window (split_frame): renamed frome split_window (remove_all_splits): renamed frome remove_all_frames (find_windows_frame): new prototype (find_frame_next): likewise (find_frame_prev): likewise (current_window): likewise (init_frame_list): likewise (set_active_frame): likewise * src/split.c (create_initial_frame): new function (init_frame_list): likewise (find_windows_frame): likewise (find_frame_next): likewise (find_frame_prev): likewise (current_window): likewise (update_frame_indicator): likewise (set_active_frame): likewise (split_frame): rename from split_window (v_split_frame): rename from v_split_window (h_split_frame): rename from h_split_window (remove_all_splits): renamed frome remove_all_frames (total_frame_area): traverses rp_window_frame list (num_frames): likewise (frame_overlaps): likewise (remove_frame): likewise (remove_frame): calls delete_frame_from_list * src/main.c (main): calls init_frame_list (init_screen): create and map the frame_window * src/events.c (new_window): the screen's frame_window is not managed (cleanup_frame): new function (unmap_notify): calls cleanup_frame if window exists in a frame (destroy_window): likewise * src/data.h (struct screen_info): remove frame field (struct rp_window_frame): new fields win, prev, next (rp_window_frame_sentinel): new global * src/actions.c (cmd_prev): jumps to last accessed window if current frame is empty. (cmd_next): likewise (cmd_remove): nothing is done if only 1 frame exists * src/data.h (struct screen_info): new field frame_window (rp_current_frame): new global (rp_current_window): removed. All dependant code updated. --- ChangeLog | 43 +++++++++++++++++++++++++++++++++++++++++ NEWS | 5 +++++ src/actions.c | 9 +++++++++ src/actions.h | 1 + src/conf.h | 11 +++++++++++ src/data.h | 1 + src/events.c | 29 +++++++++++++++++++++++++--- src/main.c | 40 ++++++++++++++++++++++++++++++++++++++- src/split.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++---------- src/split.h | 2 ++ 10 files changed, 188 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6f32688..6a6b69b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,48 @@ 2001-04-06 shawn + * src/split.h (hide_frame_indicator): new prototype + (show_frame_indicator): likewise + + * src/split.c: include + (split_frame): set the new_frame's window to NULL + (split_frame): calls show_frame_indicator once the split is done. + (set_active_frame): only call show_frame_indicator if the frame + has no window or if we switched to a different frame. + (update_frame_indicator): prints FRAME_STRING in the frame + indicator window. + (hide_frame_indicator): new function + (show_frame_indicator): likewise + + * src/main.c (rp_rat_bits): new variable + (rp_rat_mask_bits): likewise + (alrm_handler): calls hide_frame_indicator + (init_rat_cursor): new function + (init_screen): calls init_rat_cursor + + * src/events.c (unmap_notify): calls set_active_frame if the + window being unmapped was in the current frame + (destroy_window): calls set_active_frame if the + window being destroyed was in the current frame + (grab_rat): new function + (grab_rat): likewise + (handle_key): calls grab_rat and ungrab_rat + + * src/data.h (struct screen_info): new variable rat + + * src/conf.h (FRAME_INDICATOR_TIMEOUT): new #define + (FRAME_STRING): likewise + (RAT_HEIGHT): likewise + (RAT_WIDTH): likewise + (RAT_HOT_X): likewise + (RAT_HOT_Y): likewise + + * src/actions.h (cmd_curframe): new prototype + + * src/actions.c (initialize_default_keybindings): new key binds + for "curframe" + (user_commands): new command "curframe" + (cmd_curframe): new function + * src/split.c (remove_all_splits): only maximize the current window if there is one. (maximize_frame): remove unused code to retrieve the current diff --git a/NEWS b/NEWS index 0692023..f0cada9 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,11 @@ ratpoison NEWS --- history of user-visible changes. -*- outline -*- * Changes since 0.1.1 +** rat cursor changes + +When you hit the prefix key the rat cursor changes to a square to tell +you what it is waiting for another key. + ** Split windows Well, the day is finally here. You can now split windows in diff --git a/src/actions.c b/src/actions.c index b33941e..ab486bd 100644 --- a/src/actions.c +++ b/src/actions.c @@ -131,6 +131,8 @@ initialize_default_keybindings (void) add_keybinding (XK_Tab, 0, "focus"); add_keybinding (XK_Q, 0, "only"); add_keybinding (XK_R, 0, "remove"); + add_keybinding (XK_f, 0, "curframe"); + add_keybinding (XK_f, ControlMask, "curframe"); } user_command user_commands[] = @@ -161,6 +163,7 @@ user_command user_commands[] = {"only", cmd_only, arg_VOID}, {"remove", cmd_remove, arg_VOID}, {"banish", cmd_banish, arg_VOID}, + {"curframe", cmd_curframe, arg_VOID}, /* the following screen commands may or may not be able to be implemented. See the screen documentation for what should be @@ -857,3 +860,9 @@ cmd_banish (void *data) XWarpPointer (dpy, None, s->root, 0, 0, 0, 0, s->root_attr.width - 2, s->root_attr.height - 2); } + +void +cmd_curframe (void *data) +{ + show_frame_indicator(); +} diff --git a/src/actions.h b/src/actions.h index 191b825..b479ab1 100644 --- a/src/actions.h +++ b/src/actions.h @@ -70,6 +70,7 @@ void cmd_v_split (void *data); void cmd_only (void *data); void cmd_remove (void *data); void cmd_banish (void *data); +void cmd_curframe (void *data); /* void cmd_xterm (void *data); */ diff --git a/src/conf.h b/src/conf.h index e262ee4..a855a21 100644 --- a/src/conf.h +++ b/src/conf.h @@ -57,6 +57,12 @@ #define BAR_LOCATION 3 /* 0=bottom-left 1=top-left 2=bottom-right 3=top-right */ #define BAR_TIMEOUT 5 /* Number of seconds before the progam bar autohides 0=don't autohide */ +/* Number of seconds before the frame indicator disappears */ +#define FRAME_INDICATOR_TIMEOUT 1 + +/* What to display in the frame indicator */ +#define FRAME_STRING "Current Frame" + #define PADDING_LEFT 0 /* space not to be taken up around managed windows */ #define PADDING_TOP 0 #define PADDING_RIGHT 0 @@ -69,4 +75,9 @@ mostly for use with hand-helds. */ #define UNMANAGED_WINDOW_LIST "xapm","xclock","xscribble" +#define RAT_WIDTH 16 +#define RAT_HEIGHT 16 +#define RAT_HOT_X 8 +#define RAT_HOT_Y 8 + #endif /* !_ _RATPOISON_CONF_H */ diff --git a/src/data.h b/src/data.h index 080f7ee..300059a 100644 --- a/src/data.h +++ b/src/data.h @@ -84,6 +84,7 @@ struct screen_info int bar_is_raised; int screen_num; /* Our screen number as dictated my X */ Colormap def_cmap; + Cursor rat; }; struct rp_action diff --git a/src/events.c b/src/events.c index b0c9a1b..092e2bc 100644 --- a/src/events.c +++ b/src/events.c @@ -99,7 +99,10 @@ unmap_notify (XEvent *ev) XSync(dpy, False); - if (win == current_window()) cmd_other (NULL); + if (frame == rp_current_frame) + { + set_active_frame (frame); + } ignore_badwindow--; @@ -183,11 +186,11 @@ destroy_window (XDestroyWindowEvent *ev) frame = find_windows_frame (win); if (frame) cleanup_frame (frame); - if (win == current_window()) + if (frame == rp_current_frame) { PRINT_DEBUG ("Destroying the current window.\n"); - set_active_window (find_window_other ()); + set_active_frame (frame); unmanage (win); } else @@ -309,6 +312,20 @@ client_msg (XClientMessageEvent *ev) } } +static void +grab_rat () +{ + XGrabPointer (dpy, current_screen()->root, True, 0, + GrabModeAsync, GrabModeAsync, + None, current_screen()->rat, CurrentTime); +} + +static void +ungrab_rat () +{ + XUngrabPointer (dpy, CurrentTime); +} + static void handle_key (screen_info *s) { @@ -329,6 +346,10 @@ handle_key (screen_info *s) XGetInputFocus (dpy, &fwin, &revert); XSetInputFocus (dpy, s->key_window, RevertToPointerRoot, CurrentTime); + /* Change the mouse icon to indicate to the user we are waiting for + more keystrokes */ + grab_rat(); + read_key (&keysym, &mod, NULL, 0); if ((key_action = find_keybinding (keysym, mod))) @@ -352,6 +373,8 @@ handle_key (screen_info *s) free (msg); } + + ungrab_rat(); } void diff --git a/src/main.c b/src/main.c index cd79f69..9f4ff3d 100644 --- a/src/main.c +++ b/src/main.c @@ -37,6 +37,19 @@ static void init_screen (screen_info *s, int screen_num); +/* When a user hits the prefix key, the rat switches to a different + pixmap to indicate that ratpoison expects the user to hit another + key, these are the pixmaps. */ +static unsigned char rp_rat_bits[] = { + 0x00, 0x00, 0xfe, 0x7f, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, + 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, + 0x02, 0x40, 0x02, 0x40, 0xfe, 0x7f, 0x00, 0x00}; + +static unsigned char rp_rat_mask_bits[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + int rat_x; int rat_y; int rat_visible = 1; /* rat is visible by default */ @@ -139,6 +152,9 @@ alrm_handler (int signum) { hide_bar (&screens[i]); } + + hide_frame_indicator(); + XSync (dpy, False); } @@ -434,6 +450,27 @@ main (int argc, char *argv[]) return EXIT_SUCCESS; } +static void +init_rat_cursor (screen_info *s) +{ + Pixmap fore, mask; + XColor fg, bg, dummy; + + XAllocNamedColor(dpy, DefaultColormap(dpy, s->screen_num), + "black", &fg, &dummy); + XAllocNamedColor(dpy, DefaultColormap(dpy, s->screen_num), + "white", &bg, &dummy); + + fore = XCreatePixmapFromBitmapData (dpy, s->root, + rp_rat_bits, RAT_WIDTH, RAT_HEIGHT, + 1, 0, 1); + mask = XCreatePixmapFromBitmapData (dpy, s->root, + rp_rat_mask_bits, RAT_WIDTH, RAT_HEIGHT, + 1, 0, 1); + s->rat = XCreatePixmapCursor(dpy, fore, mask, + &fg, &bg, RAT_HOT_X, RAT_HOT_Y); +} + static void init_screen (screen_info *s, int screen_num) { @@ -444,6 +481,8 @@ init_screen (screen_info *s, int screen_num) s->def_cmap = DefaultColormap (dpy, screen_num); s->font = font; XGetWindowAttributes (dpy, s->root, &s->root_attr); + + init_rat_cursor (s); /* Get our program bar colors */ if (!XAllocNamedColor (dpy, s->def_cmap, FOREGROUND, &fg_color, &junk)) @@ -508,7 +547,6 @@ init_screen (screen_info *s, int screen_num) XSelectInput (dpy, s->frame_window, KeyPressMask ); XMapRaised (dpy, s->frame_window); - XSync (dpy, 0); scanwins (s); diff --git a/src/split.c b/src/split.c index a257921..0533de0 100644 --- a/src/split.c +++ b/src/split.c @@ -21,6 +21,8 @@ * Functions for handling window splitting and tiling. */ +#include + #include "ratpoison.h" rp_window_frame *rp_window_frame_sentinel; @@ -175,14 +177,6 @@ find_window_for_frame (rp_window_frame *frame) return most_recent; } -static void -update_frame_indicator () -{ - XMoveWindow (dpy, current_screen()->frame_window, - rp_current_frame->x + rp_current_frame->width / 2 - 5, - rp_current_frame->y + rp_current_frame->height / 2 - 5); -} - /* Splits the frame in 2. if way is 0 then split vertically otherwise split it horizontally. */ static void @@ -202,6 +196,8 @@ split_frame (rp_window_frame *frame, int way) rp_window_frame_sentinel->prev = new_frame; new_frame->next = rp_window_frame_sentinel; + new_frame->win = NULL; + if (way) { new_frame->x = frame->x; @@ -242,7 +238,7 @@ split_frame (rp_window_frame *frame, int way) maximize (frame->win); XRaiseWindow (dpy, frame->win->w); - update_frame_indicator(); + show_frame_indicator(); } /* Splits the window vertically in 2. */ @@ -471,10 +467,15 @@ remove_frame (rp_window_frame *frame) void set_active_frame (rp_window_frame *frame) { + rp_window_frame *old = rp_current_frame; + give_window_focus (frame->win); rp_current_frame = frame; - update_frame_indicator(); + if (!frame->win || old != rp_current_frame) + { + show_frame_indicator(); + } if( !frame->win ) { @@ -482,3 +483,43 @@ set_active_frame (rp_window_frame *frame) RevertToPointerRoot, CurrentTime); } } + +static void +update_frame_indicator () +{ + screen_info *s = current_screen (); + int width, height; + + width = BAR_X_PADDING * 2 + XTextWidth (s->font, FRAME_STRING, strlen (FRAME_STRING)); + height = (FONT_HEIGHT (s->font) + BAR_Y_PADDING * 2); + + XMoveResizeWindow (dpy, current_screen()->frame_window, + rp_current_frame->x + rp_current_frame->width / 2 - width / 2, + rp_current_frame->y + rp_current_frame->height / 2 - height / 2, + width, height); + + XClearWindow (dpy, s->frame_window); + XDrawString (dpy, s->frame_window, s->normal_gc, + BAR_X_PADDING, + BAR_Y_PADDING + s->font->max_bounds.ascent, + FRAME_STRING, strlen (FRAME_STRING)); +} + +void +hide_frame_indicator () +{ + /* Only hide the frame indicator if a window occupies the frame */ + if (rp_current_frame->win) + { + XUnmapWindow (dpy, current_screen()->frame_window); + } +} + +void +show_frame_indicator () +{ + XMapRaised (dpy, current_screen()->frame_window); + + update_frame_indicator(); + alarm (FRAME_INDICATOR_TIMEOUT); +} diff --git a/src/split.h b/src/split.h index 2fa1557..6ef0186 100644 --- a/src/split.h +++ b/src/split.h @@ -33,5 +33,7 @@ rp_window_frame *find_frame_prev (rp_window_frame *frame); rp_window *current_window (); void init_frame_list (); void set_active_frame (rp_window_frame *frame); +void show_frame_indicator (); +void hide_frame_indicator (); #endif -- cgit v1.2.3