After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 462208 - Add kinetic scrolling to gtk
Add kinetic scrolling to gtk
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Widget: GtkScrolledWindow
unspecified
Other All
: Low enhancement
: 3.4
Assigned To: gtkdev
gtkdev
touch
: 402931 601923 (view as bug list)
Depends on:
Blocks: 461268 461269 461273 461391 509179 557956
 
 
Reported: 2007-07-31 16:53 UTC by Jeff Schroeder
Modified: 2013-01-16 16:37 UTC
See Also:
GNOME target: ---
GNOME version: Unversioned Enhancement


Attachments
timeline: Add _gtk_timeline_get_elapsed_time() (2.56 KB, patch)
2011-02-11 14:10 UTC, Carlos Garcia Campos
none Details | Review
scrolledwindow: Initial kinetic scrolling support (39.26 KB, patch)
2011-02-11 14:13 UTC, Carlos Garcia Campos
none Details | Review
Tests (5.74 KB, patch)
2011-02-11 14:18 UTC, Carlos Garcia Campos
none Details | Review
scrolledwindow: Add auto-hide-scrollbars style property (9.07 KB, patch)
2011-02-21 13:54 UTC, Carlos Garcia Campos
none Details | Review
scrolledwindow: Allow selections and drag-and-drop when kinetic scrolling is enabled (9.79 KB, patch)
2011-03-23 16:56 UTC, Carlos Garcia Campos
none Details | Review
Add GtkWidget::press-and-hold signal (34.03 KB, patch)
2011-04-04 09:52 UTC, Carlos Garcia Campos
none Details | Review
scrolledwindow: Allow selections and drag-and-drop when kinetic scrolling is enabled (using press-and-hold-signal) (12.73 KB, patch)
2011-04-04 09:54 UTC, Carlos Garcia Campos
none Details | Review
Patch set for kinetic scrolling using press-and-hold for dnd and selections (105.03 KB, patch)
2011-07-20 12:45 UTC, Carlos Garcia Campos
none Details | Review
Also connect to grab-notify during press and hold (2.82 KB, patch)
2011-10-24 09:32 UTC, Carlos Garnacho
none Details | Review
update testkineticscrolling to use GtkGrid (4.36 KB, patch)
2011-10-24 09:34 UTC, Carlos Garnacho
none Details | Review

Description Jeff Schroeder 2007-07-31 16:53:13 UTC
OpenMoko was nice enough to release code demoing iphone-like kinetic scrolling
in a listview.

