summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2011-04-19 12:38:22 -0400
committerKristian Høgsberg <krh@bitplanet.net>2011-04-20 14:20:02 -0400
commit025f7b8f8e941dad8953f9d45a916543c772e3ed (patch)
treeba834b1fb1e223c5ea4b7cd34f56d493334f7db5
parent94da7e1767ec553dc3b5630fc75f1946cc1c4ef1 (diff)
compositor-x11: Use the keymap_notify immediately following the focus_in event
The event handling gets a little trickier this way but we need the keymap sent immdiately after the focus_in event to determine which keys are pressed as the compositor receives keyboard focus.
-rw-r--r--compositor/compositor-x11.c52
1 files changed, 35 insertions, 17 deletions
diff --git a/compositor/compositor-x11.c b/compositor/compositor-x11.c
index fcf4fe1..cfd713d 100644
--- a/compositor/compositor-x11.c
+++ b/compositor/compositor-x11.c
@@ -410,7 +410,7 @@ x11_compositor_handle_event(int fd, uint32_t mask, void *data)
} else {
/* Deliver the held key release now
* and fall through and handle the new
- * key press below. */
+ * event below. */
notify_key(c->base.input_device,
key_release->time,
key_release->detail - 8, 0);
@@ -418,6 +418,39 @@ x11_compositor_handle_event(int fd, uint32_t mask, void *data)
prev = NULL;
break;
}
+
+ case XCB_FOCUS_IN:
+ /* FIXME: There's a bug somewhere in xcb (I
+ * think) where we don't get all the events in
+ * the input buffer when calling
+ * xcb_poll_for_event(). What happens is we
+ * alt-tab to the compositor window, and get
+ * the focus_in(mode=while_grabbed), but not
+ * the following focus_in(mode=ungrab) which
+ * is the one we care about. */
+
+ /* assert event is keymap_notify */
+ focus_in = (xcb_focus_in_event_t *) prev;
+ keymap_notify = (xcb_keymap_notify_event_t *) event;
+ c->keys.size = 0;
+ for (i = 0; i < ARRAY_LENGTH(keymap_notify->keys) * 8; i++) {
+ set = keymap_notify->keys[i >> 3] &
+ (1 << (i & 7));
+ if (set) {
+ k = wl_array_add(&c->keys, sizeof *k);
+ *k = i;
+ }
+ }
+
+ output = x11_compositor_find_output(c, focus_in->event);
+ notify_keyboard_focus(c->base.input_device,
+ get_time(),
+ &output->base, &c->keys);
+
+ free(prev);
+ prev = NULL;
+ break;
+
default:
/* No previous event held */
break;
@@ -496,10 +529,7 @@ x11_compositor_handle_event(int fd, uint32_t mask, void *data)
if (focus_in->mode == XCB_NOTIFY_MODE_WHILE_GRABBED)
break;
- output = x11_compositor_find_output(c, focus_in->event);
- notify_keyboard_focus(c->base.input_device,
- get_time(),
- &output->base, &c->keys);
+ prev = event;
break;
case XCB_FOCUS_OUT:
@@ -510,18 +540,6 @@ x11_compositor_handle_event(int fd, uint32_t mask, void *data)
get_time(), NULL, NULL);
break;
- case XCB_KEYMAP_NOTIFY:
- keymap_notify = (xcb_keymap_notify_event_t *) event;
- c->keys.size = 0;
- for (i = 0; i < ARRAY_LENGTH(keymap_notify->keys) * 8; i++) {
- set = keymap_notify->keys[i >> 3] &
- (1 << (i & 7));
- if (set) {
- k = wl_array_add(&c->keys, sizeof *k);
- *k = i;
- }
- }
- break;
default:
break;
}