vcl/inc/unx/gtk/gtkframe.hxx |    4 ++++
 vcl/unx/gtk3/gtkframe.cxx    |    5 +++++
 vcl/unx/gtk3/gtkinst.cxx     |   35 +++++++++++++++++++++++++++++++++++
 3 files changed, 44 insertions(+)

New commits:
commit 6568d572e0c7a9c99580f3cc94273d8ddd00b781
Author:     Caolán McNamara <[email protected]>
AuthorDate: Wed Aug 3 16:50:00 2022 +0100
Commit:     Caolán McNamara <[email protected]>
CommitDate: Wed Aug 3 21:16:22 2022 +0200

    handle scroll events in surrounding GtkSalFrame if there is one
    
    Change-Id: I47f71371246f6322f41b782697d4824517375c76
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137760
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <[email protected]>

diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx
index 80696439ea79..57072134c414 100644
--- a/vcl/inc/unx/gtk/gtkframe.hxx
+++ b/vcl/inc/unx/gtk/gtkframe.hxx
@@ -633,6 +633,10 @@ public:
 #endif
     static OUString             GetPreeditDetails(GtkIMContext* pIMContext, 
std::vector<ExtTextInputAttr>& rInputFlags, sal_Int32& rCursorPos, sal_uInt8& 
rCursorFlags);
 
+#if GTK_CHECK_VERSION(4, 0, 0)
+    gboolean                    
event_controller_scroll_forward(GtkEventControllerScroll* pController, double 
delta_x, double delta_y);
+#endif
+
     const cairo_font_options_t* get_font_options();
 
     void SetColorScheme(GVariant* variant);
diff --git a/vcl/unx/gtk3/gtkframe.cxx b/vcl/unx/gtk3/gtkframe.cxx
index e4cfbdc48a59..999b1e8680a1 100644
--- a/vcl/unx/gtk3/gtkframe.cxx
+++ b/vcl/unx/gtk3/gtkframe.cxx
@@ -3383,6 +3383,11 @@ gboolean 
GtkSalFrame::signalScroll(GtkEventControllerScroll* pController, double
     return true;
 }
 
+gboolean 
GtkSalFrame::event_controller_scroll_forward(GtkEventControllerScroll* 
pController, double delta_x, double delta_y)
+{
+    return GtkSalFrame::signalScroll(pController, delta_x, delta_y, this);
+}
+
 #endif
 
 void GtkSalFrame::gestureSwipe(GtkGestureSwipe* gesture, gdouble velocity_x, 
gdouble velocity_y, gpointer frame)
diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index 8778a6ba9e8e..06c9d706d2fd 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -8420,6 +8420,33 @@ private:
         pThis->signal_adjustment_changed();
     }
 
+#if GTK_CHECK_VERSION(4, 0, 0)
+    // if the widget is inside a GtkSalFrame then ensure the event is 
processed by the GtkSalFrame and not the
+    // GtkScrollbar
+    static gboolean signalScroll(GtkEventControllerScroll* pController, double 
delta_x, double delta_y, gpointer widget)
+    {
+        GtkInstanceScrollbar* pThis = 
static_cast<GtkInstanceScrollbar*>(widget);
+
+        GtkWidget* pParent = 
widget_get_toplevel(GTK_WIDGET(pThis->m_pScrollbar));
+        GtkSalFrame* pFrame = pParent ? GtkSalFrame::getFromWindow(pParent) : 
nullptr;
+
+        return pFrame && pFrame->event_controller_scroll_forward(pController, 
delta_x, delta_y);
+    }
+#else
+    static gboolean signalScroll(GtkWidget* pWidget, GdkEventScroll* 
/*pEvent*/, gpointer widget)
+    {
+        GtkInstanceScrollbar* pThis = 
static_cast<GtkInstanceScrollbar*>(widget);
+
+        GtkWidget* pParent = 
widget_get_toplevel(GTK_WIDGET(pThis->m_pScrollbar));
+        GtkSalFrame* pFrame = pParent ? GtkSalFrame::getFromWindow(pParent) : 
nullptr;
+
+        if (pFrame)
+            g_signal_stop_emission_by_name(pWidget, "scroll-event");
+
+        return false;
+    }
+#endif
+
 public:
     GtkInstanceScrollbar(GtkScrollbar* pScrollbar, GtkInstanceBuilder* 
pBuilder, bool bTakeOwnership)
         : GtkInstanceWidget(GTK_WIDGET(pScrollbar), pBuilder, bTakeOwnership)
@@ -8431,6 +8458,14 @@ public:
 #endif
         , m_nAdjustChangedSignalId(g_signal_connect(m_pAdjustment, 
"value-changed", G_CALLBACK(signalAdjustValueChanged), this))
     {
+#if GTK_CHECK_VERSION(4, 0, 0)
+        GtkEventController* pScrollController = 
gtk_event_controller_scroll_new(GTK_EVENT_CONTROLLER_SCROLL_BOTH_AXES);
+        gtk_event_controller_set_propagation_phase(pScrollController, 
GTK_PHASE_CAPTURE);
+        g_signal_connect(pScrollController, "scroll", 
G_CALLBACK(signalScroll), this);
+        gtk_widget_add_controller(GTK_WIDGET(pScrollbar), pScrollController);
+#else
+        g_signal_connect(pScrollbar, "scroll-event", G_CALLBACK(signalScroll), 
this);
+#endif
     }
 
     virtual void adjustment_configure(int value, int lower, int upper,

Reply via email to