diff options
author | Olivier Fourdan <ofourdan@redhat.com> | 2020-03-31 14:38:08 +0200 |
---|---|---|
committer | Olivier Fourdan <ofourdan@redhat.com> | 2020-05-19 14:51:25 +0200 |
commit | 93f9138c9b42f6b0a6c5854cef7801428be6eba3 (patch) | |
tree | 8ab5d15f446ff1907d91c0bd2a8f37ecfaa19a9e | |
parent | 1ace77b923c308164d7e39495b5d8aa28a0d29fb (diff) | |
download | gtk+-93f9138c9b42f6b0a6c5854cef7801428be6eba3.tar.gz |
x11: update inhibit shortcuts on grab broken
On X11, shortcuts inhibition is emulated using a grab on the keyboard.
So if another widget ungrabs the keyboard behind our back (for example
when a popup window is dismissed) that effectively disables the effects
of the shortcut inhibition on the surface and we need to update the
shortcut inhibition status accordingly.
Check for "grab-broken" events on the surface and clear existing
shortcuts inhibition for the matching seat, so that the client can be
notified and may decide to re-enable shortcut inhibition if desired.
-rw-r--r-- | gdk/x11/gdksurface-x11.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/gdk/x11/gdksurface-x11.c b/gdk/x11/gdksurface-x11.c index 75a931f16c..30eb411d62 100644 --- a/gdk/x11/gdksurface-x11.c +++ b/gdk/x11/gdksurface-x11.c @@ -106,6 +106,8 @@ static void set_wm_name (GdkDisplay *display, const gchar *name); static void move_to_current_desktop (GdkSurface *surface); static void gdk_x11_toplevel_state_callback (GdkSurface *surface); +static gboolean gdk_x11_toplevel_event_callback (GdkSurface *surface, + GdkEvent *gdk_event); /* Return whether time1 is considered later than time2 as far as xserver * time is concerned. Accounts for wraparound. @@ -149,6 +151,9 @@ _gdk_x11_surface_get_toplevel (GdkSurface *surface) g_signal_connect (surface, "notify::state", G_CALLBACK (gdk_x11_toplevel_state_callback), NULL); + g_signal_connect (surface, "event", + G_CALLBACK (gdk_x11_toplevel_event_callback), + NULL); } return impl->toplevel; @@ -449,6 +454,9 @@ gdk_x11_surface_finalize (GObject *object) g_signal_handlers_disconnect_by_func (GDK_SURFACE (impl), gdk_x11_toplevel_state_callback, NULL); + g_signal_handlers_disconnect_by_func (GDK_SURFACE (impl), + gdk_x11_toplevel_event_callback, + NULL); _gdk_x11_surface_grab_check_destroy (GDK_SURFACE (impl)); @@ -5033,6 +5041,29 @@ gdk_x11_toplevel_state_callback (GdkSurface *surface) gdk_x11_toplevel_restore_system_shortcuts (GDK_TOPLEVEL (surface)); } +static gboolean +gdk_x11_toplevel_event_callback (GdkSurface *surface, + GdkEvent *gdk_event) +{ + GdkSeat *gdk_seat; + + if (!surface->shortcuts_inhibited) + return FALSE; + + if (gdk_event_get_event_type (gdk_event) != GDK_GRAB_BROKEN) + return FALSE; + + gdk_seat = gdk_surface_get_seat_from_event (surface, gdk_event); + if (gdk_seat != surface->current_shortcuts_inhibited_seat) + return FALSE; + + surface->current_shortcuts_inhibited_seat = NULL; + surface->shortcuts_inhibited = FALSE; + g_object_notify (G_OBJECT (surface), "shortcuts-inhibited"); + + return FALSE; +} + static void gdk_x11_toplevel_iface_init (GdkToplevelInterface *iface) { |