Merge branch 'broadway-modal-hint' into 'main'

[GTK4] gdk/broadway: Implements modal hint for Broadway surface

See merge request GNOME/gtk!4428
This commit is contained in:
Matthias Clasen
2023-01-26 02:44:54 +00:00
9 changed files with 112 additions and 0 deletions

View File

@@ -213,6 +213,7 @@ typedef enum {
BROADWAY_REQUEST_RELEASE_TEXTURE,
BROADWAY_REQUEST_SET_NODES,
BROADWAY_REQUEST_ROUNDTRIP,
BROADWAY_REQUEST_SET_MODAL_HINT,
} BroadwayRequestType;
typedef struct {
@@ -293,6 +294,12 @@ typedef struct {
guint32 show_keyboard;
} BroadwayRequestSetShowKeyboard;
typedef struct {
BroadwayRequestBase base;
guint32 id;
gboolean modal_hint;
} BroadwayRequestSetModalHint;
typedef union {
BroadwayRequestBase base;
BroadwayRequestNewSurface new_surface;
@@ -312,6 +319,7 @@ typedef union {
BroadwayRequestUploadTexture upload_texture;
BroadwayRequestReleaseTexture release_texture;
BroadwayRequestSetNodes set_nodes;
BroadwayRequestSetModalHint set_modal_hint;
} BroadwayRequest;
typedef enum {

View File

@@ -124,6 +124,7 @@ struct BroadwaySurface {
gboolean visible;
gint32 transient_for;
guint32 texture;
gboolean modal_hint;
BroadwayNode *nodes;
GHashTable *node_lookup;
};
@@ -421,6 +422,14 @@ update_event_state (BroadwayServer *server,
{
surface->x = message->configure_notify.x;
surface->y = message->configure_notify.y;
if (server->focused_surface_id != message->configure_notify.id &&
server->pointer_grab_surface_id == -1 && surface->modal_hint)
{
broadway_server_surface_raise (server, message->configure_notify.id);
broadway_server_focus_surface (server, message->configure_notify.id);
broadway_server_flush (server);
}
}
break;
case BROADWAY_EVENT_ROUNDTRIP_NOTIFY:
@@ -1568,6 +1577,7 @@ broadway_server_destroy_surface (BroadwayServer *server,
int id)
{
BroadwaySurface *surface;
gint32 transient_for = -1;
if (server->mouse_in_surface_id == id)
{
@@ -1585,11 +1595,24 @@ broadway_server_destroy_surface (BroadwayServer *server,
surface = broadway_server_lookup_surface (server, id);
if (surface != NULL)
{
if (server->focused_surface_id == id)
transient_for = surface->transient_for;
server->surfaces = g_list_remove (server->surfaces, surface);
g_hash_table_remove (server->surface_id_hash,
GINT_TO_POINTER (id));
broadway_surface_free (server, surface);
}
if (transient_for != -1)
{
surface = broadway_server_lookup_surface (server, transient_for);
if (surface != NULL)
{
broadway_server_focus_surface (server, transient_for);
broadway_server_flush (server);
}
}
}
gboolean
@@ -1710,6 +1733,19 @@ broadway_server_surface_set_transient_for (BroadwayServer *server,
}
}
void
broadway_server_surface_set_modal_hint (BroadwayServer *server,
int id, gboolean modal_hint)
{
BroadwaySurface *surface;
surface = broadway_server_lookup_surface (server, id);
if (surface == NULL)
return;
surface->modal_hint = modal_hint;
}
gboolean
broadway_server_has_client (BroadwayServer *server)
{

View File

@@ -130,6 +130,9 @@ gboolean broadway_server_surface_move_resize (BroadwayServer *
int height);
void broadway_server_focus_surface (BroadwayServer *server,
int new_focused_surface);
void broadway_server_surface_set_modal_hint (BroadwayServer *server,
int id,
gboolean modal_hint);
#endif /* __BROADWAY_SERVER__ */

View File

@@ -380,6 +380,11 @@ client_handle_request (BroadwayClient *client,
case BROADWAY_REQUEST_SET_SHOW_KEYBOARD:
broadway_server_set_show_keyboard (server, request->set_show_keyboard.show_keyboard);
break;
case BROADWAY_REQUEST_SET_MODAL_HINT:
broadway_server_surface_set_modal_hint (server,
request->set_modal_hint.id,
request->set_modal_hint.modal_hint);
break;
default:
g_warning ("Unknown request of type %d", request->base.type);
}

View File

@@ -561,6 +561,18 @@ _gdk_broadway_server_surface_set_transient_for (GdkBroadwayServer *server,
BROADWAY_REQUEST_SET_TRANSIENT_FOR);
}
void
_gdk_broadway_server_surface_set_modal_hint (GdkBroadwayServer *server,
int id, gboolean modal_hint)
{
BroadwayRequestSetModalHint msg;
msg.id = id;
msg.modal_hint = modal_hint;
gdk_broadway_server_send_message (server, msg,
BROADWAY_REQUEST_SET_MODAL_HINT);
}
static int
open_shared_memory (void)
{

View File

@@ -78,5 +78,8 @@ gboolean _gdk_broadway_server_surface_move_resize (GdkBroadwaySe
int y,
int width,
int height);
void _gdk_broadway_server_surface_set_modal_hint (GdkBroadwayServer *server,
int id,
gboolean modal_hint);
#endif /* __GDK_BROADWAY_SERVER__ */

View File

@@ -82,6 +82,25 @@ gdk_event_source_check (GSource *source)
return retval;
}
static void
handle_focus_change (GdkEvent *event)
{
GdkEvent *focus_event;
gboolean focus_in = (gdk_event_get_event_type (event) == GDK_ENTER_NOTIFY);
if (gdk_crossing_event_get_detail (event) == GDK_NOTIFY_INFERIOR)
return;
if (!gdk_crossing_event_get_focus (event) )
return;
focus_event = gdk_focus_event_new (gdk_event_get_surface (event),
gdk_event_get_device (event),
focus_in);
gdk_display_put_event (gdk_event_get_display (event), focus_event);
gdk_event_unref (focus_event);
}
void
_gdk_broadway_events_got_input (GdkDisplay *display,
BroadwayInputMsg *message)
@@ -110,6 +129,8 @@ _gdk_broadway_events_got_input (GdkDisplay *display,
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
handle_focus_change (event);
}
break;
case BROADWAY_EVENT_LEAVE:
@@ -126,6 +147,8 @@ _gdk_broadway_events_got_input (GdkDisplay *display,
message->crossing.mode,
GDK_NOTIFY_ANCESTOR);
handle_focus_change (event);
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
}

View File

@@ -709,6 +709,21 @@ gdk_broadway_surface_set_transient_for (GdkSurface *surface,
_gdk_broadway_server_surface_set_transient_for (display->server, impl->id, impl->transient_for);
}
static void
gdk_broadway_surface_set_modal_hint (GdkSurface *surface,
gboolean modal)
{
GdkBroadwayDisplay *display;
GdkBroadwaySurface *impl;
impl = GDK_BROADWAY_SURFACE (surface);
impl->modal_hint = modal;
display = GDK_BROADWAY_DISPLAY (gdk_surface_get_display (surface));
_gdk_broadway_server_surface_set_modal_hint (display->server, impl->id, impl->modal_hint);
}
static void
gdk_broadway_surface_get_geometry (GdkSurface *surface,
int *x,
@@ -1433,6 +1448,8 @@ gdk_broadway_toplevel_set_property (GObject *object,
break;
case LAST_PROP + GDK_TOPLEVEL_PROP_MODAL:
gdk_broadway_surface_set_modal_hint (surface, g_value_get_boolean (value));
g_object_notify_by_pspec (G_OBJECT (surface), pspec);
break;
case LAST_PROP + GDK_TOPLEVEL_PROP_ICON_LIST:
@@ -1479,6 +1496,10 @@ gdk_broadway_toplevel_get_property (GObject *object,
g_value_set_object (value, surface->transient_for);
break;
case LAST_PROP + GDK_TOPLEVEL_PROP_MODAL:
g_value_set_boolean (value, surface->modal_hint);
break;
case LAST_PROP + GDK_TOPLEVEL_PROP_ICON_LIST:
g_value_set_pointer (value, NULL);
break;

View File

@@ -54,6 +54,7 @@ struct _GdkBroadwaySurface
gboolean dirty;
gboolean last_synced;
gboolean modal_hint;
GdkGeometry geometry_hints;
GdkSurfaceHints geometry_hints_mask;