GNOME Bugzilla – Bug 323146
gtk_button_grab_notify clears button->in_button (shouldn't)
Last modified: 2006-12-24 06:06:45 UTC
Please describe the problem: The effect of this bug is: you mouseover a button and keep the mouse there you activate another button with the keyboard you then try to click the button you have been hovering over it's in_button flag is cleared so it does not get the "clicked" signal. moving the mouse out and back in is a workaround. This happens to me every day using redhat's anaconda installer which uses gtk. I am clicking through pages (next, next, next) and I get a popup window that I acknowledge with the spacebar. Then I have to move the mouse out and back in to be able to click again. The problem is also present in Fedora Core 4, when you try to click on the panel menus the first time, you have to mouse in, out, in to get it to work. This problem emerged in gtk 2.5.4 and is present in 2.8.8. Steps to reproduce: 1. Build gtk and run tests/testgtk. 2. Mouseover the "Close" button and leave the mouse there. 3. Activate any other button with the keyboard (use tab and space bar). 4. Try to click "Close" and see that it does not activate. Actual results: The application does not close. Note that this applies to all gtkbuttons and it's descendants (gtkcheckbutton etc). Expected results: The button should activate Does this happen every time? Yes Other information: Yes, here is a patch built against gtk+-2.6.7 (comes with Fedora Core 4) but will apply even to 2.8.8 (http://struct.org/gtk/gtk+-2.6.7-grab.patch). diff -rupN a/gtk/gtkbutton.c b/gtk/gtkbutton.c --- a/gtk/gtkbutton.c 2005-04-06 23:45:30.000000000 -0500 +++ b/gtk/gtkbutton.c 2005-12-03 14:36:38.000000000 -0600 @@ -1735,7 +1735,6 @@ gtk_button_grab_notify (GtkWidget *widge if (!was_grabbed) { - button->in_button = FALSE; gtk_real_button_released (button); } } The fix is easy to apply to any version of gtk, just remove button->in_button = FALSE; from gtk_button_grab_notify() before calling gtk_real_button_released() in gtk/gtkbutton.c (near bottom of file). I don't think this function needs to be setting whether or not the mouse is in the button. I tested that the proper state of this field is maintained even when removing this line (when you mouseout it does get set to FALSE properly).
Created attachment 55592 [details] [review] here's that patch again forgot I could attach the patch here ;)
Now that I've looked into it a little more I see what is going on with gtk_button_grab_notify. It is trying to simulate a release event with the pointer moved out of the button, but it doesn't move it back in after it is finished. I see in 2.8.8 there is another function that does this (gtk_button_grab_broken). That function could handle both events, or gtk_button_grab_notify can be updated to act the same way. I'll attach a patch of the latter since my distribution's gtk doesn't yet have gtk_button_grab_broken.
Created attachment 55761 [details] [review] save in_button state in gtk_button_grab_notify new patch
Here is a test program I am using to visually see the signals fire and see the state of the in_button and button_down fields and test how it gets affected by grabs and/or activating other buttons via keyboard shortcuts. http://struct.org/gtk/btntest.c
Apologies for spam... marking as AP4 to reflect accessibility impact.
This appears to be a duplicate of bug 56070.
2006-12-24 Matthias Clasen <mclasen@redhat.com> * gtk/gtkbutton.c (gtk_button_grab_notify): Be more careful when faking a button release. (#323146, Travis Abbott)