title: Window focusing issues lastupdated: 2008-07-30 This is a possibly long-term task, aimed at fixing various window focusing issues present in GNUstep GUI.

Outcome

Ensure that GNUstep application windows (and menus) will obtain and retain focus correctly in EWMH-compliant window managers and especially WindowMaker.

Tasks

WAITING gather information on focusing issues that are present    COLLABORATION

NEXT categorize (and prioritize?) issues    READING

  • need to figure out which ones to work on, and which ones should be part of other sub-projects

NEXT look through source code    READING

Implementation is in:

  • NSWindow (header)
    • - (void) _lossOfKeyOrMainWindow
      • tries to find another window to make key/main. Skip the main menu as potential key window unless no others were found.
      • called by:
        • - (void) orderWindow: (NSWindowOrderingMode)place relativeTo: (int)otherWin when ordering out
        • - (void) miniaturize: (id)sender
        • - (void) sendEvent: (NSEvent*)theEvent on GSAppKitWindowFocusIn when focus goes to the main menu window
    • window creation: - (id) initWithContentRect: (NSRect)contentRect styleMask: (unsigned int)aStyle backing: (NSBackingStoreType)bufferingType defer: (BOOL)flag screen: (NSScreen*)aScreen, - (void) _initBackendWindow, - (void) _startBackendWindow, - (void) _terminateBackendWindow
      • _initBackendWindow calls XGServerWindow's window:::: and setwindowlevel methods
    • - (id) initWithWindowRef: (void *)windowRef
    • - (void) becomeKeyWindow, - (void) becomeMainWindow, - (void) makeKeyAndOrderFront: (id)sender, - (void) makeKeyWindow, - (void) makeMainWindow, - (void) resignKeyWindow, - (void) resignMainWindow
    • - (void) orderBack: (id)sender, - (void) orderFront: (id)sender, - (void) orderFrontRegardless, - (void) orderOut: (id)sender, - (void) orderWindow: (NSWindowOrderingMode)place relativeTo: (int)otherWin
    • - (void) setLevel: (int)newLevel
    • - (void) _didDeminiaturize: sender, - (void) deminiaturize: sender, - (void) miniaturize: (id)sender
    • - (void) sendEvent: (NSEvent*)theEvent
      • handles events e.g. from window manager, sent via NSApplication
    • - (BOOL) hidesOnDeactivate, - (void) setHidesOnDeactivate: (BOOL)flag
  • NSApplication
    • AppIcon definitions
    • - (void) finishLaunching (where windows are first ordered)
      • find key and main windows
      • if more than one key/main window, deactivate all but one
      • if no main window, choose one
    • - (void) hide: (id)sender - (void) unhide: (id)sender, - (void) unhideWithoutActivation
    • - (void) unhideWithoutActivation
    • - (void) arrangeInFront: (id)sender
    • - (NSWindow*) keyWindow, - (NSWindow*) mainWindow
    • - (void) miniaturizeAll: sender
    • - (void) preventWindowOrdering (not implemented)
    • - (void) activateIgnoringOtherApps: (BOOL)flag, - (void) deactivate
    • - (void) mouseDown: (NSEvent*)theEvent
      • raise the app
  • XGServerWindow
    • - (void) orderwindow: (int)op : (int)otherWin : (int)winNum
    • - (void) setwindowlevel: (int)level : (int)win?
    • - (void) setinputfocus: (int)win
      • calls XSetInputFocus to claim focus
    • - (int) window: (NSRect)frame : (NSBackingStoreType)type : (unsigned int)style : (int)screen
      • the main window creation function
      • does lots of stuff
      • window isn't displayed until -orderwindow:: is called
  • XGServerEvent
    • - (void) processEvent: (XEvent *) event
      • process X11 events
      • big switch statement for all sorts of X11 events
        • ClientMessage: may call -_handleTakeFocusAtom:forContext:
        • FocusOut: calls [NSApp deactivate] if focus goes do another application; may cancel previous focus request
    • - (NSEvent *)_handleTakeFocusAtom: (XEvent)xEvent forContext: (NSGraphicsContext *)gcontext
      • called when the Window Manager wants us to take focus
      • calls -setinputfocus: for the appropriate window

