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 769287 - GtkMenuToolButton:show-menu is emitted twice and breaks dynamic menus
GtkMenuToolButton:show-menu is emitted twice and breaks dynamic menus
Product: gtk+
Classification: Platform
Component: Widget: Other
Other Linux
: Normal normal
: ---
Assigned To: gtk-bugs
Depends on:
Reported: 2016-07-28 20:52 UTC by Colomban Wendling
Modified: 2016-08-04 21:32 UTC
See Also:
GNOME target: ---
GNOME version: ---

example program (1.97 KB, text/x-csrc)
2016-07-28 20:52 UTC, Colomban Wendling
GtkMenuButton: use :toggled instead of :clicked (3.10 KB, patch)
2016-07-28 22:48 UTC, Colomban Wendling
committed Details | Review

Description Colomban Wendling 2016-07-28 20:52:42 UTC
Created attachment 332318 [details]
example program (found by bisecting) broke dynamic population of GtkMenuToolButton's menu by making the :show-menu signal be emitted twice.

This is because the new gtk_menu_button_clicked() calls gtk_toggle_button_set_active() after having emitted the signal, which calls gtk_button_clicked() if the state changed, causing a second emission of the GtkButton:clicked signal.

This is very problematic, because it has 2 side effects:

* if the :show-menu handler creates a new menu and uses gtk_menu_tool_button_set_menu() to assign it, the menu will be poped up twice.

* if the :show-menu handler clears the existing menu and re-fills it, no signal will be emitted when one of its items is activated.

Attached demo show the problem:

* If you click on the "Replace menu" arrow, the menu pops up.  If you click on the "Hello" item, it emits the :activate signal, but then re-shows the menu as if you didn't really click.

* If you click on the "Refill menu" arrow, the menu pops up.  If you click on the "Hello" item, the menu closes but no signal is emitted.


Additionally to that bug, the patch in question makes the menu pop on button *release*.  It's expected if I believe the commit message, but it's inconsistent with every other menus.  Menubars, contextual menus: they all popup the menu on button *press*, which actually allows to click on the menu, keep the button pressed, and release it on an item, which will activate it.

So, my suggestion would be reverting that patch altogether.  But well, any other fix for the actual issue would be good anyway.
Also, please backport the chosen fix to every supported previous releases (all of 3.16, 3.18 and 3.20 are affected) as it breaks certain applications that worked just fine until 3.16.
Comment 1 Colomban Wendling 2016-07-28 22:29:25 UTC could have helped, but it actually doesn't fix it for some reason.  Still reproducible on master (3.21.4).
Comment 2 Colomban Wendling 2016-07-28 22:48:40 UTC
Created attachment 332320 [details] [review]
GtkMenuButton: use :toggled instead of :clicked

And I must say that I don't get why this isn't simply done in :toggled like it used to, as :clicked emits :toggled properly -- and it fixes the bug I'm describing.  And AFAICT popovers still work just fine (popover demo does).

Attached patches fixes it that way.
Comment 3 Carlos Garnacho 2016-08-04 21:29:48 UTC
Thanks for the patch, it looks like a valid approach, and the "popup on button release" behavior is preserved, which is desirable (eg. menubuttons on headerbars or toolbars with window-dragging enabled). I'm going to push it as-is.

(In reply to Colomban Wendling from comment #1)
> ?id=65f7fb04ad3cd59ac87ac13a3a59ac18c65c610c could have helped, but it
> actually doesn't fix it for some reason.  Still reproducible on master
> (3.21.4).

It didn't help because this is not a reentrancy issue, it's just that popping down the menu sets the toggle button back to !active, which is implemented by emitting ::clicked and letting the toggle button toggle itself, this ::clicked emission popped up the menu again here.

This means that ::clicked is still emitted when the GtkMenu is popped down, which I don't see quite coherent, although I guess that if every other GtkToggleButton subclass can live with it, so can GtkMenuButton.
Comment 4 Carlos Garnacho 2016-08-04 21:32:26 UTC
Attachment 332320 [details] pushed as 6452134 - GtkMenuButton: use :toggled instead of :clicked