[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