NEXT come up with a flow for what should be correct behaviour    DESIGN

  • application with or without normal windows
  • ways of gaining focus
    • application starts
      • if a main window is created, it should be focused, otherwise focus the main menu
    • user clicks on window (i.e. window manager gives application focus)
    • user changes desktop (window manager gives application focus)
    • new window
    • application asks for focus
    • window unminiaturized
    • another window loses focus
    • double-click on application icon
    • select window from popup menu
  • ways of losing focus
    • application terminates
      • nothing to be done. We don't care what happens
    • user clicks on another window (i.e. window manager takes away focus)
    • user changes desktop (window manager takes away focus)
    • window closed
    • application releases focus
    • window miniaturized
    • application is hidden

implement focusing logic    IMPLEMENTATION

consider different window managers    TESTING

Questions

X Events (from xev, on xfwm4)

On iconize:

  • FocusOut (mode NotifyNormal, detail NotifyNonlinear)
  • UnmapNotify (from_configure NO)
  • WM_STATE set
  • _NET_WM_STATE set
  • _WIN_STATE set

On uniconize

  • MapNotify (override NO)
  • VisibilityNotify (state VisibilityUnobscured)
  • Expose (x4)
  • WM_STATE set
  • _NET_WM_STATE set
  • _WIN_STATE set
  • FocusIn

On lose focus:

  • FocusOut (mode NotifyNormal, detail NotifyNonlinear)
  • maybe: LeaveNotify (mode NotifyGrab, detail NotifyNonlinear, same_screen YES, focus YES, state 6)

On gain focus:

  • FocusIn (mode NotifyWhileGrabbed, detail NotifyNonlinear)
  • maybe: EnterNotify (mode NotifyUngrab, detail NotifyNonlinear, same_screen YES, focus YES, state 0)

Issues

DONE Application does not gain focus on initial start

  • window manager: kwin, xfwm4
  • GNUstep versions: several
  • reproducible
  • applications that don't have an initial main window (e.g. Ink)
  • when started from a terminal, the terminal keeps focus, and the application's menu may disappear (does not disappear for xfwm4)
    • no longer a problem on xfwm4 with GNUstep gui/back 0.14.0.
  • this is caused by "focus stealing prevention"
  • use _NET_WM_USER_TIME
  • works in default configuration of tested window managers
  • if other window managers pose a problem, look into using _NET_WM_ACTIVE_WINDOW

Menu disappears/appears in background while in use

  • window manager: WindowMaker (click to focus)
  • GNUstep versions: latest CVS, LiveCD
  • intermittent
  • "The problem, which I think is the same or in any case related, appears in two ways:
    • "while clicking and moving the mouse on the main application menu, the menu may disappear (but it is sitll active, the submenus will show up and work and unseen items do work).
    • "The second manifestation is similar, but involves two applications open. I click on the menu of the current one and click-drag to show the submenus, they will appear behind the other's application menu, which should be in the background. Again they work."

Two windows are key

  • window manager: WindowMaker (click to focus)
  • GNUstep versions: latest CVS, LiveCD
  • intermittent (rare)
  • two windows are key (black border) or key window is ordered behind non-key window

Closing (unfocused) preferences window makes application lose focus

When GSX11HandlesWindowDecorations set to NO, clicking miniaturize button doesn't unmap window

  • window manager: xfwm4, none
  • works in: wmaker

DONE Create new document in Ink causes application to lose focus

  • window manager: wmaker
  • works in: xfwm4
  • GNUstep versions: 1.16.0/0.14.0
  • reproducible
  • Open Ink, and select Document | New: new document does not obtain focus
  • seems to be fixed by "focus stealing prevention prevention" fix from first issue

DONE Miniaturizing from GNUstep different from miniaturizing from window manager

  • window manager: xfwm4
  • works in: wmaker
  • GNUstep versions: 1.16.0/0.14.0
  • reproducible
  • when miniaturizing from window manager, no miniwindow is produced.
  • when miniaturizing from GNUstep, then hiding, miniaturized windows show up in task list as miniaturized, non-miniaturized ones do not
  • performance impact of responding to PropertyNotify XEvents shouldn't be too bad. (A bunch of events are generated, but no noticeable impact.)
  • only respond to PropertyNotify under EWMH window managers

Double-click on appicon makes wrong window key

  • window manager: xfwm4
  • GNUstep versions: 1.16.0/0.14.0
  • application: Ink
  • If two windows open in Ink, double-clicking on appicon switches focus to the other window.
    • If app is unfocused, double-clicking on appicon switches focus to the window that was not focused before.
  • Looks like xfwm4 tries to give focus to windows when they are raised.
  • Maybe a window manager quirk. Maybe not worth fixing.

