Add libinput_event_pointer_get_axis_value_discrete() to count wheel clicks
authorPeter Hutterer <peter.hutterer@who-t.net>
Tue, 13 Jan 2015 05:15:02 +0000 (15:15 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Wed, 14 Jan 2015 23:22:14 +0000 (09:22 +1000)
The recent normalization of wheel events means we get the angle in degrees but
we don't know how this corresponds to clicks. The M325 has a 20 degree click
angle, most other mice have 15 degrees. So an angle of 60 can be 3 or 4 click
events.

Most clients care more about the click count than the angle on a mouse wheel.
Provide that value when needed.

Adding a discrete value to the axis event leaves the possibility of defining
discrete units for finger/continuous scroll sources in the future. Right now,
these will always reuturn 0.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Jonas Ã…dahl <jadahl@gmail.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
src/evdev-mt-touchpad-edge-scroll.c
src/evdev.c
src/libinput-private.h
src/libinput.c
src/libinput.h
src/libinput.sym
test/pointer.c

index a4dc093..8605034 100644 (file)
@@ -327,7 +327,8 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
                                        pointer_notify_axis(device, time,
                                                t->scroll.direction,
                                                LIBINPUT_POINTER_AXIS_SOURCE_FINGER,
-                                               0.0);
+                                               0.0,
+                                               0);
                                        t->scroll.direction = -1;
                                }
                                continue;
@@ -351,7 +352,8 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
 
                pointer_notify_axis(device, time, axis,
                                    LIBINPUT_POINTER_AXIS_SOURCE_FINGER,
-                                   *delta);
+                                   *delta,
+                                   0);
                t->scroll.direction = axis;
 
                tp_edge_scroll_handle_event(tp, t, SCROLL_EVENT_POSTED);
@@ -371,7 +373,8 @@ tp_edge_scroll_stop_events(struct tp_dispatch *tp, uint64_t time)
                        pointer_notify_axis(device, time,
                                            t->scroll.direction,
                                            LIBINPUT_POINTER_AXIS_SOURCE_FINGER,
-                                           0.0);
+                                           0.0,
+                                           0);
                        t->scroll.direction = -1;
                }
        }
index d80594d..0e78381 100644 (file)
@@ -541,16 +541,20 @@ evdev_notify_axis(struct evdev_device *device,
                  uint64_t time,
                  enum libinput_pointer_axis axis,
                  enum libinput_pointer_axis_source source,
-                 double value)
+                 double value,
+                 double discrete)
 {
-       if (device->scroll.natural_scrolling_enabled)
+       if (device->scroll.natural_scrolling_enabled) {
                value *= -1;
+               discrete *= -1;
+       }
 
        pointer_notify_axis(&device->base,
                            time,
                            axis,
                            source,
-                           value);
+                           value,
+                           discrete);
 }
 
 static inline void
@@ -577,7 +581,8 @@ evdev_process_relative(struct evdev_device *device,
                        time,
                        LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
                        LIBINPUT_POINTER_AXIS_SOURCE_WHEEL,
-                       -1 * e->value * device->scroll.wheel_click_angle);
+                       -1 * e->value * device->scroll.wheel_click_angle,
+                       -1 * e->value);
                break;
        case REL_HWHEEL:
                evdev_flush_pending_event(device, time);
@@ -586,7 +591,8 @@ evdev_process_relative(struct evdev_device *device,
                        time,
                        LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
                        LIBINPUT_POINTER_AXIS_SOURCE_WHEEL,
-                       e->value * device->scroll.wheel_click_angle);
+                       e->value * device->scroll.wheel_click_angle,
+                       e->value);
                break;
        }
 }
@@ -1864,7 +1870,8 @@ evdev_post_scroll(struct evdev_device *device,
                                  time,
                                  LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
                                  source,
-                                 dy);
+                                 dy,
+                                 0);
        }
 
        if (dx != 0.0 &&
@@ -1874,7 +1881,8 @@ evdev_post_scroll(struct evdev_device *device,
                                  time,
                                  LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
                                  source,
-                                 dx);
+                                 dx,
+                                 0);
        }
 }
 
@@ -1889,13 +1897,13 @@ evdev_stop_scroll(struct evdev_device *device,
                                    time,
                                    LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
                                    source,
-                                   0);
+                                   0, 0);
        if (device->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL))
                pointer_notify_axis(&device->base,
                                    time,
                                    LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
                                    source,
-                                   0);
+                                   0, 0);
 
        device->scroll.buildup_horizontal = 0;
        device->scroll.buildup_vertical = 0;
