compositor: implement drag'n'drop icons
authorAnder Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
Wed, 15 Feb 2012 15:02:57 +0000 (17:02 +0200)
committerKristian Høgsberg <krh@bitplanet.net>
Fri, 17 Feb 2012 04:19:39 +0000 (23:19 -0500)
Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
src/compositor.c
src/compositor.h
src/shell.c

index 13ee927..cdf648f 100644 (file)
@@ -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)
index c47f24b..e3d0955 100644 (file)
@@ -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,
index e8c739b..b84e104 100644 (file)
@@ -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: