summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Thurman <tthurman@gnome.org>2007-12-09 22:56:12 +0000
committerThomas James Alexander Thurman <tthurman@src.gnome.org>2007-12-09 22:56:12 +0000
commit4564236abf0f80eca24046eec88554f4c343066c (patch)
tree40a33822e52d5312fc5c3b225e5014b732da1a0b
parente7758d64d892d40a1799fe920a20c2527e03106e (diff)
downloadmetacity-4564236abf0f80eca24046eec88554f4c343066c.tar.gz
Recur if the keypress ended a grab, so it can be processed in its own
2007-12-08 Thomas Thurman <tthurman@gnome.org> * src/keybindings.c (meta_display_process_key_event): Recur if the keypress ended a grab, so it can be processed in its own right. Closes #112560. svn path=/trunk/; revision=3464
-rw-r--r--ChangeLog6
-rw-r--r--src/keybindings.c17
2 files changed, 23 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 14cf1868..d3d4c9f9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2007-12-08 Thomas Thurman <tthurman@gnome.org>
+
+ * src/keybindings.c (meta_display_process_key_event): Recur if the
+ keypress ended a grab, so it can be processed in its own right.
+ Closes #112560.
+
2007-12-08 Martin Meyer <elreydetodo@gmail.com>
* src/theme-parser.c (parse_draw_op_element): Fix
diff --git a/src/keybindings.c b/src/keybindings.c
index cd04c4f1..6b39ac16 100644
--- a/src/keybindings.c
+++ b/src/keybindings.c
@@ -1644,6 +1644,17 @@ process_event (MetaKeyBinding *bindings,
"No handler found for this event in this binding table\n");
}
+/* Handle a key event. May be called recursively: some key events cause
+ * grabs to be ended and then need to be processed again in their own
+ * right. This cannot cause infinite recursion because we never call
+ * ourselves when there wasn't a grab, and we always clear the grab
+ * first; the invariant is enforced using an assertion. See #112560.
+ * FIXME: We need to prove there are no race conditions here.
+ * FIXME: Does it correctly handle alt-Tab being followed by another
+ * grabbing keypress without letting go of alt?
+ * FIXME: An iterative solution would probably be simpler to understand
+ * (and help us solve the other fixmes).
+ */
void
meta_display_process_key_event (MetaDisplay *display,
MetaWindow *window,
@@ -1791,6 +1802,12 @@ meta_display_process_key_event (MetaDisplay *display,
"Ending grab op %u on key event sym %s\n",
display->grab_op, XKeysymToString (keysym));
meta_display_end_grab_op (display, event->xkey.time);
+
+ g_assert (display->grab_op == META_GRAB_OP_NONE);
+
+ /* and go round again: #112560 */
+ meta_display_process_key_event (display, window, event);
+
}
}