[PATCH v2] compositor: send a pointer motion if the focus surface moves under the pointer

Giulio Camuffo giuliocamuffo at gmail.com
Thu Feb 28 08:19:56 PST 2013


This makes weston_device_repick() return an int, 1 if the pointer moved on the
same surface, 0 otherwise. notify_motion sends the motion event on its own,
while weston_compositor_repick() checks if it returns 1 and it sends the motion
event using the time given to it by weston_output_repaint() as timestamp.
---
 src/compositor.c | 55 ++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 38 insertions(+), 17 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index 9198b3b..f05b7b5 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -770,49 +770,70 @@ weston_compositor_pick_surface(struct weston_compositor *compositor,
 	return NULL;
 }
 
-static void
+/* This functions returns 1 if the pointer moved and a pointer motion
+ * event should be sent, 0 otherwise. */
+static int
 weston_device_repick(struct weston_seat *seat)
 {
 	const struct wl_pointer_grab_interface *interface;
 	struct weston_surface *surface, *focus;
 	struct wl_pointer *pointer = seat->seat.pointer;
+	int32_t curr_x, curr_y;
+	int32_t ret = 0;
 
 	if (!pointer)
-		return;
+		return 0;
 
 	surface = weston_compositor_pick_surface(seat->compositor,
 						 pointer->x,
 						 pointer->y,
-						 &pointer->current_x,
-						 &pointer->current_y);
+						 &curr_x,
+						 &curr_y);
 
 	if (&surface->surface != pointer->current) {
 		interface = pointer->grab->interface;
 		pointer->current = &surface->surface;
 		interface->focus(pointer->grab, &surface->surface,
-				 pointer->current_x,
-				 pointer->current_y);
+				 curr_x,
+				 curr_y);
+	} else if (pointer->current_x != curr_x ||
+			pointer->current_y != curr_y) {
+		/* The current surface moved under the cursor, send
+		 * a motion event. */
+		ret = 1;
 	}
 
+	pointer->current_x = curr_x;
+	pointer->current_y = curr_y;
+
 	focus = (struct weston_surface *) pointer->grab->focus;
-	if (focus)
-		weston_surface_from_global_fixed(focus,
-						 pointer->x,
-						 pointer->y,
-					         &pointer->grab->x,
-					         &pointer->grab->y);
+	if (focus) {
+		pointer->grab->x = curr_x;
+		pointer->grab->y = curr_y;
+	}
+
+	return ret;
 }
 
 static void
-weston_compositor_repick(struct weston_compositor *compositor)
+weston_compositor_repick(struct weston_compositor *compositor, int32_t time)
 {
 	struct weston_seat *seat;
+	const struct wl_pointer_grab_interface *interface;
+	struct wl_pointer *pointer;
 
 	if (!compositor->focus)
 		return;
 
-	wl_list_for_each(seat, &compositor->seat_list, link)
-		weston_device_repick(seat);
+	wl_list_for_each(seat, &compositor->seat_list, link) {
+		pointer = seat->seat.pointer;
+		if (weston_device_repick(seat)) {
+			interface = pointer->grab->interface;
+			interface->motion(pointer->grab, time,
+			                  pointer->grab->x,
+			                  pointer->grab->y);
+        }
+    }
 }
 
 WL_EXPORT void
@@ -1117,7 +1138,7 @@ weston_output_repaint(struct weston_output *output, uint32_t msecs)
 
 	output->repaint_needed = 0;
 
-	weston_compositor_repick(ec);
+	weston_compositor_repick(ec, msecs);
 	wl_event_loop_dispatch(ec->input_loop, 0);
 
 	wl_list_for_each_safe(cb, cnext, &frame_callback_list, link) {
@@ -1953,7 +1974,7 @@ notify_pointer_focus(struct weston_seat *seat, struct weston_output *output,
 		pointer->x = x;
 		pointer->y = y;
 		compositor->focus = 1;
-		weston_compositor_repick(compositor);
+		weston_device_repick(seat);
 	} else {
 		compositor->focus = 0;
 		/* FIXME: We should call wl_pointer_set_focus(seat,
-- 
1.8.1.4



More information about the wayland-devel mailing list