[PATCH] input: Fix BorderSizeNotEmpty for redirected windows
keithp at keithp.com
Wed Jul 30 16:48:12 PDT 2014
Adam Jackson <ajax at redhat.com> writes:
> In the words of the spec, grabs are meant to fail "if the confine-to
> window lies completely outside the boundaries of the root window".
> Redirected windows (and therefore windows with backing store enabled)
> have a pWin->borderSize that's not clipped to the root window, which
> means BorderSizeNotEmpty() is always true and the grab will succeed when
> it oughtn't.
As discussed on IRC, this points out a bug in the Composite support, but
the fix doesn't match the existing server semantics. The saved composite
border clip is clipped to siblings, while borderSize is not. I didn't
consider that borderSize was used for input computations.
Let's look at where borderSize is used for events
* ConfineCursorToWindow. This ensures that the pointer remains
contained within a window. Currently, that's using borderSize, but
that's actually wrong. The protocol says that a grab's 'confine-to'
window restricts the pointer to remain 'contained' in the window:
"If a confine-to window is specified, then the pointer will be
restricted to stay contained in that window."
Containment is defined in the glossary:
"A window ‘‘contains’’ the pointer if the window is viewable and the
hotspot of the cursor is within a visible region of the window or a
visible region of one of its inferiors. The border of the window is
included as part of the window for containment. The pointer is
‘‘in’’ a window if the window contains the pointer but no inferior
contains the pointer."
This doesn't match borderSize, which is only clipped by ancestors,
not by siblings. It does match the classic borderClip however.
* PointInBorderSize. This is used only by miSpriteTrace to check
whether the cursor is inside the window shape, which is the union of
the bounding shape and the clip shape. Computing the sprite trace
already starts from the top of the tree, so it's effectively
computing the input border size; so the existing borderSize will
* BorderSizeNotEmpty. This is used to tell whether the grab confine-to
window is outside the boundaries of the root window. By checking
borderSize, the grab will fail if the window is within the root but
it or some ancestor is outside one of their ancestors. I think the
spec is busted here; if you want to confine a cursor to a window,
then some portion of that window should probably be visible. In which
case, we should be using the borderClip instead of borderSize here too.
* CheckVirtualMotion. This is used to keep the logical position of the
pointer confined while replaying events, and so the semantics must
It seems like the old server code was just broken. We can almost use the
borderClip saved by composite, except when there are nested composited
windows. In that case, we would need to recursively intersect the
saved borderClips to the root.
keith.packard at intel.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Size: 810 bytes
Desc: not available
More information about the xorg-devel