... |
... |
@@ -128,11 +128,10 @@ struct xf86libinput { |
128
|
128
|
uint32_t capabilities;
|
129
|
129
|
|
130
|
130
|
struct {
|
131
|
|
- int vdist;
|
132
|
|
- int hdist;
|
133
|
|
-
|
134
|
|
- double vdist_fraction;
|
135
|
|
- double hdist_fraction;
|
|
131
|
+ struct scroll_axis {
|
|
132
|
+ int dist;
|
|
133
|
+ double fraction;
|
|
134
|
+ } v, h;
|
136
|
135
|
} scroll;
|
137
|
136
|
|
138
|
137
|
struct {
|
... |
... |
@@ -398,7 +397,7 @@ xf86libinput_shared_disable(struct xf86libinput_device *shared_device) |
398
|
397
|
|
399
|
398
|
libinput_device_set_user_data(device, NULL);
|
400
|
399
|
libinput_path_remove_device(device);
|
401
|
|
- device = libinput_device_unref(device);
|
|
400
|
+ libinput_device_unref(device);
|
402
|
401
|
shared_device->device = NULL;
|
403
|
402
|
}
|
404
|
403
|
|
... |
... |
@@ -936,8 +935,8 @@ xf86libinput_init_pointer(InputInfoPtr pInfo) |
936
|
935
|
XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y),
|
937
|
936
|
min, max, res * 1000, 0, res * 1000, Relative);
|
938
|
937
|
|
939
|
|
- SetScrollValuator(dev, 2, SCROLL_TYPE_HORIZONTAL, driver_data->scroll.hdist, 0);
|
940
|
|
- SetScrollValuator(dev, 3, SCROLL_TYPE_VERTICAL, driver_data->scroll.vdist, 0);
|
|
938
|
+ SetScrollValuator(dev, 2, SCROLL_TYPE_HORIZONTAL, driver_data->scroll.h.dist, 0);
|
|
939
|
+ SetScrollValuator(dev, 3, SCROLL_TYPE_VERTICAL, driver_data->scroll.v.dist, 0);
|
941
|
940
|
|
942
|
941
|
return Success;
|
943
|
942
|
}
|
... |
... |
@@ -984,8 +983,8 @@ xf86libinput_init_pointer_absolute(InputInfoPtr pInfo) |
984
|
983
|
XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y),
|
985
|
984
|
min, max, res * 1000, 0, res * 1000, Absolute);
|
986
|
985
|
|
987
|
|
- SetScrollValuator(dev, 2, SCROLL_TYPE_HORIZONTAL, driver_data->scroll.hdist, 0);
|
988
|
|
- SetScrollValuator(dev, 3, SCROLL_TYPE_VERTICAL, driver_data->scroll.vdist, 0);
|
|
986
|
+ SetScrollValuator(dev, 2, SCROLL_TYPE_HORIZONTAL, driver_data->scroll.h.dist, 0);
|
|
987
|
+ SetScrollValuator(dev, 3, SCROLL_TYPE_VERTICAL, driver_data->scroll.v.dist, 0);
|
989
|
988
|
|
990
|
989
|
driver_data->has_abs = TRUE;
|
991
|
990
|
|
... |
... |
@@ -1565,40 +1564,58 @@ xf86libinput_handle_key(InputInfoPtr pInfo, struct libinput_event_keyboard *even |
1565
|
1564
|
* e.g. a 2 degree click angle requires 8 clicks before a legacy event is
|
1566
|
1565
|
* sent, but each of those clicks will send XI2.1 smooth scroll data for
|
1567
|
1566
|
* compatible clients.
|
|
1567
|
+ *
|
|
1568
|
+ * Starting with kernel v5.0 we should get REL_WHEEL_HI_RES from those
|
|
1569
|
+ * devices for the fine-grained scrolling and REL_WHEEL for the normal one,
|
|
1570
|
+ * so the use-case above shouldn't matter anymore.
|
1568
|
1571
|
*/
|
1569
|
1572
|
static inline double
|
1570
|
|
-get_scroll_fraction(struct xf86libinput *driver_data,
|
1571
|
|
- struct libinput_event_pointer *event,
|
1572
|
|
- enum libinput_pointer_axis axis)
|
|
1573
|
+get_wheel_scroll_value(struct xf86libinput *driver_data,
|
|
1574
|
+ struct libinput_event_pointer *event,
|
|
1575
|
+ enum libinput_pointer_axis axis)
|
1573
|
1576
|
{
|
1574
|
|
- double *fraction;
|
|
1577
|
+ struct scroll_axis *s;
|
1575
|
1578
|
double f;
|
1576
|
1579
|
double angle;
|
1577
|
1580
|
int discrete;
|
1578
|
1581
|
|
1579
|
1582
|
switch (axis) {
|
1580
|
1583
|
case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL:
|
1581
|
|
- fraction = &driver_data->scroll.hdist_fraction;
|
|
1584
|
+ s = &driver_data->scroll.h;
|
1582
|
1585
|
break;
|
1583
|
1586
|
case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL:
|
1584
|
|
- fraction = &driver_data->scroll.vdist_fraction;
|
|
1587
|
+ s = &driver_data->scroll.v;
|
1585
|
1588
|
break;
|
1586
|
1589
|
default:
|
1587
|
1590
|
return 0.0;
|
1588
|
1591
|
}
|
1589
|
1592
|
|
1590
|
|
- if (*fraction != 0.0)
|
1591
|
|
- return *fraction;
|
1592
|
|
-
|
1593
|
|
- /* Calculate the angle per single scroll event */
|
1594
|
1593
|
angle = libinput_event_pointer_get_axis_value(event, axis);
|
1595
|
1594
|
discrete = libinput_event_pointer_get_axis_value_discrete(event, axis);
|
|
1595
|
+
|
|
1596
|
+ /* We only need to guess the fraction on the first set of
|
|
1597
|
+ * scroll events until a discrete value arrives. Once known, we
|
|
1598
|
+ * re-use the fraction until the device goes away.
|
|
1599
|
+ */
|
|
1600
|
+ if (s->fraction != 0.0)
|
|
1601
|
+ goto out;
|
|
1602
|
+
|
|
1603
|
+ /* if we get a discrete of 0, assume REL_WHEEL_HI_RES exists and
|
|
1604
|
+ * normal scroll events are sent correctly, so skip all the
|
|
1605
|
+ * guesswork.
|
|
1606
|
+ */
|
|
1607
|
+ if (discrete == 0) {
|
|
1608
|
+ s->fraction = 1.0;
|
|
1609
|
+ goto out;
|
|
1610
|
+ }
|
|
1611
|
+
|
|
1612
|
+ /* Calculate the angle per single scroll event */
|
1596
|
1613
|
angle /= discrete;
|
1597
|
1614
|
|
1598
|
1615
|
/* We only do magic for click angles smaller than 10 degrees */
|
1599
|
1616
|
if (angle >= 10) {
|
1600
|
|
- *fraction = 1.0;
|
1601
|
|
- return 1.0;
|
|
1617
|
+ s->fraction = 1.0;
|
|
1618
|
+ goto out;
|
1602
|
1619
|
}
|
1603
|
1620
|
|
1604
|
1621
|
/* Figure out something that gets close to 15 degrees (the general
|
... |
... |
@@ -1609,9 +1626,10 @@ get_scroll_fraction(struct xf86libinput *driver_data, |
1609
|
1626
|
*/
|
1610
|
1627
|
f = round(15.0/angle);
|
1611
|
1628
|
|
1612
|
|
- *fraction = f;
|
|
1629
|
+ s->fraction = f;
|
1613
|
1630
|
|
1614
|
|
- return f;
|
|
1631
|
+out:
|
|
1632
|
+ return s->dist/s->fraction * discrete;
|
1615
|
1633
|
}
|
1616
|
1634
|
|
1617
|
1635
|
static inline bool
|
... |
... |
@@ -1628,11 +1646,7 @@ calculate_axis_value(struct xf86libinput *driver_data, |
1628
|
1646
|
|
1629
|
1647
|
source = libinput_event_pointer_get_axis_source(event);
|
1630
|
1648
|
if (source == LIBINPUT_POINTER_AXIS_SOURCE_WHEEL) {
|
1631
|
|
- double scroll_fraction;
|
1632
|
|
-
|
1633
|
|
- value = libinput_event_pointer_get_axis_value_discrete(event, axis);
|
1634
|
|
- scroll_fraction = get_scroll_fraction(driver_data, event, axis);
|
1635
|
|
- value *= driver_data->scroll.vdist/scroll_fraction;
|
|
1649
|
+ value = get_wheel_scroll_value(driver_data, event, axis);
|
1636
|
1650
|
} else {
|
1637
|
1651
|
value = libinput_event_pointer_get_axis_value(event, axis);
|
1638
|
1652
|
}
|
... |
... |
@@ -3401,8 +3415,8 @@ xf86libinput_pre_init(InputDriverPtr drv, |
3401
|
3415
|
* affect touchpad scroll speed. For wheels it doesn't matter as
|
3402
|
3416
|
* we're using the discrete value only.
|
3403
|
3417
|
*/
|
3404
|
|
- driver_data->scroll.vdist = 15;
|
3405
|
|
- driver_data->scroll.hdist = 15;
|
|
3418
|
+ driver_data->scroll.v.dist = 15;
|
|
3419
|
+ driver_data->scroll.h.dist = 15;
|
3406
|
3420
|
|
3407
|
3421
|
if (!is_subdevice) {
|
3408
|
3422
|
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_POINTER))
|
... |
... |
@@ -3624,13 +3638,13 @@ update_mode_prop_cb(ClientPtr client, pointer closure) |
3624
|
3638
|
groups[idx] = mode;
|
3625
|
3639
|
|
3626
|
3640
|
driver_data->allow_mode_group_updates = true;
|
3627
|
|
- rc = XIChangeDeviceProperty(pInfo->dev,
|
3628
|
|
- prop_mode_groups,
|
3629
|
|
- XA_INTEGER, 8,
|
3630
|
|
- PropModeReplace,
|
3631
|
|
- val->size,
|
3632
|
|
- groups,
|
3633
|
|
- TRUE);
|
|
3641
|
+ XIChangeDeviceProperty(pInfo->dev,
|
|
3642
|
+ prop_mode_groups,
|
|
3643
|
+ XA_INTEGER, 8,
|
|
3644
|
+ PropModeReplace,
|
|
3645
|
+ val->size,
|
|
3646
|
+ groups,
|
|
3647
|
+ TRUE);
|
3634
|
3648
|
driver_data->allow_mode_group_updates = false;
|
3635
|
3649
|
|
3636
|
3650
|
out:
|