AHWM Sloppy Focus

This page explains how the sloppy focus model in other window managers is broken. The basic problems are that the focus can change unexpectedly and the focus can be lost when there are focusable windows on-screen.

Since a Unix/X11 environment makes heavy use of the keyboard, the input focus model is of utmost importance. First, some definitions:

Input focus
The window with the input focus is the window currently accepting keyboard input.
Top window
When a window is "raised" it is brought above all other windows and becomes the top window. NB: the window with the input focus is not always the top window.
Root window
The root window is the bottom-most window: all other windows are on top of the root window. It is comparable to the "desktop" in other environments.
Click-to-focus
Apple MacOS and Microsoft Windows users only use click-to-focus. With this focus model, clicking on a window gives it the input focus and also raises the window.
Focus-follows-mouse
With this focus model, the input focus is always given to the window under the mouse cursor. If the mouse cursor is on top of the root window, keyboard input is thrown away. Moving the mouse cursor on top of a window does not necessarily raise the window.
Sloppy focus
With this focus model, moving the mouse cursor over a window gives the window the input focus. Moving the mouse cursor from a window into the root window does not change the input focus. The input focus may be changed in other ways as well (such as alt-tab), so it is not always true that the input focus is the window under the mouse cursor. Moving the mouse cursor on top of a window does not necessarily raise the window.
Raise delay
Raise delay is only used with sloppy focus and focus-follows-mouse. The raise delay is a time interval which determines when a window which receives the input focus via the mouse will be raised. If the raise delay is zero, moving the mouse into a window simultaneously gives the window the input focus and raises the window. The raise delay is optional in some window managers; if it is turned off, windows cannot be raised by giving them the input focus.

The most intuitive input focus model is click-to-focus. The easiest to implement in X11 is focus-follows-mouse. AHWM provides click-to-focus and sloppy focus but does not provide focus-follows-mouse.

Those who like sloppy focus use it because it allows one to change the input focus by simply "throwing" the mouse in the target window's direction without carefully positioning the mouse for a click. This is the same concept as with the MacOS menu bar: one can open a menu by simply "throwing" the mouse to the top of the screen, without carefully positioning the mouse on top of a menu (which is what one has to do with X11 and Microsoft Windows). For an introduction to this principle, read this quiz on Fitts's Law and for a more rigorous treatment, see this page.

Some people who use sloppy focus (such as AHWM's author) would like newly-focused windows to also be raised as soon as they receive the input focus. Unfortunately, this brings up a problem:

Problem 1

When "throwing" the mouse from window A to window B, the mouse cursor might temporarily pass over window C, which is in between windows A and B (see figure 1).

Figure 1
Figure 1

Since the target window is window B, we do not want window C to be focused or raised. Since we are using the mouse at the moment, it does not really matter if window C receives the input focus temporarily. It is a problem, however, if window C is raised: if this happens, the following situation could occur (figure 2):

Figure 2
Figure 2

When window C is raised, it obscures window B, the mouse cursor never reaches window B, and B is neither focused nor raised.

There are two possible solutions to this problem:

  1. No window is raised until the mouse cursor stops moving.
  2. Windows are raised after a short delay (the raise delay).
Solution 2 is not ideal, since the delay needed varies each time one uses it. In practice, it is very difficult to efficiently implement solution 1 in X11, so all modern window managers (including AHWM) use a simple fixed raise delay.

Problem 2

In X11, it is difficult to determine if the mouse cursor enters a window because the user moved it into that window or because some window reconfigured itself to be under the mouse cursor. Most window managers don't bother trying to determine why the mouse cursor entered a window, but simply focus and raise a window whenever the mouse cursor enters a window. This leads to the following situation: the mouse cursor is over the root window and window B has the input focus; window A resizes itself to be over the mouse cursor (it makes itself wider, see figure 3).

Figure 3
Figure 3

Since window A is now under the mouse cursor, most window managers will raise and focus window A. This is especially annoying if you are typing into window B when this occurs. AHWM differentiates the "enter-window" events according to cause and does not focus or raise a window unless the user moved the mouse, so it does not have this problem.

Problem 3

In problem 2, a window resized itself to be under the mouse cursor; what if a window resizes itself so it is no longer under the mouse cursor? Consider this situation: window B has the input focus, window B is raised over window A and the mouse cursor is over both windows A and B. The input focus should not change if window B resizes itself (makes itself thinner) such that it is no longer under the mouse cursor (figure 4).

Figure 4
Figure 4

Most window managers will simply focus window A upon receiving the "enter-window" event. This is not the desired behaviour: the input focus should never change unless the user initiated a mouse movement.

AHWM correctly refuses to change the input focus unless the user moves the mouse.

Problem 4

When using the sloppy focus model on some window managers, the input focus will not be changed at all unless the window manager receives the "enter-window" event. This leads to the following situation: window B has the input focus, the cursor is over the root window and window A is the next on the focus list (see figure 5).

Figure 5
Figure 5

When window B is destroyed, the "enter-window" event is not generated because the mouse cursor did not enter any window (it was over the root window before window B was destroyed and it is still over the root window). Most window managers will simply focus no window at this point and wait for the user to move the mouse over window A (try it with your favorite window manager). It is interesting to note that most window managers will do the right thing and focus window A when they are using click-to-focus.

AHWM does not have this problem: it will automatically focus window A when window B is destroyed regardless of whether the user is using click-to-focus or sloppy focus.

Problem 5

Building on the previous problem, what happens when the mouse cursor is not over the root window, but is over another window? Every modern window manager has the concept of a focus list, an ordered list of windows to focus when the currently focused window is destroyed (this is often the same list as the list of windows to use for an alt-tab action). Consider the following situation: window B has the input focus, window A is the next on the focus list and window C is under the pointer (figure 6).

Figure 6
Figure 6

When using click-to-focus, most window managers will correctly focus window A when window B is destroyed. However, when using sloppy focus, most window managers will focus window C when window B is destroyed. Thus, the behaviour is different according the input focus model.

AHWM does not have this problem. It will correctly focus the next window on the focus list (window A) when the currently focused window is destroyed, regardless of the input focus model.