mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 01:20:42 -05:00
keybindings: Fix ungrabbing of keys
XUngrabKey() doesn't work for XI2 grabs and XI2 doesn't provide API with similar functionality. As such, we have to refactor the code a bit to be able to call XIUngrabKeycode() for each key binding, then reload keybindings and finally grab the new ones. https://bugzilla.gnome.org/show_bug.cgi?id=697003
This commit is contained in:
parent
0e83b748d5
commit
2467439d94
@ -147,7 +147,8 @@ static gboolean process_workspace_switch_grab (MetaDisplay *display,
|
|||||||
XIDeviceEvent *event,
|
XIDeviceEvent *event,
|
||||||
KeySym keysym);
|
KeySym keysym);
|
||||||
|
|
||||||
static void regrab_key_bindings (MetaDisplay *display);
|
static void grab_key_bindings (MetaDisplay *display);
|
||||||
|
static void ungrab_key_bindings (MetaDisplay *display);
|
||||||
|
|
||||||
|
|
||||||
static GHashTable *key_handlers;
|
static GHashTable *key_handlers;
|
||||||
@ -702,7 +703,7 @@ rebuild_special_bindings (MetaDisplay *display)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
regrab_key_bindings (MetaDisplay *display)
|
ungrab_key_bindings (MetaDisplay *display)
|
||||||
{
|
{
|
||||||
GSList *tmp;
|
GSList *tmp;
|
||||||
GSList *windows;
|
GSList *windows;
|
||||||
@ -715,7 +716,6 @@ regrab_key_bindings (MetaDisplay *display)
|
|||||||
MetaScreen *screen = tmp->data;
|
MetaScreen *screen = tmp->data;
|
||||||
|
|
||||||
meta_screen_ungrab_keys (screen);
|
meta_screen_ungrab_keys (screen);
|
||||||
meta_screen_grab_keys (screen);
|
|
||||||
|
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
@ -727,6 +727,38 @@ regrab_key_bindings (MetaDisplay *display)
|
|||||||
MetaWindow *w = tmp->data;
|
MetaWindow *w = tmp->data;
|
||||||
|
|
||||||
meta_window_ungrab_keys (w);
|
meta_window_ungrab_keys (w);
|
||||||
|
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
meta_error_trap_pop (display);
|
||||||
|
|
||||||
|
g_slist_free (windows);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
grab_key_bindings (MetaDisplay *display)
|
||||||
|
{
|
||||||
|
GSList *tmp;
|
||||||
|
GSList *windows;
|
||||||
|
|
||||||
|
meta_error_trap_push (display); /* for efficiency push outer trap */
|
||||||
|
|
||||||
|
tmp = display->screens;
|
||||||
|
while (tmp != NULL)
|
||||||
|
{
|
||||||
|
MetaScreen *screen = tmp->data;
|
||||||
|
|
||||||
|
meta_screen_grab_keys (screen);
|
||||||
|
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
windows = meta_display_list_windows (display, META_LIST_DEFAULT);
|
||||||
|
tmp = windows;
|
||||||
|
while (tmp != NULL)
|
||||||
|
{
|
||||||
|
MetaWindow *w = tmp->data;
|
||||||
|
|
||||||
meta_window_grab_keys (w);
|
meta_window_grab_keys (w);
|
||||||
|
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
@ -967,6 +999,8 @@ meta_display_process_mapping_event (MetaDisplay *display,
|
|||||||
|
|
||||||
if (keymap_changed || modmap_changed)
|
if (keymap_changed || modmap_changed)
|
||||||
{
|
{
|
||||||
|
ungrab_key_bindings (display);
|
||||||
|
|
||||||
if (keymap_changed)
|
if (keymap_changed)
|
||||||
reload_keymap (display);
|
reload_keymap (display);
|
||||||
|
|
||||||
@ -980,7 +1014,7 @@ meta_display_process_mapping_event (MetaDisplay *display,
|
|||||||
|
|
||||||
reload_modifiers (display);
|
reload_modifiers (display);
|
||||||
|
|
||||||
regrab_key_bindings (display);
|
grab_key_bindings (display);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -995,11 +1029,12 @@ bindings_changed_callback (MetaPreference pref,
|
|||||||
switch (pref)
|
switch (pref)
|
||||||
{
|
{
|
||||||
case META_PREF_KEYBINDINGS:
|
case META_PREF_KEYBINDINGS:
|
||||||
|
ungrab_key_bindings (display);
|
||||||
rebuild_key_binding_table (display);
|
rebuild_key_binding_table (display);
|
||||||
rebuild_special_bindings (display);
|
rebuild_special_bindings (display);
|
||||||
reload_keycodes (display);
|
reload_keycodes (display);
|
||||||
reload_modifiers (display);
|
reload_modifiers (display);
|
||||||
regrab_key_bindings (display);
|
grab_key_bindings (display);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -1118,21 +1153,12 @@ meta_change_keygrab (MetaDisplay *display,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_grab_key (MetaDisplay *display,
|
change_binding_keygrabs (MetaKeyBinding *bindings,
|
||||||
Window xwindow,
|
|
||||||
int keysym,
|
|
||||||
unsigned int keycode,
|
|
||||||
int modmask)
|
|
||||||
{
|
|
||||||
meta_change_keygrab (display, xwindow, TRUE, keysym, keycode, modmask);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
grab_keys (MetaKeyBinding *bindings,
|
|
||||||
int n_bindings,
|
int n_bindings,
|
||||||
MetaDisplay *display,
|
MetaDisplay *display,
|
||||||
Window xwindow,
|
Window xwindow,
|
||||||
gboolean binding_per_window)
|
gboolean binding_per_window,
|
||||||
|
gboolean grab)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -1147,7 +1173,7 @@ grab_keys (MetaKeyBinding *bindings,
|
|||||||
!!(bindings[i].handler->flags & META_KEY_BINDING_PER_WINDOW) &&
|
!!(bindings[i].handler->flags & META_KEY_BINDING_PER_WINDOW) &&
|
||||||
bindings[i].keycode != 0)
|
bindings[i].keycode != 0)
|
||||||
{
|
{
|
||||||
meta_grab_key (display, xwindow,
|
meta_change_keygrab (display, xwindow, grab,
|
||||||
bindings[i].keysym,
|
bindings[i].keysym,
|
||||||
bindings[i].keycode,
|
bindings[i].keycode,
|
||||||
bindings[i].mask);
|
bindings[i].mask);
|
||||||
@ -1160,43 +1186,13 @@ grab_keys (MetaKeyBinding *bindings,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ungrab_all_keys (MetaDisplay *display,
|
meta_screen_change_keygrabs (MetaScreen *screen,
|
||||||
Window xwindow)
|
gboolean grab)
|
||||||
{
|
|
||||||
if (meta_is_debugging ())
|
|
||||||
meta_error_trap_push_with_return (display);
|
|
||||||
else
|
|
||||||
meta_error_trap_push (display);
|
|
||||||
|
|
||||||
XUngrabKey (display->xdisplay, AnyKey, AnyModifier,
|
|
||||||
xwindow);
|
|
||||||
|
|
||||||
if (meta_is_debugging ())
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
|
|
||||||
result = meta_error_trap_pop_with_return (display);
|
|
||||||
|
|
||||||
if (result != Success)
|
|
||||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
||||||
"Ungrabbing all keys on 0x%lx failed\n", xwindow);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
meta_error_trap_pop (display);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_screen_grab_keys (MetaScreen *screen)
|
|
||||||
{
|
{
|
||||||
MetaDisplay *display = screen->display;
|
MetaDisplay *display = screen->display;
|
||||||
if (screen->all_keys_grabbed)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (screen->keys_grabbed)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (display->overlay_key_combo.keycode != 0)
|
if (display->overlay_key_combo.keycode != 0)
|
||||||
meta_grab_key (display, screen->xroot,
|
meta_change_keygrab (display, screen->xroot, grab,
|
||||||
display->overlay_key_combo.keysym,
|
display->overlay_key_combo.keysym,
|
||||||
display->overlay_key_combo.keycode,
|
display->overlay_key_combo.keycode,
|
||||||
display->overlay_key_combo.modifiers);
|
display->overlay_key_combo.modifiers);
|
||||||
@ -1208,7 +1204,7 @@ meta_screen_grab_keys (MetaScreen *screen)
|
|||||||
{
|
{
|
||||||
if (iso_next_group_combos[i].keycode != 0)
|
if (iso_next_group_combos[i].keycode != 0)
|
||||||
{
|
{
|
||||||
meta_grab_key (display, screen->xroot,
|
meta_change_keygrab (display, screen->xroot, grab,
|
||||||
iso_next_group_combos[i].keysym,
|
iso_next_group_combos[i].keysym,
|
||||||
iso_next_group_combos[i].keycode,
|
iso_next_group_combos[i].keycode,
|
||||||
iso_next_group_combos[i].modifiers);
|
iso_next_group_combos[i].modifiers);
|
||||||
@ -1217,10 +1213,22 @@ meta_screen_grab_keys (MetaScreen *screen)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
grab_keys (screen->display->key_bindings,
|
change_binding_keygrabs (screen->display->key_bindings,
|
||||||
screen->display->n_key_bindings,
|
screen->display->n_key_bindings,
|
||||||
screen->display, screen->xroot,
|
screen->display, screen->xroot,
|
||||||
FALSE);
|
FALSE, grab);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_screen_grab_keys (MetaScreen *screen)
|
||||||
|
{
|
||||||
|
if (screen->all_keys_grabbed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (screen->keys_grabbed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
meta_screen_change_keygrabs (screen, TRUE);
|
||||||
|
|
||||||
screen->keys_grabbed = TRUE;
|
screen->keys_grabbed = TRUE;
|
||||||
}
|
}
|
||||||
@ -1228,11 +1236,23 @@ meta_screen_grab_keys (MetaScreen *screen)
|
|||||||
void
|
void
|
||||||
meta_screen_ungrab_keys (MetaScreen *screen)
|
meta_screen_ungrab_keys (MetaScreen *screen)
|
||||||
{
|
{
|
||||||
if (screen->keys_grabbed)
|
if (!screen->keys_grabbed)
|
||||||
{
|
return;
|
||||||
ungrab_all_keys (screen->display, screen->xroot);
|
|
||||||
|
meta_screen_change_keygrabs (screen, FALSE);
|
||||||
|
|
||||||
screen->keys_grabbed = FALSE;
|
screen->keys_grabbed = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_window_change_keygrabs (MetaWindow *window,
|
||||||
|
Window xwindow,
|
||||||
|
gboolean grab)
|
||||||
|
{
|
||||||
|
change_binding_keygrabs (window->display->key_bindings,
|
||||||
|
window->display->n_key_bindings,
|
||||||
|
window->display, xwindow,
|
||||||
|
TRUE, grab);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1245,7 +1265,7 @@ meta_window_grab_keys (MetaWindow *window)
|
|||||||
|| window->override_redirect)
|
|| window->override_redirect)
|
||||||
{
|
{
|
||||||
if (window->keys_grabbed)
|
if (window->keys_grabbed)
|
||||||
ungrab_all_keys (window->display, window->xwindow);
|
meta_window_change_keygrabs (window, window->xwindow, FALSE);
|
||||||
window->keys_grabbed = FALSE;
|
window->keys_grabbed = FALSE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1253,7 +1273,7 @@ meta_window_grab_keys (MetaWindow *window)
|
|||||||
if (window->keys_grabbed)
|
if (window->keys_grabbed)
|
||||||
{
|
{
|
||||||
if (window->frame && !window->grab_on_frame)
|
if (window->frame && !window->grab_on_frame)
|
||||||
ungrab_all_keys (window->display, window->xwindow);
|
meta_window_change_keygrabs (window, window->xwindow, FALSE);
|
||||||
else if (window->frame == NULL &&
|
else if (window->frame == NULL &&
|
||||||
window->grab_on_frame)
|
window->grab_on_frame)
|
||||||
; /* continue to regrab on client window */
|
; /* continue to regrab on client window */
|
||||||
@ -1261,9 +1281,7 @@ meta_window_grab_keys (MetaWindow *window)
|
|||||||
return; /* already all good */
|
return; /* already all good */
|
||||||
}
|
}
|
||||||
|
|
||||||
grab_keys (window->display->key_bindings,
|
meta_window_change_keygrabs (window,
|
||||||
window->display->n_key_bindings,
|
|
||||||
window->display,
|
|
||||||
window->frame ? window->frame->xwindow : window->xwindow,
|
window->frame ? window->frame->xwindow : window->xwindow,
|
||||||
TRUE);
|
TRUE);
|
||||||
|
|
||||||
@ -1278,11 +1296,9 @@ meta_window_ungrab_keys (MetaWindow *window)
|
|||||||
{
|
{
|
||||||
if (window->grab_on_frame &&
|
if (window->grab_on_frame &&
|
||||||
window->frame != NULL)
|
window->frame != NULL)
|
||||||
ungrab_all_keys (window->display,
|
meta_window_change_keygrabs (window, window->frame->xwindow, FALSE);
|
||||||
window->frame->xwindow);
|
|
||||||
else if (!window->grab_on_frame)
|
else if (!window->grab_on_frame)
|
||||||
ungrab_all_keys (window->display,
|
meta_window_change_keygrabs (window, window->xwindow, FALSE);
|
||||||
window->xwindow);
|
|
||||||
|
|
||||||
window->keys_grabbed = FALSE;
|
window->keys_grabbed = FALSE;
|
||||||
}
|
}
|
||||||
@ -1338,7 +1354,7 @@ meta_display_grab_accelerator (MetaDisplay *display,
|
|||||||
for (l = display->screens; l; l = l->next)
|
for (l = display->screens; l; l = l->next)
|
||||||
{
|
{
|
||||||
MetaScreen *screen = l->data;
|
MetaScreen *screen = l->data;
|
||||||
meta_grab_key (display, screen->xroot, keysym, keycode, mask);
|
meta_change_keygrab (display, screen->xroot, TRUE, keysym, keycode, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
grab = g_new0 (MetaKeyGrab, 1);
|
grab = g_new0 (MetaKeyGrab, 1);
|
||||||
|
Loading…
Reference in New Issue
Block a user