diff --git a/data/org.gnome.mutter.wayland.gschema.xml.in b/data/org.gnome.mutter.wayland.gschema.xml.in
index 44334d664..e8ee1cca7 100644
--- a/data/org.gnome.mutter.wayland.gschema.xml.in
+++ b/data/org.gnome.mutter.wayland.gschema.xml.in
@@ -49,5 +49,9 @@
F12']]]>
Switch to VT 12
+
+ Escape']]]>
+ Re-enable shortcuts
+
diff --git a/src/core/keybindings.c b/src/core/keybindings.c
index 518416ce2..697239232 100644
--- a/src/core/keybindings.c
+++ b/src/core/keybindings.c
@@ -1716,6 +1716,16 @@ process_event (MetaDisplay *display,
(!window && binding->flags & META_KEY_BINDING_PER_WINDOW))
goto not_found;
+ if (display->focus_window &&
+ !(binding->handler->flags & META_KEY_BINDING_NON_MASKABLE))
+ {
+ ClutterInputDevice *source;
+
+ source = clutter_event_get_source_device ((ClutterEvent *) event);
+ if (meta_window_shortcuts_inhibited (display->focus_window, source))
+ goto not_found;
+ }
+
/* If the compositor filtered out the keybindings, that
* means they don't want the binding to trigger, so we do
* the same thing as if the binding didn't exist. */
@@ -3364,6 +3374,23 @@ handle_rotate_monitor (MetaDisplay *display,
meta_monitor_manager_rotate_monitor (monitor_manager);
}
+static void
+handle_restore_shortcuts (MetaDisplay *display,
+ MetaScreen *screen,
+ MetaWindow *window,
+ ClutterKeyEvent *event,
+ MetaKeyBinding *binding,
+ gpointer dummy)
+{
+ ClutterInputDevice *source;
+
+ source = clutter_event_get_source_device ((ClutterEvent *) event);
+
+ meta_topic (META_DEBUG_KEYBINDINGS, "Restoring normal keyboard shortcuts\n");
+
+ meta_window_force_restore_shortcuts (display->focus_window, source);
+}
+
/**
* meta_keybindings_set_custom_handler:
* @name: The name of the keybinding to set
@@ -3674,89 +3701,96 @@ init_builtin_key_bindings (MetaDisplay *display)
add_builtin_keybinding (display,
"switch-to-session-1",
mutter_wayland_keybindings,
- META_KEY_BINDING_NONE,
+ META_KEY_BINDING_NON_MASKABLE,
META_KEYBINDING_ACTION_NONE,
handle_switch_vt, 1);
add_builtin_keybinding (display,
"switch-to-session-2",
mutter_wayland_keybindings,
- META_KEY_BINDING_NONE,
+ META_KEY_BINDING_NON_MASKABLE,
META_KEYBINDING_ACTION_NONE,
handle_switch_vt, 2);
add_builtin_keybinding (display,
"switch-to-session-3",
mutter_wayland_keybindings,
- META_KEY_BINDING_NONE,
+ META_KEY_BINDING_NON_MASKABLE,
META_KEYBINDING_ACTION_NONE,
handle_switch_vt, 3);
add_builtin_keybinding (display,
"switch-to-session-4",
mutter_wayland_keybindings,
- META_KEY_BINDING_NONE,
+ META_KEY_BINDING_NON_MASKABLE,
META_KEYBINDING_ACTION_NONE,
handle_switch_vt, 4);
add_builtin_keybinding (display,
"switch-to-session-5",
mutter_wayland_keybindings,
- META_KEY_BINDING_NONE,
+ META_KEY_BINDING_NON_MASKABLE,
META_KEYBINDING_ACTION_NONE,
handle_switch_vt, 5);
add_builtin_keybinding (display,
"switch-to-session-6",
mutter_wayland_keybindings,
- META_KEY_BINDING_NONE,
+ META_KEY_BINDING_NON_MASKABLE,
META_KEYBINDING_ACTION_NONE,
handle_switch_vt, 6);
add_builtin_keybinding (display,
"switch-to-session-7",
mutter_wayland_keybindings,
- META_KEY_BINDING_NONE,
+ META_KEY_BINDING_NON_MASKABLE,
META_KEYBINDING_ACTION_NONE,
handle_switch_vt, 7);
add_builtin_keybinding (display,
"switch-to-session-8",
mutter_wayland_keybindings,
- META_KEY_BINDING_NONE,
+ META_KEY_BINDING_NON_MASKABLE,
META_KEYBINDING_ACTION_NONE,
handle_switch_vt, 8);
add_builtin_keybinding (display,
"switch-to-session-9",
mutter_wayland_keybindings,
- META_KEY_BINDING_NONE,
+ META_KEY_BINDING_NON_MASKABLE,
META_KEYBINDING_ACTION_NONE,
handle_switch_vt, 9);
add_builtin_keybinding (display,
"switch-to-session-10",
mutter_wayland_keybindings,
- META_KEY_BINDING_NONE,
+ META_KEY_BINDING_NON_MASKABLE,
META_KEYBINDING_ACTION_NONE,
handle_switch_vt, 10);
add_builtin_keybinding (display,
"switch-to-session-11",
mutter_wayland_keybindings,
- META_KEY_BINDING_NONE,
+ META_KEY_BINDING_NON_MASKABLE,
META_KEYBINDING_ACTION_NONE,
handle_switch_vt, 11);
add_builtin_keybinding (display,
"switch-to-session-12",
mutter_wayland_keybindings,
- META_KEY_BINDING_NONE,
+ META_KEY_BINDING_NON_MASKABLE,
META_KEYBINDING_ACTION_NONE,
handle_switch_vt, 12);
}
#endif /* HAVE_NATIVE_BACKEND */
+ add_builtin_keybinding (display,
+ "restore-shortcuts",
+ mutter_wayland_keybindings,
+ META_KEY_BINDING_NON_MASKABLE,
+ META_KEYBINDING_ACTION_NONE,
+ handle_restore_shortcuts, 0);
+
/************************ PER WINDOW BINDINGS ************************/
/* These take a window as an extra parameter; they have no effect
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 0b667fb8f..521682d0a 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -535,6 +535,10 @@ struct _MetaWindowClass
gboolean user_op);
void (*main_monitor_changed) (MetaWindow *window,
const MetaLogicalMonitor *old);
+ void (*force_restore_shortcuts) (MetaWindow *window,
+ ClutterInputDevice *source);
+ gboolean (*shortcuts_inhibited) (MetaWindow *window,
+ ClutterInputDevice *source);
};
/* These differ from window->has_foo_func in that they consider
@@ -763,4 +767,9 @@ MetaPlacementRule *meta_window_get_placement_rule (MetaWindow *window);
void meta_window_force_placement (MetaWindow *window);
+void meta_window_force_restore_shortcuts (MetaWindow *window,
+ ClutterInputDevice *source);
+
+gboolean meta_window_shortcuts_inhibited (MetaWindow *window,
+ ClutterInputDevice *source);
#endif
diff --git a/src/core/window.c b/src/core/window.c
index fa01e57c1..ec3083f80 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -8066,3 +8066,17 @@ meta_window_get_placement_rule (MetaWindow *window)
{
return window->placement_rule;
}
+
+void
+meta_window_force_restore_shortcuts (MetaWindow *window,
+ ClutterInputDevice *source)
+{
+ META_WINDOW_GET_CLASS (window)->force_restore_shortcuts (window, source);
+}
+
+gboolean
+meta_window_shortcuts_inhibited (MetaWindow *window,
+ ClutterInputDevice *source)
+{
+ return META_WINDOW_GET_CLASS (window)->shortcuts_inhibited (window, source);
+}
diff --git a/src/meta/prefs.h b/src/meta/prefs.h
index 4394f74d1..df3cf6c97 100644
--- a/src/meta/prefs.h
+++ b/src/meta/prefs.h
@@ -370,13 +370,15 @@ typedef enum _MetaKeyBindingAction
* @META_KEY_BINDING_PER_WINDOW: per-window
* @META_KEY_BINDING_BUILTIN: built-in
* @META_KEY_BINDING_IS_REVERSED: is reversed
+ * @META_KEY_BINDING_NON_MASKABLE: always active
*/
typedef enum
{
META_KEY_BINDING_NONE,
- META_KEY_BINDING_PER_WINDOW = 1 << 0,
- META_KEY_BINDING_BUILTIN = 1 << 1,
- META_KEY_BINDING_IS_REVERSED = 1 << 2,
+ META_KEY_BINDING_PER_WINDOW = 1 << 0,
+ META_KEY_BINDING_BUILTIN = 1 << 1,
+ META_KEY_BINDING_IS_REVERSED = 1 << 2,
+ META_KEY_BINDING_NON_MASKABLE = 1 << 3,
} MetaKeyBindingFlags;
/**
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index 3d02a7301..ddca18f8d 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -130,6 +130,8 @@ enum {
SURFACE_DESTROY,
SURFACE_UNMAPPED,
SURFACE_CONFIGURE,
+ SURFACE_SHORTCUTS_INHIBITED,
+ SURFACE_SHORTCUTS_RESTORED,
N_SURFACE_SIGNALS
};
@@ -1334,6 +1336,8 @@ wl_surface_destructor (struct wl_resource *resource)
if (surface->wl_subsurface)
wl_resource_destroy (surface->wl_subsurface);
+ g_hash_table_destroy (surface->shortcut_inhibited_seats);
+
g_object_unref (surface);
meta_wayland_compositor_repick (compositor);
@@ -1385,6 +1389,7 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor,
sync_drag_dest_funcs (surface);
surface->outputs_to_destroy_notify_id = g_hash_table_new (NULL, NULL);
+ surface->shortcut_inhibited_seats = g_hash_table_new (NULL, NULL);
return surface;
}
@@ -1881,6 +1886,22 @@ meta_wayland_surface_class_init (MetaWaylandSurfaceClass *klass)
0, NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+
+ surface_signals[SURFACE_SHORTCUTS_INHIBITED] =
+ g_signal_new ("shortcuts-inhibited",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ surface_signals[SURFACE_SHORTCUTS_RESTORED] =
+ g_signal_new ("shortcuts-restored",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
}
static void
@@ -2219,3 +2240,29 @@ meta_wayland_surface_calculate_input_region (MetaWaylandSurface *surface)
return region;
}
+
+void
+meta_wayland_surface_inhibit_shortcuts (MetaWaylandSurface *surface,
+ MetaWaylandSeat *seat)
+{
+ g_hash_table_add (surface->shortcut_inhibited_seats, seat);
+ g_signal_emit (surface, surface_signals[SURFACE_SHORTCUTS_INHIBITED], 0);
+}
+
+void
+meta_wayland_surface_restore_shortcuts (MetaWaylandSurface *surface,
+ MetaWaylandSeat *seat)
+{
+ g_signal_emit (surface, surface_signals[SURFACE_SHORTCUTS_RESTORED], 0);
+ g_hash_table_remove (surface->shortcut_inhibited_seats, seat);
+}
+
+gboolean
+meta_wayland_surface_is_shortcuts_inhibited (MetaWaylandSurface *surface,
+ MetaWaylandSeat *seat)
+{
+ if (surface->shortcut_inhibited_seats == NULL)
+ return FALSE;
+
+ return g_hash_table_contains (surface->shortcut_inhibited_seats, seat);
+}
diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h
index 09a1dbce2..e4eada963 100644
--- a/src/wayland/meta-wayland-surface.h
+++ b/src/wayland/meta-wayland-surface.h
@@ -240,6 +240,9 @@ struct _MetaWaylandSurface
gboolean pending_pos;
GSList *pending_placement_ops;
} sub;
+
+ /* table of seats for which shortcuts are inhibited */
+ GHashTable *shortcut_inhibited_seats;
};
void meta_wayland_shell_init (MetaWaylandCompositor *compositor);
@@ -326,4 +329,13 @@ gboolean meta_wayland_surface_begin_grab_op (MetaWaylandSurface *surf
void meta_wayland_surface_window_managed (MetaWaylandSurface *surface,
MetaWindow *window);
+void meta_wayland_surface_inhibit_shortcuts (MetaWaylandSurface *surface,
+ MetaWaylandSeat *seat);
+
+void meta_wayland_surface_restore_shortcuts (MetaWaylandSurface *surface,
+ MetaWaylandSeat *seat);
+
+gboolean meta_wayland_surface_is_shortcuts_inhibited (MetaWaylandSurface *surface,
+ MetaWaylandSeat *seat);
+
#endif
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
index b5ab1ecf6..d89cac540 100644
--- a/src/wayland/meta-wayland.c
+++ b/src/wayland/meta-wayland.c
@@ -404,3 +404,40 @@ meta_wayland_finalize (void)
meta_xwayland_stop (&compositor->xwayland_manager);
}
+
+void
+meta_wayland_compositor_restore_shortcuts (MetaWaylandCompositor *compositor,
+ ClutterInputDevice *source)
+{
+ MetaWaylandKeyboard *keyboard;
+
+ /* Clutter is not multi-seat aware yet, use the default seat instead */
+ keyboard = compositor->seat->keyboard;
+ if (!keyboard || !keyboard->focus_surface)
+ return;
+
+ if (!meta_wayland_surface_is_shortcuts_inhibited (keyboard->focus_surface,
+ compositor->seat))
+ return;
+
+ meta_wayland_surface_restore_shortcuts (keyboard->focus_surface,
+ compositor->seat);
+}
+
+gboolean
+meta_wayland_compositor_is_shortcuts_inhibited (MetaWaylandCompositor *compositor,
+ ClutterInputDevice *source)
+{
+ MetaWaylandKeyboard *keyboard;
+
+ if (clutter_input_device_get_device_type (source) != CLUTTER_KEYBOARD_DEVICE)
+ return FALSE;
+
+ /* Clutter is not multi-seat aware yet, use the default seat instead */
+ keyboard = compositor->seat->keyboard;
+ if (keyboard && keyboard->focus_surface != NULL)
+ return meta_wayland_surface_is_shortcuts_inhibited (keyboard->focus_surface,
+ compositor->seat);
+
+ return FALSE;
+}
diff --git a/src/wayland/meta-wayland.h b/src/wayland/meta-wayland.h
index af8b086f0..95e796ecd 100644
--- a/src/wayland/meta-wayland.h
+++ b/src/wayland/meta-wayland.h
@@ -58,5 +58,10 @@ void meta_wayland_compositor_destroy_frame_callbacks (MetaWay
const char *meta_wayland_get_wayland_display_name (MetaWaylandCompositor *compositor);
const char *meta_wayland_get_xwayland_display_name (MetaWaylandCompositor *compositor);
+void meta_wayland_compositor_restore_shortcuts (MetaWaylandCompositor *compositor,
+ ClutterInputDevice *source);
+gboolean meta_wayland_compositor_is_shortcuts_inhibited (MetaWaylandCompositor *compositor,
+ ClutterInputDevice *source);
+
#endif
diff --git a/src/wayland/meta-window-wayland.c b/src/wayland/meta-window-wayland.c
index efe299fe3..22da3901d 100644
--- a/src/wayland/meta-window-wayland.c
+++ b/src/wayland/meta-window-wayland.c
@@ -520,6 +520,24 @@ meta_window_wayland_init (MetaWindowWayland *wl_window)
G_CALLBACK (appears_focused_changed), NULL);
}
+static void
+meta_window_wayland_force_restore_shortcuts (MetaWindow *window,
+ ClutterInputDevice *source)
+{
+ MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
+
+ meta_wayland_compositor_restore_shortcuts (compositor, source);
+}
+
+static gboolean
+meta_window_wayland_shortcuts_inhibited (MetaWindow *window,
+ ClutterInputDevice *source)
+{
+ MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
+
+ return meta_wayland_compositor_is_shortcuts_inhibited (compositor, source);
+}
+
static void
meta_window_wayland_class_init (MetaWindowWaylandClass *klass)
{
@@ -537,6 +555,8 @@ meta_window_wayland_class_init (MetaWindowWaylandClass *klass)
window_class->update_main_monitor = meta_window_wayland_update_main_monitor;
window_class->main_monitor_changed = meta_window_wayland_main_monitor_changed;
window_class->get_client_pid = meta_window_wayland_get_client_pid;
+ window_class->force_restore_shortcuts = meta_window_wayland_force_restore_shortcuts;
+ window_class->shortcuts_inhibited = meta_window_wayland_shortcuts_inhibited;
}
MetaWindow *
diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c
index 07f09223e..ad5058b8a 100644
--- a/src/x11/window-x11.c
+++ b/src/x11/window-x11.c
@@ -1504,6 +1504,27 @@ meta_window_x11_get_client_pid (MetaWindow *window)
return pid;
}
+static void
+meta_window_x11_force_restore_shortcuts (MetaWindow *window,
+ ClutterInputDevice *source)
+{
+ /*
+ * Not needed on X11 because clients can use a keyboard grab
+ * to bypass the compositor shortcuts.
+ */
+}
+
+static gboolean
+meta_window_x11_shortcuts_inhibited (MetaWindow *window,
+ ClutterInputDevice *source)
+{
+ /*
+ * On X11, we don't use a shortcuts inhibitor, clients just grab
+ * the keyboard.
+ */
+ return FALSE;
+}
+
static void
meta_window_x11_class_init (MetaWindowX11Class *klass)
{
@@ -1525,6 +1546,8 @@ meta_window_x11_class_init (MetaWindowX11Class *klass)
window_class->update_main_monitor = meta_window_x11_update_main_monitor;
window_class->main_monitor_changed = meta_window_x11_main_monitor_changed;
window_class->get_client_pid = meta_window_x11_get_client_pid;
+ window_class->force_restore_shortcuts = meta_window_x11_force_restore_shortcuts;
+ window_class->shortcuts_inhibited = meta_window_x11_shortcuts_inhibited;
}
void