From 283649b8d784311bc94013c57dff71f48da9f766 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 5 Dec 2013 16:36:40 -0500 Subject: [PATCH] Support keybindings again, too --- src/compositor/compositor.c | 32 +++++++++++++++----------------- src/core/display.c | 10 ++++++++++ src/wayland/meta-wayland.c | 2 -- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index a7d69b480..eaefa3250 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -1003,18 +1003,13 @@ meta_compositor_window_shape_changed (MetaCompositor *compositor, * application toolkit. As such, it will ignore any events sent * to the a stage that isn't its X window. * - * When a user clicks on what she thinks is the wallpaper, she - * is actually clicking on the guard window, which is an entirely - * separate top-level override-redirect window in the hierarchy. - * We want to recieve events on this guard window so that users - * can right-click on the background actor. We do this by telling - * Clutter a little white lie, by transforming clicks on the guard - * window to become clicks on the stage window, allowing Clutter - * to process the event normally. + * When running as an X window manager, we need to respond to + * events from lots of windows. Trick Clutter into translating + * these events by pretending we got an event on the stage window. */ static void -maybe_spoof_guard_window_event_as_stage_event (MetaCompScreen *info, - XEvent *event) +maybe_spoof_event_as_stage_event (MetaCompScreen *info, + XEvent *event) { MetaDisplay *display = meta_screen_get_display (info->screen); @@ -1023,19 +1018,22 @@ maybe_spoof_guard_window_event_as_stage_event (MetaCompScreen *info, { XIEvent *input_event = (XIEvent *) event->xcookie.data; - /* Only care about pointer events for now. */ switch (input_event->evtype) { case XI_Motion: case XI_ButtonPress: case XI_ButtonRelease: + case XI_KeyPress: + case XI_KeyRelease: { XIDeviceEvent *device_event = ((XIDeviceEvent *) input_event); - if (device_event->event == info->screen->guard_window) - { - Window xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)); - device_event->event = xwin; - } + + /* If this is a GTK+ widget, like a window menu, let GTK+ handle + * it as-is without mangling. */ + if (meta_ui_window_is_widget (info->screen->ui, device_event->event)) + break; + + device_event->event = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)); } break; default: @@ -1092,7 +1090,7 @@ meta_compositor_process_event (MetaCompositor *compositor, info = meta_screen_get_compositor_data (screen); - maybe_spoof_guard_window_event_as_stage_event (info, event); + maybe_spoof_event_as_stage_event (info, event); if (meta_plugin_manager_xevent_filter (info->plugin_mgr, event)) { diff --git a/src/core/display.c b/src/core/display.c index f809caa19..2ae9a5daf 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1707,9 +1707,19 @@ update_focus_window (MetaDisplay *display, if (display->focus_window) { + ClutterActor *window_actor; + meta_topic (META_DEBUG_FOCUS, "* Focus --> %s with serial %lu\n", display->focus_window->desc, serial); meta_window_set_focused_internal (display->focus_window, TRUE); + + /* XXX -- this is sort of a layer violation, but because we + * rely on the compositor for event delivery anyway, I don't + * think it's too bad... */ + + window_actor = CLUTTER_ACTOR (display->focus_window->compositor_private); + if (window_actor) + clutter_actor_grab_key_focus (window_actor); } else meta_topic (META_DEBUG_FOCUS, "* Focus --> NULL with serial %lu\n", serial); diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index f67af7e60..a6b24368e 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -215,8 +215,6 @@ meta_wayland_compositor_set_input_focus (MetaWaylandCompositor *compositor, meta_wayland_keyboard_set_focus (&compositor->seat->keyboard, surface); meta_wayland_data_device_set_keyboard_focus (compositor->seat); - - clutter_stage_set_key_focus (CLUTTER_STAGE (compositor->stage), window_actor); } void