Compare commits
	
		
			4 Commits
		
	
	
		
			3.13.90
			...
			wip/is-swi
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 2467439d94 | ||
|   | 0e83b748d5 | ||
|   | bda4af5504 | ||
|   | f97d8dfb6c | 
| @@ -458,6 +458,7 @@ void meta_display_overlay_key_activate (MetaDisplay *display); | ||||
| void meta_display_accelerator_activate (MetaDisplay *display, | ||||
|                                         guint        action, | ||||
|                                         guint        deviceid); | ||||
| void meta_display_modifiers_accelerator_activate (MetaDisplay *display); | ||||
|  | ||||
| /* In above-tab-keycode.c */ | ||||
| guint meta_display_get_above_tab_keycode (MetaDisplay *display); | ||||
|   | ||||
| @@ -139,6 +139,7 @@ enum | ||||
| { | ||||
|   OVERLAY_KEY, | ||||
|   ACCELERATOR_ACTIVATED, | ||||
|   MODIFIERS_ACCELERATOR_ACTIVATED, | ||||
|   FOCUS_WINDOW, | ||||
|   WINDOW_CREATED, | ||||
|   WINDOW_DEMANDS_ATTENTION, | ||||
| @@ -255,6 +256,14 @@ meta_display_class_init (MetaDisplayClass *klass) | ||||
|                   NULL, NULL, NULL, | ||||
|                   G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); | ||||
|  | ||||
|   display_signals[MODIFIERS_ACCELERATOR_ACTIVATED] = | ||||
|     g_signal_new ("modifiers-accelerator-activated", | ||||
|                   G_TYPE_FROM_CLASS (klass), | ||||
|                   G_SIGNAL_RUN_LAST, | ||||
|                   0, | ||||
|                   NULL, NULL, NULL, | ||||
|                   G_TYPE_NONE, 0); | ||||
|  | ||||
|   display_signals[WINDOW_CREATED] = | ||||
|     g_signal_new ("window-created", | ||||
|                   G_TYPE_FROM_CLASS (klass), | ||||
| @@ -5681,6 +5690,12 @@ meta_display_accelerator_activate (MetaDisplay *display, | ||||
|                  0, action, deviceid); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_display_modifiers_accelerator_activate (MetaDisplay *display) | ||||
| { | ||||
|   g_signal_emit (display, display_signals[MODIFIERS_ACCELERATOR_ACTIVATED], 0); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_display_get_compositor_version (MetaDisplay *display, | ||||
|                                      int         *major, | ||||
|   | ||||
| @@ -147,12 +147,17 @@ static gboolean process_workspace_switch_grab (MetaDisplay   *display, | ||||
|                                                XIDeviceEvent *event, | ||||
|                                                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 *external_grabs; | ||||
|  | ||||
| static char         *iso_next_group_option; | ||||
| static MetaKeyCombo *iso_next_group_combos; | ||||
| static int           n_iso_next_group_combos; | ||||
|  | ||||
| #define HANDLER(name) g_hash_table_lookup (key_handlers, (name)) | ||||
|  | ||||
| static void | ||||
| @@ -301,6 +306,168 @@ reload_modmap (MetaDisplay *display) | ||||
|               display->meta_mask); | ||||
| } | ||||
|  | ||||
| static int | ||||
| get_keycodes_for_keysym (MetaDisplay  *display, | ||||
|                          int           keysym, | ||||
|                          int         **keycodes) | ||||
| { | ||||
|   GArray *retval; | ||||
|   int n_keycodes; | ||||
|   int keycode; | ||||
|  | ||||
|   retval = g_array_new (FALSE, FALSE, sizeof (int)); | ||||
|  | ||||
|   keycode = display->min_keycode; | ||||
|   while (keycode <= display->max_keycode) | ||||
|     { | ||||
|       const KeySym *syms = display->keymap + (keycode - display->min_keycode) * display->keysyms_per_keycode; | ||||
|       int i = 0; | ||||
|  | ||||
|       while (i < display->keysyms_per_keycode) | ||||
|         { | ||||
|           if (syms[i] == (unsigned int)keysym) | ||||
|             g_array_append_val (retval, keycode); | ||||
|  | ||||
|           ++i; | ||||
|         } | ||||
|  | ||||
|       ++keycode; | ||||
|     } | ||||
|  | ||||
|   n_keycodes = retval->len; | ||||
|   *keycodes = (int*) g_array_free (retval, n_keycodes == 0 ? TRUE : FALSE); | ||||
|  | ||||
|   return n_keycodes; | ||||
| } | ||||
|  | ||||
| static void | ||||
| reload_iso_next_group_combos (MetaDisplay *display) | ||||
| { | ||||
|   MetaKeyCombo *combos; | ||||
|   int *keycodes; | ||||
|   int n_keycodes; | ||||
|   int n_combos; | ||||
|   int i; | ||||
|  | ||||
|   g_clear_pointer (&iso_next_group_combos, g_free); | ||||
|   n_iso_next_group_combos = 0; | ||||
|  | ||||
|   if (iso_next_group_option == NULL) | ||||
|     return; | ||||
|  | ||||
|   n_keycodes = get_keycodes_for_keysym (display, XK_ISO_Next_Group, &keycodes); | ||||
|  | ||||
|   if (g_str_equal (iso_next_group_option, "toggle") || | ||||
|       g_str_equal (iso_next_group_option, "lalt_toggle") || | ||||
|       g_str_equal (iso_next_group_option, "lwin_toggle") || | ||||
|       g_str_equal (iso_next_group_option, "rwin_toggle") || | ||||
|       g_str_equal (iso_next_group_option, "lshift_toggle") || | ||||
|       g_str_equal (iso_next_group_option, "rshift_toggle") || | ||||
|       g_str_equal (iso_next_group_option, "lctrl_toggle") || | ||||
|       g_str_equal (iso_next_group_option, "rctrl_toggle") || | ||||
|       g_str_equal (iso_next_group_option, "sclk_toggle") || | ||||
|       g_str_equal (iso_next_group_option, "menu_toggle") || | ||||
|       g_str_equal (iso_next_group_option, "caps_toggle")) | ||||
|     { | ||||
|       n_combos = n_keycodes; | ||||
|       combos = g_new (MetaKeyCombo, n_combos); | ||||
|  | ||||
|       for (i = 0; i < n_keycodes; ++i) | ||||
|         { | ||||
|           combos[i].keysym = XK_ISO_Next_Group; | ||||
|           combos[i].keycode = keycodes[i]; | ||||
|           combos[i].modifiers = 0; | ||||
|         } | ||||
|     } | ||||
|   else if (g_str_equal (iso_next_group_option, "shift_caps_toggle") || | ||||
|            g_str_equal (iso_next_group_option, "shifts_toggle")) | ||||
|     { | ||||
|       n_combos = n_keycodes; | ||||
|       combos = g_new (MetaKeyCombo, n_combos); | ||||
|  | ||||
|       for (i = 0; i < n_keycodes; ++i) | ||||
|         { | ||||
|           combos[i].keysym = XK_ISO_Next_Group; | ||||
|           combos[i].keycode = keycodes[i]; | ||||
|           combos[i].modifiers = ShiftMask; | ||||
|         } | ||||
|     } | ||||
|   else if (g_str_equal (iso_next_group_option, "alt_caps_toggle") || | ||||
|            g_str_equal (iso_next_group_option, "alt_space_toggle")) | ||||
|     { | ||||
|       n_combos = n_keycodes; | ||||
|       combos = g_new (MetaKeyCombo, n_combos); | ||||
|  | ||||
|       for (i = 0; i < n_keycodes; ++i) | ||||
|         { | ||||
|           combos[i].keysym = XK_ISO_Next_Group; | ||||
|           combos[i].keycode = keycodes[i]; | ||||
|           combos[i].modifiers = Mod1Mask; | ||||
|         } | ||||
|     } | ||||
|   else if (g_str_equal (iso_next_group_option, "ctrl_shift_toggle") || | ||||
|            g_str_equal (iso_next_group_option, "lctrl_lshift_toggle") || | ||||
|            g_str_equal (iso_next_group_option, "rctrl_rshift_toggle")) | ||||
|     { | ||||
|       n_combos = n_keycodes * 2; | ||||
|       combos = g_new (MetaKeyCombo, n_combos); | ||||
|  | ||||
|       for (i = 0; i < n_keycodes; ++i) | ||||
|         { | ||||
|           combos[i].keysym = XK_ISO_Next_Group; | ||||
|           combos[i].keycode = keycodes[i]; | ||||
|           combos[i].modifiers = ShiftMask; | ||||
|  | ||||
|           combos[i + n_keycodes].keysym = XK_ISO_Next_Group; | ||||
|           combos[i + n_keycodes].keycode = keycodes[i]; | ||||
|           combos[i + n_keycodes].modifiers = ControlMask; | ||||
|         } | ||||
|     } | ||||
|   else if (g_str_equal (iso_next_group_option, "ctrl_alt_toggle")) | ||||
|     { | ||||
|       n_combos = n_keycodes * 2; | ||||
|       combos = g_new (MetaKeyCombo, n_combos); | ||||
|  | ||||
|       for (i = 0; i < n_keycodes; ++i) | ||||
|         { | ||||
|           combos[i].keysym = XK_ISO_Next_Group; | ||||
|           combos[i].keycode = keycodes[i]; | ||||
|           combos[i].modifiers = Mod1Mask; | ||||
|  | ||||
|           combos[i + n_keycodes].keysym = XK_ISO_Next_Group; | ||||
|           combos[i + n_keycodes].keycode = keycodes[i]; | ||||
|           combos[i + n_keycodes].modifiers = ControlMask; | ||||
|         } | ||||
|     } | ||||
|   else if (g_str_equal (iso_next_group_option, "alt_shift_toggle") || | ||||
|            g_str_equal (iso_next_group_option, "lalt_lshift_toggle")) | ||||
|     { | ||||
|       n_combos = n_keycodes * 2; | ||||
|       combos = g_new (MetaKeyCombo, n_combos); | ||||
|  | ||||
|       for (i = 0; i < n_keycodes; ++i) | ||||
|         { | ||||
|           combos[i].keysym = XK_ISO_Next_Group; | ||||
|           combos[i].keycode = keycodes[i]; | ||||
|           combos[i].modifiers = Mod1Mask; | ||||
|  | ||||
|           combos[i + n_keycodes].keysym = XK_ISO_Next_Group; | ||||
|           combos[i + n_keycodes].keycode = keycodes[i]; | ||||
|           combos[i + n_keycodes].modifiers = ShiftMask; | ||||
|         } | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       n_combos = 0; | ||||
|       combos = NULL; | ||||
|     } | ||||
|  | ||||
|   g_free (keycodes); | ||||
|  | ||||
|   n_iso_next_group_combos = n_combos; | ||||
|   iso_next_group_combos = combos; | ||||
| } | ||||
|  | ||||
| static guint | ||||
| keysym_to_keycode (MetaDisplay *display, | ||||
|                    guint        keysym) | ||||
| @@ -327,6 +494,8 @@ reload_keycodes (MetaDisplay *display) | ||||
|       display->overlay_key_combo.keycode = 0; | ||||
|     } | ||||
|  | ||||
|   reload_iso_next_group_combos (display); | ||||
|  | ||||
|   if (display->key_bindings) | ||||
|     { | ||||
|       int i; | ||||
| @@ -528,10 +697,13 @@ rebuild_special_bindings (MetaDisplay *display) | ||||
|  | ||||
|   meta_prefs_get_overlay_binding (&combo); | ||||
|   display->overlay_key_combo = combo; | ||||
|  | ||||
|   g_free (iso_next_group_option); | ||||
|   iso_next_group_option = meta_prefs_get_iso_next_group_option (); | ||||
| } | ||||
|  | ||||
| static void | ||||
| regrab_key_bindings (MetaDisplay *display) | ||||
| ungrab_key_bindings (MetaDisplay *display) | ||||
| { | ||||
|   GSList *tmp; | ||||
|   GSList *windows; | ||||
| @@ -544,7 +716,6 @@ regrab_key_bindings (MetaDisplay *display) | ||||
|       MetaScreen *screen = tmp->data; | ||||
|  | ||||
|       meta_screen_ungrab_keys (screen); | ||||
|       meta_screen_grab_keys (screen); | ||||
|  | ||||
|       tmp = tmp->next; | ||||
|     } | ||||
| @@ -556,6 +727,38 @@ regrab_key_bindings (MetaDisplay *display) | ||||
|       MetaWindow *w = tmp->data; | ||||
|  | ||||
|       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); | ||||
|  | ||||
|       tmp = tmp->next; | ||||
| @@ -796,6 +999,8 @@ meta_display_process_mapping_event (MetaDisplay *display, | ||||
|  | ||||
|   if (keymap_changed || modmap_changed) | ||||
|     { | ||||
|       ungrab_key_bindings (display); | ||||
|  | ||||
|       if (keymap_changed) | ||||
|         reload_keymap (display); | ||||
|  | ||||
| @@ -809,7 +1014,7 @@ meta_display_process_mapping_event (MetaDisplay *display, | ||||
|  | ||||
|       reload_modifiers (display); | ||||
|  | ||||
|       regrab_key_bindings (display); | ||||
|       grab_key_bindings (display); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -824,11 +1029,12 @@ bindings_changed_callback (MetaPreference pref, | ||||
|   switch (pref) | ||||
|     { | ||||
|     case META_PREF_KEYBINDINGS: | ||||
|       ungrab_key_bindings (display); | ||||
|       rebuild_key_binding_table (display); | ||||
|       rebuild_special_bindings (display); | ||||
|       reload_keycodes (display); | ||||
|       reload_modifiers (display); | ||||
|       regrab_key_bindings (display); | ||||
|       grab_key_bindings (display); | ||||
|       break; | ||||
|     default: | ||||
|       break; | ||||
| @@ -947,21 +1153,12 @@ meta_change_keygrab (MetaDisplay *display, | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_grab_key (MetaDisplay *display, | ||||
|                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, | ||||
|            MetaDisplay    *display, | ||||
|            Window          xwindow, | ||||
|            gboolean        binding_per_window) | ||||
| change_binding_keygrabs (MetaKeyBinding *bindings, | ||||
|                          int             n_bindings, | ||||
|                          MetaDisplay    *display, | ||||
|                          Window          xwindow, | ||||
|                          gboolean        binding_per_window, | ||||
|                          gboolean        grab) | ||||
| { | ||||
|   int i; | ||||
|  | ||||
| @@ -976,10 +1173,10 @@ grab_keys (MetaKeyBinding *bindings, | ||||
|           !!(bindings[i].handler->flags & META_KEY_BINDING_PER_WINDOW) && | ||||
|           bindings[i].keycode != 0) | ||||
|         { | ||||
|           meta_grab_key (display, xwindow, | ||||
|                          bindings[i].keysym, | ||||
|                          bindings[i].keycode, | ||||
|                          bindings[i].mask); | ||||
|           meta_change_keygrab (display, xwindow, grab, | ||||
|                                bindings[i].keysym, | ||||
|                                bindings[i].keycode, | ||||
|                                bindings[i].mask); | ||||
|         } | ||||
|  | ||||
|       ++i; | ||||
| @@ -989,51 +1186,49 @@ grab_keys (MetaKeyBinding *bindings, | ||||
| } | ||||
|  | ||||
| static void | ||||
| ungrab_all_keys (MetaDisplay *display, | ||||
|                  Window       xwindow) | ||||
| meta_screen_change_keygrabs (MetaScreen *screen, | ||||
|                              gboolean    grab) | ||||
| { | ||||
|   if (meta_is_debugging ()) | ||||
|     meta_error_trap_push_with_return (display); | ||||
|   else | ||||
|     meta_error_trap_push (display); | ||||
|   MetaDisplay *display = screen->display; | ||||
|  | ||||
|   XUngrabKey (display->xdisplay, AnyKey, AnyModifier, | ||||
|               xwindow); | ||||
|   if (display->overlay_key_combo.keycode != 0) | ||||
|     meta_change_keygrab (display, screen->xroot, grab, | ||||
|                          display->overlay_key_combo.keysym, | ||||
|                          display->overlay_key_combo.keycode, | ||||
|                          display->overlay_key_combo.modifiers); | ||||
|  | ||||
|   if (meta_is_debugging ()) | ||||
|   if (iso_next_group_combos) | ||||
|     { | ||||
|       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); | ||||
|       int i = 0; | ||||
|       while (i < n_iso_next_group_combos) | ||||
|         { | ||||
|           if (iso_next_group_combos[i].keycode != 0) | ||||
|             { | ||||
|               meta_change_keygrab (display, screen->xroot, grab, | ||||
|                                    iso_next_group_combos[i].keysym, | ||||
|                                    iso_next_group_combos[i].keycode, | ||||
|                                    iso_next_group_combos[i].modifiers); | ||||
|             } | ||||
|           ++i; | ||||
|         } | ||||
|     } | ||||
|   else | ||||
|     meta_error_trap_pop (display); | ||||
|  | ||||
|   change_binding_keygrabs (screen->display->key_bindings, | ||||
|                            screen->display->n_key_bindings, | ||||
|                            screen->display, screen->xroot, | ||||
|                            FALSE, grab); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_screen_grab_keys (MetaScreen *screen) | ||||
| { | ||||
|   MetaDisplay *display = screen->display; | ||||
|   if (screen->all_keys_grabbed) | ||||
|     return; | ||||
|  | ||||
|   if (screen->keys_grabbed) | ||||
|     return; | ||||
|  | ||||
|   if (display->overlay_key_combo.keycode != 0) | ||||
|     meta_grab_key (display, screen->xroot, | ||||
|                    display->overlay_key_combo.keysym, | ||||
|                    display->overlay_key_combo.keycode, | ||||
|                    display->overlay_key_combo.modifiers); | ||||
|  | ||||
|   grab_keys (screen->display->key_bindings, | ||||
|              screen->display->n_key_bindings, | ||||
|              screen->display, screen->xroot, | ||||
|              FALSE); | ||||
|   meta_screen_change_keygrabs (screen, TRUE); | ||||
|  | ||||
|   screen->keys_grabbed = TRUE; | ||||
| } | ||||
| @@ -1041,11 +1236,23 @@ meta_screen_grab_keys (MetaScreen *screen) | ||||
| void | ||||
| meta_screen_ungrab_keys (MetaScreen  *screen) | ||||
| { | ||||
|   if (screen->keys_grabbed) | ||||
|     { | ||||
|       ungrab_all_keys (screen->display, screen->xroot); | ||||
|       screen->keys_grabbed = FALSE; | ||||
|     } | ||||
|   if (!screen->keys_grabbed) | ||||
|     return; | ||||
|  | ||||
|   meta_screen_change_keygrabs (screen, 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 | ||||
| @@ -1058,7 +1265,7 @@ meta_window_grab_keys (MetaWindow  *window) | ||||
|       || window->override_redirect) | ||||
|     { | ||||
|       if (window->keys_grabbed) | ||||
|         ungrab_all_keys (window->display, window->xwindow); | ||||
|         meta_window_change_keygrabs (window, window->xwindow, FALSE); | ||||
|       window->keys_grabbed = FALSE; | ||||
|       return; | ||||
|     } | ||||
| @@ -1066,7 +1273,7 @@ meta_window_grab_keys (MetaWindow  *window) | ||||
|   if (window->keys_grabbed) | ||||
|     { | ||||
|       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 && | ||||
|                window->grab_on_frame) | ||||
|         ; /* continue to regrab on client window */ | ||||
| @@ -1074,11 +1281,9 @@ meta_window_grab_keys (MetaWindow  *window) | ||||
|         return; /* already all good */ | ||||
|     } | ||||
|  | ||||
|   grab_keys (window->display->key_bindings, | ||||
|              window->display->n_key_bindings, | ||||
|              window->display, | ||||
|              window->frame ? window->frame->xwindow : window->xwindow, | ||||
|              TRUE); | ||||
|   meta_window_change_keygrabs (window, | ||||
|                                window->frame ? window->frame->xwindow : window->xwindow, | ||||
|                                TRUE); | ||||
|  | ||||
|   window->keys_grabbed = TRUE; | ||||
|   window->grab_on_frame = window->frame != NULL; | ||||
| @@ -1091,11 +1296,9 @@ meta_window_ungrab_keys (MetaWindow  *window) | ||||
|     { | ||||
|       if (window->grab_on_frame && | ||||
|           window->frame != NULL) | ||||
|         ungrab_all_keys (window->display, | ||||
|                          window->frame->xwindow); | ||||
|         meta_window_change_keygrabs (window, window->frame->xwindow, FALSE); | ||||
|       else if (!window->grab_on_frame) | ||||
|         ungrab_all_keys (window->display, | ||||
|                          window->xwindow); | ||||
|         meta_window_change_keygrabs (window, window->xwindow, FALSE); | ||||
|  | ||||
|       window->keys_grabbed = FALSE; | ||||
|     } | ||||
| @@ -1151,7 +1354,7 @@ meta_display_grab_accelerator (MetaDisplay *display, | ||||
|   for (l = display->screens; l; l = l->next) | ||||
|     { | ||||
|       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); | ||||
| @@ -1248,7 +1451,8 @@ grab_status_to_string (int status) | ||||
| static gboolean | ||||
| grab_keyboard (MetaDisplay *display, | ||||
|                Window       xwindow, | ||||
|                guint32      timestamp) | ||||
|                guint32      timestamp, | ||||
|                int          grab_mode) | ||||
| { | ||||
|   int result; | ||||
|   int grab_status; | ||||
| @@ -1269,7 +1473,7 @@ grab_keyboard (MetaDisplay *display, | ||||
|                               xwindow, | ||||
|                               timestamp, | ||||
|                               None, | ||||
|                               XIGrabModeAsync, XIGrabModeAsync, | ||||
|                               grab_mode, grab_mode, | ||||
|                               True, /* owner_events */ | ||||
|                               &mask); | ||||
|  | ||||
| @@ -1323,7 +1527,7 @@ meta_screen_grab_all_keys (MetaScreen *screen, guint32 timestamp) | ||||
|  | ||||
|   meta_topic (META_DEBUG_KEYBINDINGS, | ||||
|               "Grabbing all keys on RootWindow\n"); | ||||
|   retval = grab_keyboard (screen->display, screen->xroot, timestamp); | ||||
|   retval = grab_keyboard (screen->display, screen->xroot, timestamp, XIGrabModeAsync); | ||||
|   if (retval) | ||||
|     { | ||||
|       screen->all_keys_grabbed = TRUE; | ||||
| @@ -1376,7 +1580,7 @@ meta_window_grab_all_keys (MetaWindow  *window, | ||||
|  | ||||
|   meta_topic (META_DEBUG_KEYBINDINGS, | ||||
|               "Grabbing all keys on window %s\n", window->desc); | ||||
|   retval = grab_keyboard (window->display, grabwindow, timestamp); | ||||
|   retval = grab_keyboard (window->display, grabwindow, timestamp, XIGrabModeAsync); | ||||
|   if (retval) | ||||
|     { | ||||
|       window->keys_grabbed = FALSE; | ||||
| @@ -1403,6 +1607,44 @@ meta_window_ungrab_all_keys (MetaWindow *window, guint32 timestamp) | ||||
|     } | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_display_grab_keyboard (MetaDisplay *display, guint32 timestamp) | ||||
| { | ||||
|   grab_keyboard (display, DefaultRootWindow (display->xdisplay), timestamp, XIGrabModeSync); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_display_ungrab_keyboard (MetaDisplay *display, guint32 timestamp) | ||||
| { | ||||
|   ungrab_keyboard (display, timestamp); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_display_freeze_keyboard (MetaDisplay *display, guint32 timestamp) | ||||
| { | ||||
|   meta_error_trap_push (display); | ||||
|  | ||||
|   meta_topic (META_DEBUG_KEYBINDINGS, | ||||
|               "Freezing keyboard with timestamp %u\n", | ||||
|               timestamp); | ||||
|   XIAllowEvents (display->xdisplay, META_VIRTUAL_CORE_KEYBOARD_ID, | ||||
|                  XISyncDevice, timestamp); | ||||
|   meta_error_trap_pop (display); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_display_unfreeze_keyboard (MetaDisplay *display, guint32 timestamp) | ||||
| { | ||||
|   meta_error_trap_push (display); | ||||
|  | ||||
|   meta_topic (META_DEBUG_KEYBINDINGS, | ||||
|               "Unfreezing keyboard with timestamp %u\n", | ||||
|               timestamp); | ||||
|   XIAllowEvents (display->xdisplay, META_VIRTUAL_CORE_KEYBOARD_ID, | ||||
|                  XIAsyncDevice, timestamp); | ||||
|   meta_error_trap_pop (display); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| is_modifier (MetaDisplay *display, | ||||
|              unsigned int keycode) | ||||
| @@ -1749,6 +1991,38 @@ process_overlay_key (MetaDisplay *display, | ||||
|     return FALSE; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| process_iso_next_group (MetaDisplay *display, | ||||
|                         MetaScreen *screen, | ||||
|                         XIDeviceEvent *event, | ||||
|                         KeySym keysym) | ||||
| { | ||||
|   gboolean activate; | ||||
|   unsigned int mods; | ||||
|   int i; | ||||
|  | ||||
|   if (event->evtype != XI_KeyPress) | ||||
|     return FALSE; | ||||
|  | ||||
|   activate = FALSE; | ||||
|   mods = (event->mods.effective & 0xff & ~(display->ignored_modifier_mask)); | ||||
|  | ||||
|   for (i = 0; i < n_iso_next_group_combos; ++i) | ||||
|     { | ||||
|       if (event->detail == (int)iso_next_group_combos[i].keycode && | ||||
|           mods == iso_next_group_combos[i].modifiers) | ||||
|         { | ||||
|           activate = TRUE; | ||||
|           break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   if (activate) | ||||
|       meta_display_modifiers_accelerator_activate (display); | ||||
|  | ||||
|   return activate; | ||||
| } | ||||
|  | ||||
| /* Handle a key event. May be called recursively: some key events cause | ||||
|  * grabs to be ended and then need to be processed again in their own | ||||
|  * right. This cannot cause infinite recursion because we never call | ||||
| @@ -1823,6 +2097,10 @@ meta_display_process_key_event (MetaDisplay   *display, | ||||
|       handled = process_overlay_key (display, screen, event, keysym); | ||||
|       if (handled) | ||||
|         return TRUE; | ||||
|  | ||||
|       handled = process_iso_next_group (display, screen, event, keysym); | ||||
|       if (handled) | ||||
|         return TRUE; | ||||
|     } | ||||
|  | ||||
|   XIAllowEvents (display->xdisplay, event->deviceid, | ||||
| @@ -4516,6 +4794,12 @@ meta_display_init_keys (MetaDisplay *display) | ||||
|  | ||||
|   g_hash_table_insert (key_handlers, g_strdup ("overlay-key"), handler); | ||||
|  | ||||
|   handler = g_new0 (MetaKeyHandler, 1); | ||||
|   handler->name = g_strdup ("iso-next-group"); | ||||
|   handler->flags = META_KEY_BINDING_BUILTIN; | ||||
|  | ||||
|   g_hash_table_insert (key_handlers, g_strdup ("iso-next-group"), handler); | ||||
|  | ||||
|   handler = g_new0 (MetaKeyHandler, 1); | ||||
|   handler->name = g_strdup ("external-grab"); | ||||
|   handler->func = handle_external_grab; | ||||
|   | ||||
							
								
								
									
										105
									
								
								src/core/prefs.c
									
									
									
									
									
								
							
							
						
						
									
										105
									
								
								src/core/prefs.c
									
									
									
									
									
								
							| @@ -55,6 +55,7 @@ | ||||
| #define KEY_GNOME_ANIMATIONS "enable-animations" | ||||
| #define KEY_GNOME_CURSOR_THEME "cursor-theme" | ||||
| #define KEY_GNOME_CURSOR_SIZE "cursor-size" | ||||
| #define KEY_XKB_OPTIONS "xkb-options" | ||||
|  | ||||
| #define KEY_OVERLAY_KEY "overlay-key" | ||||
| #define KEY_WORKSPACES_ONLY_ON_PRIMARY "workspaces-only-on-primary" | ||||
| @@ -65,6 +66,7 @@ | ||||
| #define SCHEMA_GENERAL         "org.gnome.desktop.wm.preferences" | ||||
| #define SCHEMA_MUTTER          "org.gnome.mutter" | ||||
| #define SCHEMA_INTERFACE       "org.gnome.desktop.interface" | ||||
| #define SCHEMA_INPUT_SOURCES   "org.gnome.desktop.input-sources" | ||||
|  | ||||
| #define SETTINGS(s) g_hash_table_lookup (settings_schemas, (s)) | ||||
|  | ||||
| @@ -115,6 +117,7 @@ static gboolean workspaces_only_on_primary = FALSE; | ||||
|  | ||||
| static gboolean no_tab_popup = FALSE; | ||||
|  | ||||
| static char *iso_next_group_option = NULL; | ||||
|  | ||||
| static void handle_preference_update_enum (GSettings *settings, | ||||
|                                            gchar     *key); | ||||
| @@ -140,6 +143,7 @@ static gboolean theme_name_handler (GVariant*, gpointer*, gpointer); | ||||
| static gboolean mouse_button_mods_handler (GVariant*, gpointer*, gpointer); | ||||
| static gboolean button_layout_handler (GVariant*, gpointer*, gpointer); | ||||
| static gboolean overlay_key_handler (GVariant*, gpointer*, gpointer); | ||||
| static gboolean iso_next_group_handler (GVariant*, gpointer*, gpointer); | ||||
|  | ||||
| static void     do_override               (char *key, char *schema); | ||||
|  | ||||
| @@ -433,6 +437,14 @@ static MetaStringPreference preferences_string[] = | ||||
|       overlay_key_handler, | ||||
|       NULL, | ||||
|     }, | ||||
|     { | ||||
|       { "xkb-options", | ||||
|         SCHEMA_INPUT_SOURCES, | ||||
|         META_PREF_KEYBINDINGS, | ||||
|       }, | ||||
|       iso_next_group_handler, | ||||
|       NULL, | ||||
|     }, | ||||
|     { { NULL, 0, 0 }, NULL }, | ||||
|   }; | ||||
|  | ||||
| @@ -857,6 +869,11 @@ meta_prefs_init (void) | ||||
|                     G_CALLBACK (settings_changed), NULL); | ||||
|   g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_INTERFACE), settings); | ||||
|  | ||||
|   settings = g_settings_new (SCHEMA_INPUT_SOURCES); | ||||
|   g_signal_connect (settings, "changed::" KEY_XKB_OPTIONS, | ||||
|                     G_CALLBACK (settings_changed), NULL); | ||||
|   g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_INPUT_SOURCES), settings); | ||||
|  | ||||
|  | ||||
|   for (tmp = overridden_keys; tmp; tmp = tmp->next) | ||||
|     { | ||||
| @@ -1035,7 +1052,8 @@ settings_changed (GSettings *settings, | ||||
|     handle_preference_update_bool (settings, key); | ||||
|   else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32)) | ||||
|     handle_preference_update_int (settings, key); | ||||
|   else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING)) | ||||
|   else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING) || | ||||
|            g_variant_type_equal (type, G_VARIANT_TYPE_STRING_ARRAY)) | ||||
|     { | ||||
|       cursor = preferences_enum; | ||||
|       found_enum = FALSE; | ||||
| @@ -1554,6 +1572,44 @@ overlay_key_handler (GVariant *value, | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| set_iso_next_group_option (const char *option) | ||||
| { | ||||
|   if (g_strcmp0 (option, iso_next_group_option) == 0) | ||||
|     return; | ||||
|  | ||||
|   g_free (iso_next_group_option); | ||||
|   iso_next_group_option = g_strdup (option); | ||||
|  | ||||
|   queue_changed (META_PREF_KEYBINDINGS); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| iso_next_group_handler (GVariant *value, | ||||
|                         gpointer *result, | ||||
|                         gpointer  data) | ||||
| { | ||||
|   const char **xkb_options, **p; | ||||
|  | ||||
|   *result = NULL; /* ignored */ | ||||
|   xkb_options = g_variant_get_strv (value, NULL); | ||||
|  | ||||
|   for (p = xkb_options; p && *p; ++p) | ||||
|     if (g_str_has_prefix (*p, "grp:")) | ||||
|       { | ||||
|         set_iso_next_group_option (*p + 4); | ||||
|         break; | ||||
|       } | ||||
|  | ||||
|   /* If we didn't find it, it still needs to be disabled. */ | ||||
|   if (p && *p == NULL) | ||||
|     set_iso_next_group_option (NULL); | ||||
|  | ||||
|   g_free (xkb_options); | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| const PangoFontDescription* | ||||
| meta_prefs_get_titlebar_font (void) | ||||
| { | ||||
| @@ -1757,10 +1813,11 @@ static gboolean | ||||
| update_binding (MetaKeyPref *binding, | ||||
|                 gchar      **strokes) | ||||
| { | ||||
|   GSList *old_bindings, *a, *b; | ||||
|   gboolean changed; | ||||
|   unsigned int keysym; | ||||
|   unsigned int keycode; | ||||
|   MetaVirtualModifier mods; | ||||
|   gboolean changed = FALSE; | ||||
|   MetaKeyCombo *combo; | ||||
|   int i; | ||||
|  | ||||
| @@ -1768,13 +1825,9 @@ update_binding (MetaKeyPref *binding, | ||||
|               "Binding \"%s\" has new GSettings value\n", | ||||
|               binding->name); | ||||
|  | ||||
|   /* Okay, so, we're about to provide a new list of key combos for this | ||||
|    * action. Delete any pre-existing list. | ||||
|    */ | ||||
|   g_slist_foreach (binding->bindings, (GFunc) g_free, NULL); | ||||
|   g_slist_free (binding->bindings); | ||||
|   old_bindings = binding->bindings; | ||||
|   binding->bindings = NULL; | ||||
|    | ||||
|  | ||||
|   for (i = 0; strokes && strokes[i]; i++) | ||||
|     { | ||||
|       keysym = 0; | ||||
| @@ -1809,8 +1862,6 @@ update_binding (MetaKeyPref *binding, | ||||
|            * Changing the key in response to a modification could lead to cyclic calls. */ | ||||
|           continue; | ||||
|         } | ||||
|    | ||||
|       changed = TRUE; | ||||
|  | ||||
|       combo = g_malloc0 (sizeof (MetaKeyCombo)); | ||||
|       combo->keysym = keysym; | ||||
| @@ -1825,6 +1876,34 @@ update_binding (MetaKeyPref *binding, | ||||
|  | ||||
|   binding->bindings = g_slist_reverse (binding->bindings); | ||||
|  | ||||
|   a = old_bindings; | ||||
|   b = binding->bindings; | ||||
|   while (TRUE) | ||||
|     { | ||||
|       if ((!a && b) || (a && !b)) | ||||
|         { | ||||
|           changed = TRUE; | ||||
|           break; | ||||
|         } | ||||
|       else if (!a && !b) | ||||
|         { | ||||
|           changed = FALSE; | ||||
|           break; | ||||
|         } | ||||
|       else if (memcmp (a->data, b->data, sizeof (MetaKeyCombo)) != 0) | ||||
|         { | ||||
|           changed = TRUE; | ||||
|           break; | ||||
|         } | ||||
|       else | ||||
|         { | ||||
|           a = a->next; | ||||
|           b = b->next; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   g_slist_free_full (old_bindings, g_free); | ||||
|  | ||||
|   return changed; | ||||
| } | ||||
|  | ||||
| @@ -2074,6 +2153,12 @@ meta_prefs_get_overlay_binding (MetaKeyCombo *combo) | ||||
|   *combo = overlay_key_combo; | ||||
| } | ||||
|  | ||||
| char * | ||||
| meta_prefs_get_iso_next_group_option (void) | ||||
| { | ||||
|   return g_strdup (iso_next_group_option); | ||||
| } | ||||
|  | ||||
| GDesktopTitlebarAction | ||||
| meta_prefs_get_action_double_click_titlebar (void) | ||||
| { | ||||
|   | ||||
| @@ -187,4 +187,12 @@ void meta_display_unmanage_screen (MetaDisplay *display, | ||||
|  | ||||
| void meta_display_clear_mouse_mode (MetaDisplay *display); | ||||
|  | ||||
| void meta_display_grab_keyboard (MetaDisplay *display, | ||||
|                                  guint32      timestamp); | ||||
| void meta_display_ungrab_keyboard (MetaDisplay *display, | ||||
|                                    guint32      timestamp); | ||||
| void meta_display_freeze_keyboard (MetaDisplay *display, | ||||
|                                    guint32      timestamp); | ||||
| void meta_display_unfreeze_keyboard (MetaDisplay *display, | ||||
|                                      guint32      timestamp); | ||||
| #endif | ||||
|   | ||||
| @@ -353,6 +353,7 @@ typedef enum _MetaKeyBindingAction | ||||
|   META_KEYBINDING_ACTION_MOVE_TO_SIDE_W, | ||||
|   META_KEYBINDING_ACTION_MOVE_TO_CENTER, | ||||
|   META_KEYBINDING_ACTION_OVERLAY_KEY, | ||||
|   META_KEYBINDING_ACTION_ISO_NEXT_GROUP, | ||||
|  | ||||
|   META_KEYBINDING_ACTION_LAST | ||||
| } MetaKeyBindingAction; | ||||
| @@ -442,6 +443,7 @@ void meta_prefs_get_window_binding (const char          *name, | ||||
|                                     MetaVirtualModifier *modifiers); | ||||
|  | ||||
| void meta_prefs_get_overlay_binding (MetaKeyCombo *combo); | ||||
| char *meta_prefs_get_iso_next_group_option (void); | ||||
|  | ||||
| gboolean           meta_prefs_get_visual_bell      (void); | ||||
| gboolean           meta_prefs_bell_is_audible      (void); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user