Hello, I think something needs to be said somewhere about Focus events for applications that want to keep track of the focus state of their windows, and I think this would be the place to do it. I appologize that this is a little technical and specific to Xlib's focus events, but hopefully they should be familiar enough to most of you.
As it is right now, without any standard, there is little you can do to ensure that your application will work correctly under every window manager. I haven't delved into the Firefox code, but I think the notorius bug of the wrong Firefox window thinking it is focused derives from this issue, so its not something obscure. As well, KDE applications such as Kopete are affected. I used Kopete to test everything that follows as it provided an easy way to test the various cases. The problem lies with the NotifyGrab, NotifyWhileGrabbed, NotifyUngrab Focus events. There are two approaches to watching when your window loses focus: a) Ignore no events at all. Many terminal programs do this, so you get the notorius flicker when you hit a keybinding if they key is grabbed on the root window (or any window other than their own). These applications will always know when they lost focus, at the cost of thinking they have lost focus every time you press a key. An example of a) would be if you had Kopete set up to beep when you received a message in the window and it wasn't active. If Kopete used this approach (it doesn't), it would beep at you if a message came in while you are alt-tabbing, even though the window appears to be focused still on screen. I'm guessing that is why they don't use this approach. b) Ignore focus events from grabs. This fixes the problem of thinking you are not focused when you visually are, but in its place you can lose focus and have no idea. You can move focus off the Kopete window and receive messages, and it won't know to beep at you, thinking that it is still the active window. So.. some nitty gritty details for my digging around for the cause of this all.. I'm going to just talk about key events, even though the same would apply to mouse buttons but they are generally not used in these same ways. I'm also going to assume that the application is ignoring Grab-type focus events, because having the visibly focused window thinking it is not focused is a real inconsistancy to users. Active grabs: If you were to alt-tab in your window manager and bring up a focus cycling dialog, the WM is going to make an XGrabKeyboard call. This is going to send our Kopete window a FocusOut-NotifyGrab, which it will ignore. If the user selected a new window and the WM moved focus there _before_ XUngrabKeyboard'ing, the Kopete window will not get another focus event, so it will be unaware that it has lost focus (it ignored the Grab one). Two solutions are to require the WM to ungrab everything before sending focus anywhere, so the Kopete window can get a FocusIn-NotifyUngrab -> FocusOut-NotifyNormal, or require applications to listen to all focus events, which is undesirable. This gets really tricky for things that hide windows like changing desktops. Metacity currently suffers from this problem because it grabs the keyboard (for its popup dialog) and ends up hiding the focused window during the grab. The window ends up with no idea it lost focus. Passive grabs: For keybinds that are not causing an XGrabKeyboard, but are grabbed regardless (on the root window or even on the client's window), when the key is pressed a passive grab is made on the keyboard until it is released. So if focus moves while the key is still pressed, the window will again have no idea that it lost focus. This includes if the window is hidden (changing desktops). As a solution, the WM can XUngrabKeyboard to release the passive grab, or it can wait until the key is released. This way the application receives a FocusOut-NotifyNormal. I'd like to suggest that it be the requirement of WM's to ensure they don't move the focus (or hide the focused window) during a grab, but that can also limit the functionality a WM can provide. I can't see a way to provide metacity's current desktop changin behavior (changing and showing the popup dialog at the same time) without causing a Grab-type focus out on the window, without some real tricks: You'd need to ungrab the passive grab, move focus, then grab the keyboard and give focus back to a window once that grab was released on their chosen desktop. It would be so much easier to insist that applications listen to all focus events, but as I said, you don't want windows thinking that they are not focused when they logically are (and visually). I'm not really coming here with a solution to this, but rather looking for some ideas, and to have something standardized, in any way, so that you can at least guarantee the behavior you wanted from your app in any compliant environment. One possible solution to all of this would be to demand that applications ignore all focus events, and instead only use the _NET_ACTIVE_WINDOW hint to determine if they are focused or not. That should really be implemented and enforced somehow at the toolkit level, though. Thoughts anyone? _______________________________________________ wm-spec-list mailing list wm-spec-list@gnome.org http://mail.gnome.org/mailman/listinfo/wm-spec-list