From Bastien Nocera ( http://bugzilla.gnome.org/show_bug.cgi?id=461378 ):
It would be nice if it were
integrated directly in the GtkTreeView and settable via an XSetting for
example, so that system that would make use of it (ie. tablets) could just set
the flag, and get kinetic scrolling.


Demo:
http://chrislord.net/files/mokofingerscroll.ogg

Code:
http://svnweb.openmoko.org/trunk/src/target/OM-2007.2/libraries/libmokoui2/libmokoui/moko-finger-scroll.c?rev=2545&view=markup
Comment 1 Kristian Rietveld 2007-07-31 17:26:24 UTC
It's nice that several people are now hacking up kinetic scrolling in tree views, but it is not a good idea at all to rush this into GtkTreeView.  I am not going to add this to GtkTreeView, things like this need proper support in "core" GTK+ instead.

Moving to GTK+ component.
Comment 2 Nelson Benitez 2008-10-01 10:40:49 UTC
Yes, adding this to gtk+ scrollbars would permit any widget, not only treeviews, to use it.
Comment 3 Claudio Saavedra 2009-11-25 09:32:22 UTC
*** Bug 601923 has been marked as a duplicate of this bug. ***
Comment 4 Javier Jardón (IRC: jjardon) 2009-11-25 19:50:08 UTC
Midori has already a widget that maybe can be integrated into
GtkScrolledWindow:
http://git.xfce.org/apps/midori/commit/?id=96093d906754a986ef9b6dae5eae0ba8411653d4
Comment 5 Dov Grobgeld 2010-01-10 16:06:52 UTC
Couldn't this be implemented in GtkAdjustment or a subclass by adding a "motion profile" that describes the motion from the current to the final destination. The GtkAdjustment would continously send "value-changed" events to its listeners until it has settled down at its final position due to friction.

While a client does gtk_adjustment_set_value() the time stamps of the events may be remembered and from it the current "velocity" (difference between the last two set_value() calls divided with the difference in their time) may be derived, and when no more events are received the motion will continue according to the selected motion profile as described above.

The motion profile could be a theme property so it is possible to turn it on and off easily.

I think this would be pretty easy to implement and it would cause minimal changes to Gtk...
Comment 6 Dov Grobgeld 2010-01-10 16:11:20 UTC
Just one more analogy.

This is like adding physical inertia to the GtkAdjustment so that once you've got it sliding it will keep going until friction stops it. And all widgets that are attached to it, will move along.
Comment 7 Javier Jardón (IRC: jjardon) 2010-01-20 03:37:29 UTC
How Qt implement this: http://qt.nokia.com/doc/qt-maemo-4.6/qabstractkineticscroller.html
Comment 8 Daniel Svensson 2010-04-18 22:17:34 UTC
There is also:

http://maemo.gitorious.org/hildon/hildon/blobs/master/hildon/hildon-pannable-area.c

This is actually the only version I got running. My attempts in using midoris katze-scrolled failed :/.

Missing in the Hildon version is:
* no kinetic scrolling when using mouse wheel
* no kinetic scrolling when using keyboard
* no native scrollbar
* the animations when bouncing outside the beginning or end of a GtkTreeView is too fast, and I can't seem to find its config value.
Comment 9 gbz 2010-10-16 09:01:30 UTC
*** Bug 402931 has been marked as a duplicate of this bug. ***
Comment 10 Carlos Garcia Campos 2011-01-31 13:14:55 UTC
Do we want this to be a feature of existing GtkScrolledWindow or a new widget (probably derived from GtkScrolledWindow) ?
I don't see any situation where changing between kinetic and normal mode at runtime makes sense, so it's probably better to add new widget.
Comment 11 Bastien Nocera 2011-01-31 13:18:22 UTC
(In reply to comment #10)
> Do we want this to be a feature of existing GtkScrolledWindow or a new widget
> (probably derived from GtkScrolledWindow) ?
> I don't see any situation where changing between kinetic and normal mode at
> runtime makes sense, so it's probably better to add new widget.

Though we lack the ability to detect that, "swappable" laptops (that can go between tablet and full laptop modes) would probably want to be able to switch between the 2 modes.
Comment 12 Christian Dywan 2011-01-31 13:50:41 UTC
And there is another aspect: you don't want to duplicate application UI or swap widgets just because it wants to run on touchable or non-touchable devices.

I strongly prefer enhancing GtkScrolledWindow over a widget that can only be used with a touch screen.
Comment 13 Carlos Garnacho 2011-02-01 20:44:14 UTC
I'd like to suggest to have GtkScrolledWindow do this based on the device returned by gdk_event_get_source_device(). This function returns the HW device that's doing the motion event, and IMHO kinetic scrolling doesn't make much sense with a mouse, but a lot on a touchscreen for example.

in fact I think GtkSettings::gtk-touchscreen-mode should go in favor of live behavior based on the source device, but that's more widespread than this bug.
Comment 14 Paul Wise 2011-02-04 10:50:18 UTC
I have one of the laptops that Bastien mentioned (Thinkpad X201 Tablet). This laptop has keyboard, stylus and multi-touch screen (only 2 finger). The pen/stylus and touch screen are always active, in laptop or tablet mode. If you want someone to test it, please send me a mail or contact another way:

http://bonedaddy.net/pabs3/about/#contact

I also have an OpenMoko Freerunner I could test on.

Both devices run Debian testing, unstable and experimental.
Comment 15 Carlos Garcia Campos 2011-02-07 12:57:23 UTC
One problem I've seen with current implementations is that we need to synthesize events because events are propagated from child to parent in gtk+. So when a button-press event is handled by the scrolled window, it has already been hanlded by the child widget. Clutter has a captured-event signal that is emitted from parent to children. Something like that would make this thing easier, because the scrolled window would handle all events before the child widget, checking whether we are scrolling or not, and when not scrolling simply return FALSE to propagate the event to the child widget.
Do you think adding a captured-event signal would be acceptable for gtk+?
Comment 16 Matthias Clasen 2011-02-07 19:12:56 UTC
Doing proper event capture/bubble is definitively something we want for 4.0
Comment 17 Carlos Garcia Campos 2011-02-08 14:14:44 UTC
(In reply to comment #16)
> Doing proper event capture/bubble is definitively something we want for 4.0

I've just opened a separate bug report for this. I've attached the patch I'm currently using to implement kinetic scrolling without synthesize events. 

https://bugzilla.gnome.org/show_bug.cgi?id=641836
Comment 18 Carlos Garcia Campos 2011-02-11 14:10:10 UTC
Created attachment 180655 [details] [review]
timeline: Add _gtk_timeline_get_elapsed_time()

This patch simply adds a method to GtkTimeline to get the elapsed time in milliseconds since the last frame.
Comment 19 Carlos Garcia Campos 2011-02-11 14:13:49 UTC
Created attachment 180656 [details] [review]
scrolledwindow: Initial kinetic scrolling support

This is a first implementation of kinetic scrolling in GtkScrolledWindow using the mx-kinetic-scroll-view code for the animation. Some notes about the patch:

 - It's work in progress to get a review and suggestions, not a final patch.
 - It uses the captured-event so it applies on top of patch attached to bug #641836
 - At the moment it only adds one new property to enable/disable kinetic scrolling, we need to decide what other parameters we want to expose as properties (fps, overshoot, deceleration rate, elastic animation, etc.)
 - It always uses the captured-event, Chris Lord suggested to add an option to enable/disable it. Not using captured-event would allow, for example, to only let the user drag to scroll on some parts where there isn't a child widget handling button press events.
 - Scrollbars are still visible and work the same way when kinetic scroll mode is enabled. Hildon panneable area has scrollbars, just as an indicator, that fade in/out when scrolling. I'm not sure we want something like that, or even make it configurable.
 - I've implemented adjustment_interpolate() based on MxAdjustment in scrolled-window, maybe it makes sense to add gtk_adjustment_interpolate() and make it public, so that it could be used to implement other animations like smooth scrolling.
 - Elastic effect is currently unimplemented because gtk_adjustment_set_value() always clamps the value. MxAdjustment doesn't clamp the value when elastic effect is enabled. 
 - There are some problems that I'm not sure how to solve that depend on the widgets contained in the scrolled window. For example, text selections if the widget is a text view or entry, drag and drop operations, etc.
Comment 20 Carlos Garcia Campos 2011-02-11 14:18:35 UTC
Created attachment 180657 [details] [review]
Tests

Two patches to add some tests. The first one modifes the scrolled window test adding a checkbox to enable/disable kinetic scrolling at runtime. The second one contains two scrolled windows with kinetic scrolling enabled, one with a non-scrollable widget using GtkViewport and the other with a textview where you can see the problem with selections that I mentioned before.
Comment 21 Carlos Garcia Campos 2011-02-17 11:31:57 UTC
(In reply to comment #19)
> Created an attachment (id=180656) [details] [review]
> scrolledwindow: Initial kinetic scrolling support

>  - Scrollbars are still visible and work the same way when kinetic scroll mode
> is enabled. Hildon panneable area has scrollbars, just as an indicator, that
> fade in/out when scrolling. I'm not sure we want something like that, or even
> make it configurable.

I've been thinking about this and playing a bit with the theme and I've realized that we can achive mostly the same result than hildon only changing the css, for example with this:

GtkScrollbar {
    -GtkScrollbar-has-backward-stepper: false;
    -GtkScrollbar-has-forward-stepper: false;
    -GtkScrollbar-has-secondary-backward-stepper: false;
    -GtkScrollbar-has-secondary-forward-stepper: false;
    -GtkRange-trough-border: 1;
    -GtkRange-slider-width: 6;
}

GtkScrolledWindow {
    -GtkScrolledWindow-scrollbars-within-bevel: true;
    -GtkScrolledWindow-scrollbar-spacing: 0;
}

We would still need a way to auto-hide the scrollbars like hildon does, this might be another style property so that it will depend on the theme too.
Comment 22 Carlos Garcia Campos 2011-02-21 13:54:01 UTC
Created attachment 181458 [details] [review]
scrolledwindow: Add auto-hide-scrollbars style property

This patch applies on top of the previous ones.
Comment 23 Benjamin Otte (Company) 2011-02-22 13:39:22 UTC
(In reply to comment #12)
> And there is another aspect: you don't want to duplicate application UI or swap
> widgets just because it wants to run on touchable or non-touchable devices.
> 
Do you think using the same UI for touch and non-touch is a useful goal to aim for? I would assume that people want a completely different UI for touch anyway. Like what Carlos is doing with the auto-hide scrollbars, it already changes the UI of the scrolled window quite fundamentally.

I suspect the same would have to happen for other widgets, too (like making switches out of checkboxes?).
Comment 24 Carlos Garcia Campos 2011-02-23 17:13:09 UTC
(In reply to comment #19)
>  - There are some problems that I'm not sure how to solve that depend on the
> widgets contained in the scrolled window. For example, text selections if the
> widget is a text view or entry, drag and drop operations, etc.

Hildon solved these issues by only allowing selections when shift key is pressed. We could do something similar, when kinetic mode is enabled, if shift modifier (or any other actually) is present we can just return FALSE from captured-event signal to let the child widget handle the event normally.
Comment 25 Carlos Garnacho 2011-02-24 02:09:16 UTC
(In reply to comment #23)
> Do you think using the same UI for touch and non-touch is a useful goal to aim
> for? I would assume that people want a completely different UI for touch

Let's not forget that things aren't black and white anymore. There are laptops with touchscreens, some even multitouch capable, and vanilla gnome should work fine out of the box, or at least that's where I'm mentally heading to, maybe because I have one of these :)

> 
> I suspect the same would have to happen for other widgets, too (like making
> switches out of checkboxes?).

You've got a point there, doing a touch friendly UI would still require some effort/choosing from the app developer, but the most we get right in the toolkit, the most consistent the experience is.
Comment 26 Paul Wise 2011-02-24 02:47:28 UTC
I am typing this on a Lenovo X201t (running GNOME 2), which is a laptop with a screen that does stylus (pen, eraser & right click button) and 2-finger multitouch. It also has a trackpoint, a touchpad and an external mouse. It can also convert into a tablet, which hides the keyboard, trackpoint and touchpad once the screen is turned all the way around. I want all these devices to work in the way I would expect all the time. I would expect to be able to use the touchscreen to scroll windows, drag them around, resize them (with 2 fingers) in both tablet and laptop modes. I would expect the stylus would work similarly, but I might want to be able to select text by right-clicking and dragging. The mouse/trackpoint/touchpad would work as they usually do. When the keyboard is "not available" and I move the focus to a text input widget then I would expect an on-screen keyboard to show up. I'd personally like a two-finger touch gesture to do an Xorg selection paste.
Comment 27 Kristian Rietveld 2011-03-13 10:41:58 UTC
(In reply to comment #23)
> (In reply to comment #12)
> > And there is another aspect: you don't want to duplicate application UI or swap
> > widgets just because it wants to run on touchable or non-touchable devices.
> > 
> Do you think using the same UI for touch and non-touch is a useful goal to aim
> for? I would assume that people want a completely different UI for touch
> anyway. Like what Carlos is doing with the auto-hide scrollbars, it already
> changes the UI of the scrolled window quite fundamentally.

I think in general we are slowly seeing a tendency of touch and non-touch to blend into each other, like Garnacho has mentioned as well.  For example in recent Mac OS X the two-finger scrolling will do kinetic scrolling (which is actually quite useful after you've gotten used to it).  In the upcoming version of Mac OS X (Lion/10.7), they will adopt the iPhone-style small auto-hide scrollbars on desktop machines, though I do not know if this will be adopted for all scrolled windows or only a selected set.

So some touch UI is definitely making their way back into desktop UI, also because of the developments around tablet laptops and laptops with advanced multi-touch touchpads, and the toolkit will have to support this.

That said, you still do not want an application to have the same UI on a desktop machine and on a phone, the phone's screen is likely too small for that.  In this case I would argue you really want to redesign the UI for the phone.  However, you might want to re-use a couple of custom widgets you wrote for the desktop application.

I think the current argument that you do not want to duplicate UI or swap widgets mainly applies to e.g. regular laptops vs. tablet laptops and not laptops vs. phones.
Comment 28 Kristian Rietveld 2011-03-13 12:36:13 UTC
(In reply to comment #15)
> One problem I've seen with current implementations is that we need to
> synthesize events because events are propagated from child to parent in gtk+.
> So when a button-press event is handled by the scrolled window, it has already
> been hanlded by the child widget.

Isn't it the case that Hildon's pannable area creates an event window, so that the pannable area/scrolled window gets to handle button-press events first?  Nevertheless, I agree that something like a captured-event signal will likely provide a cleaner solution for the problem of whether or not to propagate a button press event to the child widget.

I did note that an event window is still being used in your current patch.  Is this because that window is still needed to create the necessary grabs?


(In reply to comment #24)
> (In reply to comment #19)
> >  - There are some problems that I'm not sure how to solve that depend on the
> > widgets contained in the scrolled window. For example, text selections if the
> > widget is a text view or entry, drag and drop operations, etc.

The captured-event signal will help us to propagate button-press events when we are not scrolling and block these from being propagated when scrolling is active.  However, what is still an open issue is how to decide whether or not to start scrolling in conjunction with the interaction with widgets that are embedded in the scrolled window.

The current patch will immediately start scrolling on button press if the dnd threshold is zero, otherwise it will propagate the button press event to the child widget first.  If after a few motion events scrolling does actually start, then you need to send some event to the child widget to not mess up its internal state, this should likely be a crossing event.  From what I recall people went to great lengths to get this right in Hildon.

As far as I can see, something like that is still necessary, or am I missing something?


> Hildon solved these issues by only allowing selections when shift key is
> pressed. We could do something similar, when kinetic mode is enabled, if shift
> modifier (or any other actually) is present we can just return FALSE from
> captured-event signal to let the child widget handle the event normally.

I don't think this is good enough, how do I press a shift key on a device without a physical keyboard?  If we include kinetic scrolling in GtkScrolledWindow, we want to be able to use this on touchscreen devices without physical keyboards as well.

My iPhone can do text selections in an entry that is scrollable (though I admit that often I have fights with it, might be better on more recent iPhones with more CPU).  Drag and drop is typically only done from a special edit mode wherein handles will show up, dragging these handles will trigger drag and drop, otherwise normal scrolling will occur.  (On a second thought, the iPhone also only does text selection after being put in a special text edit mode).

Another problem in this area is how you are going to handle a GtkScrolledWindow that is embedded in a GtkScrolledWindow which both have kinetic scrolling enabled.  I have seen iPad apps and websites doing this.

I think that all of the above problems boil down to determining when to do scrolling and when do to another action (typically child widget dependent) when a button-press and drag occur.  Not an easy problem to solve, but it appears it is possible.
Comment 29 Carlos Garcia Campos 2011-03-21 10:15:41 UTC
(In reply to comment #28)
> (In reply to comment #15)
> > One problem I've seen with current implementations is that we need to
> > synthesize events because events are propagated from child to parent in gtk+.
> > So when a button-press event is handled by the scrolled window, it has already
> > been hanlded by the child widget.
> 
> Isn't it the case that Hildon's pannable area creates an event window, so that
> the pannable area/scrolled window gets to handle button-press events first? 
> Nevertheless, I agree that something like a captured-event signal will likely
> provide a cleaner solution for the problem of whether or not to propagate a
> button press event to the child widget.
> 
> I did note that an event window is still being used in your current patch.  Is
> this because that window is still needed to create the necessary grabs?

The event window is needed to make sure we receive BUTTON_PRESS, BUTTON_RELEASE and BUTTON1_MOTION even when the child widget doesn't include those in its event mask.

> 
> (In reply to comment #24)
> > (In reply to comment #19)
> > >  - There are some problems that I'm not sure how to solve that depend on the
> > > widgets contained in the scrolled window. For example, text selections if the
> > > widget is a text view or entry, drag and drop operations, etc.
> 
> The captured-event signal will help us to propagate button-press events when we
> are not scrolling and block these from being propagated when scrolling is
> active.  However, what is still an open issue is how to decide whether or not
> to start scrolling in conjunction with the interaction with widgets that are
> embedded in the scrolled window.
> 
> The current patch will immediately start scrolling on button press if the dnd
> threshold is zero, otherwise it will propagate the button press event to the
> child widget first.  If after a few motion events scrolling does actually
> start, then you need to send some event to the child widget to not mess up its
> internal state, this should likely be a crossing event.  From what I recall
> people went to great lengths to get this right in Hildon.
> 
> As far as I can see, something like that is still necessary, or am I missing
> something?

There's a device grab in button-press that produces a crossing event. 

> 
> > Hildon solved these issues by only allowing selections when shift key is
> > pressed. We could do something similar, when kinetic mode is enabled, if shift
> > modifier (or any other actually) is present we can just return FALSE from
> > captured-event signal to let the child widget handle the event normally.
> 
> I don't think this is good enough, how do I press a shift key on a device
> without a physical keyboard?  If we include kinetic scrolling in
> GtkScrolledWindow, we want to be able to use this on touchscreen devices
> without physical keyboards as well.
> 
> My iPhone can do text selections in an entry that is scrollable (though I admit
> that often I have fights with it, might be better on more recent iPhones with
> more CPU).  Drag and drop is typically only done from a special edit mode
> wherein handles will show up, dragging these handles will trigger drag and
> drop, otherwise normal scrolling will occur.  (On a second thought, the iPhone
> also only does text selection after being put in a special text edit mode).

I was playing with an android phone and they use press and hold to select text on scrollable widgets, after the long press, current word is selected and handles are shown to expand the selection. I think we could use press and hold for both, text selection and drag and drop. If there are no motion events after long press, we don't start the scrolling and events are sent to the child widget normally. 

> Another problem in this area is how you are going to handle a GtkScrolledWindow
> that is embedded in a GtkScrolledWindow which both have kinetic scrolling
> enabled.  I have seen iPad apps and websites doing this.

hmm, good point.

> I think that all of the above problems boil down to determining when to do
> scrolling and when do to another action (typically child widget dependent) when
> a button-press and drag occur.  Not an easy problem to solve, but it appears it
> is possible.

Yes, I think press and hold could solve the issue for text selection and drag an drop.
Comment 30 Carlos Garcia Campos 2011-03-23 16:56:42 UTC
Created attachment 184149 [details] [review]
scrolledwindow: Allow selections and drag-and-drop when kinetic scrolling is enabled

This patch uses press and hold to allow selections and drand and drop operations. It doesn't use any of the patches attached to bug #315645 because we haven't decided how to implement it yet, and because I realized the approach that adds a new signal doesn't work in its current state with the captured-event. 

The general approach has changed a bit also, now instead of propagating the button press, we save it and start a timer for the long press. If the long press finishes and the scrolling hasn't started, the scrolling is cancelled and the button press event is synthesized. Any other events will propagated normally to the child widget, so that selections or dnd operations will work normally. If scrolling starts before the long press, the child widget never receives the button press and the scrolling works normally. If there's a button release before the long press, both the button press and release events are synthesized. 

This solves all the problems I had with textview and treeviews with dnd enabled. The patch also modifies the testkineticscrolling program to add a treeview with dnd enabled and editable cells.
Comment 31 Kristian Rietveld 2011-03-26 10:13:13 UTC
(In reply to comment #29)
> I was playing with an android phone and they use press and hold to select text
> on scrollable widgets, after the long press, current word is selected and
> handles are shown to expand the selection. I think we could use press and hold
> for both, text selection and drag and drop. If there are no motion events after
> long press, we don't start the scrolling and events are sent to the child
> widget normally. 
> 
> > I think that all of the above problems boil down to determining when to do
> > scrolling and when do to another action (typically child widget dependent) when
> > a button-press and drag occur.  Not an easy problem to solve, but it appears it
> > is possible.
> 
> Yes, I think press and hold could solve the issue for text selection and drag
> an drop.

I agree that this makes sense.  So you'll be able to do a normal button press and immediate release (handled as usual) and if you need to do a button press and a drag, you have to do a long press to cancel the scroll operation.  We have to make sure this is obvious to the user as well -- the child widget should maybe change mode (like the Android widget shows the handles to expand the selection).

About these handles, you should be able to drag these without the scrolling interfering again.  How would this work?  IIRC the child widget should likely signal that when a button-press has happened on the handle, scrolling should not be activated.


(In reply to comment #30)
> Created an attachment (id=184149) [details] [review]
> scrolledwindow: Allow selections and drag-and-drop when kinetic scrolling is
> enabled
> 
> This patch uses press and hold to allow selections and drand and drop
> operations. It doesn't use any of the patches attached to bug #315645 because
> we haven't decided how to implement it yet, and because I realized the approach
> that adds a new signal doesn't work in its current state with the
> captured-event. 

We should take what we have figured here into account when deciding on how to fix bug #315654.  Whereas right now a generic long press to right click translation seems to make most sense, I think that using long press in the scrolled window in this way changes the game a bit.
Comment 32 Carlos Garcia Campos 2011-03-26 11:56:02 UTC
(In reply to comment #31)
> > Yes, I think press and hold could solve the issue for text selection and drag
> > an drop.
> 
> I agree that this makes sense.  So you'll be able to do a normal button press
> and immediate release (handled as usual) and if you need to do a button press
> and a drag, you have to do a long press to cancel the scroll operation.  We
> have to make sure this is obvious to the user as well -- the child widget
> should maybe change mode (like the Android widget shows the handles to expand
> the selection).

Since this behaviour only happens when kinetic scrolling mode is enabled in GtkScrolledWindow, maybe it's enough to document it and use the press and hold animation to give visual feedback so that the user knows that another mode is about to sart and when he can start dragging to select or begin a dnd operation. 

> About these handles, you should be able to drag these without the scrolling
> interfering again.  How would this work?  IIRC the child widget should likely
> signal that when a button-press has happened on the handle, scrolling should
> not be activated.

Personally, I don't like the handles approach, but in that case, the handle would probably be another widget or another GdkWindow so that we can do the same we currently do with the scrollbars, if we detect the user clicked on the handles (the event->window is the handle one) we propagate the button press event.

> 
> (In reply to comment #30)
> > Created an attachment (id=184149) [details] [review] [details] [review]
> > scrolledwindow: Allow selections and drag-and-drop when kinetic scrolling is
> > enabled
> > 
> > This patch uses press and hold to allow selections and drand and drop
> > operations. It doesn't use any of the patches attached to bug #315645 because
> > we haven't decided how to implement it yet, and because I realized the approach
> > that adds a new signal doesn't work in its current state with the
> > captured-event. 
> 
> We should take what we have figured here into account when deciding on how to
> fix bug #315654.  Whereas right now a generic long press to right click
> translation seems to make most sense, I think that using long press in the
> scrolled window in this way changes the game a bit.

Yes, indeed.
Comment 33 Carlos Garcia Campos 2011-04-04 09:50:07 UTC
I've finally managed to use press-and-hold patch, the signal approach, by using the captured-event to implement press-and-hold too. I'll attach the patches.
Comment 34 Carlos Garcia Campos 2011-04-04 09:52:03 UTC
Created attachment 185096 [details] [review]
Add GtkWidget::press-and-hold signal

This is the press and hold patch using the captured-event
Comment 35 Carlos Garcia Campos 2011-04-04 09:54:29 UTC
Created attachment 185098 [details] [review]
scrolledwindow: Allow selections and drag-and-drop when kinetic scrolling is enabled (using press-and-hold-signal)

This patch is the same than attachment 184149 [details] [review], but using the press-and-hold signal
Comment 36 Dan Winship 2011-07-19 15:47:02 UTC
Hm... trying to test this out but having problems apply the patches. This depends on bug 641836, but not bug 315645, right? And do I apply all of the patches currently here, or just some of them?
Comment 37 Carlos Garcia Campos 2011-07-20 12:39:19 UTC
(In reply to comment #36)
> Hm... trying to test this out but having problems apply the patches. This
> depends on bug 641836, but not bug 315645, right? And do I apply all of the
> patches currently here, or just some of them?

It depends, the last patch uses press-and-hold to implement drag and drop and selections. I'll rebase my branch and attach all commits here in a single file to make it easier to test.
Comment 38 Carlos Garcia Campos 2011-07-20 12:45:47 UTC
Created attachment 192300 [details] [review]
Patch set for kinetic scrolling using press-and-hold for dnd and selections

This patch set contains all the commits to implement kinetic scrolling using press-and-hold for dnd and selections. It should apply to current git master with git am. To test it there are two tests: the existing testsscrolledwindow, that now has a checkbox to enable/diasable kinetic scrolling; and testskineticscrolling that has 3 scrollable widgets with kinetic scrolling enabled, you can drag and drop cell in the treeview and select text in the text view by using press-and-hold.
Comment 39 Dan Winship 2011-07-21 19:55:19 UTC
the patch seems completely break keyboard input...

but other than that, it's nice :)

definitely need to try to make it on-by-default for touchscreen input devices.
Comment 40 Jeff Schroeder 2011-07-21 20:05:21 UTC
What about laptops with touchscreens? Keyboard input would be desirable :)
Comment 41 Dan Winship 2011-07-21 20:13:37 UTC
Sorry, the two comments were unrelated. I meant kinetic scrolling should be on by default for touchscreens. Functioning keyboards should obviously be on by default for everyone.
Comment 42 Dan Winship 2011-07-26 15:59:07 UTC
(In reply to comment #39)
> the patch seems completely break keyboard input...

ok, that's actually a bug in the capture patch.

Text selection vs scrolling seems to work reasonably well. The big problem is that it's hard to know when you've hit the timeout between scroll and select, because the little timer animation is hidden behind my finger.
Comment 43 Carlos Garcia Campos 2011-07-28 16:46:29 UTC
(In reply to comment #42)
> (In reply to comment #39)
> > the patch seems completely break keyboard input...
> 
> ok, that's actually a bug in the capture patch.

already submitted a new patch in bug #641836.

> Text selection vs scrolling seems to work reasonably well. The big problem is
> that it's hard to know when you've hit the timeout between scroll and select,
> because the little timer animation is hidden behind my finger.

Yes, garnacho already commented it in the press-and-hold-bug:

https://bugzilla.gnome.org/show_bug.cgi?id=315645#c37
Comment 44 Matthias Clasen 2011-10-23 07:01:44 UTC
Review of attachment 192300 [details] [review]:

::: gtk/gtkscrolledwindow.c
@@ +2220,3 @@
+
+  *x_average /= n_motions;
+  *y_average /= n_motions;

Are we positive that n_motions is always > 0 here ?

@@ +2841,3 @@
+                   NULL,
+                   event->time);
+  gdk_window_lower (priv->event_window);

I see an ungrab that matches this grab in button_release_event,
but I don't see a matching call to raise the event window again - whats up with that ?
Comment 45 Matthias Clasen 2011-10-23 07:11:33 UTC
Is there any idea for how to implement overshoot ? Add a gtk_adjustment_set_value_unclamped ?

We also need some way to turn this on somewhat automatically across the board. Would it make sense to turn 'kinetic-scrolling into a tristate with a third value of 'automatic', which could then fall back to a setting ?
Comment 46 Matthias Clasen 2011-10-23 07:28:53 UTC
For the press-and-hold part, I think we need a way to enable a default implementation that automatically triggers context menus with it. We just
need to be careful that the default implementation can be overridden by
manually connecting to ::press-and-hold.
Comment 47 Carlos Garnacho 2011-10-24 09:32:22 UTC
Created attachment 199803 [details] [review]
Also connect to grab-notify during press and hold

This fixes a crash I was seeing when clicking on the scrollbars
Comment 48 Carlos Garnacho 2011-10-24 09:34:09 UTC
Created attachment 199804 [details] [review]
update testkineticscrolling to use GtkGrid

Just so it compiles on master
Comment 49 Carlos Garnacho 2011-10-24 09:50:26 UTC
After thinking on complex usecases wrt multitouch (i.e. eog scrolled window could want scrolling on 1 finger, but scrolling+zooming on 2), I think we need to expose some API here, something like:

gtk_scrolled_window_drag (GtkScrolledWindow *sw, gint x, gint y);
gtk_scrolled_window_finish_drag (GtkScrolledWindow *sw, gboolean stop_immediately)

As in that case eog might want to stop current drag and start a new one from a new center when the second touch arrives.

(In reply to comment #45)
> We also need some way to turn this on somewhat automatically across the board.
> Would it make sense to turn 'kinetic-scrolling into a tristate with a third
> value of 'automatic', which could then fall back to a setting ?

In my multitouch branch there is a GDK_SOURCE_TOUCHSCREEN, I think kinetic scrolling should happen on such source device types by default, not sure if we also want to expose that for mice and such

(In reply to comment #46)
> For the press-and-hold part, I think we need a way to enable a default
> implementation that automatically triggers context menus with it. We just
> need to be careful that the default implementation can be overridden by
> manually connecting to ::press-and-hold.

I've been also playing with that, we sadly just have the ::popup-menu binding signal, which obviously doesn't provide any coordinates, we could need an additional signal there... that, or implementing press-and-hold on widgets already implementing ::popup-menu
Comment 50 Matthias Clasen 2011-11-25 23:35:22 UTC
I have been trying to play with the touchscreens branch here, commenting out the 

   if (source != GDK_SOURCE_TOUCH)
     return GTK_CAPTURED_EVENT_NONE;

to play with it without a touchscreen - but that didn't work so well:
http://mclasen.fedorapeople.org/shell-20111125-1.webm
Comment 51 Matthias Clasen 2011-11-25 23:46:49 UTC
I _was_ able to get some kinetic scrolling (including overshoot) to happen in testkineticscrolling. I do notice though that the button field seems to miss every second click.
Comment 52 Carlos Garnacho 2011-11-26 13:27:21 UTC
(In reply to comment #50)
> to play with it without a touchscreen - but that didn't work so well:
> http://mclasen.fedorapeople.org/shell-20111125-1.webm

Hmm, indeed, I get that effect too, looks like overshooting is being confused by the scrolled window reaching the opposite adjustment limit when snapping back, I'll fix that

(In reply to comment #51)
> I _was_ able to get some kinetic scrolling (including overshoot) to happen in
> testkineticscrolling. I do notice though that the button field seems to miss
> every second click.

Right, I get it from time to time too, looks there's some situation where captured/stored event doesn't get replayed
Comment 53 Carlos Garnacho 2011-11-26 20:03:22 UTC
(In reply to comment #50)
> to play with it without a touchscreen - but that didn't work so well:
> http://mclasen.fedorapeople.org/shell-20111125-1.webm

This one is fixed in git now.

One more observation here, I'd probably punt scrollbars auto-hide (they're hidden behind a style property atm), just leaving the gap there doesn't look really nice, although we very likely don't want to relayout the child widget. I've come to think we need scrollbars as an overlay, but that's a more substantial change.
Comment 54 Matthias Clasen 2011-11-27 00:01:31 UTC
The current design thinking on scrollbars can be found here: https://live.gnome.org/GnomeOS/Design/Whiteboards/Scrolling
Comment 55 Matthias Clasen 2012-03-02 11:45:06 UTC
We do have kinetic scrolling in GtkScrolledWindow now.