forked from AuroraMiddleware/gtk
Merge branch 'gtk-3-24-focus-to-modal-parant-and-transient-for' into 'gtk-3-24'
Solution for focus loss problem for complex multi Window UI in Broadway backend See merge request GNOME/gtk!3990
This commit is contained in:
commit
4fcf3b3a7d
@ -157,7 +157,8 @@ typedef enum {
|
||||
BROADWAY_REQUEST_GRAB_POINTER,
|
||||
BROADWAY_REQUEST_UNGRAB_POINTER,
|
||||
BROADWAY_REQUEST_FOCUS_WINDOW,
|
||||
BROADWAY_REQUEST_SET_SHOW_KEYBOARD
|
||||
BROADWAY_REQUEST_SET_SHOW_KEYBOARD,
|
||||
BROADWAY_REQUEST_SET_MODAL_HINT
|
||||
} BroadwayRequestType;
|
||||
|
||||
typedef struct {
|
||||
@ -231,6 +232,12 @@ typedef struct {
|
||||
guint32 show_keyboard;
|
||||
} BroadwayRequestSetShowKeyboard;
|
||||
|
||||
typedef struct {
|
||||
BroadwayRequestBase base;
|
||||
guint32 id;
|
||||
gboolean modal_hint;
|
||||
} BroadwayRequestSetModalHint;
|
||||
|
||||
typedef union {
|
||||
BroadwayRequestBase base;
|
||||
BroadwayRequestNewWindow new_window;
|
||||
@ -248,6 +255,7 @@ typedef union {
|
||||
BroadwayRequestTranslate translate;
|
||||
BroadwayRequestFocusWindow focus_window;
|
||||
BroadwayRequestSetShowKeyboard set_show_keyboard;
|
||||
BroadwayRequestSetModalHint set_modal_hint;
|
||||
} BroadwayRequest;
|
||||
|
||||
typedef enum {
|
||||
|
@ -113,6 +113,7 @@ struct BroadwayWindow {
|
||||
gboolean is_temp;
|
||||
gboolean visible;
|
||||
gint32 transient_for;
|
||||
gboolean modal_hint;
|
||||
|
||||
BroadwayBuffer *buffer;
|
||||
gboolean buffer_synced;
|
||||
@ -276,6 +277,14 @@ update_event_state (BroadwayServer *server,
|
||||
{
|
||||
window->x = message->configure_notify.x;
|
||||
window->y = message->configure_notify.y;
|
||||
|
||||
if (server->focused_window_id != message->configure_notify.id &&
|
||||
server->pointer_grab_window_id == -1 && window->modal_hint)
|
||||
{
|
||||
broadway_server_window_raise (server, message->configure_notify.id);
|
||||
broadway_server_focus_window (server, message->configure_notify.id);
|
||||
broadway_server_flush (server);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BROADWAY_EVENT_DELETE_NOTIFY:
|
||||
@ -1435,6 +1444,7 @@ broadway_server_destroy_window (BroadwayServer *server,
|
||||
gint id)
|
||||
{
|
||||
BroadwayWindow *window;
|
||||
gint transient_for = -1;
|
||||
|
||||
if (server->mouse_in_toplevel_id == id)
|
||||
{
|
||||
@ -1453,6 +1463,9 @@ broadway_server_destroy_window (BroadwayServer *server,
|
||||
GINT_TO_POINTER (id));
|
||||
if (window != NULL)
|
||||
{
|
||||
if (server->focused_window_id == id)
|
||||
transient_for = window->transient_for;
|
||||
|
||||
server->toplevels = g_list_remove (server->toplevels, window);
|
||||
g_hash_table_remove (server->id_ht,
|
||||
GINT_TO_POINTER (id));
|
||||
@ -1463,6 +1476,17 @@ broadway_server_destroy_window (BroadwayServer *server,
|
||||
|
||||
g_free (window);
|
||||
}
|
||||
|
||||
if (transient_for != -1)
|
||||
{
|
||||
window = g_hash_table_lookup (server->id_ht,
|
||||
GINT_TO_POINTER (transient_for));
|
||||
if (window != NULL)
|
||||
{
|
||||
broadway_server_focus_window (server, transient_for);
|
||||
broadway_server_flush (server);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
@ -1588,6 +1612,20 @@ broadway_server_window_set_transient_for (BroadwayServer *server,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
broadway_server_window_set_modal_hint (BroadwayServer *server,
|
||||
gint id, gboolean modal_hint)
|
||||
{
|
||||
BroadwayWindow *window;
|
||||
|
||||
window = g_hash_table_lookup (server->id_ht,
|
||||
GINT_TO_POINTER (id));
|
||||
if (window == NULL)
|
||||
return;
|
||||
|
||||
window->modal_hint = modal_hint;
|
||||
}
|
||||
|
||||
gboolean
|
||||
broadway_server_has_client (BroadwayServer *server)
|
||||
{
|
||||
|
@ -95,5 +95,8 @@ cairo_surface_t * broadway_server_open_surface (BroadwayServer *server,
|
||||
char *name,
|
||||
int width,
|
||||
int height);
|
||||
void broadway_server_window_set_modal_hint (BroadwayServer *server,
|
||||
gint id,
|
||||
gboolean modal_hint);
|
||||
|
||||
#endif /* __BROADWAY_SERVER__ */
|
||||
|
@ -301,6 +301,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_window_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);
|
||||
}
|
||||
|
@ -523,6 +523,18 @@ _gdk_broadway_server_window_set_transient_for (GdkBroadwayServer *server,
|
||||
BROADWAY_REQUEST_SET_TRANSIENT_FOR);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_broadway_server_window_set_modal_hint (GdkBroadwayServer *server,
|
||||
gint 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 void *
|
||||
map_named_shm (char *name, gsize size, gboolean *is_shm)
|
||||
{
|
||||
|
@ -71,5 +71,8 @@ gboolean _gdk_broadway_server_window_move_resize (GdkBroadwaySer
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
void _gdk_broadway_server_window_set_modal_hint (GdkBroadwayServer *server,
|
||||
gint id,
|
||||
gboolean modal_hint);
|
||||
|
||||
#endif /* __GDK_BROADWAY_SERVER__ */
|
||||
|
@ -89,6 +89,24 @@ gdk_event_source_check (GSource *source)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_focus_change (GdkEventCrossing *event)
|
||||
{
|
||||
gboolean focus_in = (event->type != GDK_ENTER_NOTIFY);
|
||||
GdkEvent *focus_event;
|
||||
|
||||
if (event->window->parent) {
|
||||
focus_event = gdk_event_new (GDK_FOCUS_CHANGE);
|
||||
focus_event->focus_change.window = g_object_ref (event->window->parent);
|
||||
focus_event->focus_change.send_event = FALSE;
|
||||
focus_event->focus_change.in = focus_in;
|
||||
gdk_event_set_device (focus_event, gdk_event_get_device ((GdkEvent *) event));
|
||||
|
||||
gdk_event_put (focus_event);
|
||||
gdk_event_free (focus_event);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_broadway_events_got_input (BroadwayInputMsg *message)
|
||||
{
|
||||
@ -160,6 +178,8 @@ _gdk_broadway_events_got_input (BroadwayInputMsg *message)
|
||||
gdk_event_set_device (event, device_manager->core_pointer);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device_manager->core_pointer));
|
||||
|
||||
handle_focus_change (&event->crossing);
|
||||
|
||||
node = _gdk_event_queue_append (display, event);
|
||||
_gdk_windowing_got_event (display, node, event, message->base.serial);
|
||||
}
|
||||
|
@ -584,6 +584,15 @@ static void
|
||||
gdk_broadway_window_set_modal_hint (GdkWindow *window,
|
||||
gboolean modal)
|
||||
{
|
||||
GdkBroadwayDisplay *display;
|
||||
GdkWindowImplBroadway *impl;
|
||||
|
||||
impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
|
||||
|
||||
impl->modal_hint = modal;
|
||||
|
||||
display = GDK_BROADWAY_DISPLAY (gdk_window_get_display (impl->wrapper));
|
||||
_gdk_broadway_server_window_set_modal_hint (display->server, impl->id, impl->modal_hint);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -73,6 +73,7 @@ struct _GdkWindowImplBroadway
|
||||
|
||||
GdkGeometry geometry_hints;
|
||||
GdkWindowHints geometry_hints_mask;
|
||||
gboolean modal_hint;
|
||||
};
|
||||
|
||||
struct _GdkWindowImplBroadwayClass
|
||||
|
Loading…
Reference in New Issue
Block a user