2103d41
From 41be4271e18a21acbcc30d1e61653190f8ef7a6d Mon Sep 17 00:00:00 2001
2103d41
From: Paul Cornett <paulcor@users.noreply.github.com>
2103d41
Date: Fri, 5 Feb 2016 10:26:06 -0800
2103d41
Subject: [PATCH] Adapt window decorations cache for client-side decorations
2103d41
2103d41
Fixes size calculations for TLWs created after the first one,
2103d41
with Wayland, Mir and Broadway. See #17336
2103d41
2103d41
(cherry picked from commit 91ea4872813b90ff91702a11abbe644cb1e5044b)
2103d41
---
2103d41
 src/gtk/toplevel.cpp | 93 +++++++++++++++++++++++++++++++++++++++++++++++-----
2103d41
 1 file changed, 84 insertions(+), 9 deletions(-)
2103d41
2103d41
diff --git a/src/gtk/toplevel.cpp b/src/gtk/toplevel.cpp
2103d41
index 7530b0f..c3d42e8 100644
2103d41
--- a/src/gtk/toplevel.cpp
2103d41
+++ b/src/gtk/toplevel.cpp
2103d41
@@ -40,6 +40,15 @@
2103d41
 #endif
2103d41
 #ifdef GDK_WINDOWING_WAYLAND
2103d41
     #include <gdk/gdkwayland.h>
2103d41
+    #define HAS_CLIENT_DECOR
2103d41
+#endif
2103d41
+#ifdef GDK_WINDOWING_MIR
2103d41
+    #include <gdk/gdkmir.h>
2103d41
+    #define HAS_CLIENT_DECOR
2103d41
+#endif
2103d41
+#ifdef GDK_WINDOWING_BROADWAY
2103d41
+    #include <gdk/gdkbroadway.h>
2103d41
+    #define HAS_CLIENT_DECOR
2103d41
 #endif
2103d41
 
2103d41
 #include "wx/gtk/private.h"
