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: Wed, 22 Aug 2007 18:06:52 -0700

On 8/22/07, Yen-Ju Chen <yjchenx@gmail.com> wrote:
> On 8/22/07, Fred Kiefer <fredkiefer@gmx.de> wrote:
> >
> >
> > Yen-Ju Chen wrote:
> > > On 8/22/07, Fred Kiefer <fredkiefer@gmx.de> wrote:
> > >> Let me try to reduce the amount of confusion in this discussion. There
> > >> are multiple issues with focus setting in GNUstep and Yen-Ju and Andreas
> > >> are talking about to completely different ones.
> > >> Andreas has a problem when switching between applications via DO. This
> > >> should be fixed by my latest change to SVN, but this change introduced a
> > >> well known race condition when clicking on slow responding applications.
> > >> Richard and I will be looking into this some more.
> > >> Yen-Ju is concerned about the focus loss of an application when the last
> > >> window is closed. His different patches try to solve this.
> > >> As for the last patch I am a bit surprised that it changes anything. We
> > >> have similar code already in [NSWindow _lossOfKeyOrMainWindow]. The main
> > >> difference I see here is that Yen-Ju's code doesn't check if the ordered
> > >> out window was key before. But why would we have to change the focus
> > >> when the window being closed wasn't key?
> > >> The patch may still be valid, I just don't understand it.
> > >
> > >   The _lostOfKeyOrMainWindow is not called when window is closed.
> > >   When the last document window is closed,
> > >   it first receives the UnmapNotify, then FocusOut.
> > >   When FocusOut comes, GNUstep looks for where the focus is.
> > >   But at the same time, window manager may not prepare the focus yet.
> > >   So GNUstep cannot find focus on its own window, then deactivate.
> > >   As in one of my previous patch, which use usleep() to wait 1 second
> > >   between FocusOut and looking for focused window (XGetInputFocus)
> > >   in backend, it works fine.
> > >   So the race is between when window manager transfers the focus
> > >   and when GNUstep uses XGetInputFocus to get the focused window.
> > >   To solve this racing issue, GNUstep can transfer focus before the
> > > window is closed or window manager can do that.
> > >   No matter which party does so, the correct sequence would be:
> > >   1. last document window received a close action.
> > >   2. transfer focus to another window. Since it is the last document,
> > > it can only transfer to main menu.
> > >   3. last document window receive UnmapNotify.
> > >   4. last document window receive FocusOut and check where the current
> > > focus is. Since the focus is probably on main menu already, it will
> > > not deactivate.
> > >
> > >   Without step (2), step (4) will deactive the GNUstep application.
> > >   Since GNUstep knows better about where the focus should go,
> > >   I believe it may be easier to do step (2) in GNUstep.
> > >
> >
> > If the window manager closes the window without telling GNUstep, then we
> > really have a problem, but when it goes via [NSWindow close] as your
> > patch suggest then the next method called will be [NSWindow orderOut:],
> > which in turn calls [NSWindow orderWindow:relativeTo:]. Here we call
> > [NSWindow _lossOfKeyOrMainWindow] for the NSWindowOut case. That is why
> > I thought your patch shouldn't change things to much.
>
>   I notice the [NSApp keyWindow] is not correct.
>   That's why _lossKeyAndMainWindow does not work properly.
>   I am still looking into the problem.

Here is the trace I have:

(1) In NSWindow -close, it posts NSWindowWillCloseNotification.
(2) in NSApplication, _windowWillClose: is called, which resigned key
window. At this point, there is no key and main window, but main menu
and app icon.
(3). Window is order out, and _lossKeyAndMainWindow does nothing
because there is no key window.
(4) Neither main menu and app icon gets focus at this point, so when
it receive FocusOut, it deactives itself.

Does it make sense ?

Yen-Ju

