GNOME Bugzilla – Bug 109246
gnome-terminal cursor thinks that its owner has focus
Last modified: 2005-05-05 00:14:24 UTC
Package: gnome-terminal Product: gnome-terminal Synopsis: gnome-terminal cursor thinks that its owner has focus Severity: grave Priority: High Bugzilla-Product: gnome-terminal BugBuddy-GnomeVersion: 2.0 The gnome-terminal cursor looks different based on whether or not the terminal has focus. In my case, I have gnome-terminal configured with a solid square cursor that blinks when the terminal has focus. When the terminal doesn't have focus the cursor is a hollow square that doesn't blink. The cursors very often get confused, and blink as if their terminals have focus when they don't. I haven't figured out exactly what triggers the terminals to behave this way. This is evidently not related to the fact that I've configured my cursors to blink, as a fellow gnome user has mentioned that he has seen the same problem for cursors that do not blink. Coincidentally (or not), as I'm writing this bug report, two of my three gnome-terminal cursors are blinking, and neither terminal has focus. Bugtraq+: 4837677 ------- Bug moved to this database by unknown@bugzilla.gnome.org 2003-03-26 07:25 ------- Reassigning to the default owner of the component, hp@redhat.com.
If you upgrade to current versions of GTK+, this will be a *lot* better, though despite my best efforts, it's not 100% fixed.
Putting on 2.2.3; though fixing the remaining problems would require someone figuring out a reproduction sequence. It happens to me so rarely with 2.2.1 (once every few weeks) that it's not really readily debuggable.
I think this may be related to areas of the code where Gtk+ tries to compensate for no window manager running. gdkevents-x11.c has three variables to track focus: has_focus, has_focus_window, and has_pointer_focus. There seem to be situations where has_pointer_focus can become true and never get reset, and when this happens, focus events become unreliable. It has to do with override_redirect windows, and the problem can hurt any Gtk+ application which is under the override_redirect window. I am attaching a C program that came from this Eclipse bug report relating to this problem: https://bugs.eclipse.org/bugs/show_bug.cgi?id=58642 Basically, we were using XSetInputFocus and ended up confusing Gtk+ into thinking there is no window manager present. However, without using it one must grab the pointer and keyboard before being able to give focus to an override_redirect shell. Use: 1. The program is a main window with an entry in it. 2. Press a key, an override redirect window appears, also containing an entry. 3. Press a key again, we attempt to give focus to the window. 4. Press a key again, the window is destroyed. This program's behaviour is controlled by two constants at the top: const int USE_GRAB = 0 : Do not grab the pointer and mouse const int USE_GRAB = 1 : Grab the pointer and mouse const int USE_XSETINPUTFOCUS = 0 : Use gtk_widget_grab_focus const int USE_XSETINPUTFOCUS = 1 : Use XSetInputFocus Cases: USE_GRAB = 0, USE_XSETINPUTFOCUS = 1 - I think this is a close approximation of Eclipse. The window appears and is given focus fine, however when it disappears, try moving your mouse in and out of the window. Gtk+ has entered its own 'focus-follows-mouse' mode, compensating for what it believes is a lack of a Window Manager. I believe this causes all kinds of weirdness.
Created attachment 28604 [details] C program demonstrating a possible bug
Mass changing gtk+ bugs with target milestone of 2.4.2 to target 2.4.4, as Matthias said he was trying to do himself on IRC and was asking for help with. If you see this message, it means I was successful at fixing the borken-ness in bugzilla :) Sorry for the spam; just query on this message and delete all emails you get with this message, since there will probably be a lot.
*** Bug 158038 has been marked as a duplicate of this bug. ***
I'm not claiming that there are no bugs in the gdk focus handling code, but a) it should be too surprising that you can confuse gdk if you call XSetInputFocus behind its back b) not grabbing the mouse and keyboard while having an override redirect mapped is inherently broken. Try Ctrl-Alt-Left in your app. It first brings up the override redirect, then metacity switches workspaces, and you get the effect of "sticky override-redirect". You can also just move the main window out from underneath the popup by clicking on its frame...
I think what is happening is that a top-level window which has focus using RevertToParent is being destroyed, giving focus to the root window, and confusing GTK+. I think that bug 158038 and the corresponding Mozilla bug may give some more hints to other cases where this might occur. I agree that calling XSetInputFocus behind GDK's back is a bad idea, and it would be nice to get this cleaned up. I think bug 143349 is holding us back. Regarding the grab, a counterexample is tooltips, which do not require a grab. As well, most applications listen for focus events on their parent window and so will disappear when you change workspaces from that.
I'm not sure that gtk is actually confused. I mean, the focus mode is actually PointerRoot (at least metacity doesn't have a focused window at that point), and clicking on the main window to give it focus brings things back to normal. I agree that the ability to give focus to override redirect windows may be needed. Tooltips can do without grabs, since they are basically operating in an any-relevant event-kills-me mode. But it is not actually perfect. If you have tooltips on a widget which doesn't select key events, you can switch workspaces and take a "ghost tooltip" with you. You can try e.g. with the tooltips which epiphany puts on its tabs.
Can't eclipse simply move the focus to where it wants it before unmapping the override-redirect window ?
But I guess you are right that gtk is a bit confused. Or at least, it doesn not agree with metacity about who has the focus.
My general feeling on tooltip-like-windows that receive key events (this includes drawers, etc) is that the X input focus needs to stay on the main decorated window, and key events should be redirected to the popup.
If this indeed is a dupe of bug 158038 it's a rather high-visibility bug brought on by Firefox built by default with gtk2 on any window manager that's a bit different (ion2, fluxbox, etc).
We have got off track, but again, here is what I think is happening in both the Eclipse and Mozilla case: Some X window (from any app) is: - a child of the root window - has input focus - is RevertToParent - is above a GTK+ managed window - has the mouse cursor in it - gets destroyed This causes a sequence of events from X that GTK+ was not expecting, and it messes up the state of the focus variables.
Should be possible to construct a testcase from your scenario, and prove that the problem occurs with different window managers.
Is any progress being made on this? It's a very annoying problem, as it makes using firefox much more work than it should be.
Is anyone working on this bug? Firefox (I am told by Gentoo folk) no longer supports building with gtk1 support, which means that every user of these window managers can no longer use it - or new versions of it, anyways. This makes many Gtk2 apps about totally unusable for users of these window managers. I think that "major" is low, severity-wise.
Regarding Ion and this issue, here's another couple of guys who've looked at this: http://darkness.codefu.org/wordpress/2004/06/26/148 http://slashhome.org/date/2004/08/09/ion-firefox-annoying/
I agree with #17. This bug has been a major pain in the ass for presumably thousands of users over the years, can't be worked around (Ion users are advised to switch to another browser), has been analyzed reasonably thoroughly (both in this thread and pages linked to from it), and is a disgrace for the GTK project (GTK's reputation in the Ion community is.. terrible). I imagine things are no different in the Sawfish community. I can't help but feel that this is a typical example of how the open source development model can fail: the bug does not seem to affect any of the developers (they probably use other window managers), and therefore it doesn't get fixed. Very sad indeed.
Note that adding comments here is the *least* effective way of getting anything done here. It just pisses off the GTK+ developers. (OK, mailing the GTK+ developers personally to whine is probably worse.) If you care about this bug: A) Come up with a stand-alone test case. Being able to reliably reproduce the bug, preferably without having to install a different window manager would make this bug a lot more feasible to work on. Or even better: B) Come up with a patch
I'm not trying to piss anybody off. I'm trying to raise awareness of this issue in the hopes that it will one day get the (developer) attention that I feel an issue of this severity deserves. If I could write a patch, I would. But as an end user with no knowledge of GTK/X internals I simply can't (without spending large quantities of time familiarizing myself with GTK/X programming/internals just for this issue). Others are in a far better position to attempt a patch. Regarding testcases and analysis, the comments at: https://bugzilla.mozilla.org/show_bug.cgi?id=230097 and the bug report at: http://bugzilla.gnome.org/show_bug.cgi?id=158038 describe a reliable Ion testcase in extensive detail, and provide many insightful clues as to the cause of the problem. A testcase for Sawfish is described at: https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=126798 A testcase for ctwm is described at: https://bugzilla.mozilla.org/show_bug.cgi?id=216694 The author claims to be able to reproduce it for dropline gnome and metacity as well. In addition, there's Billy Biggs' C program that's already attached to this thread that demonstrates a bug that could be the cause.
I'm pretty sure that multiple different issues are getting pushed together here. - Billy Bigg's test case seems quite likely to have been demonstrating an old bug in metacity where you could leave the system in PointerRoot mode. - The ctwm bug report is likely a window manager problem with sending multiple WM_TAKE_FOCUS's with the same timestamp. - The ion bug report *might* be the same problem as the one this bug report is about, but the event traces are missing the information that would let me know what is going on.
The ion case occurs because ion is focusing a parent of the toplevel (the ion frame, it seems), and the event logic doesn't handle that. Not clear how that translates to the more general rare problems.
My test program fails on metacity 2.8.8 in the following way: 1. Set USE_GRAB = 0, USE_XSETINPUTFOCUS = 1 and compile. 2. Launch the application. Click between the window and other windows on the desktop. Note that focus_in and focus_out messages are printed to stderr. 3. Hit a key in the entry. An override_redirect window appears. 4. Hit another key. The override_redirect window gets focus. 5. Ensure the pointer is above the text entry in the first window. 6. Hit another key, the override_redirect window loses focus. 7. Click between the original window and another window on the desktop. Notice that focus_in and focus_out events are not sent for the window. When the override_redirect window disappears in step 6, a FocusIn event with a detail of NotifyPointer is sent to the original window. This sets toplevel->has_pointer_focus to be TRUE. However, no LeaveNotify is ever sent when the pointer leaves the window, nor does any paired FocusOut occur to set has_pointer_focus to FALSE. In this state, GTK+ will never send focus events for the toplevel window.
Great, thanks for the details. That explains why the ion problem occurs with metacity, and thus how Eclipse is triggering the problem. Switch RevertToParent to RevertToPointerRoot in your test case and the bug will go away. I also understand something else now ... how gnome-terminal sometimes gets broken when no combination of maninipulations of gnome-terminal will cause it to break. If any app on the screen does something like what your test-case does, then you can end up temporarily with root window focused, which breaks the next GTK+ window that gets focus... there is no requirement that it be in the same app.
Filed bug 303041 against Metacity saying that it should recover from root window focused in the same way it recovers from PointerRoot
Created attachment 46034 [details] [review] Candidate patch This attached patch fixes both the ion problem (testing with GTK+'s testtext rather than firefox) and Billy's test case for me. I'm still working on a writeup of *why* it works.
Can report that after spending an absolute eternity rebuilding the ubuntu hoary gtk2 packages with this patch included in, i no longer have any problems with the firefox/ion combination :-) Owen++
Created attachment 46040 [details] Theory behind the patch
Created attachment 46042 [details] [review] Slightly improved version Here's the version I'm actually going to apply ... it differs from the previous one in the handling of events received when grabbing/ungrabbing the pointer... while it would be hard to come with test cases, there were cases where the previous version could get confused, when for instance, one keyboard grab was overriden with another keyboard grab. This version corresponds to what's described in the writeup.
Patch applied to gtk-2-6 and HEAD 2005-05-04 Owen Taylor <otaylor@redhat.com> * gdk/x11/gdkevents-x11.c gdk/x11/gdkwindow-x11.h: Fix a bug in focus tracking when we move between has_pointer_focus and has_focus_window directly. (#109246, Billy Biggs, Niko Tyni and others) * gdk/x11/gdkevents-x11.c: Also fix some confusion that could happen in the case of no window manager + keyboard grabs, by moving to a more consistent model of when we pay attention to mode=NotifyGrab/NotifyUngrab events. * docs/focus_tracking.txt: Extensive writeup about how to track focus under X11.