[comp.windows.x] SubstructureRedirect & server out of sync bug

dshr@SUN.COM (David Rosenthal) (03/03/89)

You are correct that clients which ignore the possibility that their
operations may have been re-directed may not operate correctly.  It
did not turn out to be possible to ensure that a client would be
totally unaware of possible redirection.  Your example is but one
of the cases in which this is true.

The set of operations that may be re-directed and the consequences
of this re-direction are set out in Section 4.2 of the Inter-Client
Communications Conventions Manual.

In particular,  clients that want to move their top-level window
and operate correctly in it will need to select for ConfigureNotify
events,  and change their view of its position only when the
event arrives.  Clients which do operations (such as your example of
WarpPointer) that have global rather than window-local effects have
to be aware of this possibility.

Note that the ICCCM deprecates the whole idea of clients warping the
pointer,  anyway.

	David.

garya@stan.com (Gary Aitken) (03/03/89)

I think there is a major hole in the server operation with regards to
processing of windows effected by SubstructureRedirect set on their
parent.

Consider the following:

    Window is owned by Client, is parented to Root.
    WindowManager (WM) has set SubstructureRedirect on Root.

    Client moves Window.
    Server converts move into request and sends it to WM.
    Client does some operation (e.g. WarpPointer) relative to
    origin of Window.
    WM hasn't processed move request yet.  Server warps pointer
    to old location of window; then WM catches up and Window
    moves out from under.

If override redirect is set for the window, this problem goes away.
But the ICCCM proposal suggests that this window should really be a
transient for type window, which puts the problem back in.

For this to work properly, the server needs to operate as follows:

Any time it has redirected an operation to another client, it should
block all further requests for the window from all clients except the
client to which the request was redirected, until it receives a
complementary directive in response to the redirect.  Clients setting
SubstructureRedirect are then required to act on it.

e.g. A ConfigureWindow must be sent out following receipt of a
ConfigureRequest; a MapWindow or UnmapWindow must be sent out following
receipt of a MapRequest; a ConfigureWindow must be sent out following a
ResizeRequest.

Unless the server does this already for some requests, such as an info
request for the Window, this problem can show up all sorts of places.

Correct?  Or did I miss something somewhere?

Gary Aitken
ncar!boulder!stan!garya

rws@EXPO.LCS.MIT.EDU (Bob Scheifler) (03/03/89)

    WM hasn't processed move request yet.  Server warps pointer
    to old location of window; then WM catches up and Window
    moves out from under.

The ICCCM states that you'll get a ConfigureNotify event (even
if the WM decides not to move you) from a correctly implemented WM.  If you
want the "sync", wait for the event.  I don't see that you need the complexity
you suggest.

dshr@SUN.COM (David Rosenthal) (03/04/89)

> Consider a toolkit which needs to warp the pointer for some reason.

It had better be a very good reason indeed.  The ICCCM convention saying
that clients should not warp the pointer is not to be disregarded lightly.
After all,  we all want to be able to claim "ICCCM compliance",  don't we?

> An example would be when input objects are "chained" together;
> hitting <CR> on one entry may imply warping the pointer into the next
> one to activate input (yes, there are other ways to change the focus...).
> 
There are indeed other ways to use the focus and you had better use
one of them.  A client warping the pointer is never an acceptable method of
transferring the input focus,  neither to its top-level window nor
among its sub-windows.  If you want to transfer the focus,  use the
requests that do so.  If you want to warp the pointer,  do so because
you want to warp it,  not because you want some side-effect that you think
is going to happen when you do.

> In any case, the toolkit knows nothing of what the application has been
> doing.  In particular, it does not know if the application has moved some
> arbitrary ancestor of the destination window for the warp.  As a
> consequence, the toolkit does not know if anything has happened at all,
> so it doesn't know whether to wait for the ConfigureNotify or not; and
> it has no idea of which ancestor it should look for it on.
> 
This is a good example of one of the reasons why the ICCCM specifies that
clients should not warp the pointer.  Although,  to be fair,  it is the
application you envisage that is buggy.  It is moving the window;  it
has the responsibility to do so safely (i.e. by selecting for and
observing the ConfigureNotify).

	David.

garya@stan.com (Gary Aitken) (03/04/89)

>    The ICCCM states that you'll get a ConfigureNotify event (even
>    if the WM decides not to move you) from a correctly implemented WM.  If you
>    want the "sync", wait for the event.  I don't see that you need the
>    complexity you suggest.

Consider a toolkit which needs to warp the pointer for some reason.
An example would be when input objects are "chained" together;
hitting <CR> on one entry may imply warping the pointer into the next
one to activate input (yes, there are other ways to change the focus...).

In any case, the toolkit knows nothing of what the application has been
doing.  In particular, it does not know if the application has moved some
arbitrary ancestor of the destination window for the warp.  As a
consequence, the toolkit does not know if anything has happened at all,
so it doesn't know whether to wait for the ConfigureNotify or not; and
it has no idea of which ancestor it should look for it on.

An example is a dialog box which is reparented or moved in a context
sensitive manner.

Gary Aitken
ncar!boulder!stan!garya

rws@EXPO.LCS.MIT.EDU (Bob Scheifler) (03/04/89)

    As a
    consequence, the toolkit does not know if anything has happened at all,
    so it doesn't know whether to wait for the ConfigureNotify or not; and
    it has no idea of which ancestor it should look for it on.

The toolkit doesn't need to know.  The expectation is that you wait at
the point where you attempt the top-level geometry change, not that you
delay waiting until you attempt something that depends on the move.  The
thing/point at which a top-level change is requested should be able to
deal with this (e.g. the Shell widget in Xt).

The assumption is that this is a rather rare occurance (for windows
that are managed by the window manager), so that the delay is tolerable.
If you have data to the contrary, or have a specific proposal that is
simple and more efficient, please present the information.

[We should do this either just on xpert, or just privately, so I don't
have to redo what I've said privately.]