[PATCH wayland] Add a relative_grab request to the wl_shell_surface interface

Pekka Paalanen ppaalanen at gmail.com
Mon Aug 27 23:52:11 PDT 2012

On Mon, 27 Aug 2012 13:45:17 -0700
Daniel Stone <daniel at fooishbar.org> wrote:

> Hi,
> On 27 August 2012 11:55, Philipp Brüschweiler <blei42 at gmail.com> wrote:
> > This request can be used to grab the pointer of a specified seat. A
> > pointer grabbed in this way will be made invisible and won't send any
> > more motion events. Instead it reports relative motion using the motion
> > event on the returned object.
> >
> > A grab can be broken by the application by destroying the wl_relative_grab
> > object, or by the compositor, in which case the compositor sends a
> > destroy_me event to the application.
> >
> > Recommended behaviour for compositors is to break grabs when the keyboard
> > focus changes to a different window, e.g. by alt-tabbing out of the
> > grabbing application.

This is some good piece of doc, and I think most of it should end up in
the xml file as documentation.

> This mostly looks good to me, but I think it'd be better structured
> along the lines of wl_pointer.  So, perhaps call it wl_pointer_raw,
> have it send enter and leave events, and perhaps duplicate the button
> and motion events too.  You could basically copy the wl_pointer
> interface, really ...
> The other other alternative, now I think of it, is to add a
> wl_pointer_raw capability to wl_seat, with a wl_seat_get_pointer_raw,
> which just returns another wl_pointer interface, except that it
> returns relative co-ordinates instead.  Either way, following the
> enter and leave pattern (with surfaces) would be great.

Hi Philipp and Daniel,

following Daniel's suggestions, how would the enter/leave really work?
What would trigger them?

I think the idea behind Philipp's proposal was to let the application
decide when it wants relative events, and switch between normal and
relative at will. Could it be implemented like this?

- whenever client wants to start receiving relative events instead of
  normal events for a pointer, it calls wl_seat_get_pointer_raw, and so
  creates a wl_pointer_raw object.

- wl_pointer_raw object now produces all the pointer events, and a
  possibly existing wl_pointer produces nothing. Or do we want the
  client to destroy the wl_pointer, if it doesn't want it? I can't see
  how they could work at the same time on the compositor side.

- whenever client wants to stop receiving relative events, it destroys
  the wl_pointer_raw object.

- when the compositor breaks the grab for the relative motion, the
  clients get a wl_pointer_raw::leave event.

But when should the compositor set the relative motion grab? As a
response to pointer focus, i.e. mouse-over? Or keyboard focus? Keyboard
is actually a good question, when should keyboard focus be given to the
client, if it has wl_pointer_raw?

Do we want to enforce that in the server, or do we give the freedom to
clients in that they should properly enable and disable wl_pointer_raw
as a response to wl_pointer::enter and wl_pointer_raw::leave?

Now to think of it, maybe the following could be a well-behaving client:

- begin with normal input mode, i.e. wl_pointer yes, and
  no wl_pointer_raw.

- client works as a normal desktop app, i.e. you can click menus,
  surfaces etc.

- when the client receives a button-click inside a game-view, it creates
  a wl_pointer_raw, gets the relative motion grab implicitly in the
  server, and starts receiving relative events. The pointer focus is
  locked to the game-surface for the duration of the grab.

- if the server decides to switch input focus, for instance as a
  response to alt+tab, the client gets a wl_pointer_raw::leave. If the
  client does not destroy its wl_pointer_raw, the relative motion grab
  will be reinstated on the next mouse over (what happens with kbd
  focus?) That's not too good, so the client destroys the
  wl_pointer_raw object, and returns to the normal input mode. [Start
  from the top again.]

- if the client decides to go back to normal input mode, e.g. as a
  response to an ungrab key, it just destroys the wl_pointer_raw object.

How about interaction with wl_pointer::{enter,leave}?
Do we get a wl_pointer::leave, when wl_pointer_raw enters?
Do we get a wl_pointer::enter, when wl_pointer_raw leaves? Maybe yes,
so the client will set the cursor image.

One more thing is, if a client has two surfaces, one with normal input
and other with relative, we don't want to make the relative grab on
mouse-over on the normal surface. But the client itself can make that
work, if it properly destroys the wl_pointer_raw object.

Then there might be race conditions...

Ok, enough of my brain dump. Take this as food for thought, and don't
mind about it if it doesn't make sense. ;-)


More information about the wayland-devel mailing list