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 315645 - Support hold-as-right-click
Support hold-as-right-click
Status: RESOLVED OBSOLETE
Product: gtk+
Classification: Platform
Component: Widget: Other
3.0.x
Other Linux
: Normal enhancement
: 3.4
Assigned To: gtk-bugs
gtk-bugs
touch
Depends on:
Blocks:
 
 
Reported: 2005-09-09 15:14 UTC by Ross Burton
Modified: 2018-05-02 14:13 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
first go at a patch (26.69 KB, patch)
2007-05-23 18:55 UTC, Kristian Rietveld
needs-work Details | Review
tah_cursor_root_window.diff (2.61 KB, patch)
2007-11-12 12:29 UTC, Xan Lopez
needs-work Details | Review
patch as of October 2008 (29.01 KB, patch)
2008-10-28 08:15 UTC, Kristian Rietveld
needs-work Details | Review
updated to start animation after gtk-initial-timeout (29.31 KB, patch)
2009-05-25 03:45 UTC, Danielle Madeley
needs-work Details | Review
Patch updated to current git master (28.43 KB, patch)
2011-02-14 12:48 UTC, Carlos Garcia Campos
needs-work Details | Review
Add GtkWidget::press-and-hold signal (28.13 KB, patch)
2011-02-16 09:55 UTC, Carlos Garcia Campos
none Details | Review
Add GtkWidget::press-and-hold signal (33.31 KB, patch)
2011-02-23 13:25 UTC, Carlos Garcia Campos
needs-work Details | Review
Add support for press and hold as right click (27.86 KB, patch)
2011-03-11 10:29 UTC, Carlos Garcia Campos
needs-work Details | Review

Description Ross Burton 2005-09-09 15:14:48 UTC
Hand held devices (and people who love Mac's too much) need to have a way of
entering a right click on input devices with a single button (like a stylus).

The customary way of doing this is called "hold'n'tap", where holding down the
button for a fraction of a second and not moving much is interpretted as a right
click.  Holding and moving a large distance should be a drag as usual.

There are two ways of implementing this:
1) as a GTK+ module loaded at runtime.  GPE has a project which does this called
libgtkstylus, an updated version of which is available at
burtonini.com/temp/libgtkstylus-0.4.tar.gz.  This works at the raw event level
by using gdk_event_handler_set().

2) as a patch to GtkWidget.  Maemo has a patch which does this.  In my opinion
their patch is over-engineered: it supports arbitary callbacks on hold, not
faking a right click, and can show an amimation.  As it uses custom callbacks
the use of this patch doesn't magically make holding down work everywhere as a
right click.

This would probably be implemented as part of the gtk-stylus-mode XSetting.
Comment 1 Ross Burton 2005-09-09 16:01:39 UTC
Note, fixed implementation at http://burtonini.com/temp/libgtkstylus-0.5.tar.gz.
Comment 2 Jefferson Ietto Novo 2005-10-04 23:12:44 UTC
Is there any way to tell if the right click event will call a context menu?
because this could "break" some drawing apps.
One option to avoid it, would be check the the right click calls a context menu,
if so, use the hold-as-right-click behavior, if not, just hold the left-click...
Another option make it "hold-and-still-as-right-click". That would be holding
without moving the cursor behaving as right click but holding and moving the
cursor behaving as standard hold the left-click.
Artist, not programmer, so I can't tell how it is implemented right now without
actually using it... but still, some ideas...
Comment 3 Ross Burton 2005-10-05 06:55:05 UTC
If you hold-and-move then a left button drag is produced.
Comment 4 Tommi Komulainen 2006-03-02 15:10:40 UTC
Note that without the animation there is no feedback hinting that a contextual menu / alternate action is available in the first place. After a few seconds of nothing happening you might guess there isn't, provided that you didn't accidentally move the stylus too much while waiting.
Comment 5 Matthias Clasen 2006-03-02 16:18:24 UTC
I can see the point of the animation. 
Does maemo make use of the "arbitrary callbacks" mentioned by Ross ?
Comment 6 Tommi Komulainen 2006-03-02 16:43:59 UTC
I can see there's perhaps two separate issues related to the callbacks.

First to be able to determine the area inside the widget where the context menu makes sense in the first place, think the area below the bottom row in treeview. In some cases that area shouldn't have any context menu, in other cases it should have the same menu as when clicked on a row and in some cases a different menu.

The other case is not as much about context menu but more about secondary actions, and mostly related to (tool)buttons. There a popup menu is not necessarily the best interaction method to provide. For example for the browser back button a pop up list (menu) with history items is reasonable, but for bookmark or home button we're actually displaying a dialog in response to tap-and-hold.

