summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Hergert <christian@hergert.me>2022-03-11 00:50:10 -0800
committerChristian Hergert <christian@hergert.me>2022-03-11 14:44:06 -0800
commit6bedcf22bc0e6dda80af333b3976786c05c48393 (patch)
tree57a70e2a0db59b75eb6d453351c562dc520aa60d
parenteeb9d6c39875c5d6a0ec7b9537de1695400b681d (diff)
downloadgtk+-6bedcf22bc0e6dda80af333b3976786c05c48393.tar.gz
macos: select new key window after processing events
If we closed a key window in response to events, we need to denote another window as the new key window. This is easiest to do from an idle so that we don't clobber notification pairs of "did resign"/"did become" key window. We have a sorted set of surfaces by display server stacking, so we can take the first one we come across that is already mapped and re-show it to become key/main.
-rw-r--r--gdk/macos/gdkmacosdisplay-private.h3
-rw-r--r--gdk/macos/gdkmacosdisplay.c32
2 files changed, 35 insertions, 0 deletions
diff --git a/gdk/macos/gdkmacosdisplay-private.h b/gdk/macos/gdkmacosdisplay-private.h
index 72b5f5cd57..1edff58d04 100644
--- a/gdk/macos/gdkmacosdisplay-private.h
+++ b/gdk/macos/gdkmacosdisplay-private.h
@@ -84,6 +84,9 @@ struct _GdkMacosDisplay
int min_y;
int max_x;
int max_y;
+
+ /* A GSource to select a new main/key window */
+ guint select_key_in_idle;
};
struct _GdkMacosDisplayClass
diff --git a/gdk/macos/gdkmacosdisplay.c b/gdk/macos/gdkmacosdisplay.c
index d1398335fd..6c51ef901e 100644
--- a/gdk/macos/gdkmacosdisplay.c
+++ b/gdk/macos/gdkmacosdisplay.c
@@ -413,6 +413,34 @@ _gdk_macos_display_surface_became_key (GdkMacosDisplay *self,
gdk_surface_request_motion (GDK_SURFACE (surface));
}
+static gboolean
+select_key_in_idle_cb (gpointer data)
+{
+ GdkMacosDisplay *self = data;
+
+ g_assert (GDK_IS_MACOS_DISPLAY (self));
+
+ self->select_key_in_idle = 0;
+
+ if (self->keyboard_surface == NULL)
+ {
+ const GList *surfaces = _gdk_macos_display_get_surfaces (self);
+
+ for (const GList *iter = surfaces; iter; iter = iter->next)
+ {
+ GdkMacosSurface *surface = iter->data;
+
+ if (GDK_SURFACE_IS_MAPPED (GDK_SURFACE (surface)))
+ {
+ [surface->window showAndMakeKey:YES];
+ break;
+ }
+ }
+ }
+
+ return G_SOURCE_REMOVE;
+}
+
void
_gdk_macos_display_surface_resigned_key (GdkMacosDisplay *self,
GdkMacosSurface *surface)
@@ -457,6 +485,9 @@ _gdk_macos_display_surface_resigned_key (GdkMacosDisplay *self,
}
_gdk_macos_display_clear_sorting (self);
+
+ if (self->select_key_in_idle == 0)
+ self->select_key_in_idle = g_idle_add (select_key_in_idle_cb, self);
}
/* Raises a transient window.
@@ -564,6 +595,7 @@ gdk_macos_display_finalize (GObject *object)
_gdk_macos_display_feedback_destroy (self);
+ g_clear_handle_id (&self->select_key_in_idle, g_source_remove);
g_clear_pointer (&self->active_drags, g_hash_table_unref);
g_clear_pointer (&self->active_drops, g_hash_table_unref);
g_clear_object (&GDK_DISPLAY (self)->clipboard);