>
>   Yen-Ju
>
> >
> > >> Cheers,
> > >> Fred
> > >>
> > >>
> > >> Yen-Ju Chen wrote:
> > >>> On 8/22/07, Yen-Ju Chen <yjchenx@gmail.com> wrote:
> > >>>> On 8/22/07, Yen-Ju Chen <yjchenx@gmail.com> wrote:
> > >>>>> On 8/22/07, Andreas Höschler <ahoesch@smartsoft.de> wrote:
> > >>>>>> Hi Yen-Ju,
> > >>>>>>
> > >>>>>>> As I said, the first half of the issue is that GNUstep cannot find 
> > >>>>>>> the
> > >>>>>>> focused window while it is unmapped. So it deactivates itself.
> > >>>>>>> This patch transfers the focus to another window in the
> > >>>>>>> same GNUstep application before it is unmapped,
> > >>>>>>> therefore, fixes the problem.
> > >>>>>>>
> > >>>>>>> The second half of the problem is that after the unmapping,
> > >>>>>>> window manager tends to actively find another window to focus on,
> > >>>>>>> therefore, even GNUstep transfers the focus, it still loses it.
> > >>>>>>> So there is nothing GNUstep can do about it.
> > >>>>>>> It has to be fixed on window manager.
> > >>>>>>>
> > >>>>>>> This patch works for me, but may need to improvement.
> > >>>>>> Thanks for working on this!
> > >>>>>>
> > >>>>>> After applying your patch I can no longer switch between applications
> > >>>>>> via clicking on application windows. The clicked window is not put to
> > >>>>>> foreground!? :-(
> > >>>>   O.K. I can see why it happens. It's another racing issue. :(
> > >>>>   Well, the patch may need to move to up stream.
> > >>>   Here is the same patch, but apply on -gui when window is closed.
> > >>>   Therefore, it will not affect the situation when window loses focus,
> > >>>   but not closed (application switching).
> > >>>   The idea is the same: transfer focus to another window before it
> > >>> gets unmapped.
> > >>>   This patch does not fix "key focus on wrong window", "window
> > >>> flicking", nor "menu disappear after last document minimized".
> > >>>   It only fixes the "menu disappear after last document window closed".
> > >>>
> > >>>   Yen-Ju
> > >>>
> > >>>>   Yen-Ju
> > >>>>
> > >>>>> Do you have latest Azalea from -trunk ?
> > >>>>> There are a few changes on it to match what GNUstep does.
> > >>>>> I have no problem switching application by clicking on their windows.
> > >>>>> But I will run it for a while to see.
> > >>>>> Fixing such bug has a side-effect that it may introduce another one.  
> > >>>>> :(
> > >>>>>
> > >>>>> I am pretty sure that the problem is as I described.
> > >>>>> But the fix may not be totally correct.
> > >>>>> And it doesn't fix the loss of focus during minimization.
> > >>>>> I am also not sure whether it will break on WindowMaker.
> > >>>>>
> > >>>>> Yen-Ju
> > >>>>>
> > >>>>>> Regards,
> > >>>>>>
> > >>>>>>    Andreas
> > >>>>>>
> > >>>>>>
> > >>>>>>
> > >>>> ------------------------------------------------------------------------
> > >>>>
> > >>>> Index: NSWindow.m
> > >>>> ===================================================================
> > >>>> --- NSWindow.m       (revision 25410)
> > >>>> +++ NSWindow.m       (working copy)
> > >>>> @@ -2455,7 +2455,42 @@
> > >>>>        _f.has_opened = NO;
> > >>>>        [NSApp removeWindowsItem: self];
> > >>>>        [self orderOut: self];
> > >>>> +#if 1
> > >>>> +       /* We move focus to another window so that window manager will 
> > >>>> not
> > >>>> +          randomly assign the focus. */
> > >>>> +       NSWindow *key_win = [NSApp keyWindow];
> > >>>> +       if (key_win == nil)
> > >>>> +               key_win = [NSApp mainWindow];
> > >>>> +       if ((key_win == nil) && [[NSApp windows] count])
> > >>>> +       {
> > >>>> +               int i, count = [[NSApp windows] count];
> > >>>> +               for (i = 0; i < count; i++)
> > >>>> +               {
> > >>>> +                       key_win = [[NSApp windows] objectAtIndex: i];
> > >>>> +                       if (key_win  ==  self)
> > >>>> +                       {
> > >>>> +                               key_win = nil;
> > >>>> +                               continue;
> > >>>> +                       }
> > >>>> +                       if ([key_win isKindOfClass: [NSWindow class]])
> > >>>> +                       {
> > >>>> +                               if ([key_win canBecomeKeyWindow] == NO)
> > >>>> +                               {
> > >>>> +                                       /* Get GSCacheWindow or 
> > >>>> NSIconWindow sometimes */
> > >>>> +                                       key_win = nil;
> > >>>> +                                       continue;
> > >>>> +                               }
> > >>>> +                       }
> > >>>> +               }
> > >>>> +       }
> > >>>> +       if (key_win == nil)
> > >>>> +               key_win = [[NSApp mainMenu] window];
> > >>>> +       int key_num = [key_win windowNumber];
> > >>>> +NSLog(@"Set Input Focus to %d", key_num);
> > >>>> +    [GSServerForWindow(key_win) setinputfocus: key_num];
> > >>>> +#endif
> > >>>>
> > >>>> +
> > >>>>        RELEASE(pool);
> > >>>>
> > >>>>        _f.has_closed = YES;
> > >>
> > >
> >
> >
>




reply via email to

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