[gtk/wip/chergert/quartz4u] macos: start on showing popups



commit 7eb060725554ce315da0cda3a7bf488e230cdf6f
Author: Christian Hergert <chergert redhat com>
Date:   Fri May 8 14:05:49 2020 -0700

    macos: start on showing popups

 gdk/macos/gdkmacospopupsurface.c | 163 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 162 insertions(+), 1 deletion(-)
---
diff --git a/gdk/macos/gdkmacospopupsurface.c b/gdk/macos/gdkmacospopupsurface.c
index 77501ef70c..85d6cbc59f 100644
--- a/gdk/macos/gdkmacospopupsurface.c
+++ b/gdk/macos/gdkmacospopupsurface.c
@@ -19,9 +19,14 @@
 
 #include "config.h"
 
+#import "GdkMacosWindow.h"
+
+#include "gdkinternals.h"
 #include "gdkpopupprivate.h"
 
+#include "gdkmacosdisplay-private.h"
 #include "gdkmacospopupsurface-private.h"
+#include "gdkmacosutils-private.h"
 
 struct _GdkMacosPopupSurface
 {
@@ -33,9 +38,118 @@ struct _GdkMacosPopupSurfaceClass
   GdkMacosSurfaceClass parent_class;
 };
 
+static void
+gdk_macos_popup_surface_layout (GdkMacosPopupSurface *self,
+                                int                   width,
+                                int                   height,
+                                GdkPopupLayout       *layout)
+{
+  GdkRectangle final_rect;
+  int x, y;
+
+  g_assert (GDK_IS_MACOS_POPUP_SURFACE (self));
+  g_assert (layout != NULL);
+  g_assert (GDK_SURFACE (self)->parent);
+
+  gdk_surface_layout_popup_helper (GDK_SURFACE (self),
+                                   width,
+                                   height,
+                                   layout,
+                                   &final_rect);
+
+  gdk_surface_get_origin (GDK_SURFACE (self)->parent, &x, &y);
+
+  x += final_rect.x;
+  y += final_rect.y;
+
+  if (final_rect.width != GDK_SURFACE (self)->width ||
+      final_rect.height != GDK_SURFACE (self)->height)
+    _gdk_macos_surface_move_resize (GDK_MACOS_SURFACE (self),
+                                    x,
+                                    y,
+                                    final_rect.width,
+                                    final_rect.height);
+  else
+    _gdk_macos_surface_move (GDK_MACOS_SURFACE (self), x, y);
+
+}
+
+static void
+show_grabbing_popup (GdkSeat    *seat,
+                     GdkSurface *surface,
+                     gpointer    user_data)
+{
+  _gdk_macos_surface_show (GDK_MACOS_SURFACE (surface));
+}
+
+static gboolean
+gdk_macos_popup_surface_present (GdkPopup       *popup,
+                                 int             width,
+                                 int             height,
+                                 GdkPopupLayout *layout)
+{
+  GdkMacosPopupSurface *self = (GdkMacosPopupSurface *)popup;
+
+  g_assert (GDK_IS_MACOS_POPUP_SURFACE (self));
+
+  gdk_macos_popup_surface_layout (self, width, height, layout);
+
+  if (GDK_SURFACE_IS_MAPPED (GDK_SURFACE (self)))
+    return TRUE;
+
+  if (GDK_SURFACE (self)->autohide)
+    {
+      GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (popup));
+      GdkSeat *seat = gdk_display_get_default_seat (display);
+
+      gdk_seat_grab (seat,
+                     GDK_SURFACE (self),
+                     GDK_SEAT_CAPABILITY_ALL,
+                     TRUE,
+                     NULL, NULL,
+                     show_grabbing_popup,
+                     NULL);
+    }
+  else
+    {
+      _gdk_macos_surface_show (GDK_MACOS_SURFACE (self));
+    }
+
+  return GDK_SURFACE_IS_MAPPED (GDK_SURFACE (self));
+}
+
+static GdkGravity
+gdk_macos_popup_surface_get_surface_anchor (GdkPopup *popup)
+{
+  return GDK_SURFACE (popup)->popup.surface_anchor;
+}
+
+static GdkGravity
+gdk_macos_popup_surface_get_rect_anchor (GdkPopup *popup)
+{
+  return GDK_SURFACE (popup)->popup.rect_anchor;
+}
+
+static int
+gdk_macos_popup_surface_get_position_x (GdkPopup *popup)
+{
+  return GDK_SURFACE (popup)->x;
+}
+
+static int
+gdk_macos_popup_surface_get_position_y (GdkPopup *popup)
+{
+  return GDK_SURFACE (popup)->y;
+}
+
 static void
 popup_interface_init (GdkPopupInterface *iface)
 {
+  iface->present = gdk_macos_popup_surface_present;
+  iface->get_surface_anchor = gdk_macos_popup_surface_get_surface_anchor;
+  iface->get_rect_anchor = gdk_macos_popup_surface_get_rect_anchor;
+  iface->get_position_x = gdk_macos_popup_surface_get_position_x;
+  iface->get_position_y = gdk_macos_popup_surface_get_position_y;
 }
 
 G_DEFINE_TYPE_WITH_CODE (GdkMacosPopupSurface, _gdk_macos_popup_surface, GDK_TYPE_MACOS_SURFACE,
@@ -49,6 +163,10 @@ enum {
 static void
 _gdk_macos_popup_surface_finalize (GObject *object)
 {
+  GdkMacosPopupSurface *self = (GdkMacosPopupSurface *)object;
+
+  g_clear_object (&GDK_SURFACE (self)->parent);
+
   G_OBJECT_CLASS (_gdk_macos_popup_surface_parent_class)->finalize (object);
 }
 
@@ -58,12 +176,16 @@ _gdk_macos_popup_surface_get_property (GObject    *object,
                                        GValue     *value,
                                        GParamSpec *pspec)
 {
+  GdkSurface *surface = GDK_SURFACE (object);
+
   switch (prop_id)
     {
     case LAST_PROP + GDK_POPUP_PROP_PARENT:
+      g_value_set_object (value, surface->parent);
       break;
 
     case LAST_PROP + GDK_POPUP_PROP_AUTOHIDE:
+      g_value_set_boolean (value, surface->autohide);
       break;
 
     default:
@@ -77,12 +199,18 @@ _gdk_macos_popup_surface_set_property (GObject      *object,
                                        const GValue *value,
                                        GParamSpec   *pspec)
 {
+  GdkSurface *surface = GDK_SURFACE (object);
+
   switch (prop_id)
     {
     case LAST_PROP + GDK_POPUP_PROP_PARENT:
+      surface->parent = g_value_dup_object (value);
+      if (surface->parent)
+        surface->parent->children = g_list_prepend (surface->parent->children, surface);
       break;
 
     case LAST_PROP + GDK_POPUP_PROP_AUTOHIDE:
+      surface->autohide = g_value_get_boolean (value);
       break;
 
     default:
@@ -116,12 +244,45 @@ _gdk_macos_popup_surface_new (GdkMacosDisplay *display,
                               int              width,
                               int              height)
 {
+  GDK_BEGIN_MACOS_ALLOC_POOL;
+
+  GdkMacosWindow *window;
+  GdkMacosSurface *self;
+  NSScreen *screen;
+  NSUInteger style_mask;
+  NSRect content_rect;
+  NSRect screen_rect;
+  int nx;
+  int ny;
+
   g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (display), NULL);
   g_return_val_if_fail (!frame_clock || GDK_IS_FRAME_CLOCK (frame_clock), NULL);
   g_return_val_if_fail (!parent || GDK_IS_MACOS_SURFACE (parent), NULL);
 
-  return g_object_new (GDK_TYPE_MACOS_POPUP_SURFACE,
+  style_mask = NSWindowStyleMaskBorderless;
+
+  _gdk_macos_display_to_display_coords (display, x, y, &nx, &ny);
+
+  screen = _gdk_macos_display_get_screen_at_display_coords (display, nx, ny);
+  screen_rect = [screen frame];
+  nx -= screen_rect.origin.x;
+  ny -= screen_rect.origin.y;
+  content_rect = NSMakeRect (nx, ny - height, width, height);
+
+  window = [[GdkMacosWindow alloc] initWithContentRect:content_rect
+                                             styleMask:style_mask
+                                               backing:NSBackingStoreBuffered
+                                                 defer:NO
+                                                screen:screen];
+
+  self = g_object_new (GDK_TYPE_MACOS_POPUP_SURFACE,
                        "display", display,
                        "frame-clock", frame_clock,
+                       "native", window,
+                       "parent", parent,
                        NULL);
+
+  GDK_END_MACOS_ALLOC_POOL;
+
+  return g_steal_pointer (&self);
 }


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