[gtk/wip/chergert/macos-iosurface: 3/7] macos: delay resizing until next frame




commit f7c32979ee0e9ec06eb1b51cdda32fc11c8827f5
Author: Christian Hergert <christian hergert me>
Date:   Mon Feb 14 02:15:16 2022 -0800

    macos: delay resizing until next frame
    
    This helps increase the chances the frame bounds are updated around the
    same time we have a new buffer to deliver to the display server.

 gdk/macos/GdkMacosWindow.c          | 77 +++++++++++++++++--------------------
 gdk/macos/gdkmacossurface.c         | 23 +++++++++++
 gdk/macos/gdkmacostoplevelsurface.c | 23 +++++++++--
 3 files changed, 79 insertions(+), 44 deletions(-)
---
diff --git a/gdk/macos/GdkMacosWindow.c b/gdk/macos/GdkMacosWindow.c
index 8dda79ab4d..ba7c635b0a 100644
--- a/gdk/macos/GdkMacosWindow.c
+++ b/gdk/macos/GdkMacosWindow.c
@@ -544,15 +544,12 @@ typedef NSString *CALayerContentsGravity;
       new_frame.size.height = min_size.height;
     }
 
-  /* We could also apply aspect ratio:
-     new_frame.size.height = new_frame.size.width / [self aspectRatio].width * [self aspectRatio].height;
-  */
-
-  [self setFrame:new_frame display:YES];
-
-  /* Let the resizing be handled by GTK. */
-  if (g_main_context_pending (NULL))
-    g_main_context_iteration (NULL, FALSE);
+  /* We don't want to change the window size until we get to our
+   * next layout operation so that things are more likely to stay
+   * synchronized with contents vs frame.
+   */
+  _gdk_macos_surface_set_next_frame ([self gdkSurface], new_frame);
+  gdk_surface_request_layout (GDK_SURFACE ([self gdkSurface]));
 
   inTrackManualResize = NO;
 
@@ -561,49 +558,47 @@ typedef NSString *CALayerContentsGravity;
 
 -(void)beginManualResize:(GdkSurfaceEdge)edge
 {
+  CALayerContentsGravity gravity = kCAGravityBottomLeft;
+
   if (inMove || inManualMove || inManualResize)
     return;
 
   inManualResize = YES;
   resizeEdge = edge;
 
-  if (GDK_IS_MACOS_GL_VIEW ([self contentView]))
+
+  switch (edge)
     {
-      CALayerContentsGravity gravity = kCAGravityBottomLeft;
+    default:
+    case GDK_SURFACE_EDGE_NORTH:
+      gravity = kCAGravityTopLeft;
+      break;
 
-      switch (edge)
-        {
-        default:
-        case GDK_SURFACE_EDGE_NORTH:
-          gravity = kCAGravityTopLeft;
-          break;
-
-        case GDK_SURFACE_EDGE_NORTH_WEST:
-          gravity = kCAGravityTopRight;
-          break;
-
-        case GDK_SURFACE_EDGE_SOUTH_WEST:
-        case GDK_SURFACE_EDGE_WEST:
-          gravity = kCAGravityBottomRight;
-          break;
-
-        case GDK_SURFACE_EDGE_SOUTH:
-        case GDK_SURFACE_EDGE_SOUTH_EAST:
-          gravity = kCAGravityBottomLeft;
-          break;
-
-        case GDK_SURFACE_EDGE_EAST:
-          gravity = kCAGravityBottomLeft;
-          break;
-
-        case GDK_SURFACE_EDGE_NORTH_EAST:
-          gravity = kCAGravityTopLeft;
-          break;
-        }
+    case GDK_SURFACE_EDGE_NORTH_WEST:
+      gravity = kCAGravityTopRight;
+      break;
+
+    case GDK_SURFACE_EDGE_SOUTH_WEST:
+    case GDK_SURFACE_EDGE_WEST:
+      gravity = kCAGravityBottomRight;
+      break;
+
+    case GDK_SURFACE_EDGE_SOUTH:
+    case GDK_SURFACE_EDGE_SOUTH_EAST:
+      gravity = kCAGravityBottomLeft;
+      break;
 
-      [[[self contentView] layer] setContentsGravity:gravity];
+    case GDK_SURFACE_EDGE_EAST:
+      gravity = kCAGravityBottomLeft;
+      break;
+
+    case GDK_SURFACE_EDGE_NORTH_EAST:
+      gravity = kCAGravityTopLeft;
+      break;
     }
 
+  [[[self contentView] layer] setContentsGravity:gravity];
+
   initialResizeFrame = [self frame];
   initialResizeLocation = convert_nspoint_to_screen (self, [self mouseLocationOutsideOfEventStream]);
 }