Menu gets "stuck"

  • window manager: openbox 3.4.7.2
  • works in: xfwm4
  • GNUstep versions: SVN 20080615

"If you close or iconify a window and the one to gain focus is not owned by the same application, the app menu gets stuck. That is, at first the menu disappears because another app got focus, but if you bring it up again, it won't go away as easily. In the iconify case, the menu gets stuck right away, without first disappearing, probably because GNUstep does not take any notice at all of the action done by the window manager.

"The menu just sits there and does not receive keybord actions. Even if you interact with the menu by opening and closing sub-menus it does not get in a state where it reacts to menu shortcuts.

"It seems that opening a sub-menu and then clicking back and forth between the appicon and a window belonging to some other app fixes the problem. Also notice that when in the problematic state, double clicking the appicon does not unfocus other windows like is normally the case. Opening or focusing one of the application's own windows is another way to fix the situation."

NEXT Open window from hidden app

  • window manager: openbox 3.4.7.2, xfwm4
  • GNUstep versions: SVN 20080615

"When an application is hidden, you can still access its menu by right-clicking the app icon. If you bring to front an existing window from the Window menu or open a new one using Document->New or similar, the app stays hidden when the window appears, which means the app menu does not show. The application as a whole gets restored if you click anywhere inside the window, though."

  • should call unhide in response to some event (Mapped?)
  • or unhide in response to -[NSWindow makeKeyAndOrderFront:] or -[NSWindow makeKeyWindow]

NEXT Hide + miniwindows

  • window manager: openbox 3.4.7.2, xfwm4
  • GNUstep versions: SVN 20080615

When you hide an application that has miniaturized windows, strange things happen to those windows.

  1. When an application miniaturizes a window, Openbox marks the window as iconified the same way it does when minimizing windows by itself.
  2. When the application gets hidden, its miniwindows become invisible (!)
  3. Windows that were visible before the app got hidden are now completely inaccessible from the window manager - they are removed from the internal list of windows as well as external panels and pagers. This is probably correct behaviour since you're supposed to use the appicon to get the application back. The strange thing, however, is that the miniaturized windows are still in the window list (marked as iconified).
  4. If you restore a window using window manager features while the app is hidden (only possible with the miniaturized ones), the window appears without focus and the menu is not shown. No amount of switching between windows or iconifying/restoring the window will change this.
  5. Restoring the application while in this state, brings back the miniwindow even though the real window is now visible. Only when you focus the window will the miniwindow disappear.
  6. If instead of 4) you restore a miniaturized window by right-clicking the hidden application's app icon, the miniwindow will stay around until you do a new miniaturize/restore cycle on the window. If you close the window at this point, there is probably no way to get rid of the miniwindow at all.
  7. -[NSApplication hide:] skips windows that are not visible
    • should not skip miniaturized windows (although not visible)
    • -[NSApplication unhide] should order in miniaturized windows, but don't try to make them key (make sure they are still iconified)

Menu does not follow workspace

  • window manager: openbox 3.4.7.2, wmaker
  • works in: xfwm4
  • GNUstep versions: SVN 20080615
  • "When a window is moved to a different workspace, the menu does not follow. Maybe it would be better to just make the menus omnipresent?"
  • probably belongs to the ewmh task
  • works for xfwm4: when changing desktops, xfwm4 sends FocusOut saying that window 0 got focus. I guess other WMs send FocusOut saying that the application's other window got focus.
  • it looks like it's already supposed to be omnipresent
  • instead of making menu omnipresent, should store the current desktop. When we get a FocusIn event, check the current desktop. If the desktop is different, move menu (and other similar windows) to the desktop.

GWorkspace desktop

  • window manager: openbox 3.4.7.2
  • GNUstep versions: SVN 20080615
  • "Using GWorkspace's desktop with Openbox is impossible because when you click the dock or on the desktop itself, the desktop background is raised so that it shadows other windows."
  • probably belongs to the ewmh task, or is GWorkspace-specific

NEXT Window does not gain focus when selected from popup menu

  • window manager: xfwm4
  • GNUstep versions 1.16.0/0.14.0
  • when application is inactive, and you right-click on appicon and select a window from the window menu, the window is raised to the top, but does not obtain focus. (main menu window does not appear)
  • call unhide in response to -[NSWindow makeKeyAndOrderFront:] or -[NSWindow makeKeyWindow] (same as "Open window from hidden app")