summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog34
-rw-r--r--NEWS4
-rw-r--r--src/actions.c77
-rw-r--r--src/actions.h1
-rw-r--r--src/conf.h2
-rw-r--r--src/events.c6
-rw-r--r--src/input.c121
-rw-r--r--src/input.h2
-rw-r--r--src/split.c37
-rw-r--r--src/split.h1
10 files changed, 180 insertions, 105 deletions
diff --git a/ChangeLog b/ChangeLog
index e408ae7..56d1649 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,37 @@
+2001-10-18 shawn <sabetts@vcn.bc.ca>
+
+ * src/split.h (find_last_frame): new prototype
+
+ * src/split.c (update_last_access): new function
+ (find_last_frame): likewise
+ (split_frame): update the new frame's last_access field
+ (set_active_frame): update the new current frame's last_access field
+
+ * src/input.h (x11_mask_to_rp_mask): new prototype
+ (rp_mask_to_x11_mask): likewise
+
+ * src/input.c (x11_mask_to_rp_mask): new function
+ (rp_mask_to_x11_mask): likewise
+
+ * src/events.c (handle_key): convert X11 modifier masks to rp
+ modifier masks where appropriate.
+
+ * src/actions.h (cmd_focuslast): new prototype
+
+ * src/actions.c (initialize_default_keybindings): new keybinding
+ for "focuslast"
+ (cmd_focuslast): new function
+ (user_command): new command "focuslast"
+
+ * src/data.h (struct rp_window_frame): new field 'last_access'
+ (RP_CONTROL_MASK): new define. All code depending on the X11
+ modifier mask equivalent has been changed to use this where
+ appropriate.
+ (RP_META_MASK): likewise
+ (RP_ALT_MASK): likewise
+ (RP_SUPER_MASK): likewise
+ (RP_HYPER_MASK): likewise
+
2001-10-11 shawn <sabetts@vcn.bc.ca>
* src/bar.c (show_last_message): abort if there was no last
diff --git a/NEWS b/NEWS
index 9621a33..bf02ee9 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,10 @@
ratpoison NEWS --- history of user-visible changes. -*- outline -*-
* Changes since 1.0.0
+** new command "focuslast"
+Switch between the current frame and the last focused frame. It is
+bound to C-t M-Tab.
+
** Raise requests don't change frame focus if rudeness doesn't allow it
If a window in another frame requests to be raised, a message pops up
just like everywhere else. The old behavior was to jump focus to the
diff --git a/src/actions.c b/src/actions.c
index e60701c..3f10ffe 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -46,6 +46,7 @@ static user_command user_commands[] =
{"focusdown", cmd_focusdown, arg_VOID},
{"focusleft", cmd_focusleft, arg_VOID},
{"focusright", cmd_focusright, arg_VOID},
+ {"focuslast", cmd_focuslast, arg_VOID},
{"meta", cmd_meta, arg_STRING},
{"help", cmd_help, arg_VOID},
{"hsplit", cmd_h_split, arg_VOID},
@@ -208,7 +209,7 @@ initialize_default_keybindings (void)
add_keybinding (prefix_key.sym, prefix_key.state, "other");
add_keybinding (prefix_key.sym, 0, "meta");
- add_keybinding (XK_g, ControlMask, "abort");
+ add_keybinding (XK_g, RP_CONTROL_MASK, "abort");
add_keybinding (XK_0, 0, "select 0");
add_keybinding (XK_1, 0, "select 1");
add_keybinding (XK_2, 0, "select 2");
@@ -221,49 +222,50 @@ initialize_default_keybindings (void)
add_keybinding (XK_9, 0, "select 9");
add_keybinding (XK_minus, 0, "select -");
add_keybinding (XK_A, 0, "title");
- add_keybinding (XK_A, ControlMask, "title");
+ add_keybinding (XK_A, RP_CONTROL_MASK, "title");
add_keybinding (XK_K, 0, "kill");
- add_keybinding (XK_K, ControlMask, "kill");
+ add_keybinding (XK_K, RP_CONTROL_MASK, "kill");
add_keybinding (XK_Return, 0, "next");
- add_keybinding (XK_Return, ControlMask, "next");
+ add_keybinding (XK_Return, RP_CONTROL_MASK, "next");
add_keybinding (XK_a, 0, "time");
- add_keybinding (XK_a, ControlMask, "time");
+ add_keybinding (XK_a, RP_CONTROL_MASK, "time");
add_keybinding (XK_b, 0, "banish");
- add_keybinding (XK_b, ControlMask, "banish");
+ add_keybinding (XK_b, RP_CONTROL_MASK, "banish");
add_keybinding (XK_c, 0, "exec " TERM_PROG);
- add_keybinding (XK_c, ControlMask, "exec " TERM_PROG);
+ add_keybinding (XK_c, RP_CONTROL_MASK, "exec " TERM_PROG);
add_keybinding (XK_colon, 0, "colon");
add_keybinding (XK_exclam, 0, "exec");
- add_keybinding (XK_exclam, ControlMask, "colon exec " TERM_PROG " -e ");
+ add_keybinding (XK_exclam, RP_CONTROL_MASK, "colon exec " TERM_PROG " -e ");
add_keybinding (XK_i, 0, "info");
- add_keybinding (XK_i, ControlMask, "info");
+ add_keybinding (XK_i, RP_CONTROL_MASK, "info");
add_keybinding (XK_k, 0, "delete");
- add_keybinding (XK_k, ControlMask, "delete");
+ add_keybinding (XK_k, RP_CONTROL_MASK, "delete");
add_keybinding (XK_l, 0, "redisplay");
- add_keybinding (XK_l, ControlMask, "redisplay");
+ add_keybinding (XK_l, RP_CONTROL_MASK, "redisplay");
add_keybinding (XK_m, 0, "lastmsg");
- add_keybinding (XK_m, ControlMask, "lastmsg");
+ add_keybinding (XK_m, RP_CONTROL_MASK, "lastmsg");
add_keybinding (XK_n, 0, "next");
- add_keybinding (XK_n, ControlMask, "next");
+ add_keybinding (XK_n, RP_CONTROL_MASK, "next");
add_keybinding (XK_p, 0, "prev");
- add_keybinding (XK_p, ControlMask, "prev");
+ add_keybinding (XK_p, RP_CONTROL_MASK, "prev");
add_keybinding (XK_quoteright, 0, "select");
- add_keybinding (XK_quoteright, ControlMask, "select");
+ add_keybinding (XK_quoteright, RP_CONTROL_MASK, "select");
add_keybinding (XK_space, 0, "next");
- add_keybinding (XK_space, ControlMask, "next");
+ add_keybinding (XK_space, RP_CONTROL_MASK, "next");
add_keybinding (XK_v, 0, "version");
- add_keybinding (XK_v, ControlMask, "version");
+ add_keybinding (XK_v, RP_CONTROL_MASK, "version");
add_keybinding (XK_w, 0, "windows");
- add_keybinding (XK_w, ControlMask, "windows");
+ add_keybinding (XK_w, RP_CONTROL_MASK, "windows");
add_keybinding (XK_s, 0, "split");
- add_keybinding (XK_s, ControlMask, "split");
+ add_keybinding (XK_s, RP_CONTROL_MASK, "split");
add_keybinding (XK_S, 0, "vsplit");
- add_keybinding (XK_S, ControlMask, "vsplit");
+ add_keybinding (XK_S, RP_CONTROL_MASK, "vsplit");
add_keybinding (XK_Tab, 0, "focus");
+ add_keybinding (XK_Tab, RP_META_MASK, "focuslast");
add_keybinding (XK_Q, 0, "only");
add_keybinding (XK_R, 0, "remove");
add_keybinding (XK_f, 0, "curframe");
- add_keybinding (XK_f, ControlMask, "curframe");
+ add_keybinding (XK_f, RP_CONTROL_MASK, "curframe");
add_keybinding (XK_question, 0, "help");
}
@@ -328,23 +330,23 @@ parse_keydesc (char *keydesc)
has no hyper key. */
if (!strcmp (token, "C"))
{
- p->state |= ControlMask;
+ p->state |= RP_CONTROL_MASK;
}
- else if (!strcmp (token, "M") && rp_modifier_info.meta_mod_mask)
+ else if (!strcmp (token, "M"))
{
- p->state |= rp_modifier_info.meta_mod_mask;
+ p->state |= RP_META_MASK;
}
- else if (!strcmp (token, "A") && rp_modifier_info.alt_mod_mask)
+ else if (!strcmp (token, "A"))
{
- p->state |= rp_modifier_info.alt_mod_mask;
+ p->state |= RP_ALT_MASK;
}
- else if (!strcmp (token, "S") && rp_modifier_info.super_mod_mask)
+ else if (!strcmp (token, "S"))
{
- p->state |= rp_modifier_info.super_mod_mask;
+ p->state |= RP_SUPER_MASK;
}
- else if (!strcmp (token, "H") && rp_modifier_info.hyper_mod_mask)
+ else if (!strcmp (token, "H"))
{
- p->state |= rp_modifier_info.hyper_mod_mask;
+ p->state |= RP_HYPER_MASK;
}
else
{
@@ -509,7 +511,7 @@ cmd_meta (int interactive, void *data)
/* ev1.xkey.x_root == */
/* ev1.xkey.y_root == */
- ev1.xkey.state = prefix_key.state;
+ ev1.xkey.state = rp_mask_to_x11_mask (prefix_key.state);
ev1.xkey.keycode = XKeysymToKeycode (dpy, prefix_key.sym);
XSendEvent (dpy, current_window()->w, False, KeyPressMask, &ev1);
@@ -1923,3 +1925,16 @@ cmd_startup_message (int interactive, void *data)
return NULL;
}
+
+char *
+cmd_focuslast (int interactive, void *data)
+{
+ rp_window_frame *frame = find_last_frame();
+
+ if (frame)
+ set_active_frame (frame);
+ else
+ message (" focuslast: No other frame ");
+
+ return NULL;
+}
diff --git a/src/actions.h b/src/actions.h
index cdbd410..c675374 100644
--- a/src/actions.h
+++ b/src/actions.h
@@ -101,6 +101,7 @@ char * cmd_focusleft (int interactive, void *data);
char * cmd_focusright (int interactive, void *data);
char * cmd_restart (int interactive, void *data);
char * cmd_startup_message (int interactive, void *data);
+char * cmd_focuslast (int interactive, void *data);
/* void cmd_xterm (void *data); */
diff --git a/src/conf.h b/src/conf.h
index ca24ab3..d8eeed7 100644
--- a/src/conf.h
+++ b/src/conf.h
@@ -26,7 +26,7 @@
#include "actions.h"
#define KEY_PREFIX XK_t
-#define MODIFIER_PREFIX ControlMask
+#define MODIFIER_PREFIX RP_CONTROL_MASK
/* This is the abort key when typing input. */
#define INPUT_ABORT_KEY XK_g
diff --git a/src/events.c b/src/events.c
index 1421b2d..efdc860 100644
--- a/src/events.c
+++ b/src/events.c
@@ -412,7 +412,7 @@ handle_key (screen_info *s)
read_key (&keysym, &mod, NULL, 0);
- if ((key_action = find_keybinding (keysym, mod)))
+ if ((key_action = find_keybinding (keysym, x11_mask_to_rp_mask (mod))))
{
char *result;
XSetInputFocus (dpy, fwin, revert, CurrentTime);
@@ -427,7 +427,7 @@ handle_key (screen_info *s)
/* No key match, notify user. */
XSetInputFocus (dpy, fwin, revert, CurrentTime);
- keysym_name = keysym_to_string (keysym, mod);
+ keysym_name = keysym_to_string (keysym, x11_mask_to_rp_mask (mod));
marked_message_printf (0, 0, " %s unbound key ", keysym_name);
free (keysym_name);
}
@@ -454,7 +454,7 @@ key_press (XEvent *ev)
modifier = ev->xkey.state;
cook_keycode ( &ev->xkey, &ks, &modifier, NULL, 0, 1);
- if (ks == prefix_key.sym && (modifier == prefix_key.state))
+ if (ks == prefix_key.sym && (x11_mask_to_rp_mask (modifier) == prefix_key.state))
{
handle_key (s);
}
diff --git a/src/input.c b/src/input.c
index 811bfdd..cf8e833 100644
--- a/src/input.c
+++ b/src/input.c
@@ -28,6 +28,49 @@
#include "ratpoison.h"
+/* Convert an X11 modifier mask to the rp modifier mask equivalent, as
+ best it can (the X server may not have a hyper key defined, for
+ instance). */
+unsigned int
+x11_mask_to_rp_mask (unsigned int mask)
+{
+ unsigned int result = 0;
+
+ PRINT_DEBUG ("x11 mask = %x\n", mask);
+
+ result |= mask & ControlMask ? RP_CONTROL_MASK:0;
+ result |= mask & rp_modifier_info.meta_mod_mask ? RP_META_MASK:0;
+ result |= mask & rp_modifier_info.alt_mod_mask ? RP_ALT_MASK:0;
+ result |= mask & rp_modifier_info.hyper_mod_mask ? RP_HYPER_MASK:0;
+ result |= mask & rp_modifier_info.super_mod_mask ? RP_SUPER_MASK:0;
+
+ PRINT_DEBUG ("rp mask = %x\n", mask);
+
+ return result;
+}
+
+/* Convert an rp modifier mask to the x11 modifier mask equivalent, as
+ best it can (the X server may not have a hyper key defined, for
+ instance). */
+unsigned int
+rp_mask_to_x11_mask (unsigned int mask)
+{
+ unsigned int result = 0;
+
+ PRINT_DEBUG ("rp mask = %x\n", mask);
+
+ result |= mask & RP_CONTROL_MASK ? ControlMask:0;
+ result |= mask & RP_META_MASK ? rp_modifier_info.meta_mod_mask:0;
+ result |= mask & RP_ALT_MASK ? rp_modifier_info.alt_mod_mask:0;
+ result |= mask & RP_HYPER_MASK ? rp_modifier_info.hyper_mod_mask:0;
+ result |= mask & RP_SUPER_MASK ? rp_modifier_info.super_mod_mask:0;
+
+ PRINT_DEBUG ("x11 mask = %x\n", mask);
+
+ return result;
+}
+
+
/* Figure out what keysyms are attached to what modifiers */
void
update_modifier_map ()
@@ -125,6 +168,9 @@ grab_key (int keycode, unsigned int modifiers, Window grab_window)
unsigned int mod_list[8];
int i;
+ /* Convert to a modifier mask that X Windows will understand. */
+ modifiers = rp_mask_to_x11_mask (modifiers);
+
/* Create a list of all possible combinations of ignored
modifiers. Assumes there are only 3 ignored modifiers. */
mod_list[0] = 0;
@@ -154,11 +200,11 @@ keysym_to_string (KeySym keysym, unsigned int modifier)
name = sbuf_new (0);
- if (modifier & ControlMask) sbuf_concat (name, "C-");
- if (modifier & rp_modifier_info.meta_mod_mask) sbuf_concat (name, "M-");
- if (modifier & rp_modifier_info.alt_mod_mask) sbuf_concat (name, "A-");
- if (modifier & rp_modifier_info.hyper_mod_mask) sbuf_concat (name, "H-");
- if (modifier & rp_modifier_info.super_mod_mask) sbuf_concat (name, "S-");
+ if (modifier & RP_CONTROL_MASK) sbuf_concat (name, "C-");
+ if (modifier & RP_META_MASK) sbuf_concat (name, "M-");
+ if (modifier & RP_ALT_MASK) sbuf_concat (name, "A-");
+ if (modifier & RP_HYPER_MASK) sbuf_concat (name, "H-");
+ if (modifier & RP_SUPER_MASK) sbuf_concat (name, "S-");
sbuf_concat (name, XKeysymToString (keysym));
@@ -200,71 +246,6 @@ cook_keycode (XKeyEvent *ev, KeySym *keysym, unsigned int *mod, char *keysym_nam
return nbytes;
}
-/* void */
-/* cook_keycode (KeyCode keycode, KeySym *keysym, unsigned int *mod) */
-/* { */
-/* KeySym normal, shifted; */
-
-/* /\* FIXME: Although this should theoretically work, the mod that */
-/* mode_switch is on doesn't seem to get activated. Instead the */
-/* 2<<13 bit gets set! It doesn't seem to matter which mod I put */
-/* Mode_switch on. So if this doesn't work try uncommented the line */
-/* below and commented the current one. *\/ */
-
-/* /\* if (*mod & 8192) *\/ */
-/* if (*mod & rp_modifier_info.mode_switch_mask) */
-/* { */
-/* normal = XKeycodeToKeysym(dpy, keycode, 2); */
-/* if (normal == NoSymbol) normal = XKeycodeToKeysym(dpy, keycode, 0); */
-/* shifted = XKeycodeToKeysym(dpy, keycode, 3); */
-/* if (shifted == NoSymbol) shifted = XKeycodeToKeysym(dpy, keycode, 1); */
-
-/* /\* Remove the mode switch modifier since we have dealt with it. *\/ */
-/* *mod &= ~rp_modifier_info.mode_switch_mask; */
-/* } */
-/* else */
-/* { */
-/* normal = XKeycodeToKeysym(dpy, keycode, 0); */
-/* shifted = XKeycodeToKeysym(dpy, keycode, 1); */
-/* } */
-
-/* /\* FIXME: eew, this looks gross. *\/ */
-/* if (*mod & (ShiftMask | LockMask)) */
-/* { */
-/* /\* if the shifted code is not defined, then we use the normal */
-/* keysym and keep the shift mask *\/ */
-/* if (shifted == NoSymbol) */
-/* { */
-/* *keysym = normal; */
-/* } */
-/* /\* But if the shifted code is defined, we use it and remove the */
-/* shift mask *\/ */
-/* else if (*mod & ShiftMask) */
-/* { */
-/* *keysym = shifted; */
-/* *mod &= ~(ShiftMask | LockMask); */
-/* } */
-/* /\* If caps lock is on, use shifted for alpha keys *\/ */
-/* else if (normal >= XK_a */
-/* && normal <= XK_z */
-/* && *mod & LockMask) */
-/* { */
-/* *keysym = shifted; */
-/* } */
-/* else */
-/* { */
-/* *keysym = normal; */
-/* } */
-/* } */
-/* else */
-/* { */
-/* *keysym = normal; */
-/* } */
-
-/* PRINT_DEBUG ("cooked keysym: %ld '%c' mask: %d\n", */
-/* *keysym, (char)*keysym, *mod); */
-/* } */
-
int
read_key (KeySym *keysym, unsigned int *modifiers, char *keysym_name, int len)
{
diff --git a/src/input.h b/src/input.h
index 44f009d..65e4607 100644
--- a/src/input.h
+++ b/src/input.h
@@ -27,6 +27,8 @@ int cook_keycode (XKeyEvent *ev, KeySym *keysym, unsigned int *mod, char *keysym
char *get_input (char *prompt);
char *get_more_input (char *prompt, char *preinput);
int read_key (KeySym *keysym, unsigned int *modifiers, char *keysym_name, int len);
+unsigned int x11_mask_to_rp_mask (unsigned int mask);
+unsigned int rp_mask_to_x11_mask (unsigned int mask);
void update_modifier_map ();
void grab_key (int keycode, unsigned int modifiers, Window grab_window);
diff --git a/src/split.c b/src/split.c
index a27ec2b..2090b53 100644
--- a/src/split.c
+++ b/src/split.c
@@ -28,6 +28,15 @@
rp_window_frame *rp_window_frame_sentinel;
rp_window_frame *rp_current_frame;
+static void
+update_last_access (rp_window_frame *frame)
+{
+ static int counter = 0;
+
+ frame->last_access = counter;
+ counter++;
+}
+
rp_window *
set_frames_window (rp_window_frame *frame, rp_window *win)
{
@@ -82,6 +91,8 @@ create_initial_frame ()
{
rp_current_frame = xmalloc (sizeof (rp_window_frame));
+ update_last_access (rp_current_frame);
+
rp_window_frame_sentinel->next = rp_current_frame;
rp_window_frame_sentinel->prev = rp_current_frame;
rp_current_frame->next = rp_window_frame_sentinel;
@@ -103,6 +114,27 @@ init_frame_list ()
create_initial_frame();
}
+rp_window_frame *
+find_last_frame ()
+{
+ rp_window_frame *cur, *last = NULL;
+ int last_access = -1;
+
+ for (cur = rp_window_frame_sentinel->next;
+ cur != rp_window_frame_sentinel;
+ cur = cur->next)
+ {
+ if (cur != rp_current_frame
+ && cur->last_access > last_access)
+ {
+ last_access = cur->last_access;
+ last = cur;
+ }
+ }
+
+ return last;
+}
+
/* Return the frame that contains the window. */
rp_window_frame *
find_windows_frame (rp_window *win)
@@ -217,6 +249,10 @@ split_frame (rp_window_frame *frame, int way)
new_frame = xmalloc (sizeof (rp_window_frame));
+ /* It seems intuitive to make the last frame the newly created
+ frame. */
+ update_last_access (new_frame);
+
/* append the new frame to the list */
new_frame->prev = rp_window_frame_sentinel->prev;
rp_window_frame_sentinel->prev->next = new_frame;
@@ -541,6 +577,7 @@ set_active_frame (rp_window_frame *frame)
rp_window_frame *old = rp_current_frame;
give_window_focus (frame->win, rp_current_frame->win);
+ update_last_access (frame);
rp_current_frame = frame;
if (old != rp_current_frame && num_frames() > 1)
diff --git a/src/split.h b/src/split.h
index a2d8978..eb166ca 100644
--- a/src/split.h
+++ b/src/split.h
@@ -43,5 +43,6 @@ rp_window_frame *find_frame_right (rp_window_frame *frame);
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 ();
#endif