(Given the special need to coordinate between X and DSP being able to have the menus without animations would help in video player as the DSP needs to be stopped when X tries to draw the animation on the video area.)
Comment 7 Matthias Clasen 2006-03-03 14:37:15 UTC
The first issue is not specific to tap-and-hold at all, is it ? Thats just something that you want to do for regular right-click context menus as well.

The second one seems like you just want do do a different action in response
to the (simulated) right-click.

The last one could probably be handled by turning off the animation on a 
per-app (or maybe per-widget) base.
Comment 8 Kristian Rietveld 2006-07-17 11:23:30 UTC
(In reply to comment #7)
> The first issue is not specific to tap-and-hold at all, is it ? Thats just
> something that you want to do for regular right-click context menus as well.

I think there are some differences though, for a regular right click menu, you check the location of the pointer in the button-press handler and immediately pop up a menu if needed.

For tap-n-hold you want to check whether a menu should be popped up at the given location immediately once the stylus goes down.  If yes, the animation will be shown and a button-press event for the right mouse button will be sent after a timeout.  If not, no animation will be displayed and the "hold action" should be ignored.

> The second one seems like you just want do do a different action in response
> to the (simulated) right-click.

Seconded.

> The last one could probably be handled by turning off the animation on a 
> per-app (or maybe per-widget) base.

I guess we can just make this a widget-property.


Comment 9 Kristian Rietveld 2006-07-21 11:22:27 UTC
To bring the discussion back to live, I will give a short overview of my thoughts on the issue.  I think it's perfectly reasonable to include this feature in GtkWidget, and not provide via a GTK+ module.  However, we would of course only enable it when the touchscreen mode is enabled.

I am not really sure if we can get this feature right if we decide for always emulating a right click.  Most will probably agree that we need some kind of feedback when holding the stylus, probably in the form of an animation (maybe provided via a GdkPixbufAnimation?).  Next, I think it looks pretty silly if we show an animation, then send the button press and figure that we don't want to popup a context menu or something similar for those coordinates, so nothing happens.  To avoid this we would need some kind of callback/signal to figure out whether something will happen for given coordinates.  Of course burdening the desktop developers with this callback/signal is not really wished.  (Maemo has the "tap-and-hold-query" signal for this).

So basically I see two options:
  - No animation; and we can just emulate a button-press event;
  - With animation; but then I think a query signal/callback is really
    required (and we might also want a tap-n-hold signal rather than an emulated      click in this case ...).

Other features that are wished are:
  - Automatically enable in touchscreen mode
  - Configurable hold time
Comment 10 Michael Natterer 2006-07-21 11:50:28 UTC
I think always showing the animation is no option because not every
location on screen has a context menu. We probably need some sort
of query signal.

The other thing is the question whether we want tap-and-hold to turn
long left-clicks into right-clicks. I think this is a very bad idea
because apps need special handling for this anyway:

- they need to handle a right click while the left button is still down,
  and need to maybe do different things depending on whether
  touchscreen-mode is enabled or not.

- since we need some query signal anyway if we don't want to show the
  animation unconditionally, why not make tap-and-hold a clearly
  distinct thing also when triggering.

I would even suggest to put both query and trigger in one signal:

typedef enum {
  TAP_AND_HOLD_QUERY,
  TAP_AND_HOLD_TRIGGER,
  TAP_AND_HOLD_CANCEL
} TapAndHoldAction;

gboolean GtkWidget::tap_and_hold (GtkWidget        *widget,
                                  TapAndHoldAction  action,
                                  gint              x,
                                  gint              y);
Comment 11 Tommi Komulainen 2006-07-21 12:12:30 UTC
I agree, turning tap-and-hold to right-click is a bad idea. It should emit "GtkWidget::popup-menu" signal or similar. (So should right-click, IMHO.)
Comment 12 Kristian Rietveld 2006-09-22 13:56:55 UTC
Took the discussion to gtk-devel-list:

http://mail.gnome.org/archives/gtk-devel-list/2006-September/msg00146.html
Comment 13 Kristian Rietveld 2007-05-23 18:55:30 UTC
Created attachment 88696 [details] [review]
first go at a patch

Here's a first go at a patch.  It's based on the original Maemo patch, though the API changed and most of the code has been rewritten/refactored.  Compared to the last discussion on the mailing list, this patch has a possible solution for a "set a cursor" problem in the form of a "tap-and-hold-cursor" style property accepting both GdkCursorTypes and paths to animated image files.

The one thing I am not happy with and needs more thinking is how the tap-n-hold code is hooked up to the signal machinery in gtk_widget_init().  And handling tap-n-hold after button press (as you can try now with the included demo app) doesn't look very nice.  Maybe it's a better plan to handle tap-n-hold before emitting button-press.
Comment 14 Tommi Komulainen 2007-05-25 07:36:43 UTC
>+ * GtkWidget:tap-and-hold-cursor:
>+ *
>+ * The "tap-and-hold-cursor" specifies the cursor to use between the
>+ * query and trigger actions of the GtkWidget::tap-and-hold signal.  The
>+ * value can either be a nickname of a #GdkCursor or a path to an
>+ * animated image file.  By default the "watch" cursor is used.

This feels awkward. It's difficult, if not impossible, to provide reasonable absolute paths from gtkrc (am I installed in /usr or /opt/gnome or $HOME) This also doesn't really follow cursor / icon theming, does it?

If loading custom cursor fails, IMO it should fall back to "watch" instead of not providing any feedback.
Comment 15 Matthias Clasen 2007-05-25 21:11:58 UTC
I have to agree that the cursor property is too ugly - if custom animated cursors
are essential to the tap-and-hold experience, then we need to finish the remaining parts of bug 69436 and use that.
Comment 16 Kristian Rietveld 2007-06-26 13:24:04 UTC
I am not sure if gdk_cursor_new_from_animation() will help here -- in the end you would still have to supply a path in the app itself.

I do think that the tap-n-hold animation should be themable, and I guess it makes sense to allow for setting GdkCursors (which are animated or not, depending on the X cursor theme in use) or provide a custom animation.  I agree that setting the custom animation via real paths is not nice, as you argued above.  Instead this should become possible via the icon theme I guess?  Don't we need a blessed animation format for icon themes first for that?
Comment 17 Kristian Rietveld 2007-06-28 20:29:45 UTC
Another problem is still: when to trigger tap-n-hold?  One sensible approach is to first handle button-press, check the return value to see whether it has been handled, if not do the tap-n-hold query.  However, I don't see this working well; examples:

 - tap-n-hold on buttons will just be impossible, on button-press the GtkButton is drawn as "pressed" and TRUE is returned from the signal handler.  The tap-n-hold code will then never run.
 - GtkTreeView returns TRUE for almost every button press (I think clicking in "dead space" is the only thing that returns FALSE).  So tap-n-hold won't work at all with GtkTreeView either this way.

Another option: handle the tap-and-hold before button-press.  We install a default callback returning FALSE for the query.  A user callback can check whether tap-n-hold is wished and return TRUE/FALSE.  Though if we don't run the button-press handler if tap-n-hold query returns TRUE there are probably a lot of likewise problems.

So I think we will probably have to end up always running both the tap-n-hold and button-press handlers.  I don't have a strong preference for the order in which this has to happen yet.


Suggestions/opinions/etc?
Comment 18 Kristian Rietveld 2007-10-08 13:17:39 UTC
(As as short side note, we probably want to call this press-and-hold instead of tap-and-hold to be more "compatible" with the GTK+ naming scheme (button-press, key-press, etc)).
Comment 19 Xan Lopez 2007-11-12 12:29:11 UTC
Created attachment 98973 [details] [review]
tah_cursor_root_window.diff

Quick note, in maemo-gtk we have found that apparently the only reliable way of always showing the cursor animation on hold is to set the cursor in the root window ...

You can check the gory details in the attached patch (commited in maemo-gtk), comments welcome :)
Comment 20 Kristian Rietveld 2008-10-28 08:15:12 UTC
Created attachment 121498 [details] [review]
patch as of October 2008

