[PATCH v4] shell: support window resizing using touchscreen
Stanislav Vorobiov
s.vorobiov at samsung.com
Mon May 5 05:56:20 PDT 2014
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 f12ce39..be2c0e0 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 a631c62..2aab283 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -395,6 +395,7 @@ shell_touch_grab_end(struct shell_touch_grab *grab)
if (grab->shsurf) {
wl_list_remove(&grab->shsurf_destroy_listener.link);
grab->shsurf->grabbed = 0;
+ grab->shsurf->resize_edges = 0;
}
weston_touch_end_grab(grab->touch);
@@ -1615,6 +1616,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)
@@ -1702,6 +1711,83 @@ 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, 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. */
@@ -1766,6 +1852,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,
@@ -1775,17 +1892,35 @@ common_surface_resize(struct wl_resource *resource,
struct shell_surface *shsurf = wl_resource_get_user_data(resource);
struct weston_surface *surface;
- 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
@@ -1909,7 +2044,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;
+ }
+
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
More information about the wayland-devel
mailing list