(btw, thanks so much for the huge comment; I'm going to ignore the code and focus on how the comment relates to the core spec)
My theory is that we compute the logical pointer source and destination for each window in the system and deliver events to that window as if the pointer made that logical move. I believe (without proof) that the only windows which should receive events for any pointer motion are precisely the set of windows which would have received events under the core protocol with only a single pointer. That would mean that all we have to do is compute *which* event each one of those windows receives. Using (as Owen did) P(W) to represent the pointer window as seen by W, we walk the set of windows that are to receive events, compute P(W) (the old pointer window) and P'(W) (the new pointer window) and use those two windows to construct the correct event to deliver to W. Here's some deconstruction of your specific instructions: (X..Y) windows from X to Y not including X or Y [X..Y) windows from X to Y including X but not Y (X..Y] windows from X to Y not including X but including Y [X..Y] windows from X to Y including X and Y * EnterNotify(Virtual, B) means EnterNotify Event, detail Virtual, child = B. * * Pointer moves from A to B, nonlinear (CoreEnterLeaveNonLinear): * 1. a. if A has another pointer, goto 2. The goto seems correct -- nothing changes for A or any inferior of A. * b. otherwise, if A has a inferior with a pointer in it, * LeaveNotify(Inferior) to A This seems correct -- A sees the pointer move from A to inferior(A). * LeaveNotify(Virtual) between A and inferior(A) This seems wrong -- (A..inferior(A)) see the pointer remain in inferior(A). I'd say that no event should be generated here. In particular, LeaveNotify(Virtual) means that the focus is moving to an ancestor (of A). * 2. Find common ancestor X between A and B. * 3. Find closest pointer window P between A and X. * a. if P exists * LeaveNotify(Ancestor) to A This seems incomplete. If inferior(A) has a pointer, then A should see that pointer through a LeaveNotify(Inferior) event (already delivered above). Otherwise, A sees P's pointer. * LeaveNotify(Virtual) between A and P Again, this is incomplete -- if inferior(A) has a pointer, (A..P) should see that pointer and receive no events. Note that parent(A) should receive LeaveNotify(Virtual,A). * b. otherwise, if P does not exist, * LeaveNotify(NonLinear) to A Incomplete -- if inferior(A) has a pointer, A should see it and will have received a LeaveNotify(Inferior) above. * LeaveNotify(NonLinearVirtual) between A and X. Incomplete -- if inferior(A) has a pointer, then (A..X) should see it. X will also see other pointers, so precisely which windows X believes holds the pointer is a matter of pointer priority. Note that parent(A) should receive LeaveNotify(NonLinear, A). * 4. If X does not have a pointer, EnterNotify(NonLinearVirtual, B) to X. This seems wrong -- X shouldn't receive any event (This is window C in the non-linear case described in the protocol spec). * 5. Find closest pointer window Q between X and B. * a. if Q exists, EnterNotify(NonLinearVirtual) between X and Q I think this is incorrect; (X..Q] continue to see the pointer in Q and should receive no events. If B and inferior(B) do not contain a pointer, then (Q..B] see the pointer move from Q to B and should receive EnterNotify(Virtual) events, parent(B) should receive EnterNotify(Virtual,B) and B should receive EnterNotify(Ancestor). If B or inferior(b) do contain a pointer, then (Q..B] see the pointer move from inferior(B) to B. (Q..B) receive no events, while B receives an EnterNotify(Inferior). If inferior(B) is a child of B, then B receives EnterNotify(Inferior,inferior(B)) instead. * b. otherwise, EnterNotify(NonLinearVirtual) between X and B This is correct if B and inferior(B) do not contain a pointer. Note that parent(B) gets the child field set to B. If B or inferior(B) do contain a pointer, then (X..B) get no events. * 5. a. if B has another pointer in it, finish. Yup. * b. otherwise, if B has a inferior with a pointer in it * LeaveNotify(Virtual) between inferior(B) and B. Again, I think this is a mistake; LeaveNotify(Virtual) means the pointer is moving past the window to an ancestor. In this case, the pointer isn't moving at all as these windows see the pointer in inferior(B). * EnterNotify(Inferior) to B. Yes. * c. otherwise, EnterNotify(NonLinear) to B. Incomplete -- if Q exists, then B receives EnterNotify(Ancestor) instead. (why did you do the non-linear case first? It's the hardest...) * -------------------------------------------------------------------------- * * Pointer moves from A to B, A is an ancestor of B (CoreEnterLeaveToDescendant): * 1. a. If A has another pointer, goto 2. yes. * b. Otherwise, LeaveNotify(Inferior) to A. yes. * 2. Find highest window X that has a pointer inferior that is not an inferior of B. I assume that X is a member of (A..B). * a. if X exists, EnterNotify(Virtual, B) between A and X, No. (A..X) already see X containing a pointer. No events should be delivered. * EnterNotify(Virtual, B) to X (if X has no pointer). X sees the pointer move from inferior(X) to B, so it should receive no event. * b. otherwise, EnterNotify(Virtual, B) between A and B. Yes, but with only parent(B) receiving EnterNotify(Virtual,B), the other windows receive EnterNotify(Virtual). * * 3. a. if B has another pointer, finish Yes. * b. otherwise, if B has an inferior with a pointer in it, * LeaveNotify(Virtual, inferior(B)) between inferior(B) and B. No, (B..inferior(B)) see no pointer window change and should receive no event. * EnterNotify(Inferior, child(B)) to B. No, B has a pointer and should receive EnterNotify(Ancestor) only. * c. otherwise, EnterNotify(Ancestor) to B. Yes. * * -------------------------------------------------------------------------- * * Pointer moves from A to B, A is a child of B (CoreEnterLeaveToAncestor): * 1. a. If A has another pointer, goto 2. Right. * b. Otherwise, if A has a inferior with a pointer in it. * LeaveNotify(Inferior, inferior(A)) to A. Right, except it gets LeaveNotify(Inferior) unless inferior(A) is a child of A. * EnterNotify(Virtual, inferior(A)) between A and inferior(A). * Skip to 3. No, (A..inferior(A)] see no pointer change and should receive no event. * 2. Find closest pointer window P between A and B. * If P does not exist, P is B. * LeaveNotify(Ancestor) to A. yes. * LeaveNotify(Virtual, A) between A and P. Yes, except only parent(A) receives LeaveNotify(Virtual, A), the rest get LeaveNotify(Virtual). [P..B] receive no event, which is right. * 3. a. If B has another pointer, finish. right. * b. otherwise, EnterNotify(Inferior) to B. Right. */ -- [email protected]
signature.asc
Description: This is a digitally signed message part
_______________________________________________ xorg mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/xorg