This is the latest version of the patch as I have it.  Main difference with the previous one is that this new patch uses the "press-and-hold" naming.

Areas that still need work:
 * Signal handling.  (I dislike the current setup and don't have ideas for another one yet).

 * How to specify animations.  A style property that sets an animation/cursor from an animation or cursor theme would be nicest -- if possible right now.

 * We probably don't want to load animations on the first button press but delay 
this until we are actually going to display it.

 * Probably drop the "keyboard_triggered" part of the signal.

 * Decide whether or not to include Xan's patch (comment #19).  As far as I can see there are no real problems with it.  But still setting the cursor on the root window does not "feel" very nice.
Comment 21 Danielle Madeley 2009-05-21 09:18:07 UTC
Comment on attachment 121498 [details] [review]
patch as of October 2008

I think it would be really nice to get this upstream. I'm willing to take a crack at it.

>+  gboolean     (* press_and_hold) (GtkWidget             *widget,
>+                                   GtkPressAndHoldAction  action,
>+                                   gint                   x,
>+                                   gint                   y,
>+                                   gboolean               keyboard_triggered);
>+

Maybe make this look more like an Event?

>+  /* FIXME: Enable press and hold */
>+  g_signal_connect (widget, "button-press-event",
>+		    G_CALLBACK (gtk_widget_press_and_hold_button_press_event), NULL);

Unlike Maemo, in this patch press and hold is enabled all the time, which surely means that it's going to animate even when a signal handler is not connected. Can we check to see if there is a valid signal handler (or non-NULL vcall) to decide whether or not to start animating?

I think a style property is the right choice for the animation. gdk_cursor_new_from_name() ?

Re comment #19:

Setting the animation on the root window has funny side-effects when your app blows up, as I found out when testing Maemo's patch.
Comment 22 Danielle Madeley 2009-05-25 03:37:21 UTC
> Unlike Maemo, in this patch press and hold is enabled all the time, which
> surely means that it's going to animate even when a signal handler is not
> connected. Can we check to see if there is a valid signal handler (or non-NULL
> vcall) to decide whether or not to start animating?

Ok, I should have looked at the patch closer. This does in fact do that.
Comment 23 Danielle Madeley 2009-05-25 03:45:53 UTC
Created attachment 135295 [details] [review]
updated to start animation after gtk-initial-timeout

Updated so that the animation does not begin until after a timeout of gtk-initial-timeout.

http://git.collabora.co.uk/?p=user/davyd/gtk%2B-davyd.git;a=shortlog;h=refs/heads/press-and-hold
Comment 24 Kristian Rietveld 2009-05-29 08:22:34 UTC
(In reply to comment #21)
> (From update of attachment 121498 [details] [review] [edit])
> I think it would be really nice to get this upstream. I'm willing to take a
> crack at it.
> 
> >+  gboolean     (* press_and_hold) (GtkWidget             *widget,
> >+                                   GtkPressAndHoldAction  action,
> >+                                   gint                   x,
> >+                                   gint                   y,
> >+                                   gboolean               keyboard_triggered);
> >+
> 
> Maybe make this look more like an Event?

We have actually thought about having a "GdkEventTapAndHold" event type; but this probably makes little sense as it is not generated by the graphical backends, does not need queuing, etc.  We don't have such a corresponding event type for the tooltips API either, so in the end the press-and-hold API will end up being kind of similar to the tooltip API.
 
> >+  /* FIXME: Enable press and hold */
> >+  g_signal_connect (widget, "button-press-event",
> >+		    G_CALLBACK (gtk_widget_press_and_hold_button_press_event), NULL);
> 
> Unlike Maemo, in this patch press and hold is enabled all the time, which
> surely means that it's going to animate even when a signal handler is not
> connected. Can we check to see if there is a valid signal handler (or non-NULL
> vcall) to decide whether or not to start animating?

Even though it does check this, I am still unsure whether I like to have the entire machinery enabled by default.  But I haven't come up with a better solution yet...

> I think a style property is the right choice for the animation.
> gdk_cursor_new_from_name() ?

Look at bug 69436 as pointed out by Matthias in comment 15.  As far as I understand gdk_cursor_new_from_name() does not support animated cursors yet.

> Re comment #19:
> 
> Setting the animation on the root window has funny side-effects when your app
> blows up, as I found out when testing Maemo's patch.

Ah, good point!
Comment 25 Carlos Garcia Campos 2011-02-14 12:48:42 UTC
Created attachment 180819 [details] [review]
Patch updated to current git master

This is the same patch just updated to current git master. 

I have been talking to garnacho and maybe we could use something like this: 

http://git.gnome.org/browse/gnome-settings-daemon/tree/plugins/mouse/gsd-locate-pointer.c

to do the animation instead of using an animated cursor. We could add a new style class and the theming engine will render the animation like we currently do for GtkSpinner so that it will be themable.
Comment 26 Carlos Garcia Campos 2011-02-14 17:46:32 UTC
I've just realized that the first time, press-and-hold is not cancelled when the pointer is moved beyond the dnd threshold. This because GDK_POINTER_MOTION_MASK is added to the widget window in the button press event callback, and it should be added before. So I think we need something like has-tooltip property (maybe enable-press-and-hold) to add the GDK_POINTER_MOTION_MASK (or even GDK_BUTTON_MOTION_MASK since we are only interested on motion events while the mouse button is pressed) before button press event is emitted.
Comment 27 Carlos Garcia Campos 2011-02-16 09:55:10 UTC
Created attachment 180968 [details] [review]
Add GtkWidget::press-and-hold signal

This is a new patch to add press-and-hold signal:

 - It enables button motion events by default for all widgest to fix the issue I mentioned in previous comment. We could even limit it to button 1 motion events, press-and-hold currently works for any button but maybe it makes sense to enable it only for button 1.

 - It removes the signal connections from init(), button-press is called before emitting the button press signal, and all other signals are connected when press-and-hold query returns TRUE.

 - It removes the keyboard_triggered parameter from the signal.

 - It uses a custom animation instead of changing the cursor. At the moment it only works when compositing is running and there's rgba visual, since I'm using a transparent popup window. I'm currenly using the spinner style class just to show how it would work, but the idea is to add a new style class GTK_STYLE_CLASS_PRESS_AND_HOLD (or something like that) and implement the custom animation in the theming engine.

 - It removes the press-and-hold-cursor style property since it doesn't use cursors anymore.
Comment 28 Carlos Garcia Campos 2011-02-23 13:25:15 UTC
Created attachment 181694 [details] [review]
Add GtkWidget::press-and-hold signal

This patch adds a new style class GTK_STYLE_CLASS_PRESS_AND_HOLD and fixes the animation to work when compositing is not running. The custom animation is mostly the same than the spinner one, but making the circle close progressively.
Comment 29 Matthias Clasen 2011-02-25 23:31:24 UTC
So this seems to work.

Some questions about the general approach:

- Are we really sure this is necessary at the toolkit level, and something like mousetweaks simulated secondary click is not good enough ?

- Do we really expect people to set this up manually for each control ?!
I would expect to have some kind of default behaviour that gets controlled by touchscreen mode and just delivers right-clicks. Is that something that has 
been considered ?
Comment 30 Carlos Garcia Campos 2011-02-26 09:44:16 UTC
(In reply to comment #29)
> So this seems to work.
> 
> Some questions about the general approach:
> 
> - Are we really sure this is necessary at the toolkit level, and something like
> mousetweaks simulated secondary click is not good enough ?
> 
> - Do we really expect people to set this up manually for each control ?!
> I would expect to have some kind of default behaviour that gets controlled by
> touchscreen mode and just delivers right-clicks. Is that something that has 
> been considered ?

Yes, I thought about having a default handler that emits popup-menu, the problem is that we don't know whether the widget will handle popup-menu so we might end up showing animations that do nothing.
Comment 31 Matthias Clasen 2011-02-28 12:10:00 UTC
> Yes, I thought about having a default handler that emits popup-menu, the
> problem is that we don't know whether the widget will handle popup-menu so we
> might end up showing animations that do nothing.

I was thinking the default action would be to synthesize a right click. 
And there will be a global switch to turn hold-as-right-click on or off, system-wide, right ? I don't think it is terrible to show that animation even when the signal is not hooked up. The animation just means 'right-click coming soon', it doesn't really announce a menu.
Comment 32 Bastien Nocera 2011-02-28 12:18:14 UTC
(In reply to comment #31)
> > Yes, I thought about having a default handler that emits popup-menu, the
> > problem is that we don't know whether the widget will handle popup-menu so we
> > might end up showing animations that do nothing.
> 
> I was thinking the default action would be to synthesize a right click. 
> And there will be a global switch to turn hold-as-right-click on or off,
> system-wide, right ? I don't think it is terrible to show that animation even
> when the signal is not hooked up. The animation just means 'right-click coming
> soon', it doesn't really announce a menu.

I don't actually think any sort of animation is desirable, at least none of the touch platforms I've used have that sort of behaviour.

It might be good enough to make existing applications fit into a touch platform, but the behaviour is highly widget dependent. For example, a text entry would initiate zoom, and follow the cursor for zoom, and have the "right-click" equivalent popup when released, links would popup a contextual menu when held.

Best have the designers look into it.
Comment 33 Bastien Nocera 2011-02-28 12:21:52 UTC
(In reply to comment #31)
> > Yes, I thought about having a default handler that emits popup-menu, the
> > problem is that we don't know whether the widget will handle popup-menu so we
> > might end up showing animations that do nothing.
> 
> I was thinking the default action would be to synthesize a right click. 
> And there will be a global switch to turn hold-as-right-click on or off,
> system-wide, right ? I don't think it is terrible to show that animation even
> when the signal is not hooked up. The animation just means 'right-click coming
> soon', it doesn't really announce a menu.

I don't actually think any sort of animation is desirable, at least none of the touch platforms I've used have that sort of behaviour.

It might be good enough to make existing applications fit into a touch platform, but the behaviour is highly widget dependent. For example, a text entry would initiate zoom, and follow the cursor for zoom, and have the "right-click" equivalent popup when released, links would popup a contextual menu when held.

Best have the designers look into it.
Comment 34 Carlos Garcia Campos 2011-03-03 09:12:30 UTC
(In reply to comment #33)
> (In reply to comment #31)
> > > Yes, I thought about having a default handler that emits popup-menu, the
> > > problem is that we don't know whether the widget will handle popup-menu so we
> > > might end up showing animations that do nothing.
> > 
> > I was thinking the default action would be to synthesize a right click. 
> > And there will be a global switch to turn hold-as-right-click on or off,
> > system-wide, right ? I don't think it is terrible to show that animation even
> > when the signal is not hooked up. The animation just means 'right-click coming
> > soon', it doesn't really announce a menu.
> 
> I don't actually think any sort of animation is desirable, at least none of the
> touch platforms I've used have that sort of behaviour.
> 

Maemo in N770 and I think in N800 used an animation, I think it's a good visual feedback that something is going to happen. In N900 the animation was removed though, I don't know why.

Note that the animation can be globally disabled with GtkSettings:gtk-enable-animations, or, since the animation is defined by the theme, it can be disabled per theme too.
Comment 35 Carlos Garcia Campos 2011-03-03 09:28:15 UTC
(In reply to comment #31)
> > Yes, I thought about having a default handler that emits popup-menu, the
> > problem is that we don't know whether the widget will handle popup-menu so we
> > might end up showing animations that do nothing.
> 
> I was thinking the default action would be to synthesize a right click. 
> And there will be a global switch to turn hold-as-right-click on or off,
> system-wide, right ? I don't think it is terrible to show that animation even
> when the signal is not hooked up. The animation just means 'right-click coming
> soon', it doesn't really announce a menu.

If there's a default action and we are always going to show the animation, do we still need GtkPressAndHoldAction? or do you mean we don't even need a new signal and we can just synthesize a right-click when GtkSettings:gtk-touchscreen-mode is enabled?
Comment 36 Bastien Nocera 2011-03-03 11:39:23 UTC
(In reply to comment #34)
<snip>
> > 
> > I don't actually think any sort of animation is desirable, at least none of the
> > touch platforms I've used have that sort of behaviour.
> > 
> 
> Maemo in N770 and I think in N800 used an animation, I think it's a good visual
> feedback that something is going to happen. In N900 the animation was removed
> though, I don't know why.

Probably because an animation is not desirable ;)

> Note that the animation can be globally disabled with
> GtkSettings:gtk-enable-animations, or, since the animation is defined by the
> theme, it can be disabled per theme too.

Fair enough.
Comment 37 Carlos Garnacho 2011-03-03 12:18:12 UTC
After trying the patch, I think this looks good, 2 comments though:

* The animation looks suitable for stylus, but is too small for touchscreens, being completely covered by the finger here. So the animation size should be dependent on the gdk_event_get_source_device() returned, I guess we actually need a GdkInputSource value for touchscreens.

* Using the drag threshold is again suitable for stylus, where you control the precise position of the pen tip a lot better, but with fingers the 16 diameter threshold  falls within the finger area, so it's triggered too easily. 

Also worth mentioning, the hardware I'm testing with is actually extremely inaccurate, producing somewhat shaky coordinates within the finger press area. So even if the finger stays still, the shakiness still triggers the press to be cancelled.

About animations, I think having feedback there is good, not also for knowing that something is about to be started, but also to tell whether the action was cancelled, I personally hate it when the only way to see whether something succeeds is to wait a bit more :).
Comment 38 Claudio Saavedra 2011-03-03 13:58:49 UTC
(In reply to comment #36)
> (In reply to comment #34)

> > 
> > Maemo in N770 and I think in N800 used an animation, I think it's a good visual
> > feedback that something is going to happen. In N900 the animation was removed
> > though, I don't know why.
> 
> Probably because an animation is not desirable ;)

No, if I remember correctly, it was actually it was removed because we dropped CSM in most of the UI, giving prevalence to other sorts of user interaction. However, CSM were still supported for third-party applications (although discouraged), but without this animation.

In any case, I guess that feedback from designers is what we need here, otherwise we can bikesheed about it forever.
Comment 39 Kristian Rietveld 2011-03-05 16:45:11 UTC
I see that recent discussion questioned the general approach that should be taken with this feature.  I think there are two possibilities:

  1) Make a long press a general emulation for right clicks.  Nothing more, nothing less.  In this case, you might want to consider whether this should actually belong in GDK or not in the toolkit at all as Matthias mentioned in comment 29.

  2) Make long press a generic signal that can be implemented by widgets.  What this long press can trigger is not constrained to popup menus.  As has been mentioned in the beginning of this bug report (e.g. comment 6), you might want the long press to popup a window instead or initialize a special mode in for example a text widget (comment 33).  In this case the signal is generic for both "touchscreen" and desktop devices.  We then also need to take into account that these actions should also be accessible using the keyboard.

Option 2) is flexible but does require all widgets which rely on right clicks to provide a different means to establish the same action with a left click or long press in order for these to be usable on hand held devices (which is what I think Matthias means in comment 29).

I guess this is another question for the designers.  Based on the outcome a decision can be made about animations.
Comment 40 Kristian Rietveld 2011-03-05 17:15:38 UTC
(In reply to comment #27)
>  - It enables button motion events by default for all widgest to fix the issue
> I mentioned in previous comment. We could even limit it to button 1 motion
> events,

I am not sure if it is a good idea to have button motion events enabled by default for all widgets -- I think in theory this might have a performance impact.  For the tooltips API we have been very cautious with this, which resulted in the has-tooltip property.  This made it possible to avoid sending query-tooltip when it will be ignored anyway, and also to avoid enabling button motion events when they would not be used.

> press-and-hold currently works for any button but maybe it makes sense
> to enable it only for button 1.

In case press-and-hold becomes a generic signal (option 2), you might want to consider the extreme case of wacom tablets (for complete flexibility) where you want to support press-and-hold on button 3 as well (the back of the pen functions as right click on wacom tablets).
Comment 41 Carlos Garcia Campos 2011-03-06 11:08:29 UTC
(In reply to comment #40)
> (In reply to comment #27)
> >  - It enables button motion events by default for all widgest to fix the issue
> > I mentioned in previous comment. We could even limit it to button 1 motion
> > events,
> 
> I am not sure if it is a good idea to have button motion events enabled by
> default for all widgets -- I think in theory this might have a performance
> impact.  For the tooltips API we have been very cautious with this, which
> resulted in the has-tooltip property.  This made it possible to avoid sending
> query-tooltip when it will be ignored anyway, and also to avoid enabling button
> motion events when they would not be used.

Note that what is enabled by default is GDK_BUTTON1_MOTION_MASK, not GDK_POINTER_MOTION_MASK which is what tooltips need.
Comment 42 Carlos Garcia Campos 2011-03-11 10:29:09 UTC
Created attachment 183125 [details] [review]
Add support for press and hold as right click

This patch emulates right clicks instead of using a new signal. It only works when touchscreen mode is enabled, but in the future it could use the input device to decide whether synthesize a right click or not.
Comment 43 Pádraig Brady 2011-03-11 15:35:17 UTC
This "hold to right click" functionality is traditionally handled in the touchscreen driver. I'm unsure of the need for it in GTK, and think one would at least have to disable it if it was enabled in the touchscreen driver.
One can now enable this functionality in evdev for example:
http://cgit.freedesktop.org/xorg/driver/xf86-input-evdev/commit/?id=d9001a6b
Comment 44 Dan Winship 2011-06-20 14:18:50 UTC
Another idea: add a GtkWidget:context-menu property (of type GtkMenu). If it is set, GtkWidget itself will pop up the context menu on right-click, press-and-hold, or Shift+F10/Menu, without needing any callbacks or query signals or anything like that. (And we can deprecate GtkWidget::popup-menu, and no one ever needs to implement context menus by hand ever again.)

If you want to have press-and-hold do something other than popping up a context menu (which you shouldn't normally want to do), then you can just implement it by hand; there may be some helper methods, gtksettings, etc, you can use to get similar timeouts/thresholds/etc as in the press-and-hold-for-menu case.
Comment 45 Bastien Nocera 2011-06-20 15:05:21 UTC
(In reply to comment #44)
> Another idea: add a GtkWidget:context-menu property (of type GtkMenu). If it is
> set, GtkWidget itself will pop up the context menu on right-click,
> press-and-hold, or Shift+F10/Menu, without needing any callbacks or query
> signals or anything like that. (And we can deprecate GtkWidget::popup-menu, and
> no one ever needs to implement context menus by hand ever again.)

I'd be happy with that, as long as we manage to cut down on the number of items in the context menus, and fix them up to look decent. Having a 20 items long menu would probably suck on touchscreens.
Comment 46 Kristian Rietveld 2011-06-20 18:25:57 UTC
(In reply to comment #44)
> Another idea: add a GtkWidget:context-menu property (of type GtkMenu). If it is
> set, GtkWidget itself will pop up the context menu on right-click,
> press-and-hold, or Shift+F10/Menu, without needing any callbacks or query
> signals or anything like that. (And we can deprecate GtkWidget::popup-menu, and
> no one ever needs to implement context menus by hand ever again.)

What happens if you want to have a context menu on e.g. a tree view or icon view, which should only be popped up for certain items (for example sensitive vs. insensitive) or should show different menu contents based on the type of item?  Although I like the simplicity of a context-menu property, I think it is too limited.


> If you want to have press-and-hold do something other than popping up a context
> menu (which you shouldn't normally want to do), then you can just implement it

Why shouldn't one normally not want to popup something else than a GtkMenu?

> by hand; there may be some helper methods, gtksettings, etc, you can use to get
> similar timeouts/thresholds/etc as in the press-and-hold-for-menu case.

IMHO having people implement this by hand is to be avoided, on touchscreens it is an important feature and should be as consistent as possible.
Comment 47 Dan Winship 2011-06-20 18:41:22 UTC
(In reply to comment #46)
> Why shouldn't one normally not want to popup something else than a GtkMenu?

UI consistency

But your points about treeviews and differing contexts are valid.
Comment 48 Matthias Clasen 2011-06-20 18:52:42 UTC
(In reply to comment #44)
> Another idea: add a GtkWidget:context-menu property (of type GtkMenu). If it is
> set, GtkWidget itself will pop up the context menu on right-click,
> press-and-hold, or Shift+F10/Menu, without needing any callbacks or query
> signals or anything like that. (And we can deprecate GtkWidget::popup-menu, and
> no one ever needs to implement context menus by hand ever again.)

It sounds nice. But there will be some complications.

- We do have context menus that are dynamically constructed, via ::populate-popup signals

- We have several places where we have different context menus on different parts of a complex widget (icons in entries, links in labels).
Comment 49 Allison Karlitskaya (desrt) 2011-10-13 03:59:08 UTC
Danni just proposed that it might be useful for GtkButton to support something like key-repeat when you hold it down (similar to how GtkRange and GtkSpinButton already work).  This would be pretty useful for things like on-screen keyboards.

Should probably consider how that possibility interacts with this code and come up with a way to deal with either, depending on what the user requests.
Comment 50 Danielle Madeley 2011-10-13 04:07:23 UTC
I have filed this as bug #661622.
Comment 51 Danielle Madeley 2011-10-13 04:32:22 UTC
Catching up on this bug:

> > If you want to have press-and-hold do something other than popping up a context
> > menu (which you shouldn't normally want to do), then you can just implement it
> 
> Why shouldn't one normally not want to popup something else than a GtkMenu?

It's worth noting that on the iPhone, you can press-and-hold on a "tree view row" to show the Delete button to delete that row.
Comment 52 Adam Williamson 2014-02-11 01:45:40 UTC
2.5 year bump: any news? this is proving a bit of a problem in configuring firefox.
Comment 53 Emmanuele Bassi (:ebassi) 2014-02-11 16:57:29 UTC
(In reply to comment #52)
> 2.5 year bump: any news? this is proving a bit of a problem in configuring
> firefox.

note that even if it was fixed in gtk today, only the gtk3 port of Firefox would see this API.
Comment 54 Adam Williamson 2014-02-11 17:51:25 UTC
so, anything GTK+2-based is basically 'legacy' so far as any touch-y stuff is concerned? Just want to know for bug filing purposes, there are other issues in GTK+ 2 (e.g. no drag scrolling).
Comment 55 Emmanuele Bassi (:ebassi) 2014-02-11 18:55:18 UTC
(In reply to comment #54)
> so, anything GTK+2-based is basically 'legacy' so far as any touch-y stuff is
> concerned? Just want to know for bug filing purposes, there are other issues in
> GTK+ 2 (e.g. no drag scrolling).

unless that support happens to work on pointer events (i.e. mouse) then yes: anything touch-related won't work on GTK+ 2.x.

GtkWidget in 2.x does not have any touch event support, so it definitely cannot get touch-y stuff in applications. GDK also does not support the XInput2 extension, so it cannot even select for those events on X11.

considering the amount of event-related and widget-related code in GDK and GTK+ 3.x ended up changing behaviour and API, it's highly doubtful it'll ever be backportable.
Comment 56 Matthias Clasen 2014-09-27 23:52:22 UTC
Marking these patches as needs-work. This needs to be done in the gesture framework nowadays.
Comment 57 Emmanuele Bassi (:ebassi) 2016-11-09 13:57:41 UTC
I think this bug should be closed, and we need to file separate bugs for specific widgets to get support for long-press gestures to emit the GtkWidget::popup-menu, so that applications can populate their own menus using the same code path as Shift+F10.

For the future:

 * deprecate GtkWidget::popup-menu (in GTK 3.x, and remove it in GTK 4.x)
 * deprecate adding random menu items to GtkEntry context menus
 * add a GtkWidget:context-menu property taking a GMenuModel
 * we add a default press gesture that handles:
  * right pointer click
  * long press on touch devices
 * we add a default key press handler for Shift + F10
 * if any of these handlers are tripped, we build a GtkMenu (or a GtkPopover) for the GtkWidget:context-menu and show it
 * remove all custom context menu building in sub-types of GtkWidget, and replace them with GMenu/GAction
Comment 58 GNOME Infrastructure Team 2018-05-02 14:13:55 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to GNOME's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/gtk/issues/251.