vcl/unx/gtk3/gtkinst.cxx |   53 +++++++++++++++++++++++++++++++----------------
 1 file changed, 36 insertions(+), 17 deletions(-)

New commits:
commit 1f99fc7f94a27da5e8a00da7e74dc155780a139b
Author:     Caolán McNamara <[email protected]>
AuthorDate: Mon Nov 22 20:58:34 2021 +0000
Commit:     Caolán McNamara <[email protected]>
CommitDate: Tue Nov 23 10:54:58 2021 +0100

    gtk3: reuse popover replacement as mouse event widget
    
    Change-Id: I99aa1f1843c5ff6e4c76716178e721a96ae284fa
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125676
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <[email protected]>

diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index 87c40d6ad976..b3dab5b14ef5 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -2750,9 +2750,16 @@ protected:
         }
 
 #if !GTK_CHECK_VERSION(4, 0, 0)
-        if (!(m_pMouseEventBox && m_pMouseEventBox != m_pWidget))
+        if (!m_pMouseEventBox || m_pMouseEventBox == m_pWidget)
             return;
 
+        // GtkWindow replacement for GtkPopover case
+        if (!GTK_IS_EVENT_BOX(m_pMouseEventBox))
+        {
+            m_pMouseEventBox = nullptr;
+            return;
+        }
+
         // put things back they way we found them
         GtkWidget* pParent = gtk_widget_get_parent(m_pMouseEventBox);
 
@@ -22077,6 +22084,23 @@ public:
         , m_nSignalId(g_signal_connect(m_pPopover, "closed", 
G_CALLBACK(signalClosed), this))
         , m_pClosedEvent(nullptr)
     {
+#if !GTK_CHECK_VERSION(4, 0, 0)
+#if defined(GDK_WINDOWING_X11)
+        //under wayland a Popover will work to "escape" the parent dialog, not
+        //so under X, so come up with this hack to use a raw GtkWindow
+        GdkDisplay *pDisplay = gtk_widget_get_display(GTK_WIDGET(m_pPopover));
+        if (DLSYM_GDK_IS_X11_DISPLAY(pDisplay) && 
gtk_popover_get_constrain_to(m_pPopover) == GTK_POPOVER_CONSTRAINT_NONE)
+        {
+            m_pMenuHack = GTK_WINDOW(gtk_window_new(GTK_WINDOW_POPUP));
+            gtk_window_set_type_hint(m_pMenuHack, GDK_WINDOW_TYPE_HINT_COMBO);
+            gtk_window_set_resizable(m_pMenuHack, false);
+            g_signal_connect(m_pMenuHack, "key-press-event", 
G_CALLBACK(keyPress), this);
+            g_signal_connect(m_pMenuHack, "grab-broken-event", 
G_CALLBACK(signalGrabBroken), this);
+            g_signal_connect(m_pMenuHack, "button-press-event", 
G_CALLBACK(signalButtonPress), this);
+            g_signal_connect(m_pMenuHack, "button-release-event", 
G_CALLBACK(signalButtonRelease), this);
+        }
+#endif
+#endif
     }
 
     virtual void popup_at_rect(weld::Widget* pParent, const tools::Rectangle& 
rRect, weld::Placement ePlace) override
@@ -22115,22 +22139,6 @@ public:
         {
             if (!m_bMenuPoppedUp)
             {
-                if (!m_pMenuHack)
-                {
-                    m_pMenuHack = GTK_WINDOW(gtk_window_new(GTK_WINDOW_POPUP));
-                    gtk_window_set_type_hint(m_pMenuHack, 
GDK_WINDOW_TYPE_HINT_COMBO);
-                    bool bModal = gtk_popover_get_modal(m_pPopover);
-                    gtk_window_set_modal(m_pMenuHack, bModal);
-                    gtk_window_set_resizable(m_pMenuHack, false);
-                    g_signal_connect(m_pMenuHack, "key-press-event", 
G_CALLBACK(keyPress), this);
-                    if (bModal)
-                    {
-                         g_signal_connect(m_pMenuHack, "grab-broken-event", 
G_CALLBACK(signalGrabBroken), this);
-                         g_signal_connect(m_pMenuHack, "button-press-event", 
G_CALLBACK(signalButtonPress), this);
-                         g_signal_connect(m_pMenuHack, "button-release-event", 
G_CALLBACK(signalButtonRelease), this);
-                    }
-                }
-
                 MovePopoverContentsToWindow(GTK_WIDGET(m_pPopover), 
m_pMenuHack, pWidget, aRect, ePlace);
                 m_bMenuPoppedUp = true;
             }
@@ -22150,6 +22158,16 @@ public:
             return gtk_widget_get_visible(GTK_WIDGET(m_pMenuHack));
         return gtk_widget_get_visible(m_pWidget);
     }
+
+    virtual void ensureMouseEventWidget() override
+    {
+        if (!m_pMouseEventBox && m_pMenuHack)
+        {
+            m_pMouseEventBox = GTK_WIDGET(m_pMenuHack);
+            return;
+        }
+        GtkInstanceContainer::ensureMouseEventWidget();
+    }
 #endif
 #endif
 
@@ -22179,6 +22197,7 @@ public:
 
     virtual ~GtkInstancePopover() override
     {
+        DisconnectMouseEvents();
 #if !GTK_CHECK_VERSION(4, 0, 0)
         if (m_pMenuHack)
             gtk_widget_destroy(GTK_WIDGET(m_pMenuHack));

Reply via email to