[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