[gtk/wip/chergert/for-4-6: 50/56] macos: select new key window after processing events




commit 9462b3fea2afb3b13d5168046f199f0f485b5700
Author: Christian Hergert <christian hergert me>
Date:   Fri Mar 11 00:50:10 2022 -0800

    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.

 gdk/macos/gdkmacosdisplay-private.h |  3 +++
 gdk/macos/gdkmacosdisplay.c         | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+)
---
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);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]