GNOME Bugzilla – Bug 56070
Can't click button after setting it sensitive.
Last modified: 2010-06-16 00:44:01 UTC
I have many times reported that if you got the mouse just where the button is going to appear (gdm, nautilus-installer, ...) you won't be able to click the button, it is confusing and anoying. Here is a simple example showing it. It raises a big window with a button on it (set_sensitive = false). After 2 seconds, a timeout makes the button sensitive. If you have the mouse over the button before the timeout sets it sensitive, you WON'T be able to click the button, it will refuse to do so. Leaving the button and entering it again makes it work. I will love to fix it myself, but I don't have the skills. As perhaps it is not a simple fix, I'm sending the bug here. Try it out. Don't know if this applies to other widgets as well. gcc button.c `gtk-config --cflags gtk` `gtk-config --libs gtk` -o button-bug gcc button.c `pkg-config --cflags gtk+-2.0` `pkg-config --libs gtk+-2.0` -o button-bug Thanks.
Created attachment 639 [details] Example showing this bug
Fixing this would require GTK+ to keep track of where the mouse cursor is at all times, and synthesize enter events when a widget becomes sensitive. Not easy at all. Future plans include mostly getting rid of subwindows in GTK+, which would make this easier.
this is no longer true. Tested with gtk+ 2.2.2. Closing the bug.
I know no reason why this bug should be now fixed.
Hi Owen, I tried executing the button.c testcase again, and I can't reproduce the bug. There is no WORKSFORME resolution so I marked it fixed. The testcase fails, so why do you want the bug open?
The button still doesn't prelight properly in your test case ... and the generic GTK+ problem "If a widget is under the cursor when the widget becomes sensitive, it won't get an ENTER event" is still there.
Looking at the code, it appears that it is not simple to fix. It also appears that the root cause of this problem is the fact the underlying widget does not see the enter event while it is insensitive. Just wondering if it is possible to add an internal in_widget boolean property so that the widget can keep track of the mouse position. If the widget is then set sensitive, ENTER events could be generated if in_widget is true. I don't fully understand the code, so may talking rubbish here, it's just an idea.
Now that bug #82128 is fixed and we have a gtk_button_state_changed, I think fixing this should be easy enough. Just see if button->in_button is true at the end of that function, and change the state to active if appropriate.
Won't work because widgets don't receive events when insensitive.
*** Bug 125071 has been marked as a duplicate of this bug. ***
Created attachment 36221 [details] Another, perhaps more illustrative test case. Well, this one's causing us lots of grief. This test case illustrates our particular case where the net result of a code path is synchronously toggling the sensitivity of a clicked button to false and back again. Until the mouse leaves and re-enters, it will act insensitive (although keyboard activation works fine, as you'd expect).
Could the button perhaps check the pointer position at the moment it becomes sensitive, or at least queue up such a check for the next event loop pass?
Huge performance hit ... querying pointer position is a round-trip to the server.
Right, so that means we probably shouldn't do it from gtk_widget_set_sensitive(); we wouldn't want to incur dozens of roundtrips if the program sensitized dozens of controls. However it seems like we could stand to incur one roundtrip per event loop for the particular case where the sensitivity of a control has changed. set_sensitive should set a flag saying to do this. To me, having the GUI behave correctly and not ignore user input is important enough to justify the expense. (I guess as an optimization you might check for events, and see if any of them have told you the current mouse position, and if you got it then you wouldn't need to ask.)
*** Bug 169631 has been marked as a duplicate of this bug. ***
*** Bug 169570 has been marked as a duplicate of this bug. ***
I am the author of the dup 169570: I've mentioned that a click to a button in this case does not change *nothing* but shifts at least the focus (dotted square) to it. So, even if the ENTER event is missing and the button is not prelighted -- the button seems to get *some* event here. (I do not know the internals here.) Couldn't we use this as the trigger to treat this button as one which was entered and force it to behave normal?
Problem is this: static void gtk_button_state_changed (GtkWidget *widget, GtkStateType previous_state) { GtkButton *button = GTK_BUTTON (widget); if (!GTK_WIDGET_IS_SENSITIVE (widget)) { button->in_button = FALSE; gtk_real_button_released (button); } } Have this feeling, this makes sense in some situations, but it gives you serious trouble, when you dynamically toggle sensitivity of buttons in dependency for instance on some changing (icon view) selection.
Created attachment 51436 [details] Sample program hacking arround the problem in a cheap manner This sample program is based on comment #2. Works as long as nobody blocks the motion-notify-event (guess that's where Owen's concerns came from). Well, but this problem also should be solvable, by placing a hook into GTK+'s event loop.
*** Bug 157932 has been marked as a duplicate of this bug. ***
Well, FWIW, this bug is still not fixed in 2.6.8.
*** Bug 319791 has been marked as a duplicate of this bug. ***
Wow, this is an oldie. 2.8 here, still unfixed. :(
What is the problem with allowing insensitive widgets to receive events? If that happens, surely the problem just goes away...
*** Bug 169539 has been marked as a duplicate of this bug. ***
*** Bug 317937 has been marked as a duplicate of this bug. ***
*** Bug 333816 has been marked as a duplicate of this bug. ***
*** Bug 329391 has been marked as a duplicate of this bug. ***
Though this might be a dumb question... I understand, that polling the cursor position is considered non-performant. Trying to understand this one: The button is not highlighted because ...? ... there was no mouse-in event, right? And it is not clickable because ... ? .... no click-event was registered? I can accept that the button isn't highlighted, but the click funktion should be available since this is a loss of functionality (although this bug is not dramatically) and it destroys the workflow and the nice look and feel of WMs.
I /really/ don't understand why we can't just set the highlighted state on insensitive buttons. This problem would go away, then.
Setting highlighted state would suggest to the user that the insensitive button can be clicked / used, which would be wrong. Probably the GUI part of it could be special-cased though (when highlighted state is set, check insensitive before drawing?)
I thought that was fairly obvious, but if not it would explain why we're still pondering over this! A button in that is both HIGHLIGHTED and INSENSITIVE should be rendered without regards to the highlighted state. Solved!
I think I might have cottoned the problem. Is it that a widget can only hold one exclusive state? I think logic suggests that the "highlighted" flag should be independent of "insensitive". Would this be such a bitch to implement?
Created attachment 66285 [details] [review] gtk-sensitivity.patch Patch, against 2.9.1. At bug 316125, Tim Janik wrote: > this is a symptom of the more general problem that gtk doesn't synthesize > enter/leave events upon changing the sensitivity (or global grab) state of a > widget the way X does when windows are covered/uncovered by other windows. This patch creates a private flag PRIVATE_GTK_SYNTH_CROSSING (GTK_WIDGET_SYNTH_CROSSING) which tracks whether the pointer is in the control. When the sensitivity/global grab state changes it synthesises enter/leave events accordingly. Detail: * gtkprivate.h, gtktypebuiltins.c: define GTK_WIDGET_SYNTH_CROSSING * gtkmain.c: gtk_main_do_event(): update GTK_WIDGET_SYNTH_CROSSING with enter/leave * gtkwidget.{c,h}: _gtk_widget_synthesise_crossing_from_{grab_notify,state_changed}(): functions to call from grab-notify and state-changed to synthesise enter/leave events as appropriate. Common code in _gtk_widget_synthesise_crossing_event(). * gtkwidget.c, gtkbutton.c: call synthesis functions from grab-notify and state-changed. (gtkbutton.c needs its own callouts because a GtkButton is a NO_WINDOW control, but has its own GdkWindow. This means that the enter/leave events do not get synthesised (NO_WINDOW controls don't receive events) in gtkwidget.c. Any other control that handles its own GdkWindow outside of the GtkWidget system will need to copy the callouts in gtkbutton.c.) This appears to work well, and I think it's correct. Of course, I haven't tested it all that much yet. Changes to ABI: * added private functions _gtk_widget_synthesise_crossing_from_*. No libversion change needed. Changes to API: * private flag, functions added. No-one other than widget implementors need to care. Changes to behaviour: * widgets can receive enter events immediately after turning sensitive. This is practically indistinguishable from the user moving pointer into widget immediately after turning sensitive. The only situation I can imagine this causing trouble is in workarounds to this very bug. * widgets can receive leave events immediately after turning insensitive. I don't see this being a problem.
Performance: client overhead is low, using one bit in GtkPrivateFlags. Synthesis tests are mostly cheap bitfield checks, with the heavy stuff (gtk_widget_is_ancestor) at the end of a short-circuit so it'll only kick in if a widget is made sensitive while a grab is in effect. Actual event synthesis involves two roundtrips: gdk_display_get_pointer (QueryPointer) and gdk_window_get_origin (TranslateCoordinates). I don't know how to improve this; perhaps some Xlib guru could help?
*** Bug 314422 has been marked as a duplicate of this bug. ***
*** Bug 344835 has been marked as a duplicate of this bug. ***
The patch on bug 344835 has a very simple patch which solves the common problem of: - mouse pointer is above button - button becomes insensitive - user keeps mouse pointer there - button becomes sensitive - user tries to click This happens in places like: - Find Dialogs - Debuggers - Other 'Next' or 'Find Next' Buttons
It solves that situation, but it doesn't fix the underlying bug, and it breaks widget invariants. Care to comment on my patch?
Thanks, I'll look at your patch sometime soon. Would be really nice to get Owen's comment, too.
I applied Ed's patch and Gtk+ in Sisyphus repository now ships with it. In these two weeks, everything's ok: the patch solves the issue and doesn't seem to break anything.
I'm running with the patch. Works nicely.
*** Bug 316994 has been marked as a duplicate of this bug. ***
Would be great if the patch could go in soon as this is very annoying in anjuta: - You cannot press "Next" in the debugger toolbar (gets insensitive when the debugger is working) - You cannot use the "Find" button twice Regards, Johannes
For the record, I'm running the gtk-sensitivity patch for 5 weeks by now. Works fine.
*** Bug 327463 has been marked as a duplicate of this bug. ***
*** Bug 327408 has been marked as a duplicate of this bug. ***
*** Bug 351600 has been marked as a duplicate of this bug. ***
*** Bug 361214 has been marked as a duplicate of this bug. ***
*** Bug 172004 has been marked as a duplicate of this bug. ***
good luck guys :)
summarizing: this bug report has 20 duplicates so far, plus it would make the life on the anjuta guys easier (comment 44). the patch has been tested by a few people (see comment 41 and comment 42). however, this could introduce new problems (comment 39). matthias, any news here (comment 40)?
(In reply to comment #52) > summarizing: > this bug report has 20 duplicates so far, plus it would make the life on the > anjuta guys easier (comment 44). the patch has been tested by a few people (see > comment 41 and comment 42). however, this could introduce new problems (comment > 39). No, comment 39 is about a different patch. The patch on this bug is not known to introduce any new problems.
ok, then we should get a review for that patch - matthias: *ping*?
Hello, This bug is really annoying for the nemiver debugger as well. Matthias, please, could you tell us what you think about the last patch that seems to fix it ? Cheers, Dodji
This bug appears in several other apps in addition to the list from duplicates : - in xsane when we finish scanning a document, we can't press the button again for the next one - in gthumb when deleting an image with keyboard we can't press next to go the next image And I'm sure I already faced that behaviour in other apps, so yes it's really annoying and it would be nice to handle this quickly now that there is patch :)
*** Bug 378468 has been marked as a duplicate of this bug. ***
Created attachment 77408 [details] [review] gtk-sensitivity.patch Fix a possible assert if a button doesn't have a window. This patch is over 6 months old - any chance of a review?
Please could someone review the patch. The bug prevents the user from clicking the Step Over/Step Into/etc buttons in the Nemiver debugger. :)
*** Bug 316125 has been marked as a duplicate of this bug. ***
Some comments on the patch: 1) I think we generally write synthesize in GTK+, not synthesise 2) Regarding the 2 roundtrips to set x/y_root and x/y in the event, one idea would be to simply not fill these fields, and document that crossing events with send_event = 1 and crossing.detail == unknown may not have theese fields filled. 3) I don't know what invariants we really guarantee for enter/leave events, but shouldn't these be generated in pairs ? I.e. when generating an enter event, the pointer logically comes from somewhere else. Do we need to generate a leave event there ?
*** Bug 389640 has been marked as a duplicate of this bug. ***
(In reply to comment #61) > Some comments on the patch: > > 1) I think we generally write synthesize in GTK+, not synthesise Foiled! Curses! > 2) Regarding the 2 roundtrips to set x/y_root and x/y in the event, > one idea would be to simply not fill these fields, and document > that crossing events with send_event = 1 and crossing.detail == unknown > may not have theese fields filled. Yeah, that sounds like an option. I'd prefer to create a new GdkNotifyType in that case, maybe GDK_NOTIFY_SYNTHESIZED. > 3) I don't know what invariants we really guarantee for enter/leave > events, but shouldn't these be generated in pairs ? I.e. when generating > an enter event, the pointer logically comes from somewhere else. > Do we need to generate a leave event there ? Actually, no. When the pointer moves from a sensitive parent widget into an insensitive child widget, a leave_notify event is emitted on the parent but no corresponding enter_notify event is emitted. So if the application is keeping track of which widget the pointer is above, when the pointer is above an insensitive widget it will report the same as when the pointer is outside the application's main window. The invariant here is that keeping track of enter/leave notifies, the pointer is in at most one widget, which must be sensitive. This patch strengthens the invariant to: the pointer is in the widget it is above if and only if that widget is sensitive. Right, I'll work on your comments.
Created attachment 79225 [details] [review] gtk-sensitivity.patch Patch implementing changes suggested in comment 61. Instead of a new GdkNotifyType, created a new GdkCrossingMode, GDK_CROSSING_SYNTHESIZED. Seemed more appropriate.
Some comments: - I believe you are leaking the synthesized event. - I don't think we need the mode argument, since all callers are passing GDK_CROSSING_SYNTHESIZED - I think gdk_widget_synthesize_crossing_for_foo should be public api, so that 3rd party no-window widgets can enjoy the same fix as GtkButton. - When making those functions public, it would be nicer IMO to pull the GDK_WIDGET_SYNTH_CROSSING() check into the functions. Here is an updated patch that addresses these points. Do you agree to make those functions public ?
Created attachment 79248 [details] [review] new patch
I'm wondering whether fixing this bug will also fix the following issue that I'm having on Windows XP using GTK+ 2.10.6: 1) Start up GIMP. 2) With the brush tool selected in the tool panel, click the button for selecting a brush. This opens a dropdown panel. 3) Without moving the mouse, click again to close the panel. 4) The button is now not lit up and does not respond to mouse clicks. 5) Move the pointer off the button and back in again. Then it works again. This situation is a bit different in that the button is never actually made insensitive, but I'm guessing the dropdown panel is a modal window? I'm seeing the same behaviour in my own application when opening a modal window in response to a mouse click and then closing it again shortly after.
(In reply to comment #65) > Some comments: > > - I believe you are leaking the synthesized event. Oops. > - I don't think we need the mode argument, since all callers > are passing GDK_CROSSING_SYNTHESIZED Yes. > - I think gdk_widget_synthesize_crossing_for_foo should be > public api, so that 3rd party no-window widgets can enjoy > the same fix as GtkButton. Yes, that makes sense. This allows gtk_widget_synthesize_crossing_event to be made static and simplified, as you have done. > - When making those functions public, it would be nicer IMO > to pull the GDK_WIDGET_SYNTH_CROSSING() check into the functions. Yes, if it's external API. > Here is an updated patch that addresses these points. > Do you agree to make those functions public ? Yes, good idea.
(In reply to comment #66) > Created an attachment (id=79248) [edit] > new patch Ah... Comments: 1. You've omitted the addition to gtk_private_flags_get_type() in gtk/gtktypebuiltins.c? 2. In gtk_widget_synthesize_crossing_event(), you're leaking two refs to window. 3. You've omitted the addition to gdk/gdkevents.h in gdk/gdkevents.h? Other than that, great.
re comment 67: the current patch handles grab notifies, so it could well fix that case.
Created attachment 79585 [details] [review] updated patch
Created attachment 79586 [details] [review] fixed patch broken patch, sorry :(
Hmm, in one sense, I like the patch a lot ... the approach of sending enters/leave is is much better than GtkButton querying the pointer when it's sensitivity is changed or something. But I have some reservations as well: - Crossing events are not a widget thing (despite the current LEAVE_PENDING flag), but rather a GdkWindow thing. If you try to track the enter/leave state per widget, then you have problems with widgets with multiple windows. - I forsee problems from ignoring the detail field of the crossing event. The detail field is important if you, for example, want to distinguish the pointer being in a window or any descendent from the pointer being in the window itself. Sending events with a detail of NOTIFY_UNKNOWN basically means that any such tracking is a lost cause. - I don't like the way, in your patch, that gtk_widget_synthesize_crossing_from_grab_notify gtk_widget_synthesize_crossing_from_state_changed are made public and then GtkButton calls them. That seems to me like confusion over this is something maintained by the core widget system or by widgets. What we really want to do is make any tricky invariants handled by the core widget system, and remove hacks from the widgets. Really, if the generation of synthetic crossing events is handled properly, we should be able to remove the setting of button->in_button() from gtk_button_state_changed() and gtk_button_grab_notify(). - Should GTK_LEAVE_PENDING be removed? The purpose of it overlaps entirely with this patch, though it only handles the LEAVE side, not the ENTER side. Without working through all the details, the way I would have approached this issue is to track two "pointer windows" for each toplevel. The real pointer window is defined by the events delivered by X. (If crossing events aren't selected for a window, then it can never be the real pointer window.) The effective pointer window is: - The root window, if the widget that owns the real pointer window is insenstive, or if there is a grab widget that is not an ancestor of the real pointer window's widget. - The real pointer window otherwise. When the effective pointer window changes for a reason other than an event delivered from the window system, that's when we synthesize crossing events... we deliver all the crossing events that are defined by the X protocol spec ... so this well generally include "VIRTUAL" enters and leaves on the ancestor windows of the real pointer window. If you don't sent those VIRTUAL events, then the accounting won't work right in complex situations, where children are made insensitive, parents are made insensitive, the pointer is moved, widgets are made sensitive again ... things like that. I know that sounds like a lot more complex than what you have now ... probably not more code, but maybe trickier code. And after all those patch iterations too! But we have to keep the events that get generated well defined or it's basically impossible to know what to expect. And since the existing GTK+ system (complexity layered on top of complexity inherited from X) is complex, it's hard to make changes to it that are simple.
Created attachment 79610 [details] [review] gtk-sensitivity.patch re comment 69: the refs to window aren't leaked, they're released by gdk_event_free(). I'm an idiot.
As usual, Owen has the best idea. The approach described in comment 73 is going to work much more reliable and correctly than anything based on widget flags. Too bad it will take a bit of work to implement...
Just wanted to note that not only debuggers are blessed with the effects of this bug: Xsane: You cannot scan several pages without exiting/entering the scan button (my wife _hates_ that, and now resorts to using Ctl-Enter). Sylpheed, you cannot 'get' mail again without same. Please?
This is ridiculously irritating, I have run up against this in my application as well.
Created attachment 80856 [details] [review] gtk-sensitivity.patch Ugh. I had written a point-by-point response to comment 73. Here's some code instead; untested but it should show what I intend.
Impressive patch. It will certainly be fun to test this. It has quite a bit of overhead though, since you store the pointer window per-widget. Since your patch seems to satisfy the following conditions: 1) at most one widget at a time can have the HAS_POINTER flag set 2) you only ever look at the pointer window of a widget if it has HAS_POINTER set it should be possible to take Owens approach of storing a global pointer window per display instead. Right ? One detail I wonder about is if it can happen in _gtk_widget_synthesize_crossing that from != to but from_window == to_window (thinking of no-window widgets sharing the window with their parent), in which case + else if (from_window == to_window) + ; may cause missed events. But maybe that case can never happen...
Note to self: this is https://bugzilla.novell.com/show_bug.cgi?id=239565 Looks like we all owe a beer to Ed :)
Created attachment 81931 [details] [review] gtk-sensitivity.patch > it should be possible to take Owens approach of storing a global pointer window > per display instead. Right ? Per-screen, you mean? This iteration stores the global pointer window in a qdata on the GdkScreen; there doesn't seem to be anywhere I can add a member to a struct, unfortunately. > One detail I wonder about is if it can happen in > _gtk_widget_synthesize_crossing > that from != to but from_window == to_window (thinking of no-window widgets > sharing the window with their parent), in which case > > + else if (from_window == to_window) > + ; > > may cause missed events. But maybe that case can never happen... No, it does happen fairly often e.g. in menus or scrollbars, where a no-window widget gets Gtk+ grab. But it won't leak events, because the no-window widget isn't expecting enter/leave events anyway.
Created attachment 82307 [details] [review] gtk-sensitivity.patch Fix a stupid typo.
Created attachment 82412 [details] [review] gtk-sensitivity.patch Currently we get reentrancy in gtk_window_unset_transient_for() caused by grab removal changing selected item on menus. The easiest way to fix this is to reorder the function.
*** Bug 419147 has been marked as a duplicate of this bug. ***
What's the state of the bug? I think it is a really annoying one, a MAjor one!!!
It needs someone with the necessary time to sit down and test it thoroughly - it should produce essentially the sequence of events that are required by the X protocol specification.
I don't understand why it has to be so unnecessarily complicated - why not just consider HIGHLIGHTED and SENSITIVE to be independent flags?
Can someone increase the priority on this bug. People... 2001... we need a fix :)
Can somebody *please* comment on my suggestion in Comment #87?
For what it's worth, developers can work around this bug by simply hiding/showing the button after they make the button sensitive again. This will too fast for the user to see, and it will allow them to click the button without moving their mouse from the button. I forget where I read about this workaround (kudos to whoever came up with it!), but I've been using it in my application without any problems.
I agree with Stefan this should have a Higher priority. I'm rather new to the Linux desktop community and I noticed this during the install process... And now i encounter it during regular use, constantly having to move off a button and back on to click it... It is quite noticeable so much so that I spent time finding this bug posting. Which was not very easy to find. I think if this post was easier to locate you would have a LOT more people commenting on it :) All those migrating from windows or mac to linux will notice this. It is one of those it has to "Just Work" kind of things. Gives a very bad first impression cause it happens all the time. Now I also realize free software is um free :) so I'm not holding my breath but I think this should have a Higher priority... It really surprises me that this kind of bug can exist for so long... 6 years... :( In any case other than this 1 thing, the rest of GTK is awesome ;) Best Wishes
*** Bug 406543 has been marked as a duplicate of this bug. ***
This has been annoying me for so long I decided that it must not be a bug. I figured it was an intentional feature for preventing accidental clicks when a new window appears. :-) Otherwise it would have been fixed by now, right? If KDE doesn't have this problem, can you emulate their functionality? (In reply to comment #91) > It really surprises me that this > kind of bug can exist for so long... 6 years... :( That's free software for you...
(In reply to comment #93) > This has been annoying me for so long I decided that it must not be a bug. I > figured it was an intentional feature for preventing accidental clicks when a > new window appears. :-) Otherwise it would have been fixed by now, right? > > If KDE doesn't have this problem, can you emulate their functionality? > > (In reply to comment #91) > > It really surprises me that this > > kind of bug can exist for so long... 6 years... :( > > That's free software for you... BS, look how many patches are posted to solve this issue.
(In reply to comment #87) > I don't understand why it has to be so unnecessarily complicated - why not just > consider HIGHLIGHTED and SENSITIVE to be independent flags? That would be difficult; HIGHLIGHTED (actually PRELIGHT) and (IN)SENSITIVE are members of the GtkStateType[1] enumeration, and so PRELIGHT_INSENSITIVE would be difficult to add (lots of theme code would need changing); moreover, prelight state is set by the widget implementation, not by GTK+ core (i.e. gtkmain.c) so the only way to tell a widget to transition to a prelight state consistently with the logic as it stands is to send it a mouse-entered event. Take a look at gtk_button_enter_notify in gtkbutton.c, and note how it's the widget itself that controls the SENSITIVE state. Changing that at this stage, when there are hundreds of GTK+ widgets outside the GTK tree, would be... challenging. 1. http://developer.gnome.org/doc/API/2.0/gtk/gtk-Standard-Enumerations.html#GtkStateType
*** Bug 440433 has been marked as a duplicate of this bug. ***
Created attachment 89429 [details] program to help test this Here is a small program I wrote while trying to test this, but it's rather tricky, the only synthesized events I got were the three newly introduced ones [gtk grab, gtk ungrab, state changed]. Hope this is useful for someone.
*** Bug 446579 has been marked as a duplicate of this bug. ***
Ok, trying to write down some kind of test plan. Concepts (as outlined by Owen) - The real pointer window: this is the window that we most recently received an enter notify for (windows that don't select for crossing events can't become the real pointer window) - The real pointer widget: this is the widget to which the real pointer window belongs - The effective pointer window: this is the same as the real pointer window, unless the real pointer widget is either insensitive or there is a grab on a widget that is not an ancestor of the real pointer widget, in which case it is the root window. Theory of operation When the effective pointer window is the same as the real pointer window, we receive crossing events from the window system. When the effective pointer window changes to be different from the real pointer window, we synthesize crossing events according to the rules of the X protocol about crossing events: If the root window is becoming the effective pointer window, we generate - a leave notify with detail Ancestor on the real pointer window - leave notifies with detail Virtual on any ancestor of the real pointer window up to the toplevel - an enter notify with detail Inferior on the root window If the root window stops being the effective pointer window, we generate - a leave notify with detail Inferior on the root window - enter notifies with detail Virtual on any ancestor of the real pointer pointer window, starting at the toplevel - an enter notify with detail Ancestor on the real pointer window What to test: - Check that the tracking of real and effective pointer window and widget works correctly - Verify that we generate the expected sequence of crossing events with correct details when the real pointer widget becomes insensitive - Verify the event sequence when the real pointer widget becomes sensitive again - Verify the event sequence when a sibling widget of the real pointer widget establishes a GTK grab - Verify the event sequence when the sibling widget releases the grab again All this should be done with multi-window widgets, too
Two more test cases: - Start with the real pointer widget being insensitive, verify that moving the pointer to a sensitive sibling widget creates the expected event sequence - Start with the real pointer widget being grab-shadowed, verify that moving the pointer to a not grab-shadowed widget creates the expected event sequence This testing should be fully automatable using gdk_display_warp_pointer(). For comparison purposes, warping the pointer to/from the root window should give the same sequence of crossing events.
This looks right to me. The one case that isn't explicitly mentioned in your test plain is when the user moves the pointer into a window owned by an insensitive widget. In that case, the *ideal* sequence of events would be to treat things as if the effective pointer window moved directly to the root window, but it's probably easier to allow some extra events so, if you have window C within window B within Window A, and C's owner is insensitive and the pointer moves directly from A to C (imagine that C and B are the same size), you'd ideally want to send only a leave on A with a detail of Ancestor, but the easier thing is likely: leave on A with detail inferior enter on B with detail virtual <real enter on C with detail ancestor not delivered> <synthetic leave on C with detail ancestor *not delivered*> leave on B with detail virtual leave on A with detail virtual
Created attachment 89967 [details] [review] Updated patch that applies against trunk I'm reviewing/testing now, just posting an updated patch.
Created attachment 90241 [details] First stab at new test program Here's my first stab at a new automated test program.
Created attachment 90242 [details] Updated test Prints the detail of the crossing event.
Created attachment 90246 [details] Updated to work around g_timeout_add_seconds() bug I was having issues with g_timeout_add_seconds(4, ...) so I changed this test program to use g_timeout_add (4000, ...) instead. Also Created bug 448943 for anyone who cares. :)
Created attachment 90254 [details] updated tests Here is a slightly enhanced version of the test which dumps out more event details.
Created attachment 90280 [details] Update of mclasen's patch This updates Matthias's patch to use g_timeout_add() instead of g_timeout_add_seconds().
Created attachment 90432 [details] [review] another round of patch Here is another version of the patch that tries harder to implement the semantics outlined by Owen. It doesn't get all details right, but the event sequences look much closer to the expected ones.
FWIW, I'm unable to replicate this bug with sloppy-focus. Mouse-focus also works fine, but click-focus does replicate it. I'm on Fedora7, and I've been using the testcase from comment #11.
Please, tell be when clicking on GTK button starts to work. I'm talking about such case, like described in bug https://bugs.launchpad.net/bugs/108164 : 2: Forward button on installer dialog box does not respond to mouse clicks if mouse cursor isn't moved between 2 steps. Moving mouse cursor or the dialog box makes button "Forward" responsible again.
After celebrating the 10 years birthday of GNOME, will we have to "celebrate" the 10 years birthday of this bug ? ;-)
*** Bug 489584 has been marked as a duplicate of this bug. ***
Created attachment 98835 [details] [review] Updated patch
Matthias, regarding your comment #108, do you remember what you thought was not yet finished in it, or what it didn't yet get right? It's unclear to me in my testing what is not working as expected.
25 duplicates.
*** Bug 504963 has been marked as a duplicate of this bug. ***
This bug is getting ridiculous! Can we finally apply one of the suggested patches please? Each of the patches might be broken in one or the other way, but nevertheless they all have one __giant advantage__: They work arround or even solve this very visible and embarrassingly issue.
i think exactly the same as mathias. please apply a patch.
(In reply to comment #117) > This bug is getting ridiculous! > > Can we finally apply one of the suggested patches please? Agreed. Try navigating through pictures with gThumb and deleting a few as you go. You have to wiggle the mouse around at just the right time to get the button to respond. Otherwise it does nothing when you try to navigate. I thought this was a problem with my own computer for the first few months of using Linux, because I didn't believe something this fundamentally broken would be allowed to exist in open-source software. I'm amazed that patches exist and haven't been implemented, no matter how imperfect.
I do agree too. It has been a very long time since this bug has been reported and it's really boring. I guess won't be terrible to change the patch later or revert it a day.
Can people please stop adding comments that basically just agree with what tbf said? Adding more "I agree" comments is not productive and it's just cluttering the bug report. If we don't manage to finish the patch before the Berlin hackfest, perhaps we can allocate some time there towards this. I did devote some time to try to understand what is missing from the current patch, but I wasn't as thorough as I need to be. I'll be willing to take a stab at improving the patch once I have a better understanding of what's missing. Here's what I -think- is not correct at the moment. Matthias said in comment #99 that if the root window becomes the effective window pointer we generate: - leave notify on real pointer window, with detail Ancestor [1] - leave notify on ancestors of real pointer window, with detail Virtual [2] - enter notify on root window with detail Inferior [3] From what I can tell, here's what is actually happening: [1] - leave notify on real pointer window, detail nonlinear [2] - leave notify on ancestors, detail nonlinear-virtual [3] - Not watching the root window (need to improve the test program) And if the root window stops being the effective pointer window generate: - leave notify on root window, detail Inferior [4] - enter notify on ancestors of the real pointer window, detail Virtual [5] - enter notify on real pointer window, detail Ancestor [6] What I think is happening: [4] - Unsure, not watching the root window yet [5] - enter notify on ancestors, detail nonlinear-virtual [6] - enter notify on real pointer window, detail nonlinear
Correction to what I posted before (sorry, it's been awhile since I was looking at this stuff). What's currently happening when the root window becomes the effective window pointer is that we generate: - leave notify on real pointer window, detail Ancestor - leave notify on ancestors, detail virtual And this is correct in itself. However, the opposite is not correct I think: When the root window stops being the effective pointer window it looks like we generate: - enter notify on window (*), detail ancestor - leave notify on window (*), detail inferior - enter notify on other ancestors, detail virtual - enter notify on real pointer window, detail ancestor (*) Note that in this case 'window' is an ancestor of real pointer window. So if the mouse then moves back to the root window, you'll get this sequence: - leave notify on real pointer window, detail ancestor - leave notify on ancestors of real pointer window, detail virtual - leave notify on window, detail virtual So what is not happening correctly (the way I understand it) in our test is that window (our bottom ancestor) receives "enter notify, detail ancestor" then immediately "leave notify, detail inferior" when the mouse pointer enters our real pointer window and then when the mouse pointer leaves the real pointer window, we get another leave notify on the window.
*** Bug 508082 has been marked as a duplicate of this bug. ***
Yet another variation of this bug: As bug 508082 describes, button also miss mouse entering, when some other window has grabbed the pointer. We should consider this case, when fixing bug 56070.
(restoring previous state)
I disagree that this is a blocker for GNOME 2.22, it has been without a proper solution for more than 6 years. It seems unlikely that a new release of GNOME cannot be released without this bug properly fixed. Besides, I am not sure if the Gtk+ maintainers are willing to include the proposed patch in a stable release series, it's rather intrusive and needs to be tested thoroughly. According to the Bugzilla descriptions, the severity 'Major' or even 'Normal' seems to be the proper one, since this bug is not blocking development or testing, nor does it cause crashes, loss of data or memory leaks.
Johan: IMHO this bug is open still for social, but not for technical reasons - since there is a simple solution for the original problem. I am using it for years now: ==== photobuch-com.h === #define gtk_widget_set_sensitive gtk_widget_set_sensitive_if_changed ==== photobuch-com.c === #undef gtk_widget_set_sensitive static void adjust_hover_state (GtkWidget *widget) { /* GNOME-Bug 56070: Simulate MOUSE-ENTER effect when needed */ if (GTK_IS_BUTTON (widget) && GTK_WIDGET_IS_SENSITIVE (widget)) { gint x, y; gtk_widget_get_pointer (widget, &x, &y); GTK_BUTTON (widget)->in_button = x >= 0 && x < widget->allocation.width && y >= 0 && y < widget->allocation.height; } } void gtk_widget_set_sensitive_if_changed (GtkWidget *widget, gboolean sensitive) { g_return_if_fail (GTK_IS_WIDGET (widget)); if (GTK_WIDGET_IS_SENSITIVE (widget) != sensitive) { gtk_widget_set_sensitive (widget, sensitive); adjust_hover_state (widget); } } #define gtk_widget_set_sensitive gtk_widget_set_sensitive_if_changed ======================= This trivial approach for solving the problem was rejected since gtk_widget_get_pointer() causes an additional X server roundtrip. So agreed: The patch isn't perfect. It is a hack, but it solves the problem. Well, and this is were the social aspect of the problem kicks in: Rejecting a working solution 'cause of its uglyness, without providing a better solution within years, clearly is a social problem. It's the social aspect, not the technical one, that qualifies this bug as BLOCKER - IMHO.
I think the worry is that if the patch is applied then we may get some weird bizarre bug affecting gtk+ a year or two later and have to waste a lot of time trying to figure out what's causing it, etc. As tbf says, the patch here solves the issue at hand, so why don't we leave it up to the distributions to apply it until it gets finished and applied to gtk+ svn? That seems like a perfectly sensible solution to me. I'll try to devote more time to understand and improve the patch when I can. Previously I wasn't sure what the problem with the patch is, and Matthias didn't remember anymore. That's a blocker for improving the patch. But now I know what's not working, and I've documented it here. That's not as big of an improvement as posting a better patch, but it's still some progress. I agree with Johan that it's not a blocker for GNOME 2.22. It wasn't a blocker for any other version of GNOME, it was just annoying. I still think if we don't solve it by GNOME 2.22 then maybe we can devote some time to it at the Berlin Hackfest.
convinced. Most people don't see this as a GNOME 2.22 blocker but as a highly annoying gtk+ blocker. Hackfest should definitely be the place to cook a patch together that makes everybody happy and to get this finally erased.
I've been watching the bug for years now. Enough's enough :)
a quick newbie question if I may (sometimes newbie questions are helpful!). Anyone know how other OSs/GUIs deal with buttons becoming sensitive while the pointer is over them? Is the complexity due to the way GTK has been designed compared with other GUIs? Thanks, and apologies if this is not the place to ask this.
endolith makes a very valid comment in comment #93. It can often be a problem on Windows XP that a dialogue box can pop up with a button in the exact location where you were about to click on the button of another window/dialogue. I've had this happen to me. Please can we bear this problem in mind (if applicable) when coding a solution. I.e. ideally there would be a user configurable delay before a button becomes clickable if the dialogue box containing it has only just appeared. If we can achieve this, then we'll actually have one up on Microsoft latest OS!
10 years to (not) fix a serious usability issue. Wow. Gnome. Removing from cc list.
So I'm trying to get back into this now, and my comment #122 is not entirely accurate I see. The issue is that when you move the pointer out of the window, the sequence of events is actually dependent upon how fast you move the mouse. The same is also true when you move the pointer into the window. For example, when moving the mouse out of the window rapidly: -- leave B: native, normal, nonlinear -- leave E: native, normal, nonlinear-virtual -- leave W: native, normal, nonlinear-virtual If you move the mouse more slowly you would see: -- leave B: native, normal, ancestor -- leave E: native, normal, virtual ++ enter W: native, normal, inferior -- leave W: native, normal, nonlinear (The opposite is true when entering the window.. you will get 3 enter events, plus a spurious leave event on the window). So, I need to try to understand where this is coming from. :)
Wow. GNOME never fixes that bug??? No wonder KDE is getting good reviews. (BUT GNOME is faster and usable, so I like GNOME better...) As to the technical aspects of this, I had to wonder if this is a more complicated bug than it is. In an older version of GTK+, the button bug is clearly visible. After I compiled a newer version of GTK+, the bug disappeared. (OS: Puppy Linux 2.14 - exact version) Yet in Ubuntu there is the same bug in Feisty - which their GTK version is higher than the other one. (2.10.11 > 2.8.17) This bug scared the people who I tried to convert then to Linux. It is just a terrible mess. This bug should be fixed ASAP. There is no need for delay.
Look, I'm sure everyone hates this bug as much as the next person, but can we please not make unnecessary comments and generate useles bugspam? Everyone following this bug knows that everyone hates this bug and wants it fixed; commenting without providing useful technical details (e.g. even a half-working, proof-of-concept patch) regarding a fix is unproductive. Complaints generally do not motivate someone to fix a bug. Note that between the last comment and this one someone removed himself from the CC list -- why do you suppose he did so? I can't find the GNOME version of the following document, but this is fairly generally applicable anyway: https://bugzilla.mozilla.org/page.cgi?id=etiquette.html
Created attachment 109938 [details] [review] gtk-sensitivity.patch Update for 2.13.0.
Created attachment 114569 [details] [review] Add unit test
Created attachment 114571 [details] [review] Check button sensitivity before calling gtk_button_leave() This fixes the issue where a button could generate two synthesized leave events when it becomes insensitive while the pointer is in it. See the change in gtk_button_leave_notify().
So everything before the grab add is correct now. I'm not sure about after that.. here's the sequence of events I'm getting when I do gtk_grab_add() on the check button: Establishing GTK grab on check button C. -- leave W: synthesized, gtk-grab, ancestor ++ enter C: synthesized, gtk-grab, inferior -- leave E: synthesized, gtk-grab, ancestor ++ enter C: synthesized, gtk-grab, inferior -- leave B: synthesized, gtk-grab, ancestor ++ enter C: synthesized, gtk-grab, inferior So what I'm wondering is, should each synthesized leave event on another widget also result in a synthesized enter event on the grabbed check button? Or should we only be getting a single enter event on it?
Created attachment 114627 [details] [review] Add establish-gtk-grab unit test. This adds one more test, establish-gtk-grab.
Looking at your tests: - it would be good to also check events on the root window - it would be good to track the 'effective pointer window' - cursor_on_sensitive: looks right, you are checking the expected sequence of native events. - change_sensitivity: according to the theory layed out further up, what I would have expected here is: - a leave notify with detail Ancestor on the real pointer window - leave notifies with detail Virtual on any ancestor of the real pointer window up to the toplevel - an enter notify with detail Inferior on the root window As Owen said much further up: Sending events with a detail of NOTIFY_UNKNOWN basically means that any such tracking is a lost cause. - cursor_from_insensitive_to_sensitive: what I would have expected here is: - a leave notify with detail Inferior on the root window - enter notifies with detail Virtual on any ancestor of the real pointer pointer window, starting at the toplevel - an enter notify with detail Ancestor on the real pointer window We seem to be missing the events on the intermediate windows, and on the one event we get, the detail is wrong. This is because the event we get is a native one. - cursor_from_sensitive_to_insensitive: pretty much the same comment, we don't get events on the intermediate windows, and the detail on the one event we get is wrong. - establish_gtk_grab: What should be happening here is that first B is the effective pointer window, then when the grab takes place, B gets grab shadowed and the effective pointer window moves to root, so we should get leave notifies on B, E, W (with details Ancestor, Virtual, Virtual) and an enter on the root window (with detail Inferior). The actual sequence looks nothing like it...
I assume what might be happening in the grab case is that we get multiple synthesize_crossing calls, because it gets called in grab_notify_foreach ?
"I assume what might be happening in the grab case is that we get multiple synthesize_crossing calls, because it gets called in grab_notify_foreach ?" Yes, that's exactly why we get what we get there.
I tried adding: gdk_window_add_filter (gdk_get_default_root_window (), root_filter_func, test->window); But root_filter_func() seems to never be called. "- change_sensitivity: according to the theory layed out further up, what I would have expected here is: - a leave notify with detail Ancestor on the real pointer window - leave notifies with detail Virtual on any ancestor of the real pointer window up to the toplevel - an enter notify with detail Inferior on the root window As Owen said much further up: Sending events with a detail of NOTIFY_UNKNOWN basically means that any such tracking is a lost cause." I've fixed this, I'll post an updated patch later today.
Created attachment 114739 [details] [review] Fix state-changing crossing events This corrects the crossing events on the state change and updates the unit test to reflect it.
Created attachment 114740 [details] [review] Didn't have the unit test in the last patch Sorry, generated the last patch from svn instead of git (don't ask) and forgot to svn add the unit test. Here's an updated patch. This also adds a new unit test for when the state changes from insensitive to sensitive.
The first three tests are good now, the last three need more work. Wrt to the root window, you probably need to set an appropriate event mask: test->events_connected = TRUE; mask = gdk_window_get_events (gdk_get_default_root_window ()); mask = mask | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK; gdk_window_set_events (gdk_get_default_root_window (), mask); gdk_window_add_filter (gdk_get_default_root_window (), root_filter_func, test); But of course, this is not going to be useful, since we are not generating any native enter/leave events on the root window...
"But of course, this is not going to be useful, since we are not generating any native enter/leave events on the root window..." Does that mean I don't want to have this stuff? + synth_crossing (NULL, GDK_ENTER_NOTIFY, + gtk_widget_get_root_window (from), + mode, GDK_NOTIFY_INFERIOR);
If you look at the code for synth_crossing, calling it for the root window is a no-op, since gtk_get_event_widget returns NULL for the root window.
Created attachment 114966 [details] [review] Updates for grab-shadowing This update I think improves the events when the grab shadow is added or removed. Here is the sequence of events I get with this patch: Establishing GTK grab on check button C. -- leave B: synthesized, gtk-grab, ancestor -- leave E: synthesized, gtk-grab, ancestor -- leave W: synthesized, gtk-grab, ancestor Removing GTK grab from check button. ++ enter B: synthesized, gtk-ungrab, ancestor ++ enter E: synthesized, gtk-ungrab, ancestor ++ enter W: synthesized, gtk-ungrab, ancestor The four situations that are not currently working ideally are: Moving from insensitive widget to sensitive widget C ++ enter C: native, normal, nonlinear Moving from sensitive widget C back to insensitive widget -- leave C: native, normal, nonlinear Moving from grab-shadowed widget to C -- leave C: native, normal, nonlinear ++ enter C: native, normal, nonlinear Moving from C to grab-shadowed widget -- leave C: native, normal, nonlinear ++ enter C: native, normal, nonlinear The first two I've spent some time trying to solve, and I've gotten nowhere. My feeling is that I'd like to move on and ignore these two even though they're not working absolutely to the ideal. I'm not sure about the last two, I'd like a little bit more time with those.
Created attachment 114967 [details] [review] Unit test was missing in last patch Somehow I missed the unit test again in that last patch.
Created attachment 115171 [details] [review] Add unit test for removing gtk grab Added remove-gtk-grab unit test.
Created attachment 115604 [details] [review] Updated patch, added unit tests for moving from and to grab shadowed widgets
Created attachment 115622 [details] [review] Fix typo in unit test I was accidentally moving from B -> C for both of the last two unit tests. The last one now moves C -> B.
A day of regular desktop use didn't reveal any problem with the patch, and I could verify that it indeed fixes several of the notorious button-becomes-sensitive issues in apps. I agree that we should go with the patch as it is now. Some small janitorial things are still left to do: 1) I believe most of the 'theory of operation' explained way up by Owen should go in the a comment somewhere, maybe the doc comment for _gtk_widget_synthesize_crossing. 2) The GtkPrivateFlags changes need to be reflected in the registration of the enum type in gtktypebuiltins.c 3) tests/simple.c seems to have some C99-style comments. Those should be converted to /* */ 4) The docs for the new crossing modes should state that they were added in 2.14, and perhaps also that these modes are never native, but always synthesized (not sure) Please commit it with those changes. Congratulations on killing one of the longest-standing open bugs in GTK+.
2008-07-31 Cody Russell <bratsche@gnome.org> Bug 56070 – Can't click button after setting it sensitive. * gtk/gtkwidget.[ch] * gtk/gtkwindow.c * gtk/gtkmain.c * gtk/gtkbutton.c * gtk/gtkprivate.h * gdk/gdkevents.h: Synthesize crossing events events where necessary. * gtk/tests/crossingevents.c: Add unit tests for crossing events. Big thanks to Ed Catmur, Matthias Clasen, and everyone else who has worked on and helped out with this.
Wow... congratulations! , , , , , |_,_|_,_|_,_| , _,-=|; |, |, |, |;=-_ .-_| , | , | , | , | , | _-. |: -|:._|___|___|__.|:=- :| ||*: : . . : |*|| || | | * | * | * | | || _.-=|:*| | | | | |*:|=-._ - `._: | * | * | * | :_.' - =_ -=:.___:_____|___.: =- _= - . _ __ ___ ___ ___ __ _ . - Enjoy the pie!
Cody, we owe you (and the others who provide previous attempts at patches) big time.
Oh god it's fixed. Thanks so much, Cody!!!
Woohoo! Good job, Cody and others! sri
Vla the Impaler strikes again. Thanks, Cody :)
Cody is a hero to millions! Congrats guys.
Respect and thatnk you. I remember that bug annoyed me in our assistant window some years(!) ago. I never found a solution until now ;-) J.
Just took seven years. Not bad. Now Cody can start working on some bug from 2002. Keep up the good job dude!
What GTK+ stable release will have the correction? 2.14, I presume?
It will be included in 2.14, yes.
Thanks for fixing this Cody - much appreciated.
Hooray! I had subconsciously worked around this bug (and seen others do the same) by moving my mouse away from a button I was expecting to appear, and then back in when it was ready to click. Thanks tons for fixing it.
Anyone know if GTK+ 2.14 will get in to Ubuntu 8.10?
I guess Ubuntu 8.10 will ship GNOME 2.24 which will include gtk+ 2.14. This is totally a distro decision so you might want to ask them, but I'm quite sure about this.
Thanks Andre. And thanks to everyone involved in fixing this.
*** Bug 546434 has been marked as a duplicate of this bug. ***
(In reply to comment #171) > I guess Ubuntu 8.10 will ship GNOME 2.24 which will include gtk+ 2.14. This is > totally a distro decision so you might want to ask them, but I'm quite sure > about this. > A forum post reports that the required bug fix is present in Ubuntu 8.10 already. I have confirmed that I can't recreate the problem any more. <http://ubuntuforums.org/showthread.php?t=884134>
*** Bug 547379 has been marked as a duplicate of this bug. ***
*** Bug 557202 has been marked as a duplicate of this bug. ***
I had filed this as "gdm buttons don't work at first" <https://bugzilla.redhat.com/show_bug.cgi?id=468107>. Glad to hear it's finally been fixed, and thanks to all commenters (particularly Wouter) for brightening my day. :-)
It's FINALLY fixed! Thanks to the devs who fixed it. :) Looks like it's still going around... :P Don't know why... Read "Rick's Opinion", scroll to see.
(In reply to comment #158) > Wow... congratulations! > > , , , , > , |_,_|_,_|_,_| , > _,-=|; |, |, |, |;=-_ > .-_| , | , | , | , | , | _-. > |: -|:._|___|___|__.|:=- :| > ||*: : . . : |*|| > || | | * | * | * | | || > _.-=|:*| | | | | |*:|=-._ > - `._: | * | * | * | :_.' - > =_ -=:.___:_____|___.: =- _= > - . _ __ ___ ___ ___ __ _ . - Really hate to say this, but... The cake is a lie. Guess what broke with client-side windows? :( I can reproduce this with the test case already attached to this bug report.
On an equally sad note, the workarounds no longer work.
I think synaptic used to have the workarounds in it. Right now if I put my mouse pointer over "Reload" or "Mark All Upgrades" while they're insensitive and then they become sensitive, I can click them. Also when I run the crossingevents test it says all the tests pass. I'm using Ubuntu Karmic, so I definitely have client-side-windows.
Jon McCann tested and had the same results I did. Let's leave this open for a couple days just to see what happens. If we can't get anyone else to reproduce it then I'd like to close it again.
i'm also using karmic and i can't reproduce the bug
I went ahead and closed this again. Christian ran the unit test from gtk+ source and it all succeeded. If it turns out we do have an issue we'll open a new bug report.
ehm, i just ran into this while deleting messages from this bug in evolution :-). gtk+ 2.18.1 in debian.
something sort of relevant: quickly clicking the same button works but doing it slowly will run into this bug.
*** Bug 597143 has been marked as a duplicate of this bug. ***
This bug reappeared for me as well, when upgrading from gtk 2.18.0 to 2.18.1 some days ago using Arch Linux (Testing).
It is supposed to have been fixed in 2.18.2
*** Bug 371006 has been marked as a duplicate of this bug. ***