1
To make choice of focus window consistent for each focus method, a
2
number of guidelines should be followed. (For purposes of discussion
3
here, I'm excluding things like the panel and the desktop from
4
"windows". It is technically incorrect to do this, but I'm lazy and
5
"windows" is shorter than something like "normal windows". See the
6
end of the discussion for how these special cases are handled.) The
10
click When a user clicks on a window, focus it
11
sloppy When an EnterNotify is received, focus the window
12
mouse Same as sloppy, but also defocus when mouse enters DESKTOP
15
Note that these choices (along with the choice that clicking on a
16
window raises it for the click focus method) introduces the following
17
invariants for focus from mouse activity:
19
Focus method Invariant
20
click The window on top is focused
21
sloppy If the mouse is in a window, then it is focused; if the
22
mouse is not in a window, then the most recently used
24
mouse If the mouse is in a non-DESKTOP window, then it is focused;
25
otherwise, the designated "no_focus_window" is focused
27
However, there are a number of cases where the current focus window
28
becomes invalid and another should be chosen. Some examples are when
29
a focused window is closed or minimized, or when the user changes
30
workspaces. In these cases, there needs to be a rule consistent with
31
the above about the new window to choose.
34
click Focus the most recently used window (same as the window
36
sloppy Focus the window containing the pointer if there is such
37
a window, otherwise focus the most recently used window.
38
mouse Focus the non-DESKTOP window containing the pointer if
39
there is one, otherwise focus the designated
42
Note that "most recently used window", as used here, has a slightly
43
different connotation than "most recent to have keyboard focus". This
44
is because when a user activates a window that is a transient, its
45
ancestor(s) should be considered to be more recently used than other
46
windows that have had the keyboard focus more recently. (See bug
47
157360; this may mean that the alt-tab order should also change
48
simultaneously, although the current implementation does not do that.)
50
Also, sometimes a new window will be mapped (e.g. unminimizing a
51
window or launching a new application). Most users want to interact
52
with new windows right away, so these should typically be focused.
53
This does conflict with the invariants for sloppy and mouse focus
54
modes, so this wouldn't be true for a strict-pointer-focus mode. For
55
all other modes (non-strict-pointer-focus modes), there are only two
56
cases in which a new window shouldn't be focused:
58
1) If the window takes a while to launch and the user starts
59
interacting with a different application, the new window should
61
2) If the window that will appear was not launched by the user
62
(error dialogs, instant messaging windows, etc.), then the window
63
should not take focus when it appears.
65
To handle these cases, Marco compares timestamps of the event that
66
caused the launch and the timestamp of the last interaction with the
67
focused window. (Case 2 is handled by the application providing a
68
special timestamp of 0 for the launch time, which ensures that the
69
window that appears doesn't get focus)
71
If the newly launched window isn't focused, some things should be done
72
to alert the user that there is a window to work with:
73
1) The _NET_WM_DEMANDS_ATTENTION hint should be set
74
2) If the new window isn't modal for the focused window, it should
75
appear below the focused window so that it doesn't obscure the
76
focused window that the user is interacting with.
77
3) If the new window is modal to the focused window, the currently
78
focused window should lose focus but the modal window should
81
Additionally, the user may decide to use the keyboard instead of the mouse
82
to navigate between windows (referred to as "keynav"). This poses no
83
problems for click-to-focus (because the same invariant can be
84
maintained), but for sloppy and mouse focus it requires extra work to
85
attempt to handle the INHERENTLY CONFLICTING CONSTRAINTS. Marco does
86
this by having a mouse_mode boolean used to determine which of the two
87
sets of invariants holds. This mode is set according to which method was
88
most recently used to choose a focus window:
89
1) When receiving EnterNotify events from mouse movement, set
91
2) When using keynav to choose a focus window (e.g. alt-tab, alt-esc,
92
alt-f2, move-window-to-workspace keybindings), set mouse_mode to FALSE.
93
3) When handling events that don't choose a focus window but rather need
94
a focus_window chosen for them (e.g. switch-to-workspace keybindings),
95
don't change the mouse_mode and just use the current value.
96
Note that grabs present a special case since they can generate EnterNotify
97
and LeaveNotify events without using the mouse, thus these events should be
98
ignored when the crossing mode is NotifyGrab or NotifyUngrab. THIS
99
MOUSENAV/KEYNAV MODERATION METHOD IS NOT PERFECT--there are corner cases
100
when trying to mix-and-match between mousenav and keynav simultaneously
101
that cause problems; but it appears to be the most reasonable tradeoff and
102
works well in most cases, especially if the user sticks to just mousenav
103
for a long time or just keynav for a long time.
105
Finally, windows of type WM_DOCK or WM_DESKTOP (e.g. the desktop and
106
the panel) present a special case, at least partially due to the lack
107
of decorations. For WM_DESKTOP windows, we only focus them if the
108
user explicitly requests it (e.g. clicks on the window, uses
109
Ctrl-Alt-Tab to navigate to it, uses a keybinding to show the desktop,
110
etc.). For WM_DOCK windows, we do not focus unless we receive a very
111
explicit request (e.g. Ctrl-Alt-Tab or a _NET_ACTIVE_WINDOW message;
117
To read more about the bugs that inspired these choices:
118
- When a focused window becomes invalid and another should be chosen
119
http://bugzilla.gnome.org/show_bug.cgi?id=135810
120
- When a new window is mapped
121
http://bugzilla.gnome.org/show_bug.cgi?id=118372
122
Also, the EWMH spec, especially the parts relating to _NET_WM_USER_TIME
123
- Modal vs. non-modal dialogs that get denied focus when mapped
124
http://bugzilla.gnome.org/show_bug.cgi?id=151996
125
- Mousenav vs. Keynav in mouse and sloppy focus modes
126
http://bugzilla.gnome.org/show_bug.cgi?id=167545
127
http://bugzilla.gnome.org/show_bug.cgi?id=101190
128
http://bugzilla.gnome.org/show_bug.cgi?id=357695
129
- Not focusing panels
130
http://bugzilla.gnome.org/show_bug.cgi?id=160470
131
http://bugzilla.gnome.org/show_bug.cgi?id=120100
133
There were many bugs which had to be fixed to get all the above
134
working; they helped form these policies and/or show the difficulties
135
in implementing this policy (my apologies in advance for producing a
136
list heavily lopsided to what I've done; it's just that these bugs are
137
the ones I'm the most familiar with):
138
bug 72314 ignore LeaveNotify events from grabs
139
bug 82921 focus windows on map
140
bug 87531 only show focus for sticky windows on active workspace (pager)
141
bug 94545 focus window on workspace switch is non-deterministic
142
bug 95747 should ignore EnterNotify events with NotifyInferior detail set
143
bug 97635 sticky windows always keep focus when switching workspaces
144
bug 102665 a window unminimized from the tasklist should be focused
145
bug 107347 focus windows that manually position themselves too
146
bug 108643 focus in MRU order instead of stack order
147
bug 110970 moving a window to another workspace loses focus
148
bug 112031 closing a dialog can result in a strange focus window
149
bug 115650 add _NET_WM_USER_TIME support to gtk+ (see also 150502)
150
bug 120100 panel shouldn't be focused after workspace applet usage
151
bug 123803 need final EnterNotify after workspace switch (see also 124798)
152
bug 124981 focus clicked window in pager only if on current workspace
153
bug 125492 catch the xserver unfocusing everything and fix its braindeadedness
154
bug 128200 focus correct window on libwnck window minimize (see 107681 too)
155
bug 131582 fix race condition on window minimize/close
156
bug 133120 wrong window focused when changing workspaces
157
bug 135024 _NET_ACTIVE_WINDOW messages need timestamps
158
bug 135786 middle-clicking on focused window to lower it should defocus too
159
bug 136581 window minimization vs. activation for mouse focus
160
bug 144900 fix focus choice on "un-showing" the desktop
161
bug 147475 don't lock keyboard on workspace change
162
bug 148364 DEMANDS_ATTENTION support for marco & libwnck (and other stuff)
163
bug 149028 focus-stealing-prevention for marco-dialog (and other stuff)
164
bug 149366 windows denied focus on map occur in wrong order in alt-tab list
165
bug 149543 consistent focus window when unshowing desktop
166
bug 149589 race in focus choice from libwnck messages
167
bug 150271 make sure "run application" dialog gets focused
168
bug 150668 update gtk+ _NET_ACTIVE_WINDOW support
169
bug 151245 application startup notification forwarding (partially rejected)
170
bug 151984 Soeren's idea--backup timestamp when startup notification not used
171
bug 151990 prevent focus inconsistencies by only providing one focus method
172
bug 151996 modal dialogs denied focus should not be lowered
173
bug 152000 fix race on window close followed by rapid mouse movement
174
bug 152004 ways to handle new window versus mouse invariants
175
bug 153220 catch the root window getting focus and reset to default window
176
bug 157360 focus parents of dismissed transient windows in preference to
177
the window that most recently had focus
178
bug 159257 focus the desktop when showing it
179
bug 160470 don't focus panels on click
180
bug 163450 correct highlighting in workspace switcher popup
181
bug 164716 refuse to focus a window with a modal transient, and focus
182
the transient instead
183
bug 166524 avoid new windows being obscured by the focus window
184
bug 167545 mousenav vs. keynav in mouse and sloppy focus modes
185
<a massive heap of bugs relating to focus stealing prevention...>
188
Addendum on sloppy and mouse focus
189
You may occasionally hear people refer to sloppy or mouse focus
190
modes as inherently buggy. This is what they mean by that:
192
1) Keynav doesn't maintain the same invariants as mouse navigation
193
for these focus modes; switching back and forth between
194
navigation methods, therefore, may have or appear to have
195
inconsistencies. Examples:
196
a) If the user uses Alt-Tab to change the window with focus, then
197
starts to move the mouse, at that moment the window where the
198
mouse is does not have focus.
199
b) Users expect that a workspace they previously used will not
200
change when the return to it. This means things like window
201
position and stacking order, but also the focus window.
202
Unfortunately, using the original focus window (which would be
203
the most recently used window on that workspace) will
204
sometimes conflict with the invariants for mouse and sloppy
205
focus modes. Users are much more surprised by the invariant
206
being broken than by having the focus window changed (see bug
207
94545 and probably others), so we maintain the invariant.
208
This only matters when using Ctrl-Alt-Arrow to switch
209
workspaces instead of clicking in the workspace switcher, so
210
this really is a keynav vs mouse issue. Either that, or a
211
windows-are-being-mapped exception. ;-)
212
c) Opening a menu, then moving the mouse to a different window,
213
and then pressing escape to dismiss the menu will result in
214
the window containing the mouse not being focused. This is
215
actually correct behavior (because pressing escape shows that
216
the user is using key navigation to interact with the window
217
containing the menu) but is one of those hard-to-get-right
218
keynav and mouse focus mixture cases. (See bug 101190 for
220
d) Similar to (c), moving the mouse off the menu doesn't immediately
221
focus the window that the mouse goes over, due to an application
222
grab (we couldn't change this and wouldn't want to, but
223
technically it does break the invariant).
224
e) If mouse_mode is off and the user does something to cause focus to
225
change (e.g. switch workspaces, close or minimize a window, etc.)
226
and simultaneously tries to move the mouse, the choice of which
227
window to focus is inherently race-y. (You probably can't satisfy
228
both keynav and mousenav invariants simultaneously...)
229
2) The sloppy/mouse invariants are often not strictly maintained;
230
for example, we provide an exception to the invariant for newly
231
mapped windows. (Most find that not allowing this exception is
233
3) There are an awful lot of little cases to handle to get any focus
234
mode right, even for click-to-focus. Since mouse and sloppy
235
focus have sometimes been hard to even determine what correct
236
behavior is, it is much harder to get them completely right.
237
Plus mouse and sloppy focus users are a minority, decreasing the
238
motivation of window manager implementors to get those focus
240
4) Because of -1-, -2-, and -3-, implementations are often buggy or
241
inconsistent and people form their opinions from usage of these
243
5) Sloppy focus suffers from a bit of a discoverability problem (for
244
example, I have seen a scientist sit down to a computer for which
245
sloppy focus was in use and take a few minutes before figuring
246
out how window activation worked; granted the layout of the
247
windows in that situation was a bit unusual but it still
248
illustrates that sloppy focus is harder than it should be to
249
figure out). Mouse focus solves this problem; however, people
250
that have experience with other computing environments are
251
accustomed to being able to move their mouse outside the window
252
they are working with and still continue interacting with that
253
window, which conflicts with mouse focus.