wayland: Implement wl_pointer.axis_source/axis_stop/axis_frame emission

As per the spec:
- wl_pointer.axis_source determines the current source of
  scroll events.
- wl_pointer.axis_stop determines when there's no further
  scroll events on the given axis.
- wl_pointer.axis_discrete is emitted on "wheel"
  scroll sources, measured in ticks.
- wl_pointer.frame is meant to coalesce events that logically belong
  together, e.g. axis events in this case.

Co-Authored-By: Peter Hutterer <peter.hutterer@who-t.net>

https://bugzilla.gnome.org/show_bug.cgi?id=760637
This commit is contained in:
Carlos Garnacho 2015-09-08 14:32:50 +02:00
parent cc013e1daa
commit 935d76ba04
2 changed files with 77 additions and 1 deletions

View File

@ -242,6 +242,21 @@ pointer_handle_focus_surface_destroy (struct wl_listener *listener, void *data)
meta_wayland_pointer_set_focus (pointer, NULL);
}
static void
meta_wayland_pointer_send_frame (MetaWaylandPointer *pointer)
{
struct wl_resource *resource;
if (!pointer->focus_client)
return;
wl_resource_for_each (resource, &pointer->focus_client->pointer_resources)
{
if (wl_resource_get_version (resource) >= WL_POINTER_AXIS_SOURCE_SINCE_VERSION)
wl_pointer_send_frame (resource);
}
}
void
meta_wayland_pointer_send_motion (MetaWaylandPointer *pointer,
const ClutterEvent *event)
@ -262,6 +277,8 @@ meta_wayland_pointer_send_motion (MetaWaylandPointer *pointer,
{
wl_pointer_send_motion (resource, time, sx, sy);
}
meta_wayland_pointer_send_frame (pointer);
}
void
@ -321,6 +338,8 @@ meta_wayland_pointer_send_button (MetaWaylandPointer *pointer,
time, button,
event_type == CLUTTER_BUTTON_PRESS ? 1 : 0);
}
meta_wayland_pointer_send_frame (pointer);
}
if (pointer->button_count == 0 && event_type == CLUTTER_BUTTON_RELEASE)
@ -510,26 +529,48 @@ handle_scroll_event (MetaWaylandPointer *pointer,
{
struct wl_resource *resource;
wl_fixed_t x_value = 0, y_value = 0;
int x_discrete = 0, y_discrete = 0;
enum wl_pointer_axis_source source = -1;
if (clutter_event_is_pointer_emulated (event))
return;
switch (event->scroll.scroll_source)
{
case CLUTTER_SCROLL_SOURCE_WHEEL:
source = WL_POINTER_AXIS_SOURCE_WHEEL;
break;
case CLUTTER_SCROLL_SOURCE_FINGER:
source = WL_POINTER_AXIS_SOURCE_FINGER;
break;
case CLUTTER_SCROLL_SOURCE_CONTINUOUS:
source = WL_POINTER_AXIS_SOURCE_CONTINUOUS;
break;
default:
source = WL_POINTER_AXIS_SOURCE_WHEEL;
break;
}
switch (clutter_event_get_scroll_direction (event))
{
case CLUTTER_SCROLL_UP:
y_value = -DEFAULT_AXIS_STEP_DISTANCE;
y_discrete = -1;
break;
case CLUTTER_SCROLL_DOWN:
y_value = DEFAULT_AXIS_STEP_DISTANCE;
y_discrete = 1;
break;
case CLUTTER_SCROLL_LEFT:
x_value = -DEFAULT_AXIS_STEP_DISTANCE;
x_discrete = -1;
break;
case CLUTTER_SCROLL_RIGHT:
x_value = DEFAULT_AXIS_STEP_DISTANCE;
x_discrete = 1;
break;
case CLUTTER_SCROLL_SMOOTH:
@ -553,13 +594,44 @@ handle_scroll_event (MetaWaylandPointer *pointer,
{
wl_resource_for_each (resource, &pointer->focus_client->pointer_resources)
{
if (wl_resource_get_version (resource) >= WL_POINTER_AXIS_SOURCE_SINCE_VERSION)
wl_pointer_send_axis_source (resource, source);
/* X axis */
if (x_discrete != 0 &&
wl_resource_get_version (resource) >= WL_POINTER_AXIS_DISCRETE_SINCE_VERSION)
wl_pointer_send_axis_discrete (resource,
WL_POINTER_AXIS_HORIZONTAL_SCROLL,
x_discrete);
if (x_value)
wl_pointer_send_axis (resource, clutter_event_get_time (event),
WL_POINTER_AXIS_HORIZONTAL_SCROLL, x_value);
if ((event->scroll.finish_flags & CLUTTER_SCROLL_FINISHED_HORIZONTAL) &&
wl_resource_get_version (resource) >= WL_POINTER_AXIS_STOP_SINCE_VERSION)
wl_pointer_send_axis_stop (resource,
clutter_event_get_time (event),
WL_POINTER_AXIS_HORIZONTAL_SCROLL);
/* Y axis */
if (y_discrete != 0 &&
wl_resource_get_version (resource) >= WL_POINTER_AXIS_DISCRETE_SINCE_VERSION)
wl_pointer_send_axis_discrete (resource,
WL_POINTER_AXIS_VERTICAL_SCROLL,
y_discrete);
if (y_value)
wl_pointer_send_axis (resource, clutter_event_get_time (event),
WL_POINTER_AXIS_VERTICAL_SCROLL, y_value);
if ((event->scroll.finish_flags & CLUTTER_SCROLL_FINISHED_VERTICAL) &&
wl_resource_get_version (resource) >= WL_POINTER_AXIS_STOP_SINCE_VERSION)
wl_pointer_send_axis_stop (resource,
clutter_event_get_time (event),
WL_POINTER_AXIS_VERTICAL_SCROLL);
}
meta_wayland_pointer_send_frame (pointer);
}
}
@ -632,6 +704,8 @@ meta_wayland_pointer_broadcast_enter (MetaWaylandPointer *pointer,
&pointer->focus_client->pointer_resources)
meta_wayland_pointer_send_enter (pointer, pointer_resource,
serial, surface);
meta_wayland_pointer_send_frame (pointer);
}
static void
@ -645,6 +719,8 @@ meta_wayland_pointer_broadcast_leave (MetaWaylandPointer *pointer,
&pointer->focus_client->pointer_resources)
meta_wayland_pointer_send_leave (pointer, pointer_resource,
serial, surface);
meta_wayland_pointer_send_frame (pointer);
}
void

View File

@ -39,7 +39,7 @@
#define META_WL_DATA_DEVICE_MANAGER_VERSION 2
#define META_XDG_SHELL_VERSION 1
#define META_WL_SHELL_VERSION 1
#define META_WL_SEAT_VERSION 4
#define META_WL_SEAT_VERSION 5
#define META_WL_OUTPUT_VERSION 2
#define META_XSERVER_VERSION 1
#define META_GTK_SHELL_VERSION 2