Fix massive scroll on focus return by resetting X11 scroll valuators on focus loss
When kitty loses focus and the user scrolls in another application, X11 XI scroll valuators accumulate position values. When the user returns to kitty and scrolls, delta (value - v->value) uses the stale pre-focus-loss value, causing a massive unexpected scroll jump. Fix: reset scroll valuators (mark them uninitialized) on FocusOut so the first scroll event after focus is regained sets the baseline without firing a scroll event. Fixes #9703 Fixes #9707
This commit is contained in:
parent
7c8e797985
commit
36be8be951
3 changed files with 17 additions and 2 deletions
2
glfw/x11_init.c
vendored
2
glfw/x11_init.c
vendored
|
|
@ -247,7 +247,7 @@ read_xi_scroll_devices(void) {
|
|||
}
|
||||
if (!v) continue;
|
||||
v->value = vi->value; v->mode = vi->mode; v->resolution = vi->resolution;
|
||||
v->min = vi->min; v->max = vi->max;
|
||||
v->min = vi->min; v->max = vi->max; v->initialized = true;
|
||||
}
|
||||
}
|
||||
XIFreeDeviceInfo(devices);
|
||||
|
|
|
|||
2
glfw/x11_platform.h
vendored
2
glfw/x11_platform.h
vendored
|
|
@ -235,7 +235,7 @@ typedef struct AtomArray {
|
|||
} AtomArray;
|
||||
|
||||
typedef struct XIScrollValuator {
|
||||
double increment, value, min, max; int number, resolution, mode; bool is_vertical;
|
||||
double increment, value, min, max; int number, resolution, mode; bool is_vertical, initialized;
|
||||
} XIScrollValuator;
|
||||
|
||||
typedef struct XIScrollDevice {
|
||||
|
|
|
|||
15
glfw/x11_window.c
vendored
15
glfw/x11_window.c
vendored
|
|
@ -553,6 +553,15 @@ static void enableSmoothScrolling(_GLFWwindow* window)
|
|||
XISelectEvents(_glfw.x11.display, window->x11.handle, &em, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
resetScrollValuators(void) {
|
||||
for (unsigned i = 0; i < _glfw.x11.xi.num_scroll_devices; i++) {
|
||||
XIScrollDevice *d = &_glfw.x11.xi.scroll_devices[i];
|
||||
for (unsigned k = 0; k < d->num_valuators; k++)
|
||||
d->valuators[k].initialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Apply disabled cursor mode to a focused window
|
||||
//
|
||||
static void disableCursor(_GLFWwindow* window)
|
||||
|
|
@ -1445,6 +1454,11 @@ handle_xi_motion_event(_GLFWwindow *window, XIDeviceEvent *de) {
|
|||
}
|
||||
if (!v) continue;
|
||||
scroll_valuator_found = true;
|
||||
if (!v->initialized) {
|
||||
v->initialized = true;
|
||||
v->value = value;
|
||||
continue;
|
||||
}
|
||||
double delta = value - v->value;
|
||||
v->value = value;
|
||||
delta *= -1;
|
||||
|
|
@ -2344,6 +2358,7 @@ static void processEvent(XEvent *event)
|
|||
if (window->monitor && window->autoIconify)
|
||||
_glfwPlatformIconifyWindow(window);
|
||||
|
||||
resetScrollValuators();
|
||||
_glfwInputWindowFocus(window, false);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue