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

Giulio Camuffo giuliocamuffo at gmail.com
Tue Mar 19 13:16:27 PDT 2013


Kristian, is the timespamp i'm using now correct?

2013/2/28 Giulio Camuffo <giuliocamuffo at gmail.com>:
> 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