[gtk/wip.win32.fixes: 43/44] gdk/win32: Fix initial display of windows




commit 522de0f4566d3330667034015dac48b815394e70
Author: Chun-wei Fan <fanchunwei src gnome org>
Date:   Thu Dec 31 16:36:41 2020 +0800

    gdk/win32: Fix initial display of windows
    
    Have a bare-bones implementation of ->request_layout() and
    ->compute_size() for the Win32 surface backend so that we can properly
    display and move the windows, as we request from the Win32 APIs.
    
    Resizing is yet to be implemented and fixed...

 gdk/win32/gdksurface-win32.c | 162 +++++++++++++++++++++++++++++--------------
 gdk/win32/gdksurface-win32.h |   7 ++
 2 files changed, 118 insertions(+), 51 deletions(-)
---
diff --git a/gdk/win32/gdksurface-win32.c b/gdk/win32/gdksurface-win32.c
index b581c2a4ca..e8cd70a181 100644
--- a/gdk/win32/gdksurface-win32.c
+++ b/gdk/win32/gdksurface-win32.c
@@ -1090,6 +1090,8 @@ gdk_win32_surface_resize (GdkSurface *window,
                            outer_rect.bottom - outer_rect.top,
                            SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER));
   window->resize_count += 1;
+
+  gdk_surface_request_layout (window);
 }
 
 static void
@@ -4448,6 +4450,109 @@ gdk_win32_surface_set_input_region (GdkSurface     *window,
    */
 }
 
+static void
+compute_toplevel_size (GdkSurface *surface,
+                       gboolean    update_geometry,
+                       int        *width,
+                       int        *height)
+{
+  GdkDisplay *display = gdk_surface_get_display (surface);
+  GdkMonitor *monitor;
+  GdkToplevelSize size;
+  int bounds_width, bounds_height;
+  GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
+
+  GdkToplevelLayout *layout = impl->toplevel_layout;
+
+  monitor = gdk_display_get_monitor_at_surface (display, surface);
+  if (monitor)
+    {
+      GdkRectangle workarea;
+
+      gdk_win32_monitor_get_workarea (monitor, &workarea);
+      bounds_width = workarea.width;
+      bounds_height = workarea.height;
+    }
+  else
+    {
+      bounds_width = G_MAXINT;
+      bounds_height = G_MAXINT;
+    }
+
+  gdk_toplevel_size_init (&size, bounds_width, bounds_height);
+  gdk_toplevel_notify_compute_size (GDK_TOPLEVEL (surface), &size);
+  g_warn_if_fail (size.width > 0);
+  g_warn_if_fail (size.height > 0);
+  *width = size.width;
+  *height = size.height;
+
+  if (update_geometry)
+    {
+      GdkGeometry geometry;
+      GdkSurfaceHints mask;
+
+      if (gdk_toplevel_layout_get_resizable (layout))
+        {
+          geometry.min_width = size.min_width;
+          geometry.min_height = size.min_height;
+          mask = GDK_HINT_MIN_SIZE;
+        }
+      else
+        {
+          geometry.max_width = geometry.min_width = *width;
+          geometry.max_height = geometry.min_height = *height;
+          mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE;
+        }
+      gdk_win32_surface_set_geometry_hints (surface, &geometry, mask);
+      gdk_surface_constrain_size (&geometry, mask, *width, *height, width, height);
+
+      if (size.shadow.is_valid)
+        {
+          gdk_win32_surface_set_shadow_width (surface,
+                                              size.shadow.left,
+                                              size.shadow.right,
+                                              size.shadow.top,
+                                              size.shadow.bottom);
+        }
+    }
+}
+
+static void
+_gdk_win32_surface_request_layout (GdkSurface *surface)
+{
+  GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
+  int scale = impl->surface_scale;
+  RECT rect;
+
+  _gdk_win32_get_window_rect (surface, &rect);
+
+  impl->unscaled_width = rect.right - rect.left;
+  impl->unscaled_height = rect.bottom - rect.top;
+
+  impl->next_layout.configured_width = (impl->unscaled_width + scale - 1) / scale;
+  impl->next_layout.configured_height = (impl->unscaled_height + scale - 1) / scale;
+
+  surface->x = rect.left / scale;
+  surface->y = rect.top / scale;
+}
+
+static gboolean
+_gdk_win32_surface_compute_size (GdkSurface *surface)
+{
+  GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
+  int width, height;
+
+  if (GDK_IS_TOPLEVEL (surface))
+    compute_toplevel_size (surface, TRUE, &width, &height);
+
+  surface->width = impl->next_layout.configured_width;
+  surface->height = impl->next_layout.configured_height;
+
+  _gdk_surface_update_size (surface);
+
+  return FALSE;
+}
+
 static void
 gdk_win32_surface_class_init (GdkWin32SurfaceClass *klass)
 {
@@ -4474,6 +4579,8 @@ gdk_win32_surface_class_init (GdkWin32SurfaceClass *klass)
   impl_class->create_gl_context = _gdk_win32_surface_create_gl_context;
   impl_class->get_scale_factor = _gdk_win32_surface_get_scale_factor;
   impl_class->get_unscaled_size = _gdk_win32_surface_get_unscaled_size;
+  impl_class->request_layout = _gdk_win32_surface_request_layout;
+  impl_class->compute_size = _gdk_win32_surface_compute_size;
 }
 
 HGDIOBJ
