summaryrefslogtreecommitdiff
path: root/src/shell.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/shell.c')
-rw-r--r--src/shell.c128
1 files changed, 121 insertions, 7 deletions
diff --git a/src/shell.c b/src/shell.c
index bcde7895..c3dc3479 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -238,11 +238,23 @@ struct shell_grab {
struct wl_listener shsurf_destroy_listener;
};
+struct shell_touch_grab {
+ struct weston_touch_grab grab;
+ struct shell_surface *shsurf;
+ struct wl_listener shsurf_destroy_listener;
+ struct weston_touch *touch;
+};
+
struct weston_move_grab {
struct shell_grab base;
wl_fixed_t dx, dy;
};
+struct weston_touch_move_grab {
+ struct shell_touch_grab base;
+ wl_fixed_t dx, dy;
+};
+
struct rotate_grab {
struct shell_grab base;
struct weston_matrix rotation;
@@ -351,6 +363,36 @@ shell_grab_end(struct shell_grab *grab)
}
static void
+shell_touch_grab_start(struct shell_touch_grab *grab,
+ const struct weston_touch_grab_interface *interface,
+ struct shell_surface *shsurf,
+ struct weston_touch *touch)
+{
+ struct desktop_shell *shell = shsurf->shell;
+
+ grab->grab.interface = interface;
+ grab->shsurf = shsurf;
+ grab->shsurf_destroy_listener.notify = destroy_shell_grab_shsurf;
+ wl_signal_add(&shsurf->destroy_signal,
+ &grab->shsurf_destroy_listener);
+
+ grab->touch = touch;
+
+ weston_touch_start_grab(touch, &grab->grab);
+ if (shell->child.desktop_shell)
+ weston_touch_set_focus(touch->seat, shell->grab_surface);
+}
+
+static void
+shell_touch_grab_end(struct shell_touch_grab *grab)
+{
+ if (grab->shsurf)
+ wl_list_remove(&grab->shsurf_destroy_listener.link);
+
+ weston_touch_end_grab(grab->touch);
+}
+
+static void
center_on_output(struct weston_surface *surface,
struct weston_output *output);
@@ -1036,6 +1078,74 @@ bind_workspace_manager(struct wl_client *client,
}
static void
+touch_move_grab_down(struct weston_touch_grab *grab, uint32_t time,
+ int touch_id, wl_fixed_t sx, wl_fixed_t sy)
+{
+}
+
+static void
+touch_move_grab_up(struct weston_touch_grab *grab, uint32_t time, int touch_id)
+{
+ struct shell_touch_grab *shell_grab = container_of(grab,
+ struct shell_touch_grab,
+ grab);
+ shell_touch_grab_end(shell_grab);
+}
+
+static void
+touch_move_grab_motion(struct weston_touch_grab *grab, uint32_t time,
+ int touch_id, wl_fixed_t sx, wl_fixed_t sy)
+{
+ struct weston_touch_move_grab *move = (struct weston_touch_move_grab *) grab;
+ struct shell_surface *shsurf = move->base.shsurf;
+ struct weston_surface *es;
+ int dx = wl_fixed_to_int(grab->touch->grab_x + move->dx);
+ int dy = wl_fixed_to_int(grab->touch->grab_y + move->dy);
+
+ if (!shsurf)
+ return;
+
+ es = shsurf->surface;
+
+ weston_surface_configure(es, dx, dy,
+ es->geometry.width, es->geometry.height);
+
+ weston_compositor_schedule_repaint(es->compositor);
+}
+
+static const struct weston_touch_grab_interface touch_move_grab_interface = {
+ touch_move_grab_down,
+ touch_move_grab_up,
+ touch_move_grab_motion,
+};
+
+static int
+surface_touch_move(struct shell_surface *shsurf, struct weston_seat *seat)
+{
+ struct weston_touch_move_grab *move;
+
+ if (!shsurf)
+ return -1;
+
+ if (shsurf->type == SHELL_SURFACE_FULLSCREEN)
+ return 0;
+
+ move = malloc(sizeof *move);
+ if (!move)
+ return -1;
+
+ move->dx = wl_fixed_from_double(shsurf->surface->geometry.x) -
+ seat->touch->grab_x;
+ move->dy = wl_fixed_from_double(shsurf->surface->geometry.y) -
+ seat->touch->grab_y;
+
+ shell_touch_grab_start(&move->base, &touch_move_grab_interface, shsurf,
+ seat->touch);
+
+ return 0;
+}
+
+static void
noop_grab_focus(struct weston_pointer_grab *grab)
{
}
@@ -1118,13 +1228,17 @@ shell_surface_move(struct wl_client *client, struct wl_resource *resource,
struct weston_surface *surface;
surface = weston_surface_get_main_surface(seat->pointer->focus);
- if (seat->pointer->button_count == 0 ||
- seat->pointer->grab_serial != serial ||
- surface != shsurf->surface)
- return;
-
- if (surface_move(shsurf, seat) < 0)
- wl_resource_post_no_memory(resource);
+ if (seat->pointer->button_count > 0 && seat->pointer->grab_serial == serial) {
+ surface = weston_surface_get_main_surface(seat->pointer->focus);
+ if ((surface == shsurf->surface) &&
+ (surface_move(shsurf, seat) < 0))
+ wl_resource_post_no_memory(resource);
+ } else if (seat->touch->grab_serial == serial) {
+ surface = weston_surface_get_main_surface(seat->touch->focus);
+ if ((surface == shsurf->surface) &&
+ (surface_touch_move(shsurf, seat) < 0))
+ wl_resource_post_no_memory(resource);
+ }
}
struct weston_resize_grab {