-
Notifications
You must be signed in to change notification settings - Fork 71
Input focus
This page is dedicated to description of input focus management problems, findings and my vision of solutions.
There are several user actions which triggers focus switch:
- Window open (including application's start) or close (including application's quit). [actions.c: wSetFocusTo()] [event.c: handleMapRequest(), handleMapNotify(), handleUnmapNotify(), handleDestroyNotify()]
- Click on desired window titlebar. [actions.c: wSetFocusTo()]
- Click inside desired window. [actions.c: wSetFocusTo()]
- Double-click on application icon (in Dock or Icon Yard). [dock.c: iconDblClick(); appicon.c: iconDblClick()]
- Switch between applications with 'Cmd-Tab' key equivalent. [cycling.c: ]
- Miniaturize/deminiaturize window (with mouse or keyboard).
- Hide/unhide application (with mouse or keyboard).
- Workspace switch.
Here I describe desired behaviour of focus management part of Workspace Window Manager.
- (NSEvent *)_handleTakeFocusAtom:(XEvent)xEvent forContext:(NSGraphicsContext *)gcontext
if (generic.flags.useWindowMakerIcons == 1)
{
/*
* We must hand over control of our icon/miniwindow
* to Window Maker.
*/
if ((cWin->win_attrs.window_style
& (NSMiniWindowMask | NSIconWindowMask)) != 0
&& eventType == NSLeftMouseDown /*&& clickCount == 1*/)
{
if (cWin->parent == None)
break;
xEvent.xbutton.window = cWin->parent;
XUngrabPointer(dpy, CurrentTime);
XSendEvent(dpy, cWin->parent, True, ButtonPressMask, &xEvent);
XFlush(dpy);
if (clickCount != 2) {
break;
}
}
}
Every running application has WApplication instance. Normal X11 application exists only if at least one window was mapped.
WApplication instance for registered application should contain defined:
- app_icon - appplication icon
- windows - list of windows (at least one) which belongs to application
- menu_win for GNUstep application
GNUstep application minimal appearance is appicon and menu. For focus handling/switching tasks menu_win
must be set to make correct focus switching.
main_window
- this is the invisible window that identifies application as a group of windows. Also it's called as "group leader". Every WWindow and WAppIcon contains field Window main_window
. That's how application icon, menu and windows/panels can be identified as single application.
main_window_desc
- generated WWindow structure for main_window
. So main_window
can be used as managed WWindow.
last_focused
- should be set to last window of application that has focus before FocusOut, hide, workspace switch events. Set in wSetFocusTo()
.
last_workspace
- contains workspace number of last_focused window workspace. If, for exmaple, application has 2 windows on different workspaces, double-click on appicon should: switch to workspace where last_focused window resides, set focus to that window (activate application). Set in wSetFocusTo()
.
On application start wApplicationCreate() is called:
- creates wapp->windows array
- adds
wwin
to this array - saved
wwin
towapp->menu_win
if it's main menu (normally it is)
When new window opens (MapRequest/MapNotify, event.c) wApplicationAdd() is called:
- adds
wwin
intowapp->windows
array wapp->refcount++
When window is closed (UnmapNotify, event.c) and window is not main menu wApplicationRemoveWindow()
is called:
- removes
wwin
fromwapp->windows
array wapp->refcount--
When application quits (DestroyNotify, event.c):
- several calls to
wApplicationRemoveWindow()
is performed -
wApplicationDestroy()
is called:-
wUnmanageWindow()
forwapp->menu_win
is called -
wapp->windows
array destroyed wapp->refcount--
-
wapp
is freed
-
Copyright (c) Sergii Stoian