Applications ignoring focus events

View: New views
4 Messages — Rating Filter:   Alert me  

Applications ignoring focus events

by Dana Jansens-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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@...
http://mail.gnome.org/mailman/listinfo/wm-spec-list

Re: Applications ignoring focus events

by Dana Jansens-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 5/17/07, Dana Jansens <danakj@...> wrote:
...

Sorry, I'd just like to add one thing, in the course of writing this,
I did come across the fact that the X server seems to always send a
second FocusOut-NotifyWhileGrabbed, even after it already sent a
FocusOut-NotifyGrab with no corresonding FocusIn in between. I haven't
seen it in writing anywhere however so I'm not sure it is something to
rely on. But, maybe another solution is for toolkits/applications to
ignore NotifyGrab/NotifyUngrab, but to not ignore NotifyWhileGrabbed
focus events, for determining if a window has gained or lost logical
focus. Currently applications under both toolkits do not follow this
convention though, so maybe it would need to be mandated.
_______________________________________________
wm-spec-list mailing list
wm-spec-list@...
http://mail.gnome.org/mailman/listinfo/wm-spec-list

Re: Applications ignoring focus events

by Havoc Pennington :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

Dana Jansens wrote:
> 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?

I think what apps may need to do is distinguish X Window System focus
from user-visible window focus. You can get the X Window System focus
reliably from the X events, and user-visible window focus from
_NET_ACTIVE_WINDOW.

Metacity iirc basically does this, sometimes it will draw a window frame
as focused even though it does not have X focus.

It is a bit bad for every app to listen to PropertyNotify on
_NET_ACTIVE_WINDOW though (I think - most apps don't get PropertyNotify
on root window already, do they?), so it might be nice to have another
hint or client message that the WM uses to signal "is the focused
toplevel as displayed to the user" where this is separate from the X
concept of "will in fact get keyboard events"

In some cases I think bugs here may just be that the X focus events are
_hard_ to properly use; I think Owen had to try several times to get it
right in GTK, and I think it took me a while to get right in metacity
also. This is something a toolkit could simplify for the app layer
(though GTK does not I don't think).

For a long time gnome-terminal would keep blinking the cursor when
unfocused since it's hard to get this right.

Apps do need to track actual X focus for some purposes though, such as
showing a focus indication on text boxes, and the danger with a separate
hint is that apps could try using it for the wrong purposes and end up
with worse races or bugs than they already have.

Certainly part of the existing problem is that the whole focus situation
is just complicated (GTK compounds it on the GtkWidget level, too), and
so it's not clear that making it more complicated will help in practice,
it might just pile on the confusion even if it theoretically makes
something easier.

Havoc

_______________________________________________
wm-spec-list mailing list
wm-spec-list@...
http://mail.gnome.org/mailman/listinfo/wm-spec-list

Re: Applications ignoring focus events

by Dana Jansens-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 5/17/07, Havoc Pennington <hp@...> wrote:

> Hi,
>
> Dana Jansens wrote:
> > 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?
>
> I think what apps may need to do is distinguish X Window System focus
> from user-visible window focus. You can get the X Window System focus
> reliably from the X events, and user-visible window focus from
> _NET_ACTIVE_WINDOW.
>
> Metacity iirc basically does this, sometimes it will draw a window frame
> as focused even though it does not have X focus.
>
> It is a bit bad for every app to listen to PropertyNotify on
> _NET_ACTIVE_WINDOW though (I think - most apps don't get PropertyNotify
> on root window already, do they?), so it might be nice to have another
> hint or client message that the WM uses to signal "is the focused
> toplevel as displayed to the user" where this is separate from the X
> concept of "will in fact get keyboard events"
>
> In some cases I think bugs here may just be that the X focus events are
> _hard_ to properly use; I think Owen had to try several times to get it
> right in GTK, and I think it took me a while to get right in metacity
> also. This is something a toolkit could simplify for the app layer
> (though GTK does not I don't think).
>
> For a long time gnome-terminal would keep blinking the cursor when
> unfocused since it's hard to get this right.
>
> Apps do need to track actual X focus for some purposes though, such as
> showing a focus indication on text boxes, and the danger with a separate
> hint is that apps could try using it for the wrong purposes and end up
> with worse races or bugs than they already have.
>
> Certainly part of the existing problem is that the whole focus situation
> is just complicated (GTK compounds it on the GtkWidget level, too), and
> so it's not clear that making it more complicated will help in practice,
> it might just pile on the confusion even if it theoretically makes
> something easier.

It sounds like, at the least, toolkits need to provide focus status
(through events or polling) differently to windows than to widgets
within them. For widgets, a Grab-type focus event should count. But
for top level windows, they need to be more intelligent about it,
however that may be done: through another hint/message, or possibly
through NotifyNormal and NotifyWhileGrabbed only.

I agree that watching the root window property would be bad. It would
be like the user_time (vs user_time_window) problem, causing
applications to wake up when they didn't need to.
_______________________________________________
wm-spec-list mailing list
wm-spec-list@...
http://mail.gnome.org/mailman/listinfo/wm-spec-list