[PATCH 5/5] compositor: only update drag surfaces during output repaint

Ander Conselvan de Oliveira ander.conselvan.de.oliveira at intel.com
Tue Mar 13 08:23:59 PDT 2012


Drag surfaces were being updated in notify_* so that the relative
distance between the drag surface and the cursor hotspot was kept.
With surface attach listeners, we store this relative distance on
the input device and update when necessary.

Also, using a new drag icon listener, there's no need to update drag
surfaces on shell->map(), since they are setup as soon as necessary.
---
 src/compositor.c |   51 ++++++++++++++++++++++++++++++++-------------------
 src/compositor.h |   16 +++++++++-------
 src/shell.c      |    2 --
 3 files changed, 41 insertions(+), 28 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index 0fa7280..5c68b0f 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1443,10 +1443,6 @@ 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)
 {
@@ -1491,9 +1487,6 @@ 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;
 
@@ -1625,9 +1618,6 @@ 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;
@@ -1893,6 +1883,9 @@ bind_input_device(struct wl_client *client,
 	resource->destroy = unbind_input_device;
 }
 
+static  void
+weston_input_update_drag_surface(struct wl_input_device *input_device);
+
 static void
 device_handle_new_drag_icon(struct wl_listener *listener,
 			    struct wl_resource *resource, uint32_t time)
@@ -1902,7 +1895,7 @@ device_handle_new_drag_icon(struct wl_listener *listener,
 	device = container_of(listener, struct weston_input_device,
 			      new_drag_icon_listener);
 
-	weston_input_update_drag_surface(&device->input_device, 0, 0);
+	weston_input_update_drag_surface(&device->input_device);
 }
 
 WL_EXPORT void
@@ -1965,6 +1958,22 @@ weston_compositor_update_cursor_sprites(struct weston_compositor *compositor)
 }
 
 static void
+device_drag_surface_handle_attach(struct weston_surface_attach_listener *al,
+				  struct weston_surface *es,
+				  int32_t sx, int32_t sy)
+{
+	struct weston_input_device *device;
+
+	fprintf(stderr, "%s: %d %d\n", __func__, sx, sy);
+
+	device = container_of(al, struct weston_input_device,
+			      drag_surf_attach_listener);
+
+	device->drag_surf_x += sx;
+	device->drag_surf_y += sy;
+}
+
+static void
 device_setup_new_drag_surface(struct weston_input_device *device,
 			      struct weston_surface *surface)
 {
@@ -1974,9 +1983,16 @@ device_setup_new_drag_surface(struct weston_input_device *device,
 
 	weston_surface_set_position(device->drag_surface,
 				    input_device->x, input_device->y);
+	device->drag_surf_x = 0;
+	device->drag_surf_y = 0;
 
 	wl_list_insert(surface->surface.resource.destroy_listener_list.prev,
 		       &device->drag_surface_destroy_listener.link);
+
+	device->drag_surf_attach_listener.func =
+		device_drag_surface_handle_attach;
+	wl_list_insert(surface->attach_listener_list.prev,
+		       &device->drag_surf_attach_listener.link);
 }
 
 static void
@@ -1984,6 +2000,7 @@ device_release_drag_surface(struct weston_input_device *device)
 {
 	undef_region(&device->drag_surface->input);
 	wl_list_remove(&device->drag_surface_destroy_listener.link);
+	wl_list_remove(&device->drag_surf_attach_listener.link);
 	device->drag_surface = NULL;
 }
 
@@ -2001,8 +2018,7 @@ device_map_drag_surface(struct weston_input_device *device)
 }
 
 static  void
-weston_input_update_drag_surface(struct wl_input_device *input_device,
-				 int dx, int dy)
+weston_input_update_drag_surface(struct wl_input_device *input_device)
 {
 	int surface_changed = 0;
 	struct weston_input_device *device = (struct weston_input_device *)
@@ -2038,18 +2054,15 @@ weston_input_update_drag_surface(struct wl_input_device *input_device,
 	if (region_is_undefined(&device->drag_surface->input))
 		empty_region(&device->drag_surface->input);
 
-	if (!dx && !dy)
-		return;
-
 	weston_surface_set_position(device->drag_surface,
-				    device->drag_surface->geometry.x + dx,
-				    device->drag_surface->geometry.y + dy);
+				    device->input_device.x + device->drag_surf_x,
+				    device->input_device.y + device->drag_surf_y);
 }
 
 WL_EXPORT void
 weston_compositor_update_drag_surfaces(struct weston_compositor *compositor)
 {
-	weston_input_update_drag_surface(compositor->input_device, 0, 0);
+	weston_input_update_drag_surface(compositor->input_device);
 }
 
 static void
diff --git a/src/compositor.h b/src/compositor.h
index a1cd3bf..e1d15b0 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -103,13 +103,21 @@ struct weston_output {
 	void (*set_dpms)(struct weston_output *output, enum dpms_enum level);
 };
 
+struct weston_surface_attach_listener {
+	struct wl_list link;
+	void (*func)(struct weston_surface_attach_listener *listener,
+		     struct weston_surface *es, int sx, int sy);
+};
+
 struct weston_input_device {
 	struct wl_input_device input_device;
 	struct weston_compositor *compositor;
 	struct weston_surface *sprite;
+	int32_t hotspot_x, hotspot_y;
 	struct weston_surface *drag_surface;
 	struct wl_listener drag_surface_destroy_listener;
-	int32_t hotspot_x, hotspot_y;
+	struct weston_surface_attach_listener drag_surf_attach_listener;
+	int32_t drag_surf_x, drag_surf_y;
 	struct wl_list link;
 	uint32_t modifier_state;
 	int hw_cursor;
@@ -248,12 +256,6 @@ struct weston_region {
 	pixman_region32_t region;
 };
 
-struct weston_surface_attach_listener {
-	struct wl_list link;
-	void (*func)(struct weston_surface_attach_listener *listener,
-		     struct weston_surface *es, int sx, int sy);
-};
-
 /* Using weston_surface transformations
  *
  * To add a transformation to a surface, create a struct weston_transform, and
diff --git a/src/shell.c b/src/shell.c
index 765b0a4..878faa1 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -1505,8 +1505,6 @@ 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