<div dir="ltr">I don't have time to review the desktop-shell bits right now, but I do have a few comments on the frame.c bits.<br><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Apr 22, 2014 at 9:32 AM, Stanislav Vorobiov <span dir="ltr"><<a href="mailto:s.vorobiov@samsung.com" target="_blank">s.vorobiov@samsung.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">if the system doesn't have a pointer device<br>
common_surface_resize will crash on<br>
accessing seat->pointer->button_count. if the system<br>
does have a pointer device, but attempts to resize<br>
a window using touchscreen - nothing happens. here<br>
we implement separate window resizing path for<br>
seat->touch as it is done in common_surface_move<br>
---<br>
clients/window.c | 5 +-<br>
desktop-shell/shell.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++---<br>
shared/cairo-util.h | 2 +-<br>
shared/frame.c | 10 ++--<br>
4 files changed, 148 insertions(+), 16 deletions(-)<br>
<br>
diff --git a/clients/window.c b/clients/window.c<br>
index e770a04..185fe23 100644<br>
--- a/clients/window.c<br>
+++ b/clients/window.c<br>
@@ -2409,9 +2409,10 @@ frame_touch_down_handler(struct widget *widget, struct input *input,<br>
float x, float y, void *data)<br>
{<br>
struct window_frame *frame = data;<br>
+ enum theme_location location;<br>
<br>
- frame_touch_down(frame->frame, input, id, x, y);<br>
- frame_handle_status(frame, input, time, THEME_LOCATION_CLIENT_AREA);<br>
+ location = frame_touch_down(frame->frame, input, id, x, y);<br>
+ frame_handle_status(frame, input, time, location);<br>
}<br></blockquote><div><br></div><div>Yeah, this seems correct.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
static void<br>
diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c<br>
index bc4a258..8db5434 100644<br>
--- a/desktop-shell/shell.c<br>
+++ b/desktop-shell/shell.c<br>
@@ -1581,6 +1581,14 @@ struct weston_resize_grab {<br>
int32_t width, height;<br>
};<br>
<br>
+struct weston_touch_resize_grab {<br>
+ struct shell_touch_grab base;<br>
+ int active;<br>
+ uint32_t edges;<br>
+ int32_t width, height;<br>
+ wl_fixed_t dx, dy;<br>
+};<br>
+<br>
static void<br>
resize_grab_motion(struct weston_pointer_grab *grab, uint32_t time,<br>
wl_fixed_t x, wl_fixed_t y)<br>
@@ -1668,6 +1676,84 @@ static const struct weston_pointer_grab_interface resize_grab_interface = {<br>
resize_grab_cancel,<br>
};<br>
<br>
+static void<br>
+touch_resize_grab_down(struct weston_touch_grab *grab, uint32_t time,<br>
+ int touch_id, wl_fixed_t sx, wl_fixed_t sy)<br>
+{<br>
+}<br>
+<br>
+static void<br>
+touch_resize_grab_up(struct weston_touch_grab *grab, uint32_t time, int touch_id)<br>
+{<br>
+ struct weston_touch_resize_grab *resize =<br>
+ (struct weston_touch_resize_grab *) container_of(<br>
+ grab, struct shell_touch_grab, grab);<br>
+<br>
+ if (touch_id == 0)<br>
+ resize->active = 0;<br>
+<br>
+ if (grab->touch->num_tp == 0) {<br>
+ shell_touch_grab_end(&resize->base);<br>
+ free(resize);<br>
+ }<br>
+}<br>
+<br>
+static void<br>
+touch_resize_grab_motion(struct weston_touch_grab *grab, uint32_t time,<br>
+ int touch_id, wl_fixed_t sx, wl_fixed_t sy)<br>
+{<br>
+ struct weston_touch_resize_grab *resize = (struct weston_touch_resize_grab *) grab;<br>
+ struct weston_touch *touch = grab->touch;<br>
+ struct shell_surface *shsurf = resize->base.shsurf;<br>
+ int32_t width, height;<br>
+ wl_fixed_t from_x, from_y;<br>
+ wl_fixed_t to_x, to_y;<br>
+<br>
+ if (!shsurf || !resize->active)<br>
+ return;<br>
+<br>
+ weston_view_from_global_fixed(shsurf->view,<br>
+ resize->dx, resize->dy,<br>
+ &from_x, &from_y);<br>
+ weston_view_from_global_fixed(shsurf->view,<br>
+ touch->grab_x, touch->grab_y, &to_x, &to_y);<br>
+<br>
+ width = resize->width;<br>
+ if (resize->edges & WL_SHELL_SURFACE_RESIZE_LEFT) {<br>
+ width += wl_fixed_to_int(from_x - to_x);<br>
+ } else if (resize->edges & WL_SHELL_SURFACE_RESIZE_RIGHT) {<br>
+ width += wl_fixed_to_int(to_x - from_x);<br>
+ }<br>
+<br>
+ height = resize->height;<br>
+ if (resize->edges & WL_SHELL_SURFACE_RESIZE_TOP) {<br>
+ height += wl_fixed_to_int(from_y - to_y);<br>
+ } else if (resize->edges & WL_SHELL_SURFACE_RESIZE_BOTTOM) {<br>
+ height += wl_fixed_to_int(to_y - from_y);<br>
+ }<br>
+<br>
+ shsurf->client->send_configure(shsurf->surface,<br>
+ resize->edges, width, height);<br>
+}<br>
+<br>
+static void<br>
+touch_resize_grab_cancel(struct weston_touch_grab *grab)<br>
+{<br>
+ struct weston_touch_resize_grab *resize =<br>
+ (struct weston_touch_resize_grab *) container_of(<br>
+ grab, struct shell_touch_grab, grab);<br>
+<br>
+ shell_touch_grab_end(&resize->base);<br>
+ free(resize);<br>
+}<br>
+<br>
+static const struct weston_touch_grab_interface touch_resize_grab_interface = {<br>
+ touch_resize_grab_down,<br>
+ touch_resize_grab_up,<br>
+ touch_resize_grab_motion,<br>
+ touch_resize_grab_cancel,<br>
+};<br>
+<br>
/*<br>
* Returns the bounding box of a surface and all its sub-surfaces,<br>
* in the surface coordinates system. */<br>
@@ -1731,6 +1817,36 @@ surface_resize(struct shell_surface *shsurf,<br>
return 0;<br>
}<br>
<br>
+static int<br>
+surface_touch_resize(struct shell_surface *shsurf,<br>
+ struct weston_seat *seat, uint32_t edges)<br>
+{<br>
+ struct weston_touch_resize_grab *resize;<br>
+<br>
+ if (shsurf->state.fullscreen || shsurf->state.maximized)<br>
+ return 0;<br>
+<br>
+ if (edges == 0 || edges > 15 ||<br>
+ (edges & 3) == 3 || (edges & 12) == 12)<br>
+ return 0;<br>
+<br>
+ resize = malloc(sizeof *resize);<br>
+ if (!resize)<br>
+ return -1;<br>
+<br>
+ resize->active = 1;<br>
+ resize->edges = edges;<br>
+ surface_subsurfaces_boundingbox(shsurf->surface, NULL, NULL,<br>
+ &resize->width, &resize->height);<br>
+ resize->dx = seat->touch->grab_x;<br>
+ resize->dy = seat->touch->grab_y;<br>
+<br>
+ shell_touch_grab_start(&resize->base, &touch_resize_grab_interface, shsurf,<br>
+ seat->touch);<br>
+<br>
+ return 0;<br>
+}<br>
+<br>
static void<br>
common_surface_resize(struct wl_resource *resource,<br>
struct wl_resource *seat_resource, uint32_t serial,<br>
@@ -1743,17 +1859,30 @@ common_surface_resize(struct wl_resource *resource,<br>
if (shsurf->state.fullscreen)<br>
return;<br>
<br>
- if (seat->pointer->button_count == 0 ||<br>
- seat->pointer->grab_serial != serial ||<br>
- seat->pointer->focus == NULL)<br>
- return;<br>
+ if (seat->pointer) {<br>
+ if (seat->pointer->button_count == 0 ||<br>
+ seat->pointer->grab_serial != serial ||<br>
+ seat->pointer->focus == NULL)<br>
+ return;<br>
<br>
- surface = weston_surface_get_main_surface(seat->pointer->focus->surface);<br>
- if (surface != shsurf->surface)<br>
- return;<br>
+ surface = weston_surface_get_main_surface(seat->pointer->focus->surface);<br>
+ if (surface != shsurf->surface)<br>
+ return;<br>
+<br>
+ if (surface_resize(shsurf, seat, edges) < 0)<br>
+ wl_resource_post_no_memory(resource);<br>
+ } else if (seat->touch) {<br>
+ if (seat->touch->grab_serial != serial ||<br>
+ seat->touch->focus == NULL)<br>
+ return;<br>
+<br>
+ surface = weston_surface_get_main_surface(seat->touch->focus->surface);<br>
+ if (surface != shsurf->surface)<br>
+ return;<br>
<br>
- if (surface_resize(shsurf, seat, edges) < 0)<br>
- wl_resource_post_no_memory(resource);<br>
+ if (surface_touch_resize(shsurf, seat, edges) < 0)<br>
+ wl_resource_post_no_memory(resource);<br>
+ }<br>
}<br>
<br>
static void<br>
diff --git a/shared/cairo-util.h b/shared/cairo-util.h<br>
index 4493b0d..9643023 100644<br>
--- a/shared/cairo-util.h<br>
+++ b/shared/cairo-util.h<br>
@@ -204,7 +204,7 @@ enum theme_location<br>
frame_pointer_button(struct frame *frame, void *pointer,<br>
uint32_t button, enum frame_button_state state);<br>
<br>
-void<br>
+enum theme_location<br>
frame_touch_down(struct frame *frame, void *data, int32_t id, int x, int y);<br>
<br>
void<br>
diff --git a/shared/frame.c b/shared/frame.c<br>
index 35e6b65..74cfdec 100644<br>
--- a/shared/frame.c<br>
+++ b/shared/frame.c<br>
@@ -782,20 +782,20 @@ frame_pointer_button(struct frame *frame, void *data,<br>
return location;<br>
}<br>
<br>
-void<br>
+enum theme_location<br>
frame_touch_down(struct frame *frame, void *data, int32_t id, int x, int y)<br>
{<br>
struct frame_touch *touch = frame_touch_get(frame, data);<br>
struct frame_button *button = frame_find_button(frame, x, y);<br>
- enum theme_location location;<br>
+ enum theme_location location = THEME_LOCATION_EXTERIOR;<br>
<br>
if (id > 0)<br>
- return;<br>
+ return location;<br></blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
if (touch && button) {<br>
touch->button = button;<br>
frame_button_press(touch->button);<br>
- return;<br>
+ return location;<br>
}<br></blockquote><div><br></div><div>If we're touching a button, we should return THEME_LOCATION_TITLEBAR because that's where the touch event occurs. We should only return a default THEME_LOCATION_EXTERIOR if, for some reason, we cannot call theme_get_location.<br>
<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
location = theme_get_location(frame->theme, x, y,<br>
@@ -820,6 +820,8 @@ frame_touch_down(struct frame *frame, void *data, int32_t id, int x, int y)<br>
default:<br>
break;<br>
}<br>
+<br>
+ return location;<br>
}<br>
<br>
void<br>
</blockquote><div><br></div><div>Other than that, the frame bits look reasonable.<br></div><div>--Jason Ekstrand <br></div></div><br></div></div>