[PATCH 5/5] resizor: Lock pointer on click

Pekka Paalanen ppaalanen at gmail.com
Tue Feb 26 04:16:37 PST 2013


On Mon, 25 Feb 2013 21:33:25 -0500
Kristian Høgsberg <krh at bitplanet.net> wrote:

> We add a resize mode to resizor where you can click to resize it using
> pointer lock and relative motion.
> ---
>  clients/resizor.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 74 insertions(+)
> 
> diff --git a/clients/resizor.c b/clients/resizor.c
> index 27879a0..563a1ac 100644
> --- a/clients/resizor.c
> +++ b/clients/resizor.c
> @@ -47,6 +47,7 @@ struct resizor {
>  	struct spring width;
>  	struct spring height;
>  	struct wl_callback *frame_callback;
> +	struct wl_pointer *pointer_lock;
>  };
>  
>  static void
> @@ -213,14 +214,87 @@ show_menu(struct resizor *resizor, struct input *input, uint32_t time)
>  			 x - 10, y - 10, menu_func, entries, 4);
>  }
>  
> +
> +static void
> +pointer_handle_enter(void *data, struct wl_pointer *pointer,
> +		     uint32_t serial, struct wl_surface *surface,
> +		     wl_fixed_t sx_w, wl_fixed_t sy_w)
> +{
> +}
> +
> +static void
> +pointer_handle_leave(void *data, struct wl_pointer *pointer,
> +		     uint32_t serial, struct wl_surface *surface)
> +{
> +}
> +
> +static void
> +pointer_handle_motion(void *data, struct wl_pointer *pointer,
> +		      uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w)
> +{
> +	struct resizor *resizor = data;
> +
> +	resizor->width.current += wl_fixed_to_double(sx_w);
> +	resizor->width.previous = resizor->width.current;
> +	resizor->width.target = resizor->width.current;
> +
> +	resizor->height.current += wl_fixed_to_double(sy_w);
> +	resizor->height.previous = resizor->height.current;
> +	resizor->height.target = resizor->height.current;
> +
> +	widget_schedule_resize(resizor->widget,
> +			       resizor->width.current,
> +			       resizor->height.current);
> +}
> +
> +static void
> +pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
> +		      uint32_t time, uint32_t button, uint32_t state)
> +{
> +	struct resizor *resizor = data;
> +
> +	if (state != WL_POINTER_BUTTON_STATE_PRESSED)
> +		return;
> +
> +	wl_pointer_release(resizor->pointer_lock);
> +	resizor->pointer_lock = NULL;
> +}
> +
> +static void
> +pointer_handle_axis(void *data, struct wl_pointer *pointer,
> +		    uint32_t time, uint32_t axis, wl_fixed_t value)
> +{
> +}
> +
> +static const struct wl_pointer_listener pointer_listener = {
> +	pointer_handle_enter,
> +	pointer_handle_leave,
> +	pointer_handle_motion,
> +	pointer_handle_button,
> +	pointer_handle_axis,
> +};
> +
>  static void
>  button_handler(struct widget *widget,
>  	       struct input *input, uint32_t time,
>  	       uint32_t button, enum wl_pointer_button_state state, void *data)
>  {
>  	struct resizor *resizor = data;
> +	struct wl_seat *seat;
> +	struct wl_surface *surface;
>  
>  	switch (button) {
> +	case BTN_LEFT:
> +		if (state != WL_POINTER_BUTTON_STATE_PRESSED)
> +			break;
> +
> +		seat = input_get_seat(input);
> +		surface = window_get_wl_surface(resizor->window);
> +		resizor->pointer_lock = wl_seat_lock_pointer(seat, surface);
> +		wl_pointer_add_listener(resizor->pointer_lock,
> +					&pointer_listener, resizor);
> +		break;
> +
>  	case BTN_RIGHT:
>  		if (state == WL_POINTER_BUTTON_STATE_PRESSED)
>  			show_menu(resizor, input, time);

Hi Kristian,

on the first try without any tricks, the pointer lock seems to work
nicely. However, after I click again to release the lock, I cannot
afterwards interact with the decorations. Any left-click will always
just activate the pointer lock again. Also highlighting the window
buttons doesn't work. The same happens with both x11 and drm backends.
If I right-click to bring out the titlebar context menu and dismiss it,
the situation is fixed.

Anyway, the demo proves that the protocol runs.

Another thing, from the protocol dump:

[1989156.722] wl_pointer at 21.motion(375651311, 183.000000, 188.000000)
[1989771.085] wl_shell_surface at 15.ping(405)
[1989771.132]  -> wl_shell_surface at 15.pong(405)
[1989771.155] wl_pointer at 21.button(406, 375651925, 272, 1)
[1989771.202]  -> wl_seat at 7.lock_pointer(new id wl_pointer at 16, wl_surface at 14)
[1989771.530] wl_pointer at 21.leave(407, wl_surface at 14)
[1989771.582] wl_pointer at 16.enter(408, wl_surface at 14, 183.000000, 188.000000)
[1989826.518] wl_pointer at 16.motion(375651981, 0.000000, 1.000000)
<client renders a new size>
[1989914.548] wl_pointer at 16.button(412, 375652069, 272, 0)

I see normal wl_pointer button down, leave. Lock wl_pointer enter,
move, button up. Button down and up are both non-matching, since they
are from different wl_pointer object. Is this intended behaviour?
I'm not too clear on what grabs should eat which input events when.


Thanks,
pq


More information about the wayland-devel mailing list