@@ -4767,52 +4874,14 @@ gdk_win32_toplevel_present (GdkToplevel       *toplevel,
                             GdkToplevelLayout *layout)
 {
   GdkSurface *surface = GDK_SURFACE (toplevel);
-  GdkDisplay *display = gdk_surface_get_display (surface);
-  GdkMonitor *monitor;
-  GdkToplevelSize size;
-  int bounds_width, bounds_height;
+  GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
   int width, height;
-  GdkGeometry geometry;
-  GdkSurfaceHints mask;
   gboolean maximize;
   gboolean fullscreen;
 
-  monitor = gdk_display_get_monitor_at_surface (display, surface);
-  if (monitor)
-    {
-      GdkRectangle workarea;
-
-      gdk_win32_monitor_get_workarea (monitor, &workarea);
-      bounds_width = workarea.width;
-      bounds_height = workarea.height;
-    }
-  else
-    {
-      bounds_width = G_MAXINT;
-      bounds_height = G_MAXINT;
-    }
-
-  gdk_toplevel_size_init (&size, bounds_width, bounds_height);
-  gdk_toplevel_notify_compute_size (toplevel, &size);
-  g_warn_if_fail (size.width > 0);
-  g_warn_if_fail (size.height > 0);
-  width = size.width;
-  height = size.height;
-
-  if (gdk_toplevel_layout_get_resizable (layout))
-    {
-      geometry.min_width = size.min_width;
-      geometry.min_height = size.min_height;
-      mask = GDK_HINT_MIN_SIZE;
-    }
-  else
-    {
-      geometry.max_width = geometry.min_width = width;
-      geometry.max_height = geometry.min_height = height;
-      mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE;
-    }
-  gdk_win32_surface_set_geometry_hints (surface, &geometry, mask);
-  gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
+  g_clear_pointer (&impl->toplevel_layout, gdk_toplevel_layout_unref);
+  impl->toplevel_layout = gdk_toplevel_layout_copy (layout);
+  compute_toplevel_size (surface, FALSE, &width, &height);
   gdk_win32_surface_resize (surface, width, height);
 
   if (gdk_toplevel_layout_get_maximized (layout, &maximize))
@@ -4833,15 +4902,6 @@ gdk_win32_toplevel_present (GdkToplevel       *toplevel,
 
   gdk_win32_surface_show (surface, FALSE);
   maybe_notify_mapped (surface);
-
-  if (size.shadow.is_valid)
-    {
-      gdk_win32_surface_set_shadow_width (surface,
-                                          size.shadow.left,
-                                          size.shadow.right,
-                                          size.shadow.top,
-                                          size.shadow.bottom);
-    }
 }
 
 static gboolean
diff --git a/gdk/win32/gdksurface-win32.h b/gdk/win32/gdksurface-win32.h
index a8def428e0..f5950fcd18 100644
--- a/gdk/win32/gdksurface-win32.h
+++ b/gdk/win32/gdksurface-win32.h
@@ -338,6 +338,13 @@ struct _GdkWin32Surface
   int unscaled_width;
   int unscaled_height;
 
+  GdkToplevelLayout *toplevel_layout;
+  struct {
+    int configured_width;
+    int configured_height;
+    gboolean is_resize;
+  } next_layout;
+
 #ifdef GDK_WIN32_ENABLE_EGL
   EGLSurface egl_surface;
   EGLSurface egl_dummy_surface;


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