diff options
author | Matthias Clasen <mclasen@redhat.com> | 2020-12-03 20:07:16 +0000 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2020-12-03 20:07:16 +0000 |
commit | 6ecae6c5f8ce737c999502f5ef064f0b65b4f083 (patch) | |
tree | fbf9bc9a193bf2b65b2c742b549559134a13db5c | |
parent | 6d76b587cfc026ca3937741a118219915f6027f0 (diff) | |
parent | 004f0a65968b79917982a45184b50cb1ca34fbc8 (diff) | |
download | gtk+-6ecae6c5f8ce737c999502f5ef064f0b65b4f083.tar.gz |
Merge branch 'wip/chergert/gdk-macos-for-master' into 'master'
macos: fix motion event delivery after closing transient window
Closes #3419
See merge request GNOME/gtk!2910
-rw-r--r-- | gdk/macos/gdkmacosdisplay.c | 23 | ||||
-rw-r--r-- | gdk/macos/gdkmacossurface.c | 12 | ||||
-rw-r--r-- | gtk/gtkactionmuxer.c | 13 | ||||
-rw-r--r-- | gtk/gtkactionmuxerprivate.h | 2 | ||||
-rw-r--r-- | gtk/gtkapplication-quartz.c | 26 |
5 files changed, 67 insertions, 9 deletions
diff --git a/gdk/macos/gdkmacosdisplay.c b/gdk/macos/gdkmacosdisplay.c index 1ac55ad82f..be2d111c59 100644 --- a/gdk/macos/gdkmacosdisplay.c +++ b/gdk/macos/gdkmacosdisplay.c @@ -477,7 +477,8 @@ _gdk_macos_display_surface_removed (GdkMacosDisplay *self, if (self->keyboard_surface == surface) _gdk_macos_display_surface_resigned_key (self, surface); - g_queue_unlink (&self->sorted_surfaces, &surface->sorted); + if (queue_contains (&self->sorted_surfaces, &surface->sorted)) + g_queue_unlink (&self->sorted_surfaces, &surface->sorted); if (queue_contains (&self->main_surfaces, &surface->main)) _gdk_macos_display_surface_resigned_main (self, surface); @@ -519,23 +520,30 @@ void _gdk_macos_display_surface_resigned_key (GdkMacosDisplay *self, GdkMacosSurface *surface) { + gboolean was_keyboard_surface; + g_return_if_fail (GDK_IS_MACOS_DISPLAY (self)); g_return_if_fail (GDK_IS_MACOS_SURFACE (surface)); - if (self->keyboard_surface == surface) + was_keyboard_surface = self->keyboard_surface == surface; + + self->keyboard_surface = NULL; + + if (was_keyboard_surface) { GdkDevice *keyboard; GdkEvent *event; GdkSeat *seat; + GList *node; seat = gdk_display_get_default_seat (GDK_DISPLAY (self)); keyboard = gdk_seat_get_keyboard (seat); event = gdk_focus_event_new (GDK_SURFACE (surface), keyboard, FALSE); - _gdk_event_queue_append (GDK_DISPLAY (self), event); + node = _gdk_event_queue_append (GDK_DISPLAY (self), event); + _gdk_windowing_got_event (GDK_DISPLAY (self), node, event, + _gdk_display_get_next_serial (GDK_DISPLAY (self))); } - self->keyboard_surface = NULL; - _gdk_macos_display_clear_sorting (self); } @@ -1049,9 +1057,8 @@ _gdk_macos_display_clear_sorting (GdkMacosDisplay *self) { g_return_if_fail (GDK_IS_MACOS_DISPLAY (self)); - self->sorted_surfaces.head = NULL; - self->sorted_surfaces.tail = NULL; - self->sorted_surfaces.length = 0; + while (self->sorted_surfaces.head != NULL) + g_queue_unlink (&self->sorted_surfaces, self->sorted_surfaces.head); } const GList * diff --git a/gdk/macos/gdkmacossurface.c b/gdk/macos/gdkmacossurface.c index 5d6f2e1aaa..7c1c03f44d 100644 --- a/gdk/macos/gdkmacossurface.c +++ b/gdk/macos/gdkmacossurface.c @@ -112,15 +112,21 @@ gdk_macos_surface_hide (GdkSurface *surface) { GdkMacosSurface *self = (GdkMacosSurface *)surface; GdkSeat *seat; + gboolean was_mapped; g_assert (GDK_IS_MACOS_SURFACE (self)); + was_mapped = GDK_SURFACE_IS_MAPPED (GDK_SURFACE (self)); + seat = gdk_display_get_default_seat (surface->display); gdk_seat_ungrab (seat); [self->window hide]; _gdk_surface_clear_update_area (surface); + + if (was_mapped) + gdk_surface_freeze_updates (GDK_SURFACE (self)); } static int @@ -544,7 +550,10 @@ _gdk_macos_surface_new (GdkMacosDisplay *display, } if (ret != NULL) - _gdk_macos_surface_monitor_changed (ret); + { + gdk_surface_freeze_updates (GDK_SURFACE (ret)); + _gdk_macos_surface_monitor_changed (ret); + } g_object_unref (frame_clock); @@ -766,6 +775,7 @@ _gdk_macos_surface_show (GdkMacosSurface *self) { _gdk_macos_surface_update_position (self); gdk_surface_invalidate_rect (GDK_SURFACE (self), NULL); + gdk_surface_thaw_updates (GDK_SURFACE (self)); } } diff --git a/gtk/gtkactionmuxer.c b/gtk/gtkactionmuxer.c index ed9ee26b85..fad926ceaf 100644 --- a/gtk/gtkactionmuxer.c +++ b/gtk/gtkactionmuxer.c @@ -315,6 +315,19 @@ gtk_action_muxer_find (GtkActionMuxer *muxer, return NULL; } +GActionGroup * +gtk_action_muxer_get_group (GtkActionMuxer *muxer, + const char *group_name) +{ + Group *group; + + group = g_hash_table_lookup (muxer->groups, group_name); + if (group) + return group->group; + + return NULL; +} + static inline Action * find_observers (GtkActionMuxer *muxer, const char *action_name) diff --git a/gtk/gtkactionmuxerprivate.h b/gtk/gtkactionmuxerprivate.h index 63a8f51c6c..db69cabc9d 100644 --- a/gtk/gtkactionmuxerprivate.h +++ b/gtk/gtkactionmuxerprivate.h @@ -60,6 +60,8 @@ void gtk_action_muxer_remove (GtkActi GActionGroup * gtk_action_muxer_find (GtkActionMuxer *muxer, const char *action_name, const char **unprefixed_name); +GActionGroup * gtk_action_muxer_get_group (GtkActionMuxer *muxer, + const char *group_name); GtkActionMuxer * gtk_action_muxer_get_parent (GtkActionMuxer *muxer); void gtk_action_muxer_set_parent (GtkActionMuxer *muxer, diff --git a/gtk/gtkapplication-quartz.c b/gtk/gtkapplication-quartz.c index a744ebd89e..5472c20641 100644 --- a/gtk/gtkapplication-quartz.c +++ b/gtk/gtkapplication-quartz.c @@ -251,11 +251,37 @@ gtk_application_impl_quartz_shutdown (GtkApplicationImpl *impl) } static void +on_window_unmap_cb (GtkApplicationImpl *impl, + GtkWindow *window) +{ + GtkApplicationImplQuartz *quartz = (GtkApplicationImplQuartz *) impl; + + if ((GActionGroup *)window == gtk_action_muxer_get_group (quartz->muxer, "win")) + gtk_action_muxer_remove (quartz->muxer, "win"); +} + +static void gtk_application_impl_quartz_active_window_changed (GtkApplicationImpl *impl, GtkWindow *window) { GtkApplicationImplQuartz *quartz = (GtkApplicationImplQuartz *) impl; + /* Track unmapping of the window so we can clear the "win" field. + * Without this, we might hold on to a reference of the window + * preventing it from getting disposed. + */ + if (window != NULL && !g_object_get_data (G_OBJECT (window), "quartz-muxer-umap")) + { + gulong handler_id = g_signal_connect_object (window, + "unmap", + G_CALLBACK (on_window_unmap_cb), + impl, + G_CONNECT_SWAPPED); + g_object_set_data (G_OBJECT (window), + "quartz-muxer-unmap", + GSIZE_TO_POINTER (handler_id)); + } + gtk_action_muxer_remove (quartz->muxer, "win"); if (G_IS_ACTION_GROUP (window)) |