2103d41
@@ -82,6 +91,26 @@ static enum {
2103d41
 static bool gs_decorCacheValid;
2103d41
 #endif
2103d41
 
2103d41
+#ifdef HAS_CLIENT_DECOR
2103d41
+static bool HasClientDecor(GtkWidget* widget)
2103d41
+{
2103d41
+    GdkDisplay* display = gtk_widget_get_display(widget);
2103d41
+#ifdef GDK_WINDOWING_WAYLAND
2103d41
+    if (GDK_IS_WAYLAND_DISPLAY(display))
2103d41
+        return true;
2103d41
+#endif
2103d41
+#ifdef GDK_WINDOWING_MIR
2103d41
+    if (GDK_IS_MIR_DISPLAY(display))
2103d41
+        return true;
2103d41
+#endif
2103d41
+#ifdef GDK_WINDOWING_BROADWAY
2103d41
+    if (GDK_IS_BROADWAY_DISPLAY(display))
2103d41
+        return true;
2103d41
+#endif
2103d41
+    return false;
2103d41
+}
2103d41
+#endif // HAS_CLIENT_DECOR
2103d41
+
2103d41
 //-----------------------------------------------------------------------------
2103d41
 // RequestUserAttention related functions
2103d41
 //-----------------------------------------------------------------------------
2103d41
@@ -235,8 +264,24 @@ size_allocate(GtkWidget*, GtkAllocation* alloc, wxTopLevelWindowGTK* win)
2103d41
         GtkAllocation a;
2103d41
         gtk_widget_get_allocation(win->m_widget, &a);
2103d41
         wxSize size(a.width, a.height);
2103d41
-        size.x += win->m_decorSize.left + win->m_decorSize.right;
2103d41
-        size.y += win->m_decorSize.top + win->m_decorSize.bottom;
2103d41
+#ifdef HAS_CLIENT_DECOR
2103d41
+        if (HasClientDecor(win->m_widget))
2103d41
+        {
2103d41
+            GtkAllocation a2;
2103d41
+            gtk_widget_get_allocation(win->m_mainWidget, &a2;;
2103d41
+            wxTopLevelWindowGTK::DecorSize decorSize;
2103d41
+            decorSize.left = a2.x;
2103d41
+            decorSize.right = a.width - a2.width - a2.x;
2103d41
+            decorSize.top = a2.y;
2103d41
+            decorSize.bottom = a.height - a2.height - a2.y;
2103d41
+            win->GTKUpdateDecorSize(decorSize);
2103d41
+        }
2103d41
+        else
2103d41
+#endif
2103d41
+        {
2103d41
+            size.x += win->m_decorSize.left + win->m_decorSize.right;
2103d41
+            size.y += win->m_decorSize.top + win->m_decorSize.bottom;
2103d41
+        }
2103d41
         win->m_width  = size.x;
2103d41
         win->m_height = size.y;
2103d41
 
2103d41
@@ -1062,8 +1107,13 @@ void wxTopLevelWindowGTK::DoMoveWindow(int WXUNUSED(x), int WXUNUSED(y), int WXU
2103d41
 void wxTopLevelWindowGTK::GTKDoGetSize(int *width, int *height) const
2103d41
 {
2103d41
     wxSize size(m_width, m_height);
2103d41
-    size.x -= m_decorSize.left + m_decorSize.right;
2103d41
-    size.y -= m_decorSize.top + m_decorSize.bottom;
2103d41
+#ifdef HAS_CLIENT_DECOR
2103d41
+    if (!HasClientDecor(m_widget))
2103d41
+#endif
2103d41
+    {
2103d41
+        size.x -= m_decorSize.left + m_decorSize.right;
2103d41
+        size.y -= m_decorSize.top + m_decorSize.bottom;
2103d41
+    }
2103d41
     if (size.x < 0) size.x = 0;
2103d41
     if (size.y < 0) size.y = 0;
2103d41
 #if wxUSE_LIBHILDON2
2103d41
@@ -1171,7 +1221,12 @@ void wxTopLevelWindowGTK::DoGetClientSize( int *width, int *height ) const
2103d41
         base_type::DoGetClientSize(width, height);
2103d41
     else
2103d41
     {
2103d41
-        GTKDoGetSize(width, height);
2103d41
+        int w = m_width - (m_decorSize.left + m_decorSize.right);
2103d41
+        int h = m_height - (m_decorSize.top + m_decorSize.bottom);
2103d41
+        if (w < 0) w = 0;
2103d41
+        if (h < 0) h = 0;
2103d41
+        if (width) *width = w;
2103d41
+        if (height) *height = h;
2103d41
     }
2103d41
 }
2103d41
 
2103d41
@@ -1193,8 +1248,20 @@ void wxTopLevelWindowGTK::DoSetSizeHints( int minW, int minH,
2103d41
     hints.min_height = 1;
2103d41
     hints.max_width = INT_MAX;
2103d41
     hints.max_height = INT_MAX;
2103d41
-    const int decorSize_x = m_decorSize.left + m_decorSize.right;
2103d41
-    const int decorSize_y = m_decorSize.top + m_decorSize.bottom;
2103d41
+    int decorSize_x;
2103d41
+    int decorSize_y;
2103d41
+#ifdef HAS_CLIENT_DECOR
2103d41
+    if (HasClientDecor(m_widget))
2103d41
+    {
2103d41
+        decorSize_x = 0;
2103d41
+        decorSize_y = 0;
2103d41
+    }
2103d41
+    else
2103d41
+#endif
2103d41
+    {
2103d41
+        decorSize_x = m_decorSize.left + m_decorSize.right;
2103d41
+        decorSize_y = m_decorSize.top + m_decorSize.bottom;
2103d41
+    }
2103d41
     if (minSize.x > decorSize_x)
2103d41
         hints.min_width = minSize.x - decorSize_x;
2103d41
     if (minSize.y > decorSize_y)
2103d41
@@ -1221,11 +1288,19 @@ void wxTopLevelWindowGTK::DoSetSizeHints( int minW, int minH,
2103d41
         (GtkWindow*)m_widget, NULL, &hints, (GdkWindowHints)hints_mask);
2103d41
 }
2103d41
 
2103d41
-#ifdef GDK_WINDOWING_X11
2103d41
 void wxTopLevelWindowGTK::GTKUpdateDecorSize(const DecorSize& decorSize)
2103d41
 {
2103d41
     if (!IsMaximized() && !IsFullScreen())
2103d41
         GetCachedDecorSize() = decorSize;
2103d41
+
2103d41
+#ifdef HAS_CLIENT_DECOR
2103d41
+    if (HasClientDecor(m_widget))
2103d41
+    {
2103d41
+        m_decorSize = decorSize;
2103d41
+        return;
2103d41
+    }
2103d41
+#endif
2103d41
+#ifdef GDK_WINDOWING_X11
2103d41
     if (m_updateDecorSize && memcmp(&m_decorSize, &decorSize, sizeof(DecorSize)))
2103d41
     {
2103d41
         m_useCachedClientSize = false;
2103d41
@@ -1292,8 +1367,8 @@ void wxTopLevelWindowGTK::GTKUpdateDecorSize(const DecorSize& decorSize)
2103d41
         showEvent.SetEventObject(this);
2103d41
         HandleWindowEvent(showEvent);
2103d41
     }
2103d41
-}
2103d41
 #endif // GDK_WINDOWING_X11
2103d41
+}
2103d41
 
2103d41
 wxTopLevelWindowGTK::DecorSize& wxTopLevelWindowGTK::GetCachedDecorSize()
2103d41
 {