keybindings: fix per window keybindings

We must spoof events to clutter even if they are associated
with a MetaWindow, because keyboard events are always associated
with one (the focus window), and we must process keybindings
for window togheter with the global ones if they include Super,
because we're not going to see them again.
This commit is contained in:
Giovanni Campagna 2014-02-26 18:56:17 +01:00
parent 23b0f7be43
commit ed6821a819
2 changed files with 22 additions and 51 deletions

View File

@ -971,24 +971,22 @@ maybe_spoof_event_as_stage_event (MetaCompScreen *info,
event->xcookie.extension == display->xinput_opcode) event->xcookie.extension == display->xinput_opcode)
{ {
XIEvent *input_event = (XIEvent *) event->xcookie.data; XIEvent *input_event = (XIEvent *) event->xcookie.data;
XIDeviceEvent *device_event = ((XIDeviceEvent *) input_event);
switch (input_event->evtype) switch (input_event->evtype)
{ {
case XI_Motion: case XI_Motion:
case XI_ButtonPress: case XI_ButtonPress:
case XI_ButtonRelease: case XI_ButtonRelease:
case XI_KeyPress:
case XI_KeyRelease:
{
XIDeviceEvent *device_event = ((XIDeviceEvent *) input_event);
/* If this is a GTK+ widget, like a window menu, let GTK+ handle /* If this is a GTK+ widget, like a window menu, let GTK+ handle
* it as-is without mangling. */ * it as-is without mangling. */
if (meta_ui_window_is_widget (info->screen->ui, device_event->event)) if (meta_ui_window_is_widget (info->screen->ui, device_event->event))
break; break;
/* fall through */
case XI_KeyPress:
case XI_KeyRelease:
device_event->event = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)); device_event->event = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage));
}
break; break;
default: default:
break; break;
@ -1008,6 +1006,12 @@ meta_compositor_process_event (MetaCompositor *compositor,
XEvent *event, XEvent *event,
MetaWindow *window) MetaWindow *window)
{ {
MetaDisplay *display = compositor->display;
MetaScreen *screen = display->screens->data;
MetaCompScreen *info;
info = meta_screen_get_compositor_data (screen);
if (compositor->modal_plugin && is_grabbed_event (compositor->display, event)) if (compositor->modal_plugin && is_grabbed_event (compositor->display, event))
{ {
_meta_plugin_xevent_filter (compositor->modal_plugin, event); _meta_plugin_xevent_filter (compositor->modal_plugin, event);
@ -1017,43 +1021,12 @@ meta_compositor_process_event (MetaCompositor *compositor,
return TRUE; return TRUE;
} }
if (window) maybe_spoof_event_as_stage_event (info, event);
if (meta_plugin_manager_xevent_filter (info->plugin_mgr, event))
{ {
MetaCompScreen *info; DEBUG_TRACE ("meta_compositor_process_event (filtered,window==NULL)\n");
MetaScreen *screen; return TRUE;
screen = meta_window_get_screen (window);
info = meta_screen_get_compositor_data (screen);
if (meta_plugin_manager_xevent_filter (info->plugin_mgr, event))
{
DEBUG_TRACE ("meta_compositor_process_event (filtered,window==NULL)\n");
return TRUE;
}
}
else
{
GSList *l;
l = meta_display_get_screens (compositor->display);
while (l)
{
MetaScreen *screen = l->data;
MetaCompScreen *info;
info = meta_screen_get_compositor_data (screen);
maybe_spoof_event_as_stage_event (info, event);
if (meta_plugin_manager_xevent_filter (info->plugin_mgr, event))
{
DEBUG_TRACE ("meta_compositor_process_event (filtered,window==NULL)\n");
return TRUE;
}
l = l->next;
}
} }
if (!meta_is_wayland_compositor () && if (!meta_is_wayland_compositor () &&

View File

@ -1842,8 +1842,7 @@ process_event (MetaKeyBinding *bindings,
MetaDisplay *display, MetaDisplay *display,
MetaScreen *screen, MetaScreen *screen,
MetaWindow *window, MetaWindow *window,
ClutterKeyEvent *event, ClutterKeyEvent *event)
gboolean on_window)
{ {
int i; int i;
@ -1859,7 +1858,7 @@ process_event (MetaKeyBinding *bindings,
{ {
MetaKeyHandler *handler = bindings[i].handler; MetaKeyHandler *handler = bindings[i].handler;
if ((!on_window && handler->flags & META_KEY_BINDING_PER_WINDOW) || if ((!window && handler->flags & META_KEY_BINDING_PER_WINDOW) ||
(event->keyval != bindings[i].keysym) || (event->keyval != bindings[i].keysym) ||
(event->modifier_state != bindings[i].mask) || (event->modifier_state != bindings[i].mask) ||
meta_compositor_filter_keybinding (display->compositor, screen, &bindings[i])) meta_compositor_filter_keybinding (display->compositor, screen, &bindings[i]))
@ -1891,7 +1890,8 @@ process_event (MetaKeyBinding *bindings,
static gboolean static gboolean
process_overlay_key (MetaDisplay *display, process_overlay_key (MetaDisplay *display,
MetaScreen *screen, MetaScreen *screen,
ClutterKeyEvent *event) ClutterKeyEvent *event,
MetaWindow *window)
{ {
if (display->overlay_key_only_pressed) if (display->overlay_key_only_pressed)
{ {
@ -1913,8 +1913,7 @@ process_overlay_key (MetaDisplay *display,
*/ */
if (process_event (display->key_bindings, if (process_event (display->key_bindings,
display->n_key_bindings, display->n_key_bindings,
display, screen, NULL, event, display, screen, window, event))
FALSE))
{ {
/* As normally, after we've handled a global key /* As normally, after we've handled a global key
* binding, we unfreeze the keyboard but keep the grab * binding, we unfreeze the keyboard but keep the grab
@ -2056,7 +2055,7 @@ meta_display_process_key_event (MetaDisplay *display,
all_keys_grabbed = window ? window->all_keys_grabbed : screen->all_keys_grabbed; all_keys_grabbed = window ? window->all_keys_grabbed : screen->all_keys_grabbed;
if (!all_keys_grabbed) if (!all_keys_grabbed)
{ {
handled = process_overlay_key (display, screen, event); handled = process_overlay_key (display, screen, event, window);
if (handled) if (handled)
return TRUE; return TRUE;
@ -2150,8 +2149,7 @@ meta_display_process_key_event (MetaDisplay *display,
/* Do the normal keybindings */ /* Do the normal keybindings */
return process_event (display->key_bindings, return process_event (display->key_bindings,
display->n_key_bindings, display->n_key_bindings,
display, screen, window, event, display, screen, window, event);
!all_keys_grabbed && window);
} }
static gboolean static gboolean