summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/focus_tracking.txt161
1 files changed, 0 insertions, 161 deletions
diff --git a/docs/focus_tracking.txt b/docs/focus_tracking.txt
deleted file mode 100644
index f3576c180c..0000000000
--- a/docs/focus_tracking.txt
+++ /dev/null
@@ -1,161 +0,0 @@
-Notational conventions
-======================
-
-We have a window W that we are tracking events on. Focus
-can be on the following classes of objects
-
- None : defined by X protocol
- PointerRoot : defined by X protocol
- W : the window itself
- Ancestor : An ancestor of W, including W's root window
- Descendant : A descendant of W
- Other: : A window that is neither an ancestor or
- descendant of W
-
-has_pointer(W): the pointer is in W or one of its descendants.
-
-NotifyPointer events
-====================
-
-X sends FocusIn or FocusOut events to W with a detail of NotifyPointer
-in the following transitions, when the pointer is inside W
-
- Other => Ancestor: FocusIn
- Ancestor => {Other,None}: FocusOut
- Ancestor => PointerRoot: FocusOut, then FocusIn
- {None,W,Descendant,Other} => PointerRoot: FocusIn
- PointerRoot => Ancestor: FocusOut, then FocusIn
- PointerRoot => {None,W,Descendant,Other} => FocusOut
-
-[ Ignoring keyboard grabs for the moment ]
-
-Basic focus tracking algorithm
-==============================
-
-Keystroke events are delivered within W if and only if one of two
-predicates hold:
-
- has_focus_window(W): F==W || F==Descendant
- has_pointer_focus(W): (F==Ancestor || F==PointerRoot) && has_pointer(W)
-
-These two conditions are mutually exclusive.
-
-has_focus_window(W) is easy to track.
-
- FocusIn: detail != NotifyInferior: Set has_focus_iwndow
- FocusOut: detail != NotifyInferior: Clear has_focus_iwndow
-
-has_pointer_focus(W) is harder to track.
-
-We can separate out the transitions from !has_pointer_focus(W) to
-has_pointer_focus(W) into four cases:
-
- T1: [(F==W || F==Descendant) => F==Ancestor]; has_pointer(W)
-
- T2: [(F==W || F==Descendant) => F==PointerRoot]; has_pointer(W)
-
- T3: [(F==None || F==Other) => (F==PointerRoot || F==Ancestor)];
- has_pointer(W)
-
- T4: [!has_pointer(W) => has_pointer(W)]; (F==Ancestor || F==PointerRoot)
-
-All of these can be tracked by watching events on W.
-
-T1:, we get a FocusOut with a mode of Ancestor or Virtual
- We need to separately track has_pointer(W) to distinguish
- this from the case where we get these events and !has_pointer(W)
-
-T2, T3: together these are exactly the cases where we get
- FocusIn/NotifyPointer.
-
-For T4, we get an EnterNotify with the focus flag set. An
- EnterNotify with a focus flag set will also be sent if
- F==W, so we have to to explicitly test for that case
- using has_focus_window(W)
-
-
-The transitions from has_pointer_focus(W) to !has_pointer_focus(W)
-are exactly the opposite
-
- F1: [(F==W || F==Descendant) <= F==Ancestor]; has_pointer(W)
-
- F2: [(F==W || F==Descendant) <= F==PointerRoot]; has_pointer(W)
-
- F3: [(F==None || F==Other) <= (F==PointerRoot || F==Ancestor)];
- has_pointer(W)
-
- F4: [!has_pointer(W) <= has_pointer(W)]; (F==Ancestor || F==PointerRoot)
-
-And can be tracked in the same ways:
-
-F1: we get a FocusIn with a mode of Ancestor or Virtual
- We need to separately track has_pointer(W) to distinguish
- this from the case we get these events and !has_pointer(W)
-
-F2, F3: together these are exactly the cases where we get
- FocusOut/NotifyPointer.
-
-F4: we get an LeaveNotify with the focus flag set. An
- LeaveNotify with a focus flag set will also be sent if
- F==W, so we have to to explicitly test for that case
- using has_focus_window(W).
-
-
-Modifications for keyboard grabs
-================================
-
-The above algorithm ignores keyboard grabs, which also
-generate focus events, and needs to be modified somewhat
-to take keyboard grabs into effect. The basic idea
-is that for has_pointer_focus(W)/has_window_focus(W) we track
-them ignoring grabs and ungrabs, and then supplement
-that with another predicate has_focus(W) which pays
-attention to grabs and ungrabs.
-
-Modification 1:
-
- When tracking has_pointer_focus(W), ignore all Focus
- events with a mode of NotifyGrab or NotifyUngrab.
-
- Note that this means that with grabs, we don't perfectly.
- track the delivery of keyboard events ... since we think
- we are getting events in the case where
-
- has_pointer_focus(W) && !(G == None || G==W || G==descendant)
-
- But the X protocol doesn't provide sufficient information
- to do this right... example:
-
- F=Ancestor, G=None => F=Ancestor, G=Ancestor
-
- We stop getting events, but receive no notification.
-
- The case of no window manager and keyboard grabs is pretty
- rare in any case.
-
-Modification 2:
-
- When tracking has_focus_window(W), ignore all Focus
- events with a mode of NotifyGrab or NotifyUngrab.
-
-Modification 3: instead of calculating focus as
-
- has_focus_window(W) || has_pointer_focus(W)
-
- Calculate it as
-
- has_focus(W) || has_pointer_focus(W)
-
- where has_focus(W) is defined as:
-
- has_focus(W): F==W || F==Descendant || G=W
-
- Tracking has_focus(W) is done by
-
- FocusIn: detail != NotifyInferior, mode != NotifyWhileGrabbed:
- set has_focus
- FocusOut: detail != NotifyInferior, mode != NotifyWhileGrabbed:
- clear has_focus
-
- We still need to track has_focus_window(W) for the T4/F4
- transitions.