[PATCH weston v4 14/20] clients/resizor: Use pointer locking for resizing window
Peter Hutterer
peter.hutterer at who-t.net
Thu Nov 19 20:18:37 PST 2015
On Tue, Nov 17, 2015 at 06:11:00PM +0800, Jonas Ådahl wrote:
> Resizes the window using pointer locking when holding the left pointer
> button down. The pointer lock cursor position hint is used to warp the
> pointer to the same position relative to the bottom right corner.
>
> Signed-off-by: Jonas Ådahl <jadahl at gmail.com>
> ---
don't know the resizor code well enough, but nothing jumping out at me as
obviously wrong here :)
Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
Cheers,
Peter
> clients/resizor.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 154 insertions(+), 5 deletions(-)
>
> diff --git a/clients/resizor.c b/clients/resizor.c
> index d205eb6..95e16ea 100644
> --- a/clients/resizor.c
> +++ b/clients/resizor.c
> @@ -23,6 +23,7 @@
>
> #include "config.h"
>
> +#include <stdbool.h>
> #include <stdint.h>
> #include <stdio.h>
> #include <stdlib.h>
> @@ -50,6 +51,10 @@ struct resizor {
> struct spring width;
> struct spring height;
> struct wl_callback *frame_callback;
> + bool pointer_locked;
> + struct input *locked_input;
> + float pointer_x;
> + float pointer_y;
> };
>
> static void
> @@ -220,20 +225,158 @@ show_menu(struct resizor *resizor, struct input *input, uint32_t time)
> }
>
> static void
> +locked_pointer_handle_motion(struct window *window,
> + struct input *input,
> + uint32_t time,
> + float dx,
> + float dy,
> + void *data)
> +{
> + struct resizor *resizor = data;
> +
> + resizor->width.current += dx;
> + resizor->width.previous = resizor->width.current;
> + resizor->width.target = resizor->width.current;
> +
> + resizor->height.current += dy;
> + 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
> +handle_pointer_locked(struct window *window, struct input *input, void *data)
> +{
> + struct resizor *resizor = data;
> +
> + resizor->pointer_locked = true;
> + input_set_pointer_image(input, CURSOR_BLANK);
> +}
> +
> +static void
> +handle_pointer_unlocked(struct window *window, struct input *input, void *data)
> +{
> + struct resizor *resizor = data;
> +
> + resizor->pointer_locked = false;
> + input_set_pointer_image(input, CURSOR_LEFT_PTR);
> +}
> +
> +static const struct wl_callback_listener locked_pointer_frame_listener;
> +
> +static void
> +locked_pointer_frame_callback(void *data,
> + struct wl_callback *callback,
> + uint32_t time)
> +{
> + struct resizor *resizor = data;
> + struct wl_surface *surface;
> + struct rectangle allocation;
> + float x, y;
> +
> + if (resizor->pointer_locked) {
> + widget_get_allocation(resizor->widget, &allocation);
> +
> + x = resizor->pointer_x + (allocation.width - allocation.x);
> + y = resizor->pointer_y + (allocation.height - allocation.y);
> +
> + widget_set_locked_pointer_cursor_hint(resizor->widget, x, y);
> + }
> +
> + wl_callback_destroy(callback);
> +
> + surface = window_get_wl_surface(resizor->window);
> + callback = wl_surface_frame(surface);
> + wl_callback_add_listener(callback,
> + &locked_pointer_frame_listener,
> + resizor);
> +}
> +
> +static const struct wl_callback_listener locked_pointer_frame_listener = {
> + locked_pointer_frame_callback
> +};
> +
> +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 rectangle allocation;
> + struct wl_surface *surface;
> + struct wl_callback *callback;
>
> - switch (button) {
> - case BTN_RIGHT:
> - if (state == WL_POINTER_BUTTON_STATE_PRESSED)
> - show_menu(resizor, input, time);
> - break;
> + if (button == BTN_RIGHT && state == WL_POINTER_BUTTON_STATE_PRESSED) {
> + show_menu(resizor, input, time);
> + } else if (button == BTN_LEFT &&
> + state == WL_POINTER_BUTTON_STATE_PRESSED) {
> + window_get_allocation(resizor->window, &allocation);
> +
> + resizor->width.current = allocation.width;
> + resizor->width.previous = allocation.width;
> + resizor->width.target = allocation.width;
> +
> + resizor->height.current = allocation.height;
> + resizor->height.previous = allocation.height;
> + resizor->height.target = allocation.height;
> +
> + window_lock_pointer(resizor->window, input);
> + window_set_pointer_locked_handler(resizor->window,
> + handle_pointer_locked);
> + window_set_pointer_unlocked_handler(resizor->window,
> + handle_pointer_unlocked);
> + resizor->locked_input = input;
> +
> + surface = window_get_wl_surface(resizor->window);
> + callback = wl_surface_frame(surface);
> + wl_callback_add_listener(callback,
> + &locked_pointer_frame_listener,
> + resizor);
> + } else if (button == BTN_LEFT &&
> + state == WL_POINTER_BUTTON_STATE_RELEASED) {
> + input_set_pointer_image(input, CURSOR_LEFT_PTR);
> + window_unlock_pointer(resizor->window);
> }
> }
>
> +static void
> +set_cursor_inv_offset(struct resizor *resizor, float x, float y)
> +{
> + struct rectangle allocation;
> +
> + widget_get_allocation(resizor->widget, &allocation);
> +
> + resizor->pointer_x = x - (allocation.width - allocation.x);
> + resizor->pointer_y = y - (allocation.height - allocation.y);
> +}
> +
> +static int
> +enter_handler(struct widget *widget,
> + struct input *input,
> + float x, float y, void *data)
> +{
> + struct resizor *resizor = data;
> +
> + set_cursor_inv_offset(resizor, x , y);
> +
> + return CURSOR_LEFT_PTR;
> +}
> +
> +static int
> +motion_handler(struct widget *widget,
> + struct input *input, uint32_t time,
> + float x, float y, void *data)
> +{
> + struct resizor *resizor = data;
> +
> + set_cursor_inv_offset(resizor, x , y);
> +
> + return CURSOR_LEFT_PTR;
> +}
> +
> static struct resizor *
> resizor_create(struct display *display)
> {
> @@ -251,6 +394,12 @@ resizor_create(struct display *display)
> window_set_keyboard_focus_handler(resizor->window,
> keyboard_focus_handler);
>
> + widget_set_enter_handler(resizor->widget, enter_handler);
> + widget_set_motion_handler(resizor->widget, motion_handler);
> +
> + window_set_locked_pointer_motion_handler(
> + resizor->window, locked_pointer_handle_motion);
> +
> widget_set_button_handler(resizor->widget, button_handler);
>
> resizor->height.previous = 400;
> --
> 2.4.3
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
>
More information about the wayland-devel
mailing list