[gtk/wip/chergert/for-4-6: 28/56] macos: add clamp helper to keep rectangle in workarea




commit 42f9ea07e241e69682c5a5c7334b482775e15377
Author: Christian Hergert <christian hergert me>
Date:   Wed Mar 2 00:34:27 2022 -0800

    macos: add clamp helper to keep rectangle in workarea
    
    This helper is useful to ensure we are consistent with how we keep a
    window clamped to the workarea of a monitor when placing windows on
    screen. (This does not affect snap-to-edges).

 gdk/macos/gdkmacosdisplay-wm.c      | 41 ++++++++-----------------------------
 gdk/macos/gdkmacosmonitor-private.h |  2 ++
 gdk/macos/gdkmacosmonitor.c         | 26 +++++++++++++++++++++++
 3 files changed, 37 insertions(+), 32 deletions(-)
---
diff --git a/gdk/macos/gdkmacosdisplay-wm.c b/gdk/macos/gdkmacosdisplay-wm.c
index 7b508a4a9e..4f0672013c 100644
--- a/gdk/macos/gdkmacosdisplay-wm.c
+++ b/gdk/macos/gdkmacosdisplay-wm.c
@@ -20,7 +20,7 @@
 #include "config.h"
 
 #include "gdkmacosdisplay-private.h"
-#include "gdkmacosmonitor.h"
+#include "gdkmacosmonitor-private.h"
 #include "gdkmacossurface-private.h"
 #include "gdkmacostoplevelsurface-private.h"
 
@@ -36,47 +36,28 @@ _gdk_macos_display_position_toplevel_with_parent (GdkMacosDisplay *self,
 {
   GdkRectangle surface_rect;
   GdkRectangle parent_rect;
-  GdkRectangle workarea;
   GdkMonitor *monitor;
 
   g_assert (GDK_IS_MACOS_DISPLAY (self));
   g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (surface));
   g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (parent));
 
-  /* If x/y is set, we should place relative to parent */
-  if (GDK_SURFACE (surface)->x != 0 || GDK_SURFACE (surface)->y != 0)
-    {
-      *x = parent->root_x + GDK_SURFACE (surface)->x;
-      *y = parent->root_y + GDK_SURFACE (surface)->y;
-      return;
-    }
+  monitor = _gdk_macos_surface_get_best_monitor (parent);
 
   /* Try to center on top of the parent but also try to make the whole thing
    * visible in case that lands us under the topbar/panel/etc.
    */
-  surface_rect.x = surface->root_x + surface->shadow_left;
-  surface_rect.y = surface->root_y + surface->shadow_top;
+  parent_rect.x = parent->root_x + parent->shadow_left;
+  parent_rect.y = parent->root_y + parent->shadow_top;
+  parent_rect.width = GDK_SURFACE (parent)->width - parent->shadow_left - parent->shadow_right;
+  parent_rect.height = GDK_SURFACE (parent)->height - parent->shadow_top - parent->shadow_bottom;
+
   surface_rect.width = GDK_SURFACE (surface)->width - surface->shadow_left - surface->shadow_right;
   surface_rect.height = GDK_SURFACE (surface)->height - surface->shadow_top - surface->shadow_bottom;
-
-  parent_rect.x = parent->root_x + surface->shadow_left;
-  parent_rect.y = parent->root_y + surface->shadow_top;
-  parent_rect.width = GDK_SURFACE (parent)->width - surface->shadow_left - surface->shadow_right;
-  parent_rect.height = GDK_SURFACE (parent)->height - surface->shadow_top - surface->shadow_bottom;
-
-  /* Try to place centered atop parent */
   surface_rect.x = parent_rect.x + ((parent_rect.width - surface_rect.width) / 2);
   surface_rect.y = parent_rect.y + ((parent_rect.height - surface_rect.height) / 2);
 
-  /* Now make sure that we don't overlap the top-bar */
-  monitor = _gdk_macos_surface_get_best_monitor (parent);
-  gdk_macos_monitor_get_workarea (monitor, &workarea);
-
-  if (surface_rect.x < workarea.x)
-    surface_rect.x = workarea.x;
-
-  if (surface_rect.y < workarea.y)
-    surface_rect.y = workarea.y;
+  _gdk_macos_monitor_clamp (GDK_MACOS_MONITOR (monitor), &surface_rect);
 
   *x = surface_rect.x - surface->shadow_left;
   *y = surface_rect.y - surface->shadow_top;
@@ -123,11 +104,7 @@ _gdk_macos_display_position_toplevel (GdkMacosDisplay *self,
   surface_rect.x = workarea.x + ((workarea.width - surface_rect.width) / 2);
   surface_rect.y = workarea.y + ((workarea.height - surface_rect.height) / 2);
 
-  if (surface_rect.x < workarea.x)
-    surface_rect.x = workarea.x;
-
-  if (surface_rect.y < workarea.y)
-    surface_rect.y = workarea.y;
+  _gdk_macos_monitor_clamp (GDK_MACOS_MONITOR (surface->best_monitor), &surface_rect);
 
   *x = surface_rect.x - surface->shadow_left;
   *y = surface_rect.y - surface->shadow_top;
diff --git a/gdk/macos/gdkmacosmonitor-private.h b/gdk/macos/gdkmacosmonitor-private.h
index dfde4142c0..1a4e197f76 100644
--- a/gdk/macos/gdkmacosmonitor-private.h
+++ b/gdk/macos/gdkmacosmonitor-private.h
@@ -41,6 +41,8 @@ void               _gdk_macos_monitor_add_frame_callback    (GdkMacosMonitor   *
                                                              GdkMacosSurface   *surface);
 void               _gdk_macos_monitor_remove_frame_callback (GdkMacosMonitor   *self,
                                                              GdkMacosSurface   *surface);
+void               _gdk_macos_monitor_clamp                 (GdkMacosMonitor   *self,
+                                                             GdkRectangle      *area);
 
 G_END_DECLS
 
diff --git a/gdk/macos/gdkmacosmonitor.c b/gdk/macos/gdkmacosmonitor.c
index bfec76b7ef..a9aba3634b 100644
--- a/gdk/macos/gdkmacosmonitor.c
+++ b/gdk/macos/gdkmacosmonitor.c
@@ -431,3 +431,29 @@ _gdk_macos_monitor_remove_frame_callback (GdkMacosMonitor *self,
         gdk_display_link_source_pause (self->display_link);
     }
 }
+
+void
+_gdk_macos_monitor_clamp (GdkMacosMonitor *self,
+                          GdkRectangle    *area)
+{
+  GdkRectangle workarea;
+  GdkRectangle geom;
+
+  g_return_if_fail (GDK_IS_MACOS_MONITOR (self));
+  g_return_if_fail (area != NULL);
+
+  gdk_macos_monitor_get_workarea (GDK_MONITOR (self), &workarea);
+  gdk_monitor_get_geometry (GDK_MONITOR (self), &geom);
+
+  if (area->x + area->width > workarea.x + workarea.width)
+    area->x = workarea.x + workarea.width - area->width;
+
+  if (area->x < workarea.x)
+    area->x = workarea.x;
+
+  if (area->y + area->height > workarea.y + workarea.height)
+    area->y = workarea.y + workarea.height - area->height;
+
+  if (area->y < workarea.y)
+    area->y = workarea.y;
+}


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