Compare commits

...

1 Commits

Author SHA1 Message Date
Nelson Benítez León
b82ecb5d93 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
2022-09-03 21:41:50 -04:00

View File

@@ -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;
}