Merge branch 'win32-inhibit' into 'main'

gdk-win32: implement basic inhibit-system-shortcuts

See merge request GNOME/gtk!5206
This commit is contained in:
Luca Bacci 2022-11-10 11:18:23 +00:00
commit aebbf7cc61

View File

@ -60,6 +60,7 @@ static void compute_toplevel_size (GdkSurface *surface,
gboolean update_geometry,
int *width,
int *height);
static void gdk_win32_toplevel_state_callback (GdkSurface *surface);
static gpointer parent_class = NULL;
static GSList *modal_window_stack = NULL;
@ -211,6 +212,10 @@ gdk_surface_win32_finalize (GObject *object)
g_assert (surface->transient_owner == NULL);
g_assert (surface->transient_children == NULL);
g_signal_handlers_disconnect_by_func (GDK_SURFACE (object),
gdk_win32_toplevel_state_callback,
NULL);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@ -662,6 +667,13 @@ _gdk_win32_display_create_surface (GdkDisplay *display,
impl->hdc = GetDC (impl->handle);
impl->inhibit_configure = TRUE;
if (surface_type == GDK_SURFACE_TOPLEVEL)
{
g_signal_connect (surface, "notify::state",
G_CALLBACK (gdk_win32_toplevel_state_callback),
NULL);
}
return surface;
}
@ -3750,8 +3762,6 @@ gdk_win32_get_window_size_and_position_from_client_rect (GdkSurface *window,
SIZE *window_size,
POINT *window_position)
{
GdkWin32Surface *impl = GDK_WIN32_SURFACE (window);
/* Turn client area into window area */
_gdk_win32_adjust_client_rect (window, window_rect);
@ -4706,6 +4716,10 @@ gdk_win32_popup_get_property (GObject *object,
g_value_set_boolean (value, surface->autohide);
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;
@ -4732,6 +4746,9 @@ gdk_win32_popup_set_property (GObject *object,
surface->autohide = g_value_get_boolean (value);
break;
case LAST_PROP + GDK_TOPLEVEL_PROP_SHORTCUTS_INHIBITED:
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -5008,6 +5025,65 @@ gdk_win32_toplevel_supports_edge_constraints (GdkToplevel *toplevel)
return FALSE;
}
static void
gdk_win32_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_TOPLEVEL_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;
// TODO: install a WH_KEYBOARD_LL hook to take alt-tab/win etc.
surface->shortcuts_inhibited = TRUE;
surface->current_shortcuts_inhibited_seat = gdk_seat;
g_object_notify (G_OBJECT (toplevel), "shortcuts-inhibited");
}
static void
gdk_win32_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_win32_toplevel_state_callback (GdkSurface *surface)
{
if (surface->state & GDK_TOPLEVEL_STATE_FOCUSED)
return;
if (surface->shortcuts_inhibited)
gdk_win32_toplevel_restore_system_shortcuts (GDK_TOPLEVEL (surface));
}
static void
gdk_win32_toplevel_iface_init (GdkToplevelInterface *iface)
{
@ -5017,6 +5093,8 @@ gdk_win32_toplevel_iface_init (GdkToplevelInterface *iface)
iface->focus = gdk_win32_toplevel_focus;
iface->show_window_menu = gdk_win32_toplevel_show_window_menu;
iface->supports_edge_constraints = gdk_win32_toplevel_supports_edge_constraints;
iface->inhibit_system_shortcuts = gdk_win32_toplevel_inhibit_system_shortcuts;
iface->restore_system_shortcuts = gdk_win32_toplevel_restore_system_shortcuts;
iface->begin_resize = gdk_win32_toplevel_begin_resize;
iface->begin_move = gdk_win32_toplevel_begin_move;
}
@ -5074,7 +5152,6 @@ gdk_win32_surface_get_queued_window_rect (GdkSurface *surface,
RECT *return_window_rect)
{
RECT window_rect;
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
_gdk_win32_get_window_client_area_rect (surface, scale, &window_rect);