discuss-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: focus problem


From: Yen-Ju Chen
Subject: Re: focus problem
Date: Tue, 21 Aug 2007 18:12:38 -0700

I took a look for the focus issue about "menu disappears when last
document window is closed".
I found that when GNUstep receives a FocusOut event,
it immediately tries to see where is the current focus and decide what to do.
It works fine when the focus is transfered from window A to window B
with XSetInputFocus().
But when a window A is closed (Unmap), window manager has to process
the unmap event first, then decide where to focus to.

So the sequence for window manager is:
(1) unmap event on old X window
(2) focus out event on old X window
(3) focus in event on new X window

There is a good chance that GNUstep try to
get the focused window between (2) and (3).
To prove that, I try this patch:

Index: Source/x11/XGServerEvent.m
===================================================================
--- Source/x11/XGServerEvent.m  (revision 25408)
+++ Source/x11/XGServerEvent.m  (working copy)
@@ -1013,7 +1013,7 @@
         {
           Window       fw;
           int          rev;

+usleep(1000000);
           /*
            * See where the focus has moved to -
            * If it has gone to 'none' or 'PointerRoot' then

It waits a second so that window manager has time to
set the focus to new window and it works !
So I believe it is a racing issue between GNUstep and window manager.
GNUstep try to get the focused window while window manager haven't
have time to prepare it.
And it only happens during window closing because unmapping also
generates FocusOut[1] event.
This document[2] describes the focus handling in great details.

Currently, if the focus falls into None or PointerRoot,
GNUstep deactives itself, therefore, menu disappears.
While I haven't have a fix yet, here is the possible one
(a) if focus falls into None, GNUstep does not deactivates
because it means one of the GNUstep's window is closed
and focus is not transfers to any other window or background (root window).
(b) if focus falls into PointerRoot,
it is more complicated and I have not idea yet. :)

[1]http://tronche.com/gui/x/xlib/events/input-focus/
[2]http://tronche.com/gui/x/xlib/events/input-focus/normal-and-grabbed.html

Yen-Ju

On 8/21/07, Fred Kiefer <fredkiefer@gmx.de> wrote:
> Andreas Höschler wrote:
> > Hi Yen-Ju,
> >
> > I have played some more with Azalea and the focus problem. The problem
> > can easily be reproduced by adding a menu item to any application and doing
> >
> > - (void)test
> > {
> >     [[NSWorkspace sharedWorkspace] launchApplication:@"TextEdit"];
> > }
> >
> > in the corresponding method. I tried this with GNOME, Window Maker and
> > Azalea. With all three window managers I got the same result. If the
> > above method is called for the first time (TextEdit.app not yet
> > running), then the application is correctly started and gets key focus.
> > However, if the app is already running, then it is activated, but it
> > does not get key focus.
> >
> > This seems to be a general problem in GNUstep, nothing specifically
> > related to Azalea.
> >
>
>
> I think I finally found the reason for this problem and as often it
> turns out to be rather simple and actually the same problem as the one I
> already solved:
> The time send along with the XSetInputFocus call is to old, so the
> request to set the focus is ignored by the X server.
> For this last problem this was caused by the variable generic.lastTime
> not being set up properly, it was initialized with 1 and not with
> CurrentTime. In our new case the problem is more subtle. The code tries
> to keep the time of the last event to use this as the time for the focus
> change, based on the reasoning the any focus change must be triggered by
> an event and if we set the stored time for every event we are always as
> current as the focus change. This reasoning isn't true for the case
> where an application gets activated without an event. In our case it was
> activated by a DO call from another program. Now the last event time for
> the application that is to activate is older then the one at the server
> and the request gets ignored.
> One simple workaround here is to always use CurrentTime as the time for
> the focus change. This of course has some risks, we work around the
> protection mechanism of the X server and may easily end up with a race
> condition, when a user switches focus too fast. But for the moment this
> is the best solution I see.
>
> Any comments?
>
> Fred
>
>
> _______________________________________________
> Discuss-gnustep mailing list
> Discuss-gnustep@gnu.org
> http://lists.gnu.org/mailman/listinfo/discuss-gnustep
>




reply via email to

[Prev in Thread] Current Thread [Next in Thread]