windowManager: Implement keybinding_filter hook
We are currently using a hack to allow a select set of keybindings in the overview. Implement the new MetaPlugin keybinding_filter hook, which provides a cleaner way to achieve the same. https://bugzilla.gnome.org/show_bug.cgi?id=688202
This commit is contained in:
parent
490206b5b2
commit
034408971d
@ -167,8 +167,6 @@ function start() {
|
|||||||
|
|
||||||
_startDate = new Date();
|
_startDate = new Date();
|
||||||
|
|
||||||
global.stage.connect('captured-event', _globalKeyPressHandler);
|
|
||||||
|
|
||||||
log('GNOME Shell started at ' + _startDate);
|
log('GNOME Shell started at ' + _startDate);
|
||||||
|
|
||||||
let perfModuleName = GLib.getenv("SHELL_PERF_MODULE");
|
let perfModuleName = GLib.getenv("SHELL_PERF_MODULE");
|
||||||
@ -465,86 +463,6 @@ function getWindowActorsForWorkspace(workspaceIndex) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function encapsulates hacks to make certain global keybindings
|
|
||||||
// work even when we are in one of our modes where global keybindings
|
|
||||||
// are disabled with a global grab. (When there is a global grab, then
|
|
||||||
// all key events will be delivered to the stage, so ::captured-event
|
|
||||||
// on the stage can be used for global keybindings.)
|
|
||||||
function _globalKeyPressHandler(actor, event) {
|
|
||||||
if (modalCount == 0)
|
|
||||||
return false;
|
|
||||||
if (event.type() != Clutter.EventType.KEY_PRESS && event.type() != Clutter.EventType.KEY_RELEASE)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!sessionMode.allowKeybindingsWhenModal) {
|
|
||||||
if (modalCount > (overview.visible ? 1 : 0))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let symbol = event.get_key_symbol();
|
|
||||||
let keyCode = event.get_key_code();
|
|
||||||
let ignoredModifiers = global.display.get_ignored_modifier_mask();
|
|
||||||
let modifierState = event.get_state() & ~ignoredModifiers;
|
|
||||||
|
|
||||||
// This relies on the fact that Clutter.ModifierType is the same as Gdk.ModifierType
|
|
||||||
let action = global.display.get_keybinding_action(keyCode, modifierState);
|
|
||||||
|
|
||||||
if (event.type() == Clutter.EventType.KEY_PRESS) {
|
|
||||||
if (action == Meta.KeyBindingAction.SWITCH_PANELS) {
|
|
||||||
ctrlAltTabManager.popup(modifierState & Clutter.ModifierType.SHIFT_MASK,
|
|
||||||
modifierState);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (action) {
|
|
||||||
// left/right would effectively act as synonyms for up/down if we enabled them;
|
|
||||||
// but that could be considered confusing; we also disable them in the main view.
|
|
||||||
//
|
|
||||||
// case Meta.KeyBindingAction.WORKSPACE_LEFT:
|
|
||||||
// if (!sessionMode.hasWorkspaces)
|
|
||||||
// return false;
|
|
||||||
//
|
|
||||||
// wm.actionMoveWorkspaceLeft();
|
|
||||||
// return true;
|
|
||||||
// case Meta.KeyBindingAction.WORKSPACE_RIGHT:
|
|
||||||
// if (!sessionMode.hasWorkspaces)
|
|
||||||
// return false;
|
|
||||||
//
|
|
||||||
// wm.actionMoveWorkspaceRight();
|
|
||||||
// return true;
|
|
||||||
case Meta.KeyBindingAction.WORKSPACE_UP:
|
|
||||||
if (!sessionMode.hasWorkspaces)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
wm.actionMoveWorkspace(Meta.MotionDirection.UP);
|
|
||||||
return true;
|
|
||||||
case Meta.KeyBindingAction.WORKSPACE_DOWN:
|
|
||||||
if (!sessionMode.hasWorkspaces)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
wm.actionMoveWorkspace(Meta.MotionDirection.DOWN);
|
|
||||||
return true;
|
|
||||||
case Meta.KeyBindingAction.PANEL_RUN_DIALOG:
|
|
||||||
case Meta.KeyBindingAction.COMMAND_2:
|
|
||||||
if (!sessionMode.hasRunDialog)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
openRunDialog();
|
|
||||||
return true;
|
|
||||||
case Meta.KeyBindingAction.PANEL_MAIN_MENU:
|
|
||||||
overview.hide();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else if (event.type() == Clutter.EventType.KEY_RELEASE) {
|
|
||||||
if (action == Meta.KeyBindingAction.OVERLAY_KEY) {
|
|
||||||
overview.hide();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function _findModal(actor) {
|
function _findModal(actor) {
|
||||||
for (let i = 0; i < modalActorFocusStack.length; i++) {
|
for (let i = 0; i < modalActorFocusStack.length; i++) {
|
||||||
if (modalActorFocusStack[i].actor == actor)
|
if (modalActorFocusStack[i].actor == actor)
|
||||||
|
@ -99,6 +99,7 @@ const WindowManager = new Lang.Class({
|
|||||||
this._shellwm.connect('unmaximize', Lang.bind(this, this._unmaximizeWindow));
|
this._shellwm.connect('unmaximize', Lang.bind(this, this._unmaximizeWindow));
|
||||||
this._shellwm.connect('map', Lang.bind(this, this._mapWindow));
|
this._shellwm.connect('map', Lang.bind(this, this._mapWindow));
|
||||||
this._shellwm.connect('destroy', Lang.bind(this, this._destroyWindow));
|
this._shellwm.connect('destroy', Lang.bind(this, this._destroyWindow));
|
||||||
|
this._shellwm.connect('filter-keybinding', Lang.bind(this, this._filterKeybinding));
|
||||||
|
|
||||||
this._workspaceSwitcherPopup = null;
|
this._workspaceSwitcherPopup = null;
|
||||||
Meta.keybindings_set_custom_handler('switch-to-workspace-left',
|
Meta.keybindings_set_custom_handler('switch-to-workspace-left',
|
||||||
@ -424,6 +425,36 @@ const WindowManager = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_filterKeybinding: function(shellwm, binding) {
|
||||||
|
if (!Main.sessionMode.allowKeybindingsWhenModal) {
|
||||||
|
if (Main.modalCount > (Main.overview.visible ? 1 : 0))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
let action = Meta.prefs_get_keybinding_action(binding.get_name());
|
||||||
|
switch (action) {
|
||||||
|
// left/right would effectively act as synonyms for up/down if we enabled them;
|
||||||
|
// but that could be considered confusing; we also disable them in the main view.
|
||||||
|
//
|
||||||
|
// case Meta.KeyBindingAction.WORKSPACE_LEFT:
|
||||||
|
// case Meta.KeyBindingAction.WORKSPACE_RIGHT:
|
||||||
|
case Meta.KeyBindingAction.WORKSPACE_UP:
|
||||||
|
case Meta.KeyBindingAction.WORKSPACE_DOWN:
|
||||||
|
return !Main.sessionMode.hasWorkspaces;
|
||||||
|
|
||||||
|
case Meta.KeyBindingAction.PANEL_RUN_DIALOG:
|
||||||
|
case Meta.KeyBindingAction.COMMAND_2:
|
||||||
|
case Meta.KeyBindingAction.PANEL_MAIN_MENU:
|
||||||
|
case Meta.KeyBindingAction.OVERLAY_KEY:
|
||||||
|
case Meta.KeyBindingAction.SWITCH_PANELS:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Main.modalCount == 0 && binding.is_builtin())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
_switchWorkspace : function(shellwm, from, to, direction) {
|
_switchWorkspace : function(shellwm, from, to, direction) {
|
||||||
if (!this._shouldAnimate()) {
|
if (!this._shouldAnimate()) {
|
||||||
shellwm.completed_switch_workspace();
|
shellwm.completed_switch_workspace();
|
||||||
|
@ -72,6 +72,9 @@ static void gnome_shell_plugin_kill_switch_workspace (MetaPlugin *plugin);
|
|||||||
|
|
||||||
static gboolean gnome_shell_plugin_xevent_filter (MetaPlugin *plugin,
|
static gboolean gnome_shell_plugin_xevent_filter (MetaPlugin *plugin,
|
||||||
XEvent *event);
|
XEvent *event);
|
||||||
|
|
||||||
|
static gboolean gnome_shell_plugin_keybinding_filter (MetaPlugin *plugin,
|
||||||
|
MetaKeyBinding *binding);
|
||||||
static const MetaPluginInfo *gnome_shell_plugin_plugin_info (MetaPlugin *plugin);
|
static const MetaPluginInfo *gnome_shell_plugin_plugin_info (MetaPlugin *plugin);
|
||||||
|
|
||||||
|
|
||||||
@ -126,8 +129,9 @@ gnome_shell_plugin_class_init (GnomeShellPluginClass *klass)
|
|||||||
plugin_class->kill_window_effects = gnome_shell_plugin_kill_window_effects;
|
plugin_class->kill_window_effects = gnome_shell_plugin_kill_window_effects;
|
||||||
plugin_class->kill_switch_workspace = gnome_shell_plugin_kill_switch_workspace;
|
plugin_class->kill_switch_workspace = gnome_shell_plugin_kill_switch_workspace;
|
||||||
|
|
||||||
plugin_class->xevent_filter = gnome_shell_plugin_xevent_filter;
|
plugin_class->xevent_filter = gnome_shell_plugin_xevent_filter;
|
||||||
plugin_class->plugin_info = gnome_shell_plugin_plugin_info;
|
plugin_class->keybinding_filter = gnome_shell_plugin_keybinding_filter;
|
||||||
|
plugin_class->plugin_info = gnome_shell_plugin_plugin_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -337,6 +341,13 @@ gnome_shell_plugin_xevent_filter (MetaPlugin *plugin,
|
|||||||
return clutter_x11_handle_event (xev) != CLUTTER_X11_FILTER_CONTINUE;
|
return clutter_x11_handle_event (xev) != CLUTTER_X11_FILTER_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gnome_shell_plugin_keybinding_filter (MetaPlugin *plugin,
|
||||||
|
MetaKeyBinding *binding)
|
||||||
|
{
|
||||||
|
return _shell_wm_filter_keybinding (get_shell_wm (), binding);
|
||||||
|
}
|
||||||
|
|
||||||
static const
|
static const
|
||||||
MetaPluginInfo *gnome_shell_plugin_plugin_info (MetaPlugin *plugin)
|
MetaPluginInfo *gnome_shell_plugin_plugin_info (MetaPlugin *plugin)
|
||||||
{
|
{
|
||||||
|
@ -35,6 +35,9 @@ void _shell_wm_kill_window_effects (ShellWM *wm,
|
|||||||
MetaWindowActor *actor);
|
MetaWindowActor *actor);
|
||||||
void _shell_wm_kill_switch_workspace (ShellWM *wm);
|
void _shell_wm_kill_switch_workspace (ShellWM *wm);
|
||||||
|
|
||||||
|
gboolean _shell_wm_filter_keybinding (ShellWM *wm,
|
||||||
|
MetaKeyBinding *binding);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __SHELL_WM_PRIVATE_H__ */
|
#endif /* __SHELL_WM_PRIVATE_H__ */
|
||||||
|
@ -26,6 +26,7 @@ enum
|
|||||||
SWITCH_WORKSPACE,
|
SWITCH_WORKSPACE,
|
||||||
KILL_SWITCH_WORKSPACE,
|
KILL_SWITCH_WORKSPACE,
|
||||||
KILL_WINDOW_EFFECTS,
|
KILL_WINDOW_EFFECTS,
|
||||||
|
FILTER_KEYBINDING,
|
||||||
|
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
@ -115,6 +116,14 @@ shell_wm_class_init (ShellWMClass *klass)
|
|||||||
NULL, NULL, NULL,
|
NULL, NULL, NULL,
|
||||||
G_TYPE_NONE, 1,
|
G_TYPE_NONE, 1,
|
||||||
META_TYPE_WINDOW_ACTOR);
|
META_TYPE_WINDOW_ACTOR);
|
||||||
|
shell_wm_signals[FILTER_KEYBINDING] =
|
||||||
|
g_signal_new ("filter-keybinding",
|
||||||
|
G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
0,
|
||||||
|
g_signal_accumulator_true_handled, NULL, NULL,
|
||||||
|
G_TYPE_BOOLEAN, 1,
|
||||||
|
META_TYPE_KEY_BINDING);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -267,6 +276,17 @@ _shell_wm_destroy (ShellWM *wm,
|
|||||||
g_signal_emit (wm, shell_wm_signals[DESTROY], 0, actor);
|
g_signal_emit (wm, shell_wm_signals[DESTROY], 0, actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_shell_wm_filter_keybinding (ShellWM *wm,
|
||||||
|
MetaKeyBinding *binding)
|
||||||
|
{
|
||||||
|
gboolean rv;
|
||||||
|
|
||||||
|
g_signal_emit (wm, shell_wm_signals[FILTER_KEYBINDING], 0, binding, &rv);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* shell_wm_new:
|
* shell_wm_new:
|
||||||
* @plugin: the #MetaPlugin
|
* @plugin: the #MetaPlugin
|
||||||
|
Loading…
x
Reference in New Issue
Block a user