[gtk/scrollable_parents_have_precedence: 1323/1323] Prioritize scrolling a GtkScrolledWindow over its child widgets




commit b82ecb5d932cab17db85b3b4adac7be2784ff55d
Author: Nelson Benítez León <nbenitezl gmail com>
Date:   Sat Sep 3 15:08:37 2022 -0400

    Prioritize scrolling a GtkScrolledWindow over its child widgets
    
    Scrolling a GtkScrolledWindow should have precedence
    over child widgets that also react to scrolling
    like GtkComboBox, GtkScale and GtkSpinButton,
    because otherwise when you're in the middle of
    scrolling the window you can involuntarily
    scroll over the widgets and change its values.
    
    This problem can be seen in applications like
    pavucontrol, gnome-control-center audio page,
    gnome-tweaks, devhelp prefs, and so on.
    
    However this patch allows to scroll the child
    widgets when the GtkScrolledWindow itself cannot
    be scrolled (i.e. when no scrollbars are shown
    because window height exceeds the content).
    
    Fixes issue #3092

 gtk/gtkscrolledwindow.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
---
diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c
index bc48c6c6c7..3759c5b4b3 100644
--- a/gtk/gtkscrolledwindow.c
+++ b/gtk/gtkscrolledwindow.c
@@ -408,6 +408,10 @@ static void scrolled_window_scroll (GtkScrolledWindow        *scrolled_window,
                                     double                    delta_x,
                                     double                    delta_y,
                                     GtkEventControllerScroll *scroll);
+static gboolean scroll_controller_scroll (GtkEventControllerScroll *scroll,
+                                          double                    delta_x,
+                                          double                    delta_y,
+                                          GtkScrolledWindow        *scrolled_window);
 
 static guint signals[LAST_SIGNAL] = {0};
 static GParamSpec *properties[NUM_PROPERTIES];
@@ -1229,6 +1233,19 @@ get_wheel_detent_scroll_step (GtkScrolledWindow *sw,
   return scroll_step;
 }
 
+/* Returns whether @window can currently be scrolled
+ * i.e. the scrollbars can move because the content excedes the page_size */
+static gboolean
+content_can_be_scrolled (GtkScrolledWindow *window)
+{
+  GtkAdjustment *vadj;
+  gdouble upper, page_size;
+
+  vadj = gtk_scrolled_window_get_vadjustment (window);
+  g_object_get (vadj, "upper", &upper, "page_size", &page_size, NULL);
+  return !G_APPROX_VALUE ((upper - page_size), 0.0, DBL_EPSILON);
+}
+
 static gboolean
 captured_scroll_cb (GtkEventControllerScroll *scroll,
                     double                    delta_x,
@@ -1246,6 +1263,12 @@ captured_scroll_cb (GtkEventControllerScroll *scroll,
       return GDK_EVENT_STOP;
     }
 
+  if (content_can_be_scrolled (scrolled_window))
+    {
+      scroll_controller_scroll (scroll, delta_x, delta_y, scrolled_window);
+      return GDK_EVENT_STOP;
+    }
+
   return GDK_EVENT_PROPAGATE;
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]