index 84a0d44..415e53e 100644 (file)
@@ -280,7 +280,8 @@ pointer_notify_axis(struct libinput_device *device,
                    uint64_t time,
                    enum libinput_pointer_axis axis,
                    enum libinput_pointer_axis_source source,
-                   double value);
+                   double value,
+                   double discrete);
 
 void
 touch_notify_touch_down(struct libinput_device *device,
index 426c306..37df962 100644 (file)
@@ -67,6 +67,7 @@ struct libinput_event_pointer {
        enum libinput_pointer_axis axis;
        enum libinput_pointer_axis_source source;
        double value;
+       double discrete;
 };
 
 struct libinput_event_touch {
@@ -391,6 +392,12 @@ libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event)
        return event->value;
 }
 
+LIBINPUT_EXPORT double
+libinput_event_pointer_get_axis_value_discrete(struct libinput_event_pointer *event)
+{
+       return event->discrete;
+}
+
 LIBINPUT_EXPORT enum libinput_pointer_axis_source
 libinput_event_pointer_get_axis_source(struct libinput_event_pointer *event)
 {
@@ -994,7 +1001,8 @@ pointer_notify_axis(struct libinput_device *device,
                    uint64_t time,
                    enum libinput_pointer_axis axis,
                    enum libinput_pointer_axis_source source,
-                   double value)
+                   double value,
+                   double discrete)
 {
        struct libinput_event_pointer *axis_event;
 
@@ -1007,6 +1015,7 @@ pointer_notify_axis(struct libinput_device *device,
                .axis = axis,
                .value = value,
                .source = source,
+               .discrete = discrete,
        };
 
        post_device_event(device, time,
index f605e52..c6dd57e 100644 (file)
@@ -683,6 +683,8 @@ libinput_event_pointer_get_axis(struct libinput_event_pointer *event);
  * @ref LIBINPUT_EVENT_POINTER_AXIS.
  *
  * @return the axis value of this event
+ *
+ * @see libinput_event_pointer_get_axis_value_discrete
  */
 double
 libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event);
@@ -726,6 +728,25 @@ enum libinput_pointer_axis_source
 libinput_event_pointer_get_axis_source(struct libinput_event_pointer *event);
 
 /**
+ * @ingroup pointer
+ *
+ * Return the axis value in discrete steps for a given axis event. How a
+ * value translates into a discrete step depends on the source.
+ *
+ * If the source is @ref LIBINPUT_POINTER_AXIS_SOURCE_WHEEL, the discrete
+ * value correspond to the number of physical mouse clicks.
+ *
+ * If the source is @ref LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS or @ref
+ * LIBINPUT_POINTER_AXIS_SOURCE_FINGER, the discrete value is always 0.
+ *
+ * @return The discrete value for the given event.
+ *
+ * @see libinput_event_pointer_get_axis_value
+ */
+double
+libinput_event_pointer_get_axis_value_discrete(struct libinput_event_pointer *event);
+
+/**
  * @ingroup event_pointer
  *
  * @return The generic libinput_event of this event
index 826bfde..d9ebbc2 100644 (file)
@@ -73,6 +73,7 @@ global:
        libinput_event_pointer_get_axis;
        libinput_event_pointer_get_axis_source;
        libinput_event_pointer_get_axis_value;
+       libinput_event_pointer_get_axis_value_discrete;
        libinput_event_pointer_get_base_event;
        libinput_event_pointer_get_button_state;
        libinput_event_pointer_get_button;
index d12c9f6..2055c41 100644 (file)
@@ -353,9 +353,12 @@ test_wheel_event(struct litest_device *dev, int which, int amount)
           up by a factor 15 */
        const int scroll_step = 15;
        int expected = amount * scroll_step;
+       int discrete = amount;
 
-       if (libinput_device_config_scroll_get_natural_scroll_enabled(dev->libinput_device))
+       if (libinput_device_config_scroll_get_natural_scroll_enabled(dev->libinput_device)) {
                expected *= -1;
+               discrete *= -1;
+       }
 
        /* mouse scroll wheels are 'upside down' */
        if (which == REL_WHEEL)
@@ -379,6 +382,8 @@ test_wheel_event(struct litest_device *dev, int which, int amount)
        ck_assert_int_eq(libinput_event_pointer_get_axis_value(ptrev), expected);
        ck_assert_int_eq(libinput_event_pointer_get_axis_source(ptrev),
                         LIBINPUT_POINTER_AXIS_SOURCE_WHEEL);
+       ck_assert_int_eq(libinput_event_pointer_get_axis_value_discrete(ptrev),
+                        discrete);
        libinput_event_destroy(event);
 }