mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-08-04 06:36:24 +00:00
Make XI2 scroll offset type detection more robust
Since we have to use heuristics, lets at least collect stats for a few events before deciding.
This commit is contained in:
parent
99639f1373
commit
c0b549fee8
3 changed files with 37 additions and 15 deletions
6
glfw/x11_init.c
vendored
6
glfw/x11_init.c
vendored
|
|
@ -216,8 +216,12 @@ read_xi_scroll_devices(void) {
|
|||
if (_glfw.x11.xi.num_scroll_devices >= arraysz(_glfw.x11.xi.scroll_devices)) continue;
|
||||
d = &_glfw.x11.xi.scroll_devices[_glfw.x11.xi.num_scroll_devices++];
|
||||
*d = (XIScrollDevice){
|
||||
.is_highres=is_highres, .is_finger_based=is_finger_based, .deviceid=device->deviceid, .sourceid=scroll->sourceid,
|
||||
.is_finger_based=is_finger_based, .deviceid=device->deviceid, .sourceid=scroll->sourceid,
|
||||
};
|
||||
if (is_highres) {
|
||||
d->type_detected = true;
|
||||
d->offset_type = GLFW_SCROLL_OFFEST_HIGHRES;
|
||||
}
|
||||
memcpy(d->name, device->name, MIN(sizeof(d->name)-1, strlen(device->name)));
|
||||
}
|
||||
if (d->num_valuators >= arraysz(d->valuators)) continue;
|
||||
|
|
|
|||
4
glfw/x11_platform.h
vendored
4
glfw/x11_platform.h
vendored
|
|
@ -239,12 +239,14 @@ typedef struct XIScrollValuator {
|
|||
} XIScrollValuator;
|
||||
|
||||
typedef struct XIScrollDevice {
|
||||
bool is_highres;
|
||||
bool is_finger_based;
|
||||
bool type_detected;
|
||||
int deviceid, sourceid;
|
||||
XIScrollValuator valuators[8];
|
||||
unsigned num_valuators;
|
||||
char name[32];
|
||||
unsigned num_events;
|
||||
GLFWOffsetType offset_type;
|
||||
} XIScrollDevice;
|
||||
|
||||
typedef struct XdndSelectionRequest {
|
||||
|
|
|
|||
42
glfw/x11_window.c
vendored
42
glfw/x11_window.c
vendored
|
|
@ -1415,6 +1415,11 @@ handle_mouse_move_event(_GLFWwindow *window, const int x, const int y) {
|
|||
window->x11.lastCursorPosY = y;
|
||||
}
|
||||
|
||||
static bool
|
||||
number_has_fractional_part(double x) {
|
||||
return fabs(x - round(x)) >= 1e-6;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_xi_motion_event(_GLFWwindow *window, XIDeviceEvent *de) {
|
||||
XIScrollDevice *d = NULL;
|
||||
|
|
@ -1442,24 +1447,35 @@ handle_xi_motion_event(_GLFWwindow *window, XIDeviceEvent *de) {
|
|||
scroll_valuator_found = true;
|
||||
double delta = value - v->value;
|
||||
v->value = value;
|
||||
if (v->is_vertical) delta *= -1;
|
||||
delta *= -1;
|
||||
double *off = v->is_vertical ? &yOffset : &xOffset;
|
||||
*off = delta;
|
||||
if (!d->is_highres) {
|
||||
if (v->increment == 120.) type = GLFW_SCROLL_OFFEST_V120;
|
||||
else {
|
||||
// XInput2 has no reliable way to distinguish high res scroll devices so we
|
||||
// assume that if fractional values are seen it must be high res. Sigh, Linux, the
|
||||
// land of truly wondrous wonders. See https://github.com/kovidgoyal/kitty/issues/9649
|
||||
double int_part; bool delta_is_fractional = modf(delta, &int_part) != 0.;
|
||||
if (delta_is_fractional) d->is_highres = true;
|
||||
else {
|
||||
type = GLFW_SCROLL_OFFSET_LINES;
|
||||
if (v->increment != 0) *off /= v->increment;
|
||||
d->num_events++;
|
||||
if (!d->type_detected) {
|
||||
if (v->increment == 120.) {
|
||||
d->type_detected = true;
|
||||
d->offset_type = GLFW_SCROLL_OFFEST_V120;
|
||||
} else {
|
||||
bool delta_is_fractional = number_has_fractional_part(delta);
|
||||
if (delta_is_fractional) {
|
||||
if (fabs(delta * 120 - round(delta * 120)) < 0.01) {
|
||||
d->type_detected = d->num_events > 2;
|
||||
d->offset_type = GLFW_SCROLL_OFFEST_V120;
|
||||
} else {
|
||||
d->type_detected = true;
|
||||
d->offset_type = GLFW_SCROLL_OFFEST_HIGHRES;
|
||||
}
|
||||
} else {
|
||||
d->type_detected = d->num_events > 2;
|
||||
d->offset_type = GLFW_SCROLL_OFFSET_LINES;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (d->offset_type == GLFW_SCROLL_OFFSET_LINES) {
|
||||
if (v->increment != 0) *off /= v->increment;
|
||||
}
|
||||
}
|
||||
type = d->offset_type;
|
||||
if (xOffset != 0 || yOffset != 0) {
|
||||
// Get keyboard modifiers
|
||||
int mods = translateState(de->mods.effective);
|
||||
|
|
@ -1473,7 +1489,7 @@ handle_xi_motion_event(_GLFWwindow *window, XIDeviceEvent *de) {
|
|||
};
|
||||
|
||||
// For high-resolution, finger-based scrolling, use timer-based momentum scrolling
|
||||
if (d->is_highres && d->is_finger_based && type == GLFW_SCROLL_OFFEST_HIGHRES) {
|
||||
if (d->is_finger_based && type == GLFW_SCROLL_OFFEST_HIGHRES) {
|
||||
// Reset the timer on each scroll event
|
||||
x11_cancel_momentum_scroll_timer();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue