Add compositor hook to process keybindings selectively

Currently keybindings are blocked while the compositor holds a grab; if
we want a keybinding to be available anyway, we use captured ClutterEvents
to determine the KeyBindingAction the event would have triggered and
run our own handlers (ugh).
Instead, provide a hook to allow the compositor to filter out keybindings
before processing them normally, regardless of whether the compositor
holds a grab or not.

https://bugzilla.gnome.org/show_bug.cgi?id=688202
This commit is contained in:
Florian Müllner 2012-08-10 02:27:18 +02:00
parent 90952ac5c8
commit 424fc5245a
7 changed files with 39 additions and 4 deletions

View File

@ -815,6 +815,19 @@ meta_compositor_process_event (MetaCompositor *compositor,
return FALSE;
}
gboolean
meta_compositor_filter_keybinding (MetaCompositor *compositor,
MetaScreen *screen,
MetaKeyBinding *binding)
{
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
if (info->plugin_mgr)
return meta_plugin_manager_filter_keybinding (info->plugin_mgr, binding);
return FALSE;
}
void
meta_compositor_show_window (MetaCompositor *compositor,
MetaWindow *window,

View File

@ -281,6 +281,19 @@ meta_plugin_manager_switch_workspace (MetaPluginManager *plugin_mgr,
return retval;
}
gboolean
meta_plugin_manager_filter_keybinding (MetaPluginManager *plugin_mgr,
MetaKeyBinding *binding)
{
MetaPlugin *plugin = plugin_mgr->plugin;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
if (klass->keybinding_filter)
return klass->keybinding_filter (plugin, binding);
return FALSE;
}
/*
* The public method that the compositor hooks into for desktop switching.
*

View File

@ -67,6 +67,9 @@ gboolean meta_plugin_manager_switch_workspace (MetaPluginManager *mgr,
gint to,
MetaMotionDirection direction);
gboolean meta_plugin_manager_filter_keybinding (MetaPluginManager *mgr,
MetaKeyBinding *binding);
gboolean meta_plugin_manager_xevent_filter (MetaPluginManager *mgr,
XEvent *xev);

View File

@ -1959,9 +1959,6 @@ event_callback (XEvent *event,
{
case KeyPress:
case KeyRelease:
if (display->grab_op == META_GRAB_OP_COMPOSITOR)
break;
/* For key events, it's important to enforce single-handling, or
* we can get into a confused state. So if a keybinding is
* handled (because it's one of our hot-keys, or because we are

View File

@ -29,6 +29,7 @@
#include <config.h>
#include "keybindings-private.h"
#include "workspace-private.h"
#include <meta/compositor.h>
#include <meta/errors.h>
#include "edge-resistance.h"
#include "ui.h"
@ -1412,7 +1413,8 @@ process_event (MetaKeyBinding *bindings,
event->type != KeyPress ||
bindings[i].keycode != event->xkey.keycode ||
((event->xkey.state & 0xff & ~(display->ignored_modifier_mask)) !=
bindings[i].mask))
bindings[i].mask) ||
meta_compositor_filter_keybinding (display->compositor, screen, &bindings[i]))
continue;
/*

View File

@ -71,6 +71,10 @@ gboolean meta_compositor_process_event (MetaCompositor *compositor,
XEvent *event,
MetaWindow *window);
gboolean meta_compositor_filter_keybinding (MetaCompositor *compositor,
MetaScreen *screen,
MetaKeyBinding *binding);
/* At a high-level, a window is not-visible or visible. When a
* window is added (with add_window()) it is not visible.
* show_window() indicates a transition from not-visible to

View File

@ -105,6 +105,9 @@ struct _MetaPluginClass
gboolean (*xevent_filter) (MetaPlugin *plugin,
XEvent *event);
gboolean (*keybinding_filter) (MetaPlugin *plugin,
MetaKeyBinding *binding);
const MetaPluginInfo * (*plugin_info) (MetaPlugin *plugin);
};