diff options
Diffstat (limited to 'src/shell.c')
-rw-r--r-- | src/shell.c | 128 |
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 { |