summaryrefslogtreecommitdiff
path: root/gdk/x11/gdksurface-x11.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdk/x11/gdksurface-x11.c')
-rw-r--r--gdk/x11/gdksurface-x11.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/gdk/x11/gdksurface-x11.c b/gdk/x11/gdksurface-x11.c
index d4348a4e18..3607629819 100644
--- a/gdk/x11/gdksurface-x11.c
+++ b/gdk/x11/gdksurface-x11.c
@@ -109,6 +109,7 @@ static void set_wm_name (GdkDisplay *display,
Window xwindow,
const gchar *name);
static void move_to_current_desktop (GdkSurface *surface);
+static void gdk_x11_toplevel_state_callback (GdkSurface *surface);
/* Return whether time1 is considered later than time2 as far as xserver
* time is concerned. Accounts for wraparound.
@@ -148,6 +149,9 @@ _gdk_x11_surface_get_toplevel (GdkSurface *surface)
{
impl->toplevel = g_new0 (GdkToplevelX11, 1);
impl->toplevel->have_focused = FALSE;
+ g_signal_connect (surface, "notify::state",
+ G_CALLBACK (gdk_x11_toplevel_state_callback),
+ NULL);
}
return impl->toplevel;
@@ -445,6 +449,10 @@ gdk_x11_surface_finalize (GObject *object)
if (impl->toplevel->in_frame)
unhook_surface_changed (GDK_SURFACE (impl));
+ g_signal_handlers_disconnect_by_func (GDK_SURFACE (impl),
+ gdk_x11_toplevel_state_callback,
+ NULL);
+
_gdk_x11_surface_grab_check_destroy (GDK_SURFACE (impl));
if (!GDK_SURFACE_DESTROYED (impl))
@@ -4725,6 +4733,9 @@ gdk_x11_toplevel_set_property (GObject *object,
g_object_notify_by_pspec (G_OBJECT (surface), pspec);
break;
+ case LAST_PROP + GDK_TOPLEVEL_PROP_SHORTCUTS_INHIBITED:
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -4785,6 +4796,10 @@ gdk_x11_toplevel_get_property (GObject *object,
g_value_set_enum (value, surface->fullscreen_mode);
break;
+ case LAST_PROP + GDK_TOPLEVEL_PROP_SHORTCUTS_INHIBITED:
+ g_value_set_boolean (value, surface->shortcuts_inhibited);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -4909,6 +4924,63 @@ gdk_x11_toplevel_supports_edge_constraints (GdkToplevel *toplevel)
}
static void
+gdk_x11_toplevel_inhibit_system_shortcuts (GdkToplevel *toplevel,
+ GdkEvent *gdk_event)
+{
+ GdkSurface *surface = GDK_SURFACE (toplevel);
+ GdkSeat *gdk_seat;
+ GdkGrabStatus status;
+
+ if (surface->shortcuts_inhibited)
+ return; /* Already inhibited */
+
+ if (!(surface->state & GDK_SURFACE_STATE_FOCUSED))
+ return;
+
+ gdk_seat = gdk_surface_get_seat_from_event (surface, gdk_event);
+
+ if (!(gdk_seat_get_capabilities (gdk_seat) & GDK_SEAT_CAPABILITY_KEYBOARD))
+ return;
+
+ status = gdk_seat_grab (gdk_seat, surface, GDK_SEAT_CAPABILITY_KEYBOARD,
+ TRUE, NULL, gdk_event, NULL, NULL);
+
+ if (status != GDK_GRAB_SUCCESS)
+ return;
+
+ surface->shortcuts_inhibited = TRUE;
+ surface->current_shortcuts_inhibited_seat = gdk_seat;
+ g_object_notify (G_OBJECT (toplevel), "shortcuts-inhibited");
+}
+
+static void
+gdk_x11_toplevel_restore_system_shortcuts (GdkToplevel *toplevel)
+{
+ GdkSurface *surface = GDK_SURFACE (toplevel);
+ GdkSeat *gdk_seat;
+
+ if (!surface->shortcuts_inhibited)
+ return; /* Not inhibited */
+
+ gdk_seat = surface->current_shortcuts_inhibited_seat;
+ gdk_seat_ungrab (gdk_seat);
+ surface->current_shortcuts_inhibited_seat = NULL;
+
+ surface->shortcuts_inhibited = FALSE;
+ g_object_notify (G_OBJECT (toplevel), "shortcuts-inhibited");
+}
+
+static void
+gdk_x11_toplevel_state_callback (GdkSurface *surface)
+{
+ if (surface->state & GDK_SURFACE_STATE_FOCUSED)
+ return;
+
+ if (surface->shortcuts_inhibited)
+ gdk_x11_toplevel_restore_system_shortcuts (GDK_TOPLEVEL (surface));
+}
+
+static void
gdk_x11_toplevel_iface_init (GdkToplevelInterface *iface)
{
iface->present = gdk_x11_toplevel_present;
@@ -4917,6 +4989,8 @@ gdk_x11_toplevel_iface_init (GdkToplevelInterface *iface)
iface->focus = gdk_x11_toplevel_focus;
iface->show_window_menu = gdk_x11_toplevel_show_window_menu;
iface->supports_edge_constraints = gdk_x11_toplevel_supports_edge_constraints;
+ iface->inhibit_system_shortcuts = gdk_x11_toplevel_inhibit_system_shortcuts;
+ iface->restore_system_shortcuts = gdk_x11_toplevel_restore_system_shortcuts;
}
typedef struct {