[gtk/wip/chergert/macos-iosurface: 2/2] macos: delay window resize until compute-size
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/chergert/macos-iosurface: 2/2] macos: delay window resize until compute-size
- Date: Sat, 12 Feb 2022 19:05:05 +0000 (UTC)
commit 8148d663b0fd334c3eec901e8fadb32409f2acb6
Author: Christian Hergert <christian hergert me>
Date: Fri Feb 11 22:10:40 2022 -0800
macos: delay window resize until compute-size
In GTK 4, we have the ability to perform sizing changes from compute-size
during the layout phase. Since the macOS backend already tracks window
resizes manually, we can avoid doing the setFrame: immediately and instead
do it within the frame clock.
Doing so gives us vastly better resize experience as we're more likely to
get the size change and updated contents in the same frame.
gdk/macos/GdkMacosWindow.c | 15 ++++++---------
gdk/macos/gdkmacossurface-private.h | 4 ++++
gdk/macos/gdkmacossurface.c | 23 +++++++++++++++++++++++
gdk/macos/gdkmacostoplevelsurface.c | 23 ++++++++++++++++++++---
4 files changed, 53 insertions(+), 12 deletions(-)
---
diff --git a/gdk/macos/GdkMacosWindow.c b/gdk/macos/GdkMacosWindow.c
index 8cecb4a534..fda0087a75 100644
--- a/gdk/macos/GdkMacosWindow.c
+++ b/gdk/macos/GdkMacosWindow.c
@@ -560,15 +560,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:NO];
-
- /* 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;
diff --git a/gdk/macos/gdkmacossurface-private.h b/gdk/macos/gdkmacossurface-private.h
index b3e0b2006b..3cfcf1076a 100644
--- a/gdk/macos/gdkmacossurface-private.h
+++ b/gdk/macos/gdkmacossurface-private.h
@@ -60,6 +60,8 @@ struct _GdkMacosSurface
int shadow_bottom;
int shadow_left;
+ cairo_rectangle_int_t next_frame;
+
gint64 pending_frame_counter;
guint did_initial_present : 1;
@@ -123,6 +125,8 @@ void _gdk_macos_surface_move_resize (GdkMacosSurface
int height);
gboolean _gdk_macos_surface_is_tracking (GdkMacosSurface *self,
NSTrackingArea *area);
+void _gdk_macos_surface_set_next_frame (GdkMacosSurface *self,
+ NSRect next_frame);
void _gdk_macos_surface_monitor_changed (GdkMacosSurface *self);
GdkMonitor *_gdk_macos_surface_get_best_monitor (GdkMacosSurface *self);
void _gdk_macos_surface_reposition_children (GdkMacosSurface *self);
diff --git a/gdk/macos/gdkmacossurface.c b/gdk/macos/gdkmacossurface.c
index 85a921ebf8..6966db7894 100644
--- a/gdk/macos/gdkmacossurface.c
+++ b/gdk/macos/gdkmacossurface.c
@@ -708,6 +708,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]