[gtk: 4/88] gdk/toplevel: Make gdk_toplevel_present() async




commit 641915974be5113ab3bb16e1b5aa0be274d66608
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Fri Nov 20 16:56:36 2020 +0100

    gdk/toplevel: Make gdk_toplevel_present() async
    
    The plan is to concencrate size computations as part of the frame clock
    dispatch, meaning we shouldn't do it synchronously in the present()
    function.
    
    Still, in Wayland, and maybe elsewhere, it is done in the present()
    function, e.g. when no state change was made, but this will eventually
    be changed.

 gdk/broadway/gdksurface-broadway.c |   4 +-
 gdk/gdktoplevel.c                  |  16 +++---
 gdk/gdktoplevel.h                  |   2 +-
 gdk/gdktoplevelprivate.h           |   2 +-
 gdk/wayland/gdksurface-wayland.c   | 106 ++++++++++++++++++++-----------------
 gdk/x11/gdksurface-x11.c           |   6 +--
 6 files changed, 69 insertions(+), 67 deletions(-)
---
diff --git a/gdk/broadway/gdksurface-broadway.c b/gdk/broadway/gdksurface-broadway.c
index d9e45ad077..bc5f3eb6c9 100644
--- a/gdk/broadway/gdksurface-broadway.c
+++ b/gdk/broadway/gdksurface-broadway.c
@@ -1524,7 +1524,7 @@ show_surface (GdkSurface *surface)
     gdk_surface_invalidate_rect (surface, NULL);
 }
 
-static gboolean
+static void
 gdk_broadway_toplevel_present (GdkToplevel       *toplevel,
                                GdkToplevelLayout *layout)
 {
@@ -1583,8 +1583,6 @@ gdk_broadway_toplevel_present (GdkToplevel       *toplevel,
     gdk_broadway_surface_unmaximize (surface);
 
   show_surface (surface);
-
-  return TRUE;
 }
 
 static gboolean
diff --git a/gdk/gdktoplevel.c b/gdk/gdktoplevel.c
index 34328db10d..4cff2bb3dd 100644
--- a/gdk/gdktoplevel.c
+++ b/gdk/gdktoplevel.c
@@ -51,11 +51,10 @@ enum
 
 static guint signals[N_SIGNALS] = { 0 };
 
-static gboolean
+static void
 gdk_toplevel_default_present (GdkToplevel       *toplevel,
                               GdkToplevelLayout *layout)
 {
-  return FALSE;
 }
 
 static gboolean
@@ -239,18 +238,17 @@ gdk_toplevel_install_properties (GObjectClass *object_class,
  * compute the preferred size of the toplevel surface. See
  * #GdkToplevel::compute-size for details.
  *
- * Presenting may fail.
- *
- * Returns: %FALSE if @toplevel failed to be presented, otherwise %TRUE.
+ * Presenting is asynchronous and the specified layout parameters are not
+ * guaranteed to be respected.
  */
-gboolean
+void
 gdk_toplevel_present (GdkToplevel       *toplevel,
                       GdkToplevelLayout *layout)
 {
-  g_return_val_if_fail (GDK_IS_TOPLEVEL (toplevel), FALSE);
-  g_return_val_if_fail (layout != NULL, FALSE);
+  g_return_if_fail (GDK_IS_TOPLEVEL (toplevel));
+  g_return_if_fail (layout != NULL);
 
-  return GDK_TOPLEVEL_GET_IFACE (toplevel)->present (toplevel, layout);
+  GDK_TOPLEVEL_GET_IFACE (toplevel)->present (toplevel, layout);
 }
 
 /**
diff --git a/gdk/gdktoplevel.h b/gdk/gdktoplevel.h
index 05fafa4b5f..28402feb10 100644
--- a/gdk/gdktoplevel.h
+++ b/gdk/gdktoplevel.h
@@ -129,7 +129,7 @@ GDK_AVAILABLE_IN_ALL
 G_DECLARE_INTERFACE (GdkToplevel, gdk_toplevel, GDK, TOPLEVEL, GObject)
 
 GDK_AVAILABLE_IN_ALL
-gboolean        gdk_toplevel_present            (GdkToplevel       *toplevel,
+void            gdk_toplevel_present            (GdkToplevel       *toplevel,
                                                  GdkToplevelLayout *layout);
 
 GDK_AVAILABLE_IN_ALL
diff --git a/gdk/gdktoplevelprivate.h b/gdk/gdktoplevelprivate.h
index 989ac29c46..52dcdca0ad 100644
--- a/gdk/gdktoplevelprivate.h
+++ b/gdk/gdktoplevelprivate.h
@@ -13,7 +13,7 @@ struct _GdkToplevelInterface
 {
   GTypeInterface g_iface;
 
-  gboolean      (* present)             (GdkToplevel       *toplevel,
+  void          (* present)             (GdkToplevel       *toplevel,
                                          GdkToplevelLayout *layout);
   gboolean      (* minimize)            (GdkToplevel       *toplevel);
   gboolean      (* lower)               (GdkToplevel       *toplevel);
diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c
index 1c6c27c1c0..27eb433a58 100644
--- a/gdk/wayland/gdksurface-wayland.c
+++ b/gdk/wayland/gdksurface-wayland.c
@@ -4756,79 +4756,87 @@ gdk_wayland_toplevel_class_init (GdkWaylandToplevelClass *class)
   gdk_toplevel_install_properties (object_class, 1);
 }
 
-static void
-reconfigure_callback (void               *data,
-                      struct wl_callback *callback,
-                      uint32_t            time)
+static gboolean
+did_maximize_layout_change (GdkToplevel       *toplevel,
+                            GdkToplevelLayout *layout)
 {
-  gboolean *done = (gboolean *) data;
+  GdkSurface *surface = GDK_SURFACE (toplevel);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
-  *done = TRUE;
-}
+  if (!impl->toplevel.layout)
+    return TRUE;
 
-static const struct wl_callback_listener reconfigure_listener = {
-  reconfigure_callback
-};
+  if (gdk_toplevel_layout_get_maximized (impl->toplevel.layout) !=
+      gdk_toplevel_layout_get_maximized (layout))
+    return TRUE;
+
+  return FALSE;
+}
 
 static gboolean
+did_fullscreen_layout_change (GdkToplevel       *toplevel,
+                              GdkToplevelLayout *layout)
+{
+  GdkSurface *surface = GDK_SURFACE (toplevel);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
+
+  if (!impl->toplevel.layout)
+    return TRUE;
+
+  if (gdk_toplevel_layout_get_fullscreen (impl->toplevel.layout) !=
+      gdk_toplevel_layout_get_fullscreen (layout))
+    return TRUE;
+
+  if (gdk_toplevel_layout_get_fullscreen_monitor (impl->toplevel.layout) !=
+      gdk_toplevel_layout_get_fullscreen_monitor (layout))
+    return TRUE;
+
+  return FALSE;
+}
+
+static void
 gdk_wayland_toplevel_present (GdkToplevel       *toplevel,
                               GdkToplevelLayout *layout)
 {
   GdkSurface *surface = GDK_SURFACE (toplevel);
   GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
-  GdkWaylandDisplay *display_wayland;
-  struct wl_callback *callback;
-  gboolean done = FALSE;
-  int last_configure_serial = impl->last_configure_serial;
-  gboolean needs_reconfigure = TRUE;
+  gboolean pending_configure = FALSE;
 
-  if (gdk_toplevel_layout_get_maximized (layout))
-    {
-      gdk_wayland_surface_maximize (surface);
-      needs_reconfigure = FALSE;
-    }
-  else
+  if (did_maximize_layout_change (toplevel, layout))
     {
-      gdk_wayland_surface_unmaximize (surface);
+      if (gdk_toplevel_layout_get_maximized (layout))
+        gdk_wayland_surface_maximize (surface);
+      else
+        gdk_wayland_surface_unmaximize (surface);
+      pending_configure = TRUE;
     }
 
-  if (gdk_toplevel_layout_get_fullscreen (layout))
+  if (did_fullscreen_layout_change (toplevel, layout))
     {
-      GdkMonitor *monitor = gdk_toplevel_layout_get_fullscreen_monitor (layout);
-      if (monitor)
-        gdk_wayland_surface_fullscreen_on_monitor (surface, monitor);
+      if (gdk_toplevel_layout_get_fullscreen (layout))
+        {
+          GdkMonitor *monitor;
+
+          monitor = gdk_toplevel_layout_get_fullscreen_monitor (layout);
+          if (monitor)
+            gdk_wayland_surface_fullscreen_on_monitor (surface, monitor);
+          else
+            gdk_wayland_surface_fullscreen (surface);
+        }
       else
-        gdk_wayland_surface_fullscreen (surface);
-      needs_reconfigure = FALSE;
+        {
+          gdk_wayland_surface_unfullscreen (surface);
+        }
+      pending_configure = TRUE;
     }
-  else
-    gdk_wayland_surface_unfullscreen (surface);
 
   g_clear_pointer (&impl->toplevel.layout, gdk_toplevel_layout_unref);
   impl->toplevel.layout = gdk_toplevel_layout_copy (layout);
 
   gdk_wayland_surface_show (surface, FALSE);
 
-  display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
-  callback = wl_display_sync (display_wayland->wl_display);
-  wl_proxy_set_queue ((struct wl_proxy *) callback, impl->event_queue);
-  wl_callback_add_listener (callback,
-                            &reconfigure_listener,
-                            &done);
-  while (is_realized_toplevel (impl) &&
-         (!impl->initial_configure_received || !done))
-    wl_display_dispatch_queue (display_wayland->wl_display, impl->event_queue);
-
-  wl_callback_destroy (callback);
-
-  if (needs_reconfigure &&
-      last_configure_serial == impl->last_configure_serial &&
-      !(surface->state & (GDK_TOPLEVEL_STATE_MAXIMIZED |
-                          GDK_TOPLEVEL_STATE_FULLSCREEN |
-                          GDK_TOPLEVEL_STATE_TILED)))
+  if (!pending_configure)
     configure_surface_geometry (surface);
-
-  return TRUE;
 }
 
 static gboolean
diff --git a/gdk/x11/gdksurface-x11.c b/gdk/x11/gdksurface-x11.c
index 24b536cb96..c4b14e11e3 100644
--- a/gdk/x11/gdksurface-x11.c
+++ b/gdk/x11/gdksurface-x11.c
@@ -4849,7 +4849,7 @@ gdk_x11_toplevel_class_init (GdkX11ToplevelClass *class)
   gdk_toplevel_install_properties (object_class, LAST_PROP);
 }
 
-static gboolean
+static void
 gdk_x11_toplevel_present (GdkToplevel       *toplevel,
                           GdkToplevelLayout *layout)
 {
@@ -4922,7 +4922,7 @@ gdk_x11_toplevel_present (GdkToplevel       *toplevel,
     gdk_x11_surface_unfullscreen (surface);
 
   if (surface->destroyed)
-    return TRUE;
+    return;
 
   was_mapped = GDK_SURFACE_IS_MAPPED (surface);
 
@@ -4933,8 +4933,6 @@ gdk_x11_toplevel_present (GdkToplevel       *toplevel,
 
   if (!was_mapped)
     gdk_surface_invalidate_rect (surface, NULL);
-
-  return TRUE;
 }
 
 static gboolean


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