forked from 12to11/12to11
Fix scroll axis interpolation with the libinput driver
* atoms.c (names, XLInitAtoms): Intern "libinput Scrolling Pixel Distance". * compositor.h: Update atom. * seat.c (struct _DeviceInfo): New field `scroll_pixel_distance'. (UpdateScrollPixelDistance): New function. (RecordDeviceInformation, HandlePropertyChanged): Update that field whenever necessary. (InterpolateAxes, SendScrollAxis): Fix NULL pointer dereference and always interpolate axes by the scroll pixel distance whenever available. (HandleValuatorMotion): Don't scale axis values by 10.
This commit is contained in:
parent
b0db38043a
commit
a220f29723
3 changed files with 76 additions and 18 deletions
6
atoms.c
6
atoms.c
|
@ -111,6 +111,7 @@ static const char *names[] =
|
||||||
"CONNECTOR_ID",
|
"CONNECTOR_ID",
|
||||||
"_NET_WM_PID",
|
"_NET_WM_PID",
|
||||||
"_NET_WM_PING",
|
"_NET_WM_PING",
|
||||||
|
"libinput Scrolling Pixel Distance",
|
||||||
|
|
||||||
/* These are automatically generated from mime.txt. */
|
/* These are automatically generated from mime.txt. */
|
||||||
DirectTransferAtomNames
|
DirectTransferAtomNames
|
||||||
|
@ -133,7 +134,7 @@ Atom _NET_WM_OPAQUE_REGION, _XL_BUFFER_RELEASE, _NET_WM_SYNC_REQUEST_COUNTER,
|
||||||
XdndEnter, XdndPosition, XdndStatus, XdndLeave, XdndDrop, XdndFinished,
|
XdndEnter, XdndPosition, XdndStatus, XdndLeave, XdndDrop, XdndFinished,
|
||||||
_NET_WM_FRAME_TIMINGS, _NET_WM_BYPASS_COMPOSITOR, WM_STATE,
|
_NET_WM_FRAME_TIMINGS, _NET_WM_BYPASS_COMPOSITOR, WM_STATE,
|
||||||
_NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_MENU, _NET_WM_WINDOW_TYPE_DND,
|
_NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_MENU, _NET_WM_WINDOW_TYPE_DND,
|
||||||
CONNECTOR_ID, _NET_WM_PID, _NET_WM_PING;
|
CONNECTOR_ID, _NET_WM_PID, _NET_WM_PING, libinput_Scrolling_Pixel_Distance;
|
||||||
|
|
||||||
XrmQuark resource_quark, app_quark, QString;
|
XrmQuark resource_quark, app_quark, QString;
|
||||||
|
|
||||||
|
@ -290,9 +291,10 @@ XLInitAtoms (void)
|
||||||
CONNECTOR_ID = atoms[61];
|
CONNECTOR_ID = atoms[61];
|
||||||
_NET_WM_PID = atoms[62];
|
_NET_WM_PID = atoms[62];
|
||||||
_NET_WM_PING = atoms[63];
|
_NET_WM_PING = atoms[63];
|
||||||
|
libinput_Scrolling_Pixel_Distance = atoms[64];
|
||||||
|
|
||||||
/* This is automatically generated. */
|
/* This is automatically generated. */
|
||||||
DirectTransferAtomInit (atoms, 64);
|
DirectTransferAtomInit (atoms, 65);
|
||||||
|
|
||||||
/* Now, initialize quarks. */
|
/* Now, initialize quarks. */
|
||||||
resource_quark = XrmPermStringToQuark (compositor.resource_name);
|
resource_quark = XrmPermStringToQuark (compositor.resource_name);
|
||||||
|
|
|
@ -1177,7 +1177,7 @@ extern Atom _NET_WM_OPAQUE_REGION, _XL_BUFFER_RELEASE,
|
||||||
XdndProxy, XdndEnter, XdndPosition, XdndStatus, XdndLeave, XdndDrop,
|
XdndProxy, XdndEnter, XdndPosition, XdndStatus, XdndLeave, XdndDrop,
|
||||||
XdndFinished, _NET_WM_FRAME_TIMINGS, _NET_WM_BYPASS_COMPOSITOR, WM_STATE,
|
XdndFinished, _NET_WM_FRAME_TIMINGS, _NET_WM_BYPASS_COMPOSITOR, WM_STATE,
|
||||||
_NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_MENU, _NET_WM_WINDOW_TYPE_DND,
|
_NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_MENU, _NET_WM_WINDOW_TYPE_DND,
|
||||||
CONNECTOR_ID, _NET_WM_PID, _NET_WM_PING;
|
CONNECTOR_ID, _NET_WM_PID, _NET_WM_PING, libinput_Scrolling_Pixel_Distance;
|
||||||
|
|
||||||
extern XrmQuark resource_quark, app_quark, QString;
|
extern XrmQuark resource_quark, app_quark, QString;
|
||||||
|
|
||||||
|
|
86
seat.c
86
seat.c
|
@ -565,6 +565,9 @@ struct _DeviceInfo
|
||||||
{
|
{
|
||||||
/* Some flags associated with this device. */
|
/* Some flags associated with this device. */
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
|
/* The libinput scroll pixel distance, if available. Else 15. */
|
||||||
|
int scroll_pixel_distance;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SetMask(ptr, event) \
|
#define SetMask(ptr, event) \
|
||||||
|
@ -1918,6 +1921,44 @@ UpdateScrollMethods (DeviceInfo *info, int deviceid)
|
||||||
XFree (data);
|
XFree (data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
UpdateScrollPixelDistance (DeviceInfo *info, int deviceid)
|
||||||
|
{
|
||||||
|
unsigned char *data;
|
||||||
|
Status rc;
|
||||||
|
Atom actual_type;
|
||||||
|
int actual_format;
|
||||||
|
unsigned long nitems, bytes_after;
|
||||||
|
|
||||||
|
data = NULL;
|
||||||
|
|
||||||
|
/* This only works with the libinput driver. */
|
||||||
|
rc = XIGetProperty (compositor.display, deviceid,
|
||||||
|
libinput_Scrolling_Pixel_Distance,
|
||||||
|
0, 1, False, XIAnyPropertyType,
|
||||||
|
&actual_type, &actual_format,
|
||||||
|
&nitems, &bytes_after, &data);
|
||||||
|
|
||||||
|
/* If there aren't enough items in the data, or the format is wrong,
|
||||||
|
return. */
|
||||||
|
if (rc != Success || nitems < 1 || actual_format != 32 || !data)
|
||||||
|
{
|
||||||
|
if (data)
|
||||||
|
XFree (data);
|
||||||
|
|
||||||
|
/* Set the distance to the default, 15. */
|
||||||
|
info->scroll_pixel_distance = 15;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now set the scroll pixel distance. */
|
||||||
|
info->scroll_pixel_distance = ((long *) data)[0];
|
||||||
|
|
||||||
|
/* And free the data. */
|
||||||
|
XLFree (data);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
RecordDeviceInformation (XIDeviceInfo *deviceinfo)
|
RecordDeviceInformation (XIDeviceInfo *deviceinfo)
|
||||||
{
|
{
|
||||||
|
@ -1946,6 +1987,10 @@ RecordDeviceInformation (XIDeviceInfo *deviceinfo)
|
||||||
only works with the libinput driver. */
|
only works with the libinput driver. */
|
||||||
UpdateScrollMethods (info, deviceinfo->deviceid);
|
UpdateScrollMethods (info, deviceinfo->deviceid);
|
||||||
|
|
||||||
|
/* Obtain the "libinput Scrolling Pixel Distance" property and
|
||||||
|
use it if available. If not, default to 15. */
|
||||||
|
UpdateScrollPixelDistance (info, deviceinfo->deviceid);
|
||||||
|
|
||||||
/* Uncatch errors. */
|
/* Uncatch errors. */
|
||||||
UncatchXErrors (NULL);
|
UncatchXErrors (NULL);
|
||||||
}
|
}
|
||||||
|
@ -2602,6 +2647,9 @@ HandlePropertyChanged (XIPropertyEvent *event)
|
||||||
/* Update scroll methods for the device whose property
|
/* Update scroll methods for the device whose property
|
||||||
changed. */
|
changed. */
|
||||||
UpdateScrollMethods (info, event->deviceid);
|
UpdateScrollMethods (info, event->deviceid);
|
||||||
|
else if (event->property == libinput_Scrolling_Pixel_Distance)
|
||||||
|
/* Update the scroll pixel distance. */
|
||||||
|
UpdateScrollPixelDistance (info, event->deviceid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Seat *
|
static Seat *
|
||||||
|
@ -3705,15 +3753,21 @@ FindScrollValuator (Seat *seat, int number)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
InterpolateAxes (Surface *surface, double movement_x,
|
InterpolateAxes (Surface *surface, DeviceInfo *info,
|
||||||
double movement_y, double *x_out,
|
double movement_x, double movement_y,
|
||||||
double *y_out)
|
double *x_out, double *y_out)
|
||||||
{
|
{
|
||||||
/* This is the algorithm used by most programs. */
|
if (!info)
|
||||||
*x_out = movement_x * pow (ViewWidth (surface->view),
|
{
|
||||||
2.0 / 3.0);
|
/* Multiply the deltas by 15 if no device was found. */
|
||||||
*x_out = movement_y * pow (ViewHeight (surface->view),
|
*x_out = movement_x * 15;
|
||||||
2.0 / 3.0);
|
*y_out = movement_y * 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Multiply these deltas by the scrolling pixel distance to obtain
|
||||||
|
the original delta. */
|
||||||
|
*x_out = movement_x * info->scroll_pixel_distance;
|
||||||
|
*y_out = movement_y * info->scroll_pixel_distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -3749,12 +3803,14 @@ SendScrollAxis (Seat *seat, Surface *surface, Time time,
|
||||||
if (wl_resource_get_version (pointer->resource) < 8
|
if (wl_resource_get_version (pointer->resource) < 8
|
||||||
/* Send pixel-wise axis events from devices that are most
|
/* Send pixel-wise axis events from devices that are most
|
||||||
likely touchpads. */
|
likely touchpads. */
|
||||||
|| (deviceinfo->flags & DeviceCanFingerScroll
|
|| (deviceinfo
|
||||||
|| deviceinfo->flags & DeviceCanEdgeScroll))
|
&& (deviceinfo->flags & DeviceCanFingerScroll
|
||||||
|
|| deviceinfo->flags & DeviceCanEdgeScroll)))
|
||||||
{
|
{
|
||||||
/* Interpolate the increment-relative axis values to pixel
|
/* Interpolate the increment-relative axis values to pixel
|
||||||
values. */
|
values. */
|
||||||
InterpolateAxes (surface, axis_x, axis_y, &axis_x, &axis_y);
|
InterpolateAxes (surface, deviceinfo, axis_x, axis_y,
|
||||||
|
&axis_x, &axis_y);
|
||||||
|
|
||||||
if (axis_x != 0.0)
|
if (axis_x != 0.0)
|
||||||
wl_pointer_send_axis (pointer->resource, time,
|
wl_pointer_send_axis (pointer->resource, time,
|
||||||
|
@ -3774,12 +3830,12 @@ SendScrollAxis (Seat *seat, Surface *surface, Time time,
|
||||||
if (axis_x != 0.0)
|
if (axis_x != 0.0)
|
||||||
wl_pointer_send_axis_value120 (pointer->resource,
|
wl_pointer_send_axis_value120 (pointer->resource,
|
||||||
WL_POINTER_AXIS_HORIZONTAL_SCROLL,
|
WL_POINTER_AXIS_HORIZONTAL_SCROLL,
|
||||||
axis_x * 12);
|
axis_x * 120);
|
||||||
|
|
||||||
if (axis_y != 0.0)
|
if (axis_y != 0.0)
|
||||||
wl_pointer_send_axis_value120 (pointer->resource,
|
wl_pointer_send_axis_value120 (pointer->resource,
|
||||||
WL_POINTER_AXIS_VERTICAL_SCROLL,
|
WL_POINTER_AXIS_VERTICAL_SCROLL,
|
||||||
axis_y * 12);
|
axis_y * 120);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (axis_y == 0.0 && axis_x == 0.0)
|
if (axis_y == 0.0 && axis_x == 0.0)
|
||||||
|
@ -3862,8 +3918,8 @@ HandleValuatorMotion (Seat *seat, Surface *dispatch, double x, double y,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value && dispatch)
|
if (value && dispatch)
|
||||||
SendScrollAxis (seat, dispatch, event->time, x, y,
|
SendScrollAxis (seat, dispatch, event->time, x, y, total_x,
|
||||||
total_x * 10, total_y * 10, flags,
|
total_y, flags,
|
||||||
/* Also pass the event source device ID, which is
|
/* Also pass the event source device ID, which is
|
||||||
used in an attempt to determine the axis
|
used in an attempt to determine the axis
|
||||||
source. */
|
source. */
|
||||||
|
|
Loading…
Add table
Reference in a new issue