From 30eebc7c2196d87c1e4d195b6336e148f0cc7f05 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Wed, 15 Feb 2012 17:02:57 +0200 Subject: [PATCH] compositor: implement drag'n'drop icons Signed-off-by: Ander Conselvan de Oliveira --- src/compositor.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ src/compositor.h | 4 +++ src/shell.c | 2 ++ 3 files changed, 74 insertions(+) diff --git a/src/compositor.c b/src/compositor.c index 13ee9275..cdf648ff 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -827,6 +827,9 @@ weston_compositor_top(struct weston_compositor *compositor) list = list->next; if (list->next == &input_device->sprite->link) list = list->next; + if (input_device->drag_surface && + list->next == &input_device->drag_surface->link) + list = list->next; return list; } @@ -966,6 +969,8 @@ weston_output_repaint(struct weston_output *output, int msecs) overlap, surface_overlap; int32_t width, height; + weston_compositor_update_drag_surfaces(ec); + width = output->current->width + output->border.left + output->border.right; height = output->current->height + @@ -1326,6 +1331,10 @@ idle_handler(void *data) return 1; } +static void +weston_input_update_drag_surface(struct wl_input_device *input_device, + int dx, int dy); + WL_EXPORT void notify_motion(struct wl_input_device *device, uint32_t time, int x, int y) { @@ -1370,6 +1379,9 @@ notify_motion(struct wl_input_device *device, uint32_t time, int x, int y) y = max_y; } + weston_input_update_drag_surface(device, + x - device->x, y - device->y); + device->x = x; device->y = y; @@ -1498,6 +1510,9 @@ notify_pointer_focus(struct wl_input_device *device, struct weston_compositor *compositor = wd->compositor; if (output) { + weston_input_update_drag_surface(device, x - device->x, + y - device->y); + device->x = x; device->y = y; compositor->focus = 1; @@ -1789,6 +1804,59 @@ weston_input_device_release(struct weston_input_device *device) wl_input_device_release(&device->input_device); } +static void +weston_input_update_drag_surface(struct wl_input_device *input_device, + int dx, int dy) +{ + int surface_changed = 0; + struct weston_input_device *device = (struct weston_input_device *) + input_device; + + if (!device->drag_surface && !input_device->drag_surface) + return; + + if (device->drag_surface && input_device->drag_surface && + (&device->drag_surface->surface.resource != + &input_device->drag_surface->resource)) + /* between calls to this funcion we got a new drag_surface */ + surface_changed = 1; + + if (!input_device->drag_surface || surface_changed) { + device->drag_surface->pickable = 1; + device->drag_surface = NULL; + if (!surface_changed) + return; + } + + if (!device->drag_surface || surface_changed) { + device->drag_surface = (struct weston_surface *) + input_device->drag_surface; + device->drag_surface->pickable = 0; + + weston_surface_set_position(device->drag_surface, + input_device->x, input_device->y); + } + + if (device->drag_surface->output == NULL && + device->drag_surface->buffer) { + wl_list_insert(weston_compositor_top(device->compositor), + &device->drag_surface->link); + } + + if (!dx && !dy) + return; + + weston_surface_set_position(device->drag_surface, + device->drag_surface->geometry.x + dx, + device->drag_surface->geometry.y + dy); +} + +WL_EXPORT void +weston_compositor_update_drag_surfaces(struct weston_compositor *compositor) +{ + weston_input_update_drag_surface(compositor->input_device, 0, 0); +} + static void bind_output(struct wl_client *client, void *data, uint32_t version, uint32_t id) diff --git a/src/compositor.h b/src/compositor.h index c47f24b5..e3d09552 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -83,6 +83,7 @@ struct weston_input_device { struct wl_input_device input_device; struct weston_compositor *compositor; struct weston_surface *sprite; + struct weston_surface *drag_surface; int32_t hotspot_x, hotspot_y; struct wl_list link; uint32_t modifier_state; @@ -368,6 +369,9 @@ void weston_compositor_wake(struct weston_compositor *compositor); void weston_compositor_activity(struct weston_compositor *compositor); +void +weston_compositor_update_drag_surfaces(struct weston_compositor *compositor); + struct weston_binding; typedef void (*weston_binding_handler_t)(struct wl_input_device *device, diff --git a/src/shell.c b/src/shell.c index e8c739bd..b84e1048 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1366,6 +1366,8 @@ map(struct weston_shell *base, struct weston_surface *surface, surface->geometry.height = height; surface->geometry.dirty = 1; + weston_compositor_update_drag_surfaces(compositor); + /* initial positioning, see also configure() */ switch (surface_type) { case SHELL_SURFACE_TOPLEVEL: