The implicit grab may be finished so the pointer lies on top of the other
scrollbar, in this case one scrollbar should lose the hovering state, and
the other should gain it. So we must check for proximity in both indicators.
We were not taking the scrollable borders into account when
requesting size for the scrolled window, which could lead
to underallocating the scrollbars at size allocation time
when we *did* take the borders into account.
This is most notable with treeviews, where we have the
headers as borders, and was causing the treeview-crash-too-wide
reftest to fail.
And use it to handle kinetic scrolling in the GtkScrolledWindow.
However, dropping the delta check causes the X11-based kinetic
scroll to break since we don't have the stop event here. Correct handling of
xf86-input-libinput-based scroll events is still being discussed.
https://bugzilla.gnome.org/show_bug.cgi?id=756729
Otherwise it's attempted through a timeout, which gets cancelled early after,
and the slider disappears after a while with no mouse activity despite the
ongoing implicit grab.
Once the grab is finished, check_update_scrollbar_proximity() will be called
again on both scrollbars, and the fade out animation will be triggered as a
result.
https://bugzilla.gnome.org/show_bug.cgi?id=754745
These days exposure happens only on the native windows (generally the
toplevel window) and is propagated down recursively. The expose event
is only useful for backwards compat, and in fact, for double buffered
widgets we totally ignore the event (and non-double buffering breaks
on wayland).
So, by not setting the mask we avoid emitting these events and then
later ignoring them.
We still keep it on eventbox, fixed and layout as these are used
in weird ways that want backwards compat.
In order to play along with child widgets that use scroll events for anything
else than scrolling, it will be better to do this in the bubble phase, so
the child widget has an opportunity to GDK_EVENT_STOP the event before we
trigger kinetic scrolling.
This of course won't work for widgets that choose to reimplement scroll event
handling themselves, they should be smart at resorting to GtkScrolledWindow's
scroll event handling.
This fixes kinetic scrolling kicking in too pervasively on widgets that eg.
implement zoom on scroll events.
https://bugzilla.gnome.org/show_bug.cgi?id=753495
The libinput driver will send a 0/0 scroll event on touchpads and other
devices where it knows scrolling stopped for sure. Use these events to
trigger kinetic scrolling from there.
The mechanism is similar to GtkGestureSwipe, we keep a backlog of the
latest dx/dy till a previous point in time, and calculate the final
velocities from there, with the difference we're dealing with scroll
units, and not pixel distances.
https://bugzilla.gnome.org/show_bug.cgi?id=749770
If a GtkScrolledWindow is just unmapped and promptly mapped again, the
indicators are left in a semi-visible state, so the GdkWindow isn't raised
properly above scrolledwindow content. This inconsistent state went away
the next time the indicator is hidden.
So, reset all state about indicator window visibility, animation
progress and conceil timer on ::unmap, this will be enough to make the
indicators start out hidden like on newly created scrolledwindows.
Libinput will use 0.0f on the "scrolling finished" event, so check for this
instead of rounding (<1 values are sort of frequent on touchpads). This
impedes bug #745315 to resurface after commit d563b943ed.
When the scrolledwindow receives scroll events, it ensures the timeout to
maybe start the "snap back to edges" animation is reset, but it does nothing
about the animation source. It must be reset just the same, to maybe be
started after the timeout fires up.
The code managing scrollbars visibility was too pervasively checking for
mouse devices, leaving pen/eraser/cursor devices with no scrollbars at
all. Relax these checks a bit, and actually toggle full-width scrollbars
on pen/eraser devices, so it is an easier target.
https://bugzilla.gnome.org/show_bug.cgi?id=747608
The coordinate translations here were not working properly
for window widgets inside the scrolled window, as can be
seen e.g. for the horizontal scrollbar of the 'Tree View'
example in gtk3-demo.
https://bugzilla.gnome.org/show_bug.cgi?id=747406
When moving over a non-expanded indicator from the outside, we were
not expanding it, due to on_scrollbar being true. This can be seen
e.g. when moving from the content pane over to the sidebar indicator
in gtk3-demo. We must still ensure that the indicator is expanded
when receiving motion events over the indicator.
https://bugzilla.gnome.org/show_bug.cgi?id=747407
This path is only intended to be triggered on events directed towards the
child of the scrolledwindow, so make it explicitly so. This avoids scrollbar
"over" state flashing when dragging finishes within the slider.
https://bugzilla.gnome.org/show_bug.cgi?id=746961
It has been a long-standing request to interpret scroll events
with Shift held down as horizontal instead of vertical, and
some applications are already doing this on their own.
https://bugzilla.gnome.org/show_bug.cgi?id=132197
When the scrollbars are overlayed, the size requisition of the
scrolled window should not depend on whether the scrollbars are
visible or not. This was not quite the case, because we forgot
one case where scrollbar size was still added to the requisition.
This is not specified specifically by the attached controllers, so let
the scrolledwindow set the mask, as motion events with no buttons pressed
are interesting to it.
https://bugzilla.gnome.org/show_bug.cgi?id=745344
If a scrollbar is not shown (because of policies, or because it isn't
necessary), it doesn't make sense to start fade animations on its window
on captured motion events.
gtk_scrolled_window_allocate_scrollbar was calling
gtk_scrolled_window_allocate_child just to get the relative
allocation, overlooking the fact that that function is only
safe to call if the scrolled window _has_ a child. Unfortunately,
gtk_scrolled_window_allocate_scrollbar will sometimes get called
when that is not the case. Since we are really only interested
in the relative allocation, just get that directly. This
fixes a segfault in the style-properties-nth-child reftest.
At the time of creating the indicator window, the scrollbar allocation is
poked and reused as the initial window dimensions. This usually happens
on two circumstances, either initially (so a ::size-allocate is emitted,
relocating the windows in the right places), or post-initialization when
calling set_overlay_scrolling() (so the scrollbars already have a valid
size allocation)
However, if the scrolledwindow is unrealized, and later re-realized again,
the scrollbars will already have a valid allocation, although 0,0 based
due to being contained in the previous indicator window. This comes out
wrong then, and the indicator window is given 0,0 based coordinates too.
Fix this by refactoring the scrollbar allocation code out of size_allocate,
and also use that given size at the time of creating the indicator windows,
this will provide the right widget-relative allocation anytime.
This avoids showing the scrollbars if we are positive the child widget
is being manipulated, regardless of the pointer being close to any of these.
On the next motion event after finishing the operation, the scrollbar will
be shown if necessary.
https://bugzilla.gnome.org/show_bug.cgi?id=743894
In that case the scrolledwindow still gets events through the captured
handler, and can thus still control visibility, so hiding the indicators
in this case can only lead to flashing.
This will be used to just detect when an edge of the scrollable area is
reached - as opposed to the edge-overshot signal that is emitted when
the user scrolls past the edge.
https://bugzilla.gnome.org/show_bug.cgi?id=742848