[PATCH v3] shell: support window resizing using touchscreen
Stanislav Vorobiov
s.vorobiov at samsung.com
Fri Apr 25 03:18:05 PDT 2014
Ping
On 04/23/2014 05:41 PM, Jason Ekstrand wrote:
>
>
>
> On Wed, Apr 23, 2014 at 1:02 AM, Stanislav Vorobiov <s.vorobiov at samsung.com <mailto:s.vorobiov at samsung.com>> wrote:
>
> if the system doesn't have a pointer device
> common_surface_resize will crash on
> accessing seat->pointer->button_count. if the system
> does have a pointer device, but attempts to resize
> a window using touchscreen - nothing happens. here
> we implement separate window resizing path for
> seat->touch as it is done in common_surface_move
> ---
> clients/window.c | 5 +-
> desktop-shell/shell.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++---
> shared/cairo-util.h | 2 +-
> shared/frame.c | 20 ++++---
> 4 files changed, 159 insertions(+), 21 deletions(-)
>
> diff --git a/clients/window.c b/clients/window.c
> index e770a04..185fe23 100644
> --- a/clients/window.c
> +++ b/clients/window.c
> @@ -2409,9 +2409,10 @@ frame_touch_down_handler(struct widget *widget, struct input *input,
> float x, float y, void *data)
> {
> struct window_frame *frame = data;
> + enum theme_location location;
>
> - frame_touch_down(frame->frame, input, id, x, y);
> - frame_handle_status(frame, input, time, THEME_LOCATION_CLIENT_AREA);
> + location = frame_touch_down(frame->frame, input, id, x, y);
> + frame_handle_status(frame, input, time, location);
> }
>
> static void
> diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
> index bc4a258..23125af 100644
> --- a/desktop-shell/shell.c
> +++ b/desktop-shell/shell.c
> @@ -1581,6 +1581,14 @@ struct weston_resize_grab {
> int32_t width, height;
> };
>
> +struct weston_touch_resize_grab {
> + struct shell_touch_grab base;
> + int active;
> + uint32_t edges;
> + int32_t width, height;
> + wl_fixed_t dx, dy;
> +};
> +
> static void
> resize_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
> wl_fixed_t x, wl_fixed_t y)
> @@ -1668,6 +1676,84 @@ static const struct weston_pointer_grab_interface resize_grab_interface = {
> resize_grab_cancel,
> };
>
> +static void
> +touch_resize_grab_down(struct weston_touch_grab *grab, uint32_t time,
> + int touch_id, wl_fixed_t sx, wl_fixed_t sy)
> +{
> +}
> +
> +static void
> +touch_resize_grab_up(struct weston_touch_grab *grab, uint32_t time, int touch_id)
> +{
> + struct weston_touch_resize_grab *resize =
> + (struct weston_touch_resize_grab *) container_of(
> + grab, struct shell_touch_grab, grab);
> +
> + if (touch_id == 0)
> + resize->active = 0;
> +
> + if (grab->touch->num_tp == 0) {
> + shell_touch_grab_end(&resize->base);
> + free(resize);
> + }
> +}
> +
> +static void
> +touch_resize_grab_motion(struct weston_touch_grab *grab, uint32_t time,
> + int touch_id, wl_fixed_t sx, wl_fixed_t sy)
> +{
> + struct weston_touch_resize_grab *resize = (struct weston_touch_resize_grab *) grab;
> + struct weston_touch *touch = grab->touch;
> + struct shell_surface *shsurf = resize->base.shsurf;
> + int32_t width, height;
> + wl_fixed_t from_x, from_y;
> + wl_fixed_t to_x, to_y;
> +
> + if (!shsurf || !resize->active)
> + return;
> +
> + weston_view_from_global_fixed(shsurf->view,
> + resize->dx, resize->dy,
> + &from_x, &from_y);
> + weston_view_from_global_fixed(shsurf->view,
> + touch->grab_x, touch->grab_y, &to_x, &to_y);
> +
> + width = resize->width;
> + if (resize->edges & WL_SHELL_SURFACE_RESIZE_LEFT) {
> + width += wl_fixed_to_int(from_x - to_x);
> + } else if (resize->edges & WL_SHELL_SURFACE_RESIZE_RIGHT) {
> + width += wl_fixed_to_int(to_x - from_x);
> + }
> +
> + height = resize->height;
> + if (resize->edges & WL_SHELL_SURFACE_RESIZE_TOP) {
> + height += wl_fixed_to_int(from_y - to_y);
> + } else if (resize->edges & WL_SHELL_SURFACE_RESIZE_BOTTOM) {
> + height += wl_fixed_to_int(to_y - from_y);
> + }
> +
> + shsurf->client->send_configure(shsurf->surface,
> + resize->edges, width, height);
> +}
> +
> +static void
> +touch_resize_grab_cancel(struct weston_touch_grab *grab)
> +{
> + struct weston_touch_resize_grab *resize =
> + (struct weston_touch_resize_grab *) container_of(
> + grab, struct shell_touch_grab, grab);
> +
> + shell_touch_grab_end(&resize->base);
> + free(resize);
> +}
> +
> +static const struct weston_touch_grab_interface touch_resize_grab_interface = {
> + touch_resize_grab_down,
> + touch_resize_grab_up,
> + touch_resize_grab_motion,
> + touch_resize_grab_cancel,
> +};
> +
> /*
> * Returns the bounding box of a surface and all its sub-surfaces,
> * in the surface coordinates system. */
> @@ -1731,6 +1817,37 @@ surface_resize(struct shell_surface *shsurf,
> return 0;
> }
>
> +static int
> +surface_touch_resize(struct shell_surface *shsurf,
> + struct weston_seat *seat, uint32_t edges)
> +{
> + struct weston_touch_resize_grab *resize;
> +
> + if (shsurf->state.fullscreen || shsurf->state.maximized)
> + return 0;
> +
> + if (edges == 0 || edges > 15 ||
> + (edges & 3) == 3 || (edges & 12) == 12)
> + return 0;
> +
> + resize = malloc(sizeof *resize);
> + if (!resize)
> + return -1;
> +
> + resize->active = 1;
> + resize->edges = edges;
> + surface_subsurfaces_boundingbox(shsurf->surface, NULL, NULL,
> + &resize->width, &resize->height);
> + resize->dx = seat->touch->grab_x;
> + resize->dy = seat->touch->grab_y;
> +
> + shsurf->resize_edges = edges;
> + shell_touch_grab_start(&resize->base, &touch_resize_grab_interface, shsurf,
> + seat->touch);
> +
> + return 0;
> +}
> +
> static void
> common_surface_resize(struct wl_resource *resource,
> struct wl_resource *seat_resource, uint32_t serial,
> @@ -1743,17 +1860,35 @@ common_surface_resize(struct wl_resource *resource,
> if (shsurf->state.fullscreen)
> return;
>
> - if (seat->pointer->button_count == 0 ||
> - seat->pointer->grab_serial != serial ||
> - seat->pointer->focus == NULL)
> - return;
> + if (seat->pointer) {
> + if (seat->pointer->button_count == 0 ||
> + seat->pointer->grab_serial != serial ||
> + seat->pointer->focus == NULL)
> + goto out;
> +
> + surface = weston_surface_get_main_surface(seat->pointer->focus->surface);
> + if (surface != shsurf->surface)
> + goto out;
> +
> + if (surface_resize(shsurf, seat, edges) < 0)
> + wl_resource_post_no_memory(resource);
>
> - surface = weston_surface_get_main_surface(seat->pointer->focus->surface);
> - if (surface != shsurf->surface)
> return;
> + }
> +
> +out:
> + if (seat->touch) {
> + if (seat->touch->grab_serial != serial ||
> + seat->touch->focus == NULL)
> + return;
>
> - if (surface_resize(shsurf, seat, edges) < 0)
> - wl_resource_post_no_memory(resource);
> + surface = weston_surface_get_main_surface(seat->touch->focus->surface);
> + if (surface != shsurf->surface)
> + return;
> +
> + if (surface_touch_resize(shsurf, seat, edges) < 0)
> + wl_resource_post_no_memory(resource);
> + }
> }
>
> static void
> @@ -1877,7 +2012,7 @@ xdg_ping_timeout_handler(void *data)
> continue;
> if (seat->pointer->focus->surface->resource == NULL)
> continue;
> -
> +
> shsurf = get_shell_surface(seat->pointer->focus->surface);
> if (shsurf &&
> wl_resource_get_client(shsurf->resource) == sc->client)
> diff --git a/shared/cairo-util.h b/shared/cairo-util.h
> index 4493b0d..9643023 100644
> --- a/shared/cairo-util.h
> +++ b/shared/cairo-util.h
> @@ -204,7 +204,7 @@ enum theme_location
> frame_pointer_button(struct frame *frame, void *pointer,
> uint32_t button, enum frame_button_state state);
>
> -void
> +enum theme_location
> frame_touch_down(struct frame *frame, void *data, int32_t id, int x, int y);
>
> void
> diff --git a/shared/frame.c b/shared/frame.c
> index 35e6b65..833117c 100644
> --- a/shared/frame.c
> +++ b/shared/frame.c
> @@ -782,27 +782,27 @@ frame_pointer_button(struct frame *frame, void *data,
> return location;
> }
>
> -void
> +enum theme_location
> frame_touch_down(struct frame *frame, void *data, int32_t id, int x, int y)
> {
> struct frame_touch *touch = frame_touch_get(frame, data);
> struct frame_button *button = frame_find_button(frame, x, y);
> - enum theme_location location;
> + enum theme_location location = THEME_LOCATION_EXTERIOR;
>
> if (id > 0)
> - return;
> -
> - if (touch && button) {
> - touch->button = button;
> - frame_button_press(touch->button);
> - return;
> - }
> + return location;
>
> location = theme_get_location(frame->theme, x, y,
> frame->width, frame->height,
> frame->flags & FRAME_FLAG_MAXIMIZED ?
> THEME_FRAME_MAXIMIZED : 0);
>
> + if (touch && button) {
> + touch->button = button;
> + frame_button_press(touch->button);
> + return location;
> + }
>
>
> Yeah, this is much better. frame.c bits look good to me!
> --Jason Ekstrand
>
>
> +
> switch (location) {
> case THEME_LOCATION_TITLEBAR:
> frame->status |= FRAME_STATUS_MOVE;
> @@ -820,6 +820,8 @@ frame_touch_down(struct frame *frame, void *data, int32_t id, int x, int y)
> default:
> break;
> }
> +
> + return location;
> }
>
> void
> --
> 1.7.9.5
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org <mailto:wayland-devel at lists.freedesktop.org>
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
>
>
More information about the wayland-devel
mailing list