diff --git a/gdk/macos/gdkmacossurface.c b/gdk/macos/gdkmacossurface.c
index c637bd0685..937b0de5d4 100644
--- a/gdk/macos/gdkmacossurface.c
+++ b/gdk/macos/gdkmacossurface.c
@@ -687,6 +687,29 @@ _gdk_macos_surface_resize (GdkMacosSurface *self,
   _gdk_macos_surface_move_resize (self, -1, -1, width, height);
 }
 
+void
+_gdk_macos_surface_set_next_frame (GdkMacosSurface *self,
+                                   NSRect           next_frame)
+{
+  GdkDisplay *display;
+
+  g_return_if_fail (GDK_IS_MACOS_SURFACE (self));
+
+  display = gdk_surface_get_display (GDK_SURFACE (self));
+
+  _gdk_macos_display_from_display_coords (GDK_MACOS_DISPLAY (display),
+                                          next_frame.origin.x,
+                                          next_frame.origin.y + next_frame.size.height,
+                                          &self->next_frame.x, &self->next_frame.y);
+  self->next_frame.width = next_frame.size.width;
+  self->next_frame.height = next_frame.size.height;
+
+  self->next_frame_set = TRUE;
+  self->geometry_dirty = TRUE;
+
+  gdk_surface_request_layout (GDK_SURFACE (self));
+}
+
 void
 _gdk_macos_surface_update_fullscreen_state (GdkMacosSurface *self)
 {
diff --git a/gdk/macos/gdkmacostoplevelsurface.c b/gdk/macos/gdkmacostoplevelsurface.c
index 17b1cec708..cf09fff73c 100644
--- a/gdk/macos/gdkmacostoplevelsurface.c
+++ b/gdk/macos/gdkmacostoplevelsurface.c
@@ -419,8 +419,16 @@ _gdk_macos_toplevel_surface_compute_size (GdkSurface *surface)
   g_warn_if_fail (size.width > 0);
   g_warn_if_fail (size.height > 0);
 
-  width = surface->width;
-  height = surface->height;
+  if (GDK_MACOS_SURFACE (self)->next_frame_set)
+    {
+      width = GDK_MACOS_SURFACE (self)->next_frame.width;
+      height = GDK_MACOS_SURFACE (self)->next_frame.height;
+    }
+  else
+    {
+      width = surface->width;
+      height = surface->height;
+    }
 
   if (self->layout != NULL &&
       gdk_toplevel_layout_get_resizable (self->layout))
@@ -446,7 +454,16 @@ _gdk_macos_toplevel_surface_compute_size (GdkSurface *surface)
   gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
 
   _gdk_macos_surface_set_geometry_hints (GDK_MACOS_SURFACE (self), &geometry, mask);
-  _gdk_macos_surface_resize (GDK_MACOS_SURFACE (self), width, height);
+
+  if (GDK_MACOS_SURFACE (self)->next_frame_set)
+    _gdk_macos_surface_move_resize (GDK_MACOS_SURFACE (self),
+                                    GDK_MACOS_SURFACE (self)->next_frame.x,
+                                    GDK_MACOS_SURFACE (self)->next_frame.y,
+                                    width, height);
+  else
+    _gdk_macos_surface_resize (GDK_MACOS_SURFACE (self), width, height);
+
+  GDK_MACOS_SURFACE (self)->next_frame_set = FALSE;
 
   return FALSE;
 }


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