diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index b3756aa0d..1e63bbe80 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -51,9 +51,12 @@ #include "meta-wayland-private.h" #include "meta-cursor.h" #include "meta-cursor-tracker-private.h" +#include "meta-surface-actor-wayland.h" #include +#define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int (10) + static void meta_wayland_pointer_end_popup_grab (MetaWaylandPointer *pointer); static void @@ -355,6 +358,177 @@ count_buttons (const ClutterEvent *event) return count; } +static void +update_current_focus (MetaWaylandPointer *pointer, + MetaWaylandSurface *surface) +{ + pointer->current = surface; + if (surface != pointer->focus_surface) + { + const MetaWaylandPointerGrabInterface *interface = + pointer->grab->interface; + interface->focus (pointer->grab, surface); + } +} + +static void +repick_for_event (MetaWaylandPointer *pointer, + const ClutterEvent *for_event) +{ + ClutterActor *actor = NULL; + MetaWaylandSurface *surface = NULL; + MetaDisplay *display = meta_get_display (); + + if (meta_grab_op_should_block_wayland (display->grab_op)) + { + update_current_focus (pointer, NULL); + return; + } + + if (for_event) + { + actor = clutter_event_get_source (for_event); + } + else + { + ClutterDeviceManager *device_manager = clutter_device_manager_get_default (); + ClutterInputDevice *device = clutter_device_manager_get_device (device_manager, META_VIRTUAL_CORE_POINTER_ID); + ClutterStage *stage = clutter_input_device_get_pointer_stage (device); + + if (stage) + actor = clutter_stage_get_actor_at_pos (stage, + CLUTTER_PICK_REACTIVE, + wl_fixed_to_double (pointer->x), + wl_fixed_to_double (pointer->y)); + } + + if (META_IS_SURFACE_ACTOR_WAYLAND (actor)) + surface = meta_surface_actor_wayland_get_surface (META_SURFACE_ACTOR_WAYLAND (actor)); + + update_current_focus (pointer, surface); +} + +static void +notify_motion (MetaWaylandPointer *pointer, + const ClutterEvent *event) +{ + repick_for_event (pointer, event); + + pointer->grab->interface->motion (pointer->grab, event); +} + +static void +handle_motion_event (MetaWaylandPointer *pointer, + const ClutterEvent *event) +{ + notify_motion (pointer, event); +} + +static void +handle_button_event (MetaWaylandPointer *pointer, + const ClutterEvent *event) +{ + gboolean implicit_grab; + + notify_motion (pointer, event); + + implicit_grab = (event->type == CLUTTER_BUTTON_PRESS) && (pointer->button_count == 1); + if (implicit_grab) + { + pointer->grab_button = clutter_event_get_button (event); + pointer->grab_time = clutter_event_get_time (event); + pointer->grab_x = pointer->x; + pointer->grab_y = pointer->y; + } + + pointer->grab->interface->button (pointer->grab, event); + + if (implicit_grab) + pointer->grab_serial = wl_display_get_serial (pointer->display); +} + +static void +handle_scroll_event (MetaWaylandPointer *pointer, + const ClutterEvent *event) +{ + struct wl_resource *resource; + struct wl_list *l; + wl_fixed_t x_value = 0, y_value = 0; + + notify_motion (pointer, event); + + if (clutter_event_is_pointer_emulated (event)) + return; + + switch (clutter_event_get_scroll_direction (event)) + { + case CLUTTER_SCROLL_UP: + y_value = -DEFAULT_AXIS_STEP_DISTANCE; + break; + + case CLUTTER_SCROLL_DOWN: + y_value = DEFAULT_AXIS_STEP_DISTANCE; + break; + + case CLUTTER_SCROLL_LEFT: + x_value = -DEFAULT_AXIS_STEP_DISTANCE; + break; + + case CLUTTER_SCROLL_RIGHT: + x_value = DEFAULT_AXIS_STEP_DISTANCE; + break; + + case CLUTTER_SCROLL_SMOOTH: + { + double dx, dy; + clutter_event_get_scroll_delta (event, &dx, &dy); + x_value = wl_fixed_from_double (dx); + y_value = wl_fixed_from_double (dy); + } + break; + + default: + return; + } + + l = &pointer->focus_resource_list; + wl_resource_for_each (resource, l) + { + if (x_value) + wl_pointer_send_axis (resource, clutter_event_get_time (event), + WL_POINTER_AXIS_HORIZONTAL_SCROLL, x_value); + if (y_value) + wl_pointer_send_axis (resource, clutter_event_get_time (event), + WL_POINTER_AXIS_VERTICAL_SCROLL, y_value); + } +} + +gboolean +meta_wayland_pointer_handle_event (MetaWaylandPointer *pointer, + const ClutterEvent *event) +{ + switch (event->type) + { + case CLUTTER_MOTION: + handle_motion_event (pointer, event); + break; + + case CLUTTER_BUTTON_PRESS: + case CLUTTER_BUTTON_RELEASE: + handle_button_event (pointer, event); + break; + + case CLUTTER_SCROLL: + handle_scroll_event (pointer, event); + break; + + default: + break; + } + + return FALSE; +} + void meta_wayland_pointer_update (MetaWaylandPointer *pointer, const ClutterEvent *event) @@ -378,31 +552,6 @@ meta_wayland_pointer_update (MetaWaylandPointer *pointer, } } -static void -pointer_set_cursor (struct wl_client *client, - struct wl_resource *resource, - uint32_t serial, - struct wl_resource *surface_resource, - int32_t x, int32_t y) -{ - MetaWaylandPointer *pointer = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface; - - surface = (surface_resource ? wl_resource_get_user_data (surface_resource) : NULL); - - if (pointer->focus_surface == NULL) - return; - if (wl_resource_get_client (pointer->focus_surface->resource) != client) - return; - if (pointer->focus_serial - serial > G_MAXUINT32 / 2) - return; - - pointer->hotspot_x = x; - pointer->hotspot_y = y; - set_cursor_surface (pointer, surface); - meta_wayland_pointer_update_cursor_surface (pointer); -} - static void move_resources (struct wl_list *destination, struct wl_list *source) { @@ -676,6 +825,12 @@ meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer, return TRUE; } +void +meta_wayland_pointer_repick (MetaWaylandPointer *pointer) +{ + repick_for_event (pointer, NULL); +} + void meta_wayland_pointer_get_relative_coordinates (MetaWaylandPointer *pointer, MetaWaylandSurface *surface, @@ -700,19 +855,6 @@ meta_wayland_pointer_get_relative_coordinates (MetaWaylandPointer *pointer, *sy = wl_fixed_from_double (yf); } -void -meta_wayland_pointer_update_current_focus (MetaWaylandPointer *pointer, - MetaWaylandSurface *surface) -{ - pointer->current = surface; - if (surface != pointer->focus_surface) - { - const MetaWaylandPointerGrabInterface *interface = - pointer->grab->interface; - interface->focus (pointer->grab, surface); - } -} - void meta_wayland_pointer_update_cursor_surface (MetaWaylandPointer *pointer) { @@ -738,6 +880,31 @@ meta_wayland_pointer_update_cursor_surface (MetaWaylandPointer *pointer) meta_cursor_reference_unref (cursor); } +static void +pointer_set_cursor (struct wl_client *client, + struct wl_resource *resource, + uint32_t serial, + struct wl_resource *surface_resource, + int32_t x, int32_t y) +{ + MetaWaylandPointer *pointer = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface; + + surface = (surface_resource ? wl_resource_get_user_data (surface_resource) : NULL); + + if (pointer->focus_surface == NULL) + return; + if (wl_resource_get_client (pointer->focus_surface->resource) != client) + return; + if (pointer->focus_serial - serial > G_MAXUINT32 / 2) + return; + + pointer->hotspot_x = x; + pointer->hotspot_y = y; + set_cursor_surface (pointer, surface); + meta_wayland_pointer_update_cursor_surface (pointer); +} + static void pointer_release (struct wl_client *client, struct wl_resource *resource) diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h index e45e35765..32e9458cb 100644 --- a/src/wayland/meta-wayland-pointer.h +++ b/src/wayland/meta-wayland-pointer.h @@ -86,6 +86,10 @@ void meta_wayland_pointer_update (MetaWaylandPointer *pointer, const ClutterEvent *event); +gboolean +meta_wayland_pointer_handle_event (MetaWaylandPointer *pointer, + const ClutterEvent *event); + void meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, MetaWaylandSurface *surface); @@ -101,16 +105,15 @@ gboolean meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer, MetaWaylandSurface *popup); +void +meta_wayland_pointer_repick (MetaWaylandPointer *pointer); + void meta_wayland_pointer_get_relative_coordinates (MetaWaylandPointer *pointer, MetaWaylandSurface *surface, wl_fixed_t *x, wl_fixed_t *y); -void -meta_wayland_pointer_update_current_focus (MetaWaylandPointer *pointer, - MetaWaylandSurface *surface); - void meta_wayland_pointer_update_cursor_surface (MetaWaylandPointer *pointer); diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index 4e3ef8e6e..4498102bf 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -38,9 +38,6 @@ #include "meta-shaped-texture-private.h" #include "meta-wayland-stage.h" #include "meta-cursor-tracker-private.h" -#include "meta-surface-actor-wayland.h" - -#define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int (10) static void unbind_resource (struct wl_resource *resource) @@ -183,138 +180,6 @@ meta_wayland_seat_update (MetaWaylandSeat *seat, } } -static void -repick_for_event (MetaWaylandPointer *pointer, - const ClutterEvent *for_event) -{ - ClutterActor *actor = NULL; - MetaWaylandSurface *surface = NULL; - MetaDisplay *display = meta_get_display (); - - if (meta_grab_op_should_block_wayland (display->grab_op)) - { - meta_wayland_pointer_update_current_focus (pointer, NULL); - return; - } - - if (for_event) - { - actor = clutter_event_get_source (for_event); - } - else - { - ClutterDeviceManager *device_manager = clutter_device_manager_get_default (); - ClutterInputDevice *device = clutter_device_manager_get_device (device_manager, META_VIRTUAL_CORE_POINTER_ID); - ClutterStage *stage = clutter_input_device_get_pointer_stage (device); - - if (stage) - actor = clutter_stage_get_actor_at_pos (stage, - CLUTTER_PICK_REACTIVE, - wl_fixed_to_double (pointer->x), - wl_fixed_to_double (pointer->y)); - } - - if (META_IS_SURFACE_ACTOR_WAYLAND (actor)) - surface = meta_surface_actor_wayland_get_surface (META_SURFACE_ACTOR_WAYLAND (actor)); - - meta_wayland_pointer_update_current_focus (pointer, surface); -} - -static void -notify_motion (MetaWaylandPointer *pointer, - const ClutterEvent *event) -{ - repick_for_event (pointer, event); - - pointer->grab->interface->motion (pointer->grab, event); -} - -static void -handle_motion_event (MetaWaylandPointer *pointer, - const ClutterEvent *event) -{ - notify_motion (pointer, event); -} - -static void -handle_button_event (MetaWaylandPointer *pointer, - const ClutterEvent *event) -{ - gboolean implicit_grab; - - notify_motion (pointer, event); - - implicit_grab = (event->type == CLUTTER_BUTTON_PRESS) && (pointer->button_count == 1); - if (implicit_grab) - { - pointer->grab_button = clutter_event_get_button (event); - pointer->grab_time = clutter_event_get_time (event); - pointer->grab_x = pointer->x; - pointer->grab_y = pointer->y; - } - - pointer->grab->interface->button (pointer->grab, event); - - if (implicit_grab) - pointer->grab_serial = wl_display_get_serial (pointer->display); -} - -static void -handle_scroll_event (MetaWaylandPointer *pointer, - const ClutterEvent *event) -{ - struct wl_resource *resource; - struct wl_list *l; - wl_fixed_t x_value = 0, y_value = 0; - - notify_motion (pointer, event); - - if (clutter_event_is_pointer_emulated (event)) - return; - - switch (clutter_event_get_scroll_direction (event)) - { - case CLUTTER_SCROLL_UP: - y_value = -DEFAULT_AXIS_STEP_DISTANCE; - break; - - case CLUTTER_SCROLL_DOWN: - y_value = DEFAULT_AXIS_STEP_DISTANCE; - break; - - case CLUTTER_SCROLL_LEFT: - x_value = -DEFAULT_AXIS_STEP_DISTANCE; - break; - - case CLUTTER_SCROLL_RIGHT: - x_value = DEFAULT_AXIS_STEP_DISTANCE; - break; - - case CLUTTER_SCROLL_SMOOTH: - { - double dx, dy; - clutter_event_get_scroll_delta (event, &dx, &dy); - x_value = wl_fixed_from_double (dx); - y_value = wl_fixed_from_double (dy); - } - break; - - default: - return; - } - - l = &pointer->focus_resource_list; - wl_resource_for_each (resource, l) - { - if (x_value) - wl_pointer_send_axis (resource, clutter_event_get_time (event), - WL_POINTER_AXIS_HORIZONTAL_SCROLL, x_value); - if (y_value) - wl_pointer_send_axis (resource, clutter_event_get_time (event), - WL_POINTER_AXIS_VERTICAL_SCROLL, y_value); - } -} - gboolean meta_wayland_seat_handle_event (MetaWaylandSeat *seat, const ClutterEvent *event) @@ -322,17 +187,10 @@ meta_wayland_seat_handle_event (MetaWaylandSeat *seat, switch (event->type) { case CLUTTER_MOTION: - handle_motion_event (&seat->pointer, event); - break; - case CLUTTER_BUTTON_PRESS: case CLUTTER_BUTTON_RELEASE: - handle_button_event (&seat->pointer, event); - break; - case CLUTTER_SCROLL: - handle_scroll_event (&seat->pointer, event); - break; + return meta_wayland_pointer_handle_event (&seat->pointer, event); case CLUTTER_KEY_PRESS: case CLUTTER_KEY_RELEASE: @@ -349,7 +207,7 @@ meta_wayland_seat_handle_event (MetaWaylandSeat *seat, void meta_wayland_seat_repick (MetaWaylandSeat *seat) { - repick_for_event (&seat->pointer, NULL); + meta_wayland_pointer_repick (&seat->pointer); } void