vcl/unx/gtk3/gtkinst.cxx |   35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

New commits:
commit 76d95da3d253dca847f78037275c1a29b5516885
Author:     Caolán McNamara <[email protected]>
AuthorDate: Thu Mar 2 10:03:11 2023 +0000
Commit:     Christian Lohmaier <[email protected]>
CommitDate: Thu Mar 9 12:40:59 2023 +0000

    Resolves: tdf#153885 keep popovers with application window parent inside 
that
    
    for wayland.  If the popover window is the application window, contrain
    it within the application window so it won't be cut off off screen,
    because gtk under wayland just puts it when it wants to be regardless of
    screen bounds.
    
    Leave dialog hosted ones alone, like format, watermark, which are likely
    presented in the middle of the screen and are too small to constrain the
    popover inside.
    
    Change-Id: Ibdc0749613a3b587414e88be7d0aea81c637f31a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148095
    Tested-by: Jenkins
    Reviewed-by: Christian Lohmaier <[email protected]>

diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index 75b3f418c72e..a55c01cf8934 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -11722,6 +11722,38 @@ public:
 #endif
         return eRet;
     }
+
+    // tdf#153885 for wayland if the popover window is the application
+    // window, contrain it within the application window so it won't
+    // be cut off off screen. Leave dialog hosted ones alone, like
+    // format, watermark, which are likely presented in the middle
+    // of the screen and are too small to constrain the popover inside.
+    void ConstrainApplicationWindowPopovers(GtkToggleButton* pItem)
+    {
+#if defined(GDK_WINDOWING_WAYLAND)
+        GdkDisplay *pDisplay = gtk_widget_get_display(GTK_WIDGET(pItem));
+        if (DLSYM_GDK_IS_WAYLAND_DISPLAY(pDisplay) && 
GTK_IS_MENU_BUTTON(pItem))
+        {
+            GtkMenuButton* pMenuButton = GTK_MENU_BUTTON(pItem);
+            if (GtkPopover* pPopover = 
gtk_menu_button_get_popover(pMenuButton))
+            {
+                if (gtk_popover_get_constrain_to(pPopover) == 
GTK_POPOVER_CONSTRAINT_NONE)
+                {
+                    GtkWidget* pTopLevel = 
widget_get_toplevel(GTK_WIDGET(pItem));
+                    GtkSalFrame* pFrame = pTopLevel ? 
GtkSalFrame::getFromWindow(pTopLevel) : nullptr;
+                    if (pFrame)
+                    {
+                        // the toplevel is an application window
+                        gtk_popover_set_constrain_to(pPopover, 
GTK_POPOVER_CONSTRAINT_WINDOW);
+                    }
+                }
+            }
+        }
+#else
+        (void)pItem;
+#endif
+    }
+
 #endif
 }
 
@@ -11880,6 +11912,9 @@ private:
 
     static void signalItemToggled(GtkToggleButton* pItem, gpointer widget)
     {
+#if !GTK_CHECK_VERSION(4, 0, 0)
+        ConstrainApplicationWindowPopovers(pItem);
+#endif
         GtkInstanceToolbar* pThis = static_cast<GtkInstanceToolbar*>(widget);
         SolarMutexGuard aGuard;
         pThis->signal_item_toggled(pItem);

Reply via email to