[PATCH 6/7] compositor: implement drag'n'drop icons

Ander Conselvan de Oliveira ander.conselvan.de.oliveira at intel.com
Wed Feb 15 07:02:57 PST 2012


Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira at intel.com>
---
 src/compositor.c |   68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/compositor.h |    4 +++
 src/shell.c      |    2 +
 3 files changed, 74 insertions(+), 0 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index 13ee927..cdf648f 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 c47f24b..e3d0955 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 d9ba168..99b3ea6 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -1293,6 +1293,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:
-- 
1.7.4.1



More information about the wayland-devel mailing list