[gtk: 2/3] gdk/toplevellayout: Change API to be about intent, not full state




commit 142f7862ed0aaa72177286f614430f8a555ad1cb
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Wed Dec 16 11:53:19 2020 +0100

    gdk/toplevellayout: Change API to be about intent, not full state
    
    When being fullscreen, and wanting to unfullscreen but not caring about
    whether to go unmaximized or maximized (as this information is lost), if
    the GdkToplevelLayout represents the full intended state, we won't be
    able to do the right thing.
    
    To avoid this issue, make the GdkToplevelLayout API intend based, where
    if one e.g. doesn't call gdk_toplevel_set_maximized() with anything, the
    backend will not attempt to change the maximized state.
    
    This means we can also remove the old 'initially_maximized' and
    'initially_fullscreen' fields from the private GtkWindow struct, as we
    only deal with intents now.

 gdk/broadway/gdksurface-broadway.c  |  12 ++-
 gdk/gdktoplevellayout.c             |  49 ++++++++---
 gdk/gdktoplevellayout.h             |   6 +-
 gdk/macos/gdkmacostoplevelsurface.c |  24 ++++--
 gdk/wayland/gdksurface-wayland.c    |  52 ++----------
 gdk/win32/gdksurface-win32.c        |  24 ++++--
 gdk/x11/gdksurface-x11.c            |  34 +++++---
 gtk/gtkwindow.c                     | 162 ++++++++++++++++++------------------
 8 files changed, 194 insertions(+), 169 deletions(-)
---
diff --git a/gdk/broadway/gdksurface-broadway.c b/gdk/broadway/gdksurface-broadway.c
index d44b2281f0..0d90e270a6 100644
--- a/gdk/broadway/gdksurface-broadway.c
+++ b/gdk/broadway/gdksurface-broadway.c
@@ -1542,6 +1542,7 @@ gdk_broadway_toplevel_present (GdkToplevel       *toplevel,
   int width, height;
   GdkGeometry geometry;
   GdkSurfaceHints mask;
+  gboolean maximize;
 
   gdk_broadway_surface_unminimize (surface);
 
@@ -1583,10 +1584,13 @@ gdk_broadway_toplevel_present (GdkToplevel       *toplevel,
   gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
   gdk_broadway_surface_toplevel_resize (surface, width, height);
 
-  if (gdk_toplevel_layout_get_maximized (layout))
-    gdk_broadway_surface_maximize (surface);
-  else
-    gdk_broadway_surface_unmaximize (surface);
+  if (gdk_toplevel_layout_get_maximized (layout, &maximize))
+    {
+      if (maximize)
+        gdk_broadway_surface_maximize (surface);
+      else
+        gdk_broadway_surface_unmaximize (surface);
+    }
 
   if (size.shadow.is_valid)
     {
diff --git a/gdk/gdktoplevellayout.c b/gdk/gdktoplevellayout.c
index 577b03be41..0de2720b00 100644
--- a/gdk/gdktoplevellayout.c
+++ b/gdk/gdktoplevellayout.c
@@ -40,7 +40,10 @@ struct _GdkToplevelLayout
   grefcount ref_count;
 
   guint resizable  : 1;
+
+  guint maximized_valid : 1;
   guint maximized  : 1;
+  guint fullscreen_valid : 1;
   guint fullscreen : 1;
   GdkMonitor *fullscreen_monitor;
 };
@@ -70,7 +73,9 @@ gdk_toplevel_layout_new (void)
   layout = g_new0 (GdkToplevelLayout, 1);
   g_ref_count_init (&layout->ref_count);
   layout->resizable = TRUE;
+  layout->maximized_valid = FALSE;
   layout->maximized = FALSE;
+  layout->fullscreen_valid = FALSE;
   layout->fullscreen = FALSE;
   layout->fullscreen_monitor = NULL;
 
@@ -125,7 +130,9 @@ gdk_toplevel_layout_copy (GdkToplevelLayout *layout)
   g_ref_count_init (&new_layout->ref_count);
 
   new_layout->resizable = layout->resizable;
+  new_layout->maximized_valid = layout->maximized_valid;
   new_layout->maximized = layout->maximized;
+  new_layout->fullscreen_valid = layout->fullscreen_valid;
   new_layout->fullscreen = layout->fullscreen;
   if (layout->fullscreen_monitor)
     new_layout->fullscreen_monitor = g_object_ref (layout->fullscreen_monitor);
@@ -151,7 +158,9 @@ gdk_toplevel_layout_equal (GdkToplevelLayout *layout,
   g_return_val_if_fail (other, FALSE);
 
   return layout->resizable == other->resizable &&
+         layout->maximized_valid == other->maximized_valid &&
          layout->maximized == other->maximized &&
+         layout->fullscreen_valid == other->fullscreen_valid &&
          layout->fullscreen == other->fullscreen &&
          layout->fullscreen_monitor == other->fullscreen_monitor;
 }
@@ -198,22 +207,32 @@ void
 gdk_toplevel_layout_set_maximized (GdkToplevelLayout *layout,
                                    gboolean           maximized)
 {
+  layout->maximized_valid = TRUE;
   layout->maximized = maximized;
 }
 
 /**
  * gdk_toplevel_layout_get_maximized:
  * @layout: a #GdkToplevelLayout
+ * @maximized: (out): set to %TRUE if the toplevel should be maximized
  *
- * Returns whether the layout should present the
- * surface as maximized.
+ * If the layout specifies whether to the toplevel should go maximized,
+ * the value pointed to by @maximized is set to %TRUE if it should go
+ * fullscreen, or %FALSE, if it should go unmaximized.
  *
- * Returns: %TRUE if the layout is maximized
+ * Returns: whether the @layout specifies the maximized state for the toplevel
  */
 gboolean
-gdk_toplevel_layout_get_maximized (GdkToplevelLayout *layout)
+gdk_toplevel_layout_get_maximized (GdkToplevelLayout *layout,
+                                   gboolean          *maximized)
 {
-  return layout->maximized;
+  if (layout->maximized_valid)
+    {
+      *maximized = layout->maximized;
+      return TRUE;
+    }
+
+  return FALSE;
 }
 
 /**
@@ -230,6 +249,7 @@ gdk_toplevel_layout_set_fullscreen (GdkToplevelLayout *layout,
                                     gboolean           fullscreen,
                                     GdkMonitor        *monitor)
 {
+  layout->fullscreen_valid = TRUE;
   layout->fullscreen = fullscreen;
   if (monitor)
     layout->fullscreen_monitor = g_object_ref (monitor);
@@ -238,16 +258,25 @@ gdk_toplevel_layout_set_fullscreen (GdkToplevelLayout *layout,
 /**
  * gdk_toplevel_layout_get_fullscreen:
  * @layout: a #GdkToplevelLayout
+ * @fullscreen: (out): location to store whether the toplevel should be fullscreen
  *
- * Returns whether the layout should cause the surface
- * to be fullscreen when presented.
+ * If the layout specifies whether to the toplevel should go fullscreen,
+ * the value pointed to by @fullscreen is set to %TRUE if it should go
+ * fullscreen, or %FALSE, if it should go unfullscreen.
  *
- * Returns: %TRUE if @layout is fullscreen
+ * Returns: whether the @layout specifies the fullscreen state for the toplevel
  */
 gboolean
-gdk_toplevel_layout_get_fullscreen (GdkToplevelLayout *layout)
+gdk_toplevel_layout_get_fullscreen (GdkToplevelLayout *layout,
+                                    gboolean          *fullscreen)
 {
-  return layout->fullscreen;
+  if (layout->fullscreen_valid)
+    {
+      *fullscreen = layout->fullscreen;
+      return TRUE;
+    }
+
+  return FALSE;
 }
 
 /**
diff --git a/gdk/gdktoplevellayout.h b/gdk/gdktoplevellayout.h
index 62f2790f75..69aaea8564 100644
--- a/gdk/gdktoplevellayout.h
+++ b/gdk/gdktoplevellayout.h
@@ -66,10 +66,12 @@ void                    gdk_toplevel_layout_set_fullscreen (GdkToplevelLayout *l
                                                             GdkMonitor        *monitor);
 
 GDK_AVAILABLE_IN_ALL
-gboolean                gdk_toplevel_layout_get_maximized (GdkToplevelLayout *layout);
+gboolean                gdk_toplevel_layout_get_maximized (GdkToplevelLayout *layout,
+                                                           gboolean          *maximize);
 
 GDK_AVAILABLE_IN_ALL
-gboolean                gdk_toplevel_layout_get_fullscreen (GdkToplevelLayout *layout);
+gboolean                gdk_toplevel_layout_get_fullscreen (GdkToplevelLayout *layout,
+                                                            gboolean          *fullscreen);
 
 GDK_AVAILABLE_IN_ALL
 GdkMonitor *            gdk_toplevel_layout_get_fullscreen_monitor (GdkToplevelLayout *layout);
diff --git a/gdk/macos/gdkmacostoplevelsurface.c b/gdk/macos/gdkmacostoplevelsurface.c
index dbd244bf43..e1f60e8221 100644
--- a/gdk/macos/gdkmacostoplevelsurface.c
+++ b/gdk/macos/gdkmacostoplevelsurface.c
@@ -96,6 +96,8 @@ _gdk_macos_toplevel_surface_present (GdkToplevel       *toplevel,
   GdkGeometry geometry;
   GdkSurfaceHints mask;
   NSWindowStyleMask style_mask;
+  gboolean maximize;
+  gboolean fullscreen
 
   g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (self));
   g_assert (GDK_IS_MACOS_WINDOW (nswindow));
@@ -169,16 +171,22 @@ _gdk_macos_toplevel_surface_present (GdkToplevel       *toplevel,
   _gdk_macos_surface_resize (GDK_MACOS_SURFACE (self), width, height);
 
   /* Maximized state */
-  if (gdk_toplevel_layout_get_maximized (layout))
-    _gdk_macos_toplevel_surface_maximize (self);
-  else
-    _gdk_macos_toplevel_surface_unmaximize (self);
+  if (gdk_toplevel_layout_get_maximized (layout, &maximize))
+    {
+      if (maximize)
+        _gdk_macos_toplevel_surface_maximize (self);
+      else
+        _gdk_macos_toplevel_surface_unmaximize (self);
+    }
 
   /* Fullscreen state */
-  if (gdk_toplevel_layout_get_fullscreen (layout))
-    _gdk_macos_toplevel_surface_fullscreen (self);
-  else
-    _gdk_macos_toplevel_surface_unfullscreen (self);
+  if (gdk_toplevel_layout_get_fullscreen (layout, &fullscreen))
+    {
+      if (fullscreen)
+        _gdk_macos_toplevel_surface_fullscreen (self);
+      else
+        _gdk_macos_toplevel_surface_unfullscreen (self);
+    }
 
   if (GDK_SURFACE (self)->transient_for != NULL)
     {
diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c
index 602d76b773..dd0d1891fa 100644
--- a/gdk/wayland/gdksurface-wayland.c
+++ b/gdk/wayland/gdksurface-wayland.c
@@ -4865,48 +4865,6 @@ gdk_wayland_toplevel_class_init (GdkWaylandToplevelClass *class)
   gdk_toplevel_install_properties (object_class, 1);
 }
 
-static gboolean
-did_maximize_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_maximized (impl->toplevel.layout) !=
-      gdk_toplevel_layout_get_maximized (layout) ||
-      !!(surface->state & GDK_TOPLEVEL_STATE_MAXIMIZED) !=
-      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) ||
-      !!(surface->state & GDK_TOPLEVEL_STATE_FULLSCREEN) !=
-      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)
@@ -4914,19 +4872,21 @@ gdk_wayland_toplevel_present (GdkToplevel       *toplevel,
   GdkSurface *surface = GDK_SURFACE (toplevel);
   GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   gboolean pending_configure = FALSE;
+  gboolean maximize;
+  gboolean fullscreen;
 
-  if (did_maximize_layout_change (toplevel, layout))
+  if (gdk_toplevel_layout_get_maximized (layout, &maximize))
     {
-      if (gdk_toplevel_layout_get_maximized (layout))
+      if (maximize)
         gdk_wayland_surface_maximize (surface);
       else
         gdk_wayland_surface_unmaximize (surface);
       pending_configure = TRUE;
     }
 
-  if (did_fullscreen_layout_change (toplevel, layout))
+  if (gdk_toplevel_layout_get_fullscreen (layout, &fullscreen))
     {
-      if (gdk_toplevel_layout_get_fullscreen (layout))
+      if (fullscreen)
         {
           GdkMonitor *monitor;
 
diff --git a/gdk/win32/gdksurface-win32.c b/gdk/win32/gdksurface-win32.c
index 263fcc6c60..4c6a5067a0 100644
--- a/gdk/win32/gdksurface-win32.c
+++ b/gdk/win32/gdksurface-win32.c
@@ -4942,6 +4942,8 @@ gdk_win32_toplevel_present (GdkToplevel       *toplevel,
   int width, height;
   GdkGeometry geometry;
   GdkSurfaceHints mask;
+  gboolean maximize;
+  gboolean fullscreen;
 
   monitor = gdk_display_get_monitor_at_surface (display, surface);
   if (monitor)
@@ -4981,15 +4983,21 @@ gdk_win32_toplevel_present (GdkToplevel       *toplevel,
   gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
   gdk_win32_surface_resize (surface, width, height);
 
-  if (gdk_toplevel_layout_get_maximized (layout))
-    gdk_win32_surface_maximize (surface);
-  else
-    gdk_win32_surface_unmaximize (surface);
+  if (gdk_toplevel_layout_get_maximized (layout, &maximize))
+    {
+      if (maximize)
+        gdk_win32_surface_maximize (surface);
+      else
+        gdk_win32_surface_unmaximize (surface);
+    }
 
-  if (gdk_toplevel_layout_get_fullscreen (layout))
-    gdk_win32_surface_fullscreen (surface);
-  else
-    gdk_win32_surface_unfullscreen (surface);
+  if (gdk_toplevel_layout_get_fullscreen (layout, &fullscreen))
+    {
+      if (fullscreen)
+        gdk_win32_surface_fullscreen (surface);
+      else
+        gdk_win32_surface_unfullscreen (surface);
+    }
 
   show_surface (surface);
 
diff --git a/gdk/x11/gdksurface-x11.c b/gdk/x11/gdksurface-x11.c
index 293134371e..d67dacf77c 100644
--- a/gdk/x11/gdksurface-x11.c
+++ b/gdk/x11/gdksurface-x11.c
@@ -5078,6 +5078,8 @@ gdk_x11_toplevel_present (GdkToplevel       *toplevel,
   GdkX11Surface *impl = GDK_X11_SURFACE (surface);
   int width, height;
   gboolean was_mapped;
+  gboolean maximize;
+  gboolean fullscreen;
 
   if (surface->destroyed)
     return;
@@ -5092,23 +5094,31 @@ gdk_x11_toplevel_present (GdkToplevel       *toplevel,
   if (compute_toplevel_size (surface, DONT_UPDATE_GEOMETRY, &width, &height))
     gdk_x11_surface_toplevel_resize (surface, width, height);
 
-  if (gdk_toplevel_layout_get_maximized (layout))
-    gdk_x11_surface_maximize (surface);
-  else
-    gdk_x11_surface_unmaximize (surface);
+  if (gdk_toplevel_layout_get_maximized (layout, &maximize))
+    {
+      if (maximize)
+        gdk_x11_surface_maximize (surface);
+      else
+        gdk_x11_surface_unmaximize (surface);
+    }
 
-  if (gdk_toplevel_layout_get_fullscreen (layout))
+  if (gdk_toplevel_layout_get_fullscreen (layout, &fullscreen))
     {
-      GdkMonitor *fullscreen_monitor =
-        gdk_toplevel_layout_get_fullscreen_monitor (layout);
+      if (fullscreen)
+        {
+          GdkMonitor *fullscreen_monitor =
+            gdk_toplevel_layout_get_fullscreen_monitor (layout);
 
-      if (fullscreen_monitor)
-        gdk_x11_surface_fullscreen_on_monitor (surface, fullscreen_monitor);
+          if (fullscreen_monitor)
+            gdk_x11_surface_fullscreen_on_monitor (surface, fullscreen_monitor);
+          else
+            gdk_x11_surface_fullscreen (surface);
+        }
       else
-        gdk_x11_surface_fullscreen (surface);
+        {
+          gdk_x11_surface_unfullscreen (surface);
+        }
     }
-  else
-    gdk_x11_surface_unfullscreen (surface);
 
   impl->next_layout.surface_geometry_dirty = TRUE;
   gdk_surface_request_layout (surface);
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 71b8a579d2..18177a204c 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -208,10 +208,8 @@ typedef struct
   guint    decorated                 : 1;
   guint    deletable                 : 1;
   guint    destroy_with_parent       : 1;
-  guint    fullscreen_initially      : 1;
   guint    minimize_initially        : 1;
   guint    is_active                 : 1;
-  guint    maximize_initially        : 1;
   guint    mnemonics_visible         : 1;
   guint    focus_visible             : 1;
   guint    modal                     : 1;
@@ -236,7 +234,6 @@ typedef struct
   GList *foci;
 
   GtkConstraintSolver *constraint_solver;
-  GdkToplevelLayout *layout;
 
   int surface_width;
   int surface_height;
@@ -325,7 +322,6 @@ struct _GtkWindowGeometryInfo
   GtkWindowLastGeometryInfo last;
 };
 
-
 static void gtk_window_constructed        (GObject           *object);
 static void gtk_window_dispose            (GObject           *object);
 static void gtk_window_finalize           (GObject           *object);
@@ -432,8 +428,8 @@ static void        gtk_window_css_changed               (GtkWidget      *widget,
 static void _gtk_window_set_is_active (GtkWindow *window,
                                       gboolean   is_active);
 static void gtk_window_present_toplevel (GtkWindow *window);
-static void gtk_window_update_toplevel (GtkWindow *window);
-static GdkToplevelLayout * gtk_window_compute_layout (GtkWindow *window);
+static void gtk_window_update_toplevel (GtkWindow         *window,
+                                        GdkToplevelLayout *layout);
 
 static void gtk_window_release_application (GtkWindow *window);
 
@@ -1133,10 +1129,7 @@ gtk_window_is_maximized (GtkWindow *window)
 
   g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
 
-  if (_gtk_widget_get_mapped (GTK_WIDGET (window)))
-    return priv->maximized;
-  else
-    return priv->maximize_initially;
+  return priv->maximized;
 }
 
 /**
@@ -1163,10 +1156,7 @@ gtk_window_is_fullscreen (GtkWindow *window)
 
   g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
 
-  if (_gtk_widget_get_mapped (GTK_WIDGET (window)))
-    return priv->fullscreen;
-  else
-    return priv->fullscreen_initially;
+  return priv->fullscreen;
 }
 
 void
@@ -2440,7 +2430,6 @@ gtk_window_dispose (GObject *object)
   g_list_free_full (priv->foci, (GDestroyNotify) gtk_pointer_focus_unref);
   priv->foci = NULL;
 
-  g_clear_pointer (&priv->layout, gdk_toplevel_layout_unref);
   gtk_window_set_focus (window, NULL);
   gtk_window_set_default_widget (window, NULL);
 
@@ -3728,7 +3717,7 @@ gtk_window_hide (GtkWidget *widget)
 }
 
 static GdkToplevelLayout *
-gtk_window_compute_layout (GtkWindow *window)
+gtk_window_compute_base_layout (GtkWindow *window)
 {
   GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
   GdkToplevelLayout *layout;
@@ -3736,10 +3725,6 @@ gtk_window_compute_layout (GtkWindow *window)
   layout = gdk_toplevel_layout_new ();
 
   gdk_toplevel_layout_set_resizable (layout, priv->resizable);
-  gdk_toplevel_layout_set_maximized (layout, priv->maximize_initially);
-  gdk_toplevel_layout_set_fullscreen (layout,
-                                      priv->fullscreen_initially,
-                                      priv->initial_fullscreen_monitor);
 
   return layout;
 }
@@ -3748,25 +3733,25 @@ static void
 gtk_window_present_toplevel (GtkWindow *window)
 {
   GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
+  GdkToplevelLayout *layout;
 
-  if (!priv->layout)
-    priv->layout = gtk_window_compute_layout (window);
-
-  gdk_toplevel_present (GDK_TOPLEVEL (priv->surface), priv->layout);
+  layout = gtk_window_compute_base_layout (window);
+  gdk_toplevel_layout_set_maximized (layout, priv->maximized);
+  gdk_toplevel_layout_set_fullscreen (layout, priv->fullscreen,
+                                      priv->initial_fullscreen_monitor);
+  gdk_toplevel_present (GDK_TOPLEVEL (priv->surface), layout);
+  gdk_toplevel_layout_unref (layout);
 }
 
 static void
-gtk_window_update_toplevel (GtkWindow *window)
+gtk_window_update_toplevel (GtkWindow         *window,
+                            GdkToplevelLayout *layout)
 {
   GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
   
   if (_gtk_widget_get_mapped (GTK_WIDGET (window)))
-    {
-      g_clear_pointer (&priv->layout, gdk_toplevel_layout_unref);
-      priv->layout = gtk_window_compute_layout (window);
-
-      gdk_toplevel_present (GDK_TOPLEVEL (priv->surface), priv->layout);
-    }
+    gdk_toplevel_present (GDK_TOPLEVEL (priv->surface), layout);
+  gdk_toplevel_layout_unref (layout);
 }
 
 static void
@@ -3827,15 +3812,10 @@ gtk_window_unmap (GtkWidget *widget)
   GtkWindow *window = GTK_WINDOW (widget);
   GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
   GtkWidget *child = priv->child;
-  GdkToplevelState state;
 
   GTK_WIDGET_CLASS (gtk_window_parent_class)->unmap (widget);
   gdk_surface_hide (priv->surface);
 
-  state = gdk_toplevel_get_state (GDK_TOPLEVEL (priv->surface));
-  priv->minimize_initially = (state & GDK_TOPLEVEL_STATE_MINIMIZED) != 0;
-  priv->maximize_initially = (state & GDK_TOPLEVEL_STATE_MAXIMIZED) != 0;
-
   if (priv->title_box != NULL)
     gtk_widget_unmap (priv->title_box);
 
@@ -4502,7 +4482,6 @@ surface_state_changed (GtkWidget *widget)
   if (changed_mask & GDK_TOPLEVEL_STATE_FULLSCREEN)
     {
       priv->fullscreen = (new_surface_state & GDK_TOPLEVEL_STATE_FULLSCREEN) ? TRUE : FALSE;
-      priv->fullscreen_initially = priv->fullscreen;
 
       g_object_notify_by_pspec (G_OBJECT (widget), window_props[PROP_FULLSCREENED]);
     }
@@ -4510,7 +4489,6 @@ surface_state_changed (GtkWidget *widget)
   if (changed_mask & GDK_TOPLEVEL_STATE_MAXIMIZED)
     {
       priv->maximized = (new_surface_state & GDK_TOPLEVEL_STATE_MAXIMIZED) ? TRUE : FALSE;
-      priv->maximize_initially = priv->maximized;
 
       g_object_notify_by_pspec (G_OBJECT (widget), window_props[PROP_MAXIMIZED]);
     }
@@ -5179,7 +5157,8 @@ gtk_window_unminimize (GtkWindow *window)
 
   priv->minimize_initially = FALSE;
 
-  gtk_window_update_toplevel (window);
+  gtk_window_update_toplevel (window,
+                              gtk_window_compute_base_layout (window));
 }
 
 /**
@@ -5203,19 +5182,20 @@ void
 gtk_window_maximize (GtkWindow *window)
 {
   GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
-  gboolean was_maximized_initially;
 
   g_return_if_fail (GTK_IS_WINDOW (window));
 
-  was_maximized_initially = priv->maximize_initially;
-  priv->maximize_initially = TRUE;
-
   if (_gtk_widget_get_mapped (GTK_WIDGET (window)))
     {
-      gtk_window_update_toplevel (window);
+      GdkToplevelLayout *layout;
+
+      layout = gtk_window_compute_base_layout (window);
+      gdk_toplevel_layout_set_maximized (layout, TRUE);
+      gtk_window_update_toplevel (window, layout);
     }
-  else if (!was_maximized_initially)
+  else if (!priv->maximized)
     {
+      priv->maximized = TRUE;
       g_object_notify_by_pspec (G_OBJECT (window), window_props[PROP_MAXIMIZED]);
     }
 }
@@ -5238,19 +5218,35 @@ void
 gtk_window_unmaximize (GtkWindow *window)
 {
   GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
-  gboolean was_maximized_initially;
 
   g_return_if_fail (GTK_IS_WINDOW (window));
 
-  was_maximized_initially = priv->maximize_initially;
-  priv->maximize_initially = FALSE;
+  if (_gtk_widget_get_mapped (GTK_WIDGET (window)))
+    {
+      GdkToplevelLayout *layout;
 
-  gtk_window_update_toplevel (window);
+      layout = gtk_window_compute_base_layout (window);
+      gdk_toplevel_layout_set_maximized (layout, FALSE);
+      gtk_window_update_toplevel (window, layout);
+    }
+  else if (priv->maximized)
+    {
+      priv->maximized = FALSE;
+      g_object_notify_by_pspec (G_OBJECT (window), window_props[PROP_MAXIMIZED]);
+    }
+}
 
-  if (_gtk_widget_get_mapped (GTK_WIDGET (window)))
-    gtk_window_update_toplevel (window);
-  else if (was_maximized_initially)
-    g_object_notify_by_pspec (G_OBJECT (window), window_props[PROP_MAXIMIZED]);
+static void
+unset_fullscreen_monitor (GtkWindow *window)
+{
+  GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
+
+  if (priv->initial_fullscreen_monitor)
+    {
+      g_signal_handlers_disconnect_by_func (priv->initial_fullscreen_monitor, unset_fullscreen_monitor, 
window);
+      g_object_unref (priv->initial_fullscreen_monitor);
+      priv->initial_fullscreen_monitor = NULL;
+    }
 }
 
 /**
@@ -5271,29 +5267,23 @@ void
 gtk_window_fullscreen (GtkWindow *window)
 {
   GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
-  gboolean was_fullscreen_initially;
 
   g_return_if_fail (GTK_IS_WINDOW (window));
 
-  was_fullscreen_initially = priv->fullscreen_initially;
-  priv->fullscreen_initially = TRUE;
+  unset_fullscreen_monitor (window);
 
   if (_gtk_widget_get_mapped (GTK_WIDGET (window)))
-    gtk_window_update_toplevel (window);
-  else if (!was_fullscreen_initially)
-    g_object_notify_by_pspec (G_OBJECT (window), window_props[PROP_FULLSCREENED]);
-}
-
-static void
-unset_fullscreen_monitor (GtkWindow *window)
-{
-  GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
+    {
+      GdkToplevelLayout *layout;
 
-  if (priv->initial_fullscreen_monitor)
+      layout = gtk_window_compute_base_layout (window);
+      gdk_toplevel_layout_set_fullscreen (layout, TRUE, NULL);
+      gtk_window_update_toplevel (window, layout);
+    }
+  else if (!priv->fullscreen)
     {
-      g_signal_handlers_disconnect_by_func (priv->initial_fullscreen_monitor, unset_fullscreen_monitor, 
window);
-      g_object_unref (priv->initial_fullscreen_monitor);
-      priv->initial_fullscreen_monitor = NULL;
+      priv->fullscreen = TRUE;
+      g_object_notify_by_pspec (G_OBJECT (window), window_props[PROP_FULLSCREENED]);
     }
 }
 
@@ -5330,9 +5320,19 @@ gtk_window_fullscreen_on_monitor (GtkWindow  *window,
                             G_CALLBACK (unset_fullscreen_monitor), window);
   g_object_ref (priv->initial_fullscreen_monitor);
 
-  priv->fullscreen_initially = TRUE;
+  if (_gtk_widget_get_mapped (GTK_WIDGET (window)))
+    {
+      GdkToplevelLayout *layout;
 
-  gtk_window_update_toplevel (window);
+      layout = gtk_window_compute_base_layout (window);
+      gdk_toplevel_layout_set_fullscreen (layout, TRUE, monitor);
+      gtk_window_update_toplevel (window, layout);
+    }
+  else if (!priv->fullscreen)
+    {
+      priv->fullscreen = TRUE;
+      g_object_notify_by_pspec (G_OBJECT (window), window_props[PROP_FULLSCREENED]);
+    }
 }
 
 /**
@@ -5355,20 +5355,24 @@ void
 gtk_window_unfullscreen (GtkWindow *window)
 {
   GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
-  gboolean was_fullscreen_initially;
 
   g_return_if_fail (GTK_IS_WINDOW (window));
 
-  was_fullscreen_initially = priv->fullscreen_initially;
   unset_fullscreen_monitor (window);
-  priv->fullscreen_initially = FALSE;
-
-  gtk_window_update_toplevel (window);
 
   if (_gtk_widget_get_mapped (GTK_WIDGET (window)))
-    gtk_window_update_toplevel (window);
-  else if (was_fullscreen_initially)
-    g_object_notify_by_pspec (G_OBJECT (window), window_props[PROP_FULLSCREENED]);
+    {
+      GdkToplevelLayout *layout;
+
+      layout = gtk_window_compute_base_layout (window);
+      gdk_toplevel_layout_set_fullscreen (layout, FALSE, NULL);
+      gtk_window_update_toplevel (window, layout);
+    }
+  else if (priv->fullscreen)
+    {
+      priv->fullscreen = FALSE;
+      g_object_notify_by_pspec (G_OBJECT (window), window_props[PROP_FULLSCREENED]);
+    }
 }
 
 /**


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