~ubuntu-branches/ubuntu/vivid/marco/vivid

« back to all changes in this revision

Viewing changes to doc/how-to-get-focus-right.txt

  • Committer: Package Import Robot
  • Author(s): Mike Gabriel
  • Date: 2014-01-21 19:52:39 UTC
  • Revision ID: package-import@ubuntu.com-20140121195239-c4k1v8umdw1u4n29
Tags: upstream-1.6.2
ImportĀ upstreamĀ versionĀ 1.6.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
7
basics are easy:
 
8
 
 
9
Focus method  Behavior
 
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
 
13
              window
 
14
 
 
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:
 
18
 
 
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
 
23
              window is focused.
 
24
    mouse     If the mouse is in a non-DESKTOP window, then it is focused;
 
25
              otherwise, the designated "no_focus_window" is focused
 
26
 
 
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.
 
32
 
 
33
Focus method  Behavior
 
34
    click     Focus the most recently used window (same as the window
 
35
              on top)
 
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
 
40
              "no_focus_window".
 
41
 
 
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.)
 
49
 
 
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:
 
57
 
 
58
  1) If the window takes a while to launch and the user starts
 
59
     interacting with a different application, the new window should
 
60
     not take focus.
 
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.
 
64
 
 
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)
 
70
 
 
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
 
79
     appear on top.
 
80
 
 
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
 
90
     mouse_mode to TRUE.
 
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.
 
104
 
 
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;
 
112
not normal clicks).
 
113
 
 
114
 
 
115
 
 
116
 
 
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
 
132
 
 
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...>
 
186
 
 
187
 
 
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:
 
191
 
 
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
 
219
        more details)
 
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
 
232
     confusing)
 
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
 
239
     modes right.
 
240
  4) Because of -1-, -2-, and -3-, implementations are often buggy or
 
241
     inconsistent and people form their opinions from usage of these
 
242
     implementations.
 
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.