[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