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

New commits:
commit 11a5ddbb17ddb06c12464f9e961aa9eb42cbf9f9
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Thu Mar 2 10:03:11 2023 +0000
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Thu Mar 2 11:33:22 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/+/148091
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index 9e224392b37f..52b0f031d9f3 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -11726,6 +11726,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
 }
 
@@ -11884,6 +11916,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