mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-06-26 19:01:27 +00:00
Cleanup X11 momentum-scroll
Dont cancel on the synthetic key events x11 generates for scrolling. Also use correct timestamp for duration and expiry of physical events.
This commit is contained in:
parent
cac2c6d2f9
commit
d0249c1e72
3 changed files with 37 additions and 23 deletions
5
glfw/internal.h
vendored
5
glfw/internal.h
vendored
|
|
@ -887,6 +887,11 @@ MonitorGeometry _glfwPlatformGetMonitorGeometry(_GLFWmonitor* monitor);
|
|||
bool _glfwPlatformGrabKeyboard(bool grab);
|
||||
void glfw_handle_scroll_event_for_momentum(_GLFWwindow *w, const GLFWScrollEvent *ev, bool stopped, bool is_finger_based);
|
||||
#define glfw_cancel_momentum_scroll() glfw_handle_scroll_event_for_momentum(NULL, NULL, false, false)
|
||||
#ifdef _GLFW_X11
|
||||
#define momentum_scroll_gesture_detection_timeout_ms 50
|
||||
#else
|
||||
#define momentum_scroll_gesture_detection_timeout_ms 0
|
||||
#endif
|
||||
|
||||
char* _glfw_strdup(const char* source);
|
||||
|
||||
|
|
|
|||
13
glfw/momentum-scroll.c
vendored
13
glfw/momentum-scroll.c
vendored
|
|
@ -147,6 +147,7 @@ send_momentum_event(bool is_start) {
|
|||
m = GLFW_MOMENTUM_PHASE_ENDED;
|
||||
if (s.timer_id) glfwRemoveTimer(s.timer_id);
|
||||
s.timer_id = 0;
|
||||
s.state = NONE;
|
||||
}
|
||||
GLFWScrollEvent e = {
|
||||
.offset_type=GLFW_SCROLL_OFFEST_HIGHRES, .momentum_type=m, .unscaled.x=s.velocity.x, .unscaled.y=s.velocity.y,
|
||||
|
|
@ -179,12 +180,14 @@ void
|
|||
glfw_handle_scroll_event_for_momentum(
|
||||
_GLFWwindow *w, const GLFWScrollEvent *ev, bool stopped, bool is_finger_based
|
||||
) {
|
||||
const bool is_synthetic_momentum_start_event = stopped && momentum_scroll_gesture_detection_timeout_ms;
|
||||
if (!w) { cancel_existing_scroll(true); return; }
|
||||
if (!is_finger_based || ev->offset_type != GLFW_SCROLL_OFFEST_HIGHRES || s.friction < 0 || s.friction >= 1) {
|
||||
_glfwInputScroll(w, ev);
|
||||
return;
|
||||
}
|
||||
monotonic_t now = monotonic();
|
||||
if (is_synthetic_momentum_start_event) now -= ms_to_monotonic_t(momentum_scroll_gesture_detection_timeout_ms);
|
||||
if (s.state == PHYSICAL_EVENT_IN_PROGRESS) {
|
||||
s.physical_event.displacement.x += ev->unscaled.x;
|
||||
s.physical_event.displacement.y += ev->unscaled.y;
|
||||
|
|
@ -200,13 +203,15 @@ glfw_handle_scroll_event_for_momentum(
|
|||
else if (ev->unscaled.x > 0) s.scale = ev->x_offset / ev->unscaled.x;
|
||||
if (s.window_id && s.window_id != w->id) cancel_existing_scroll(true);
|
||||
if (s.state != PHYSICAL_EVENT_IN_PROGRESS) cancel_existing_scroll(false);
|
||||
// Check for change in direction
|
||||
double ldx, ldy; last_sample_delta(&ldx, &ldy);
|
||||
if (ldx * ev->x_offset < 0 || ldy * ev->y_offset < 0) cancel_existing_scroll(true);
|
||||
if (!is_synthetic_momentum_start_event) {
|
||||
// Check for change in direction
|
||||
double ldx, ldy; last_sample_delta(&ldx, &ldy);
|
||||
if (ldx * ev->x_offset < 0 || ldy * ev->y_offset < 0) cancel_existing_scroll(true);
|
||||
}
|
||||
s.window_id = w->id;
|
||||
s.keyboard_modifiers = ev->keyboard_modifiers;
|
||||
if (ev->offset_type == GLFW_SCROLL_OFFEST_HIGHRES) {
|
||||
add_sample(ev->unscaled.x, ev->unscaled.y, now);
|
||||
if (!is_synthetic_momentum_start_event) add_sample(ev->unscaled.x, ev->unscaled.y, now);
|
||||
if (stopped) s.state = is_suitable_for_momentum() ? MOMENTUM_IN_PROGRESS : NONE;
|
||||
else s.state = PHYSICAL_EVENT_IN_PROGRESS;
|
||||
} else {
|
||||
|
|
|
|||
42
glfw/x11_window.c
vendored
42
glfw/x11_window.c
vendored
|
|
@ -52,7 +52,6 @@
|
|||
static struct {
|
||||
unsigned long long timer_id;
|
||||
GLFWid window_id;
|
||||
bool is_finger_based;
|
||||
GLFWScrollEvent last_event;
|
||||
} x11_momentum_scroll_state = {0};
|
||||
|
||||
|
|
@ -61,13 +60,13 @@ x11_scroll_stop_timer_callback(unsigned long long timer_id UNUSED, void *data UN
|
|||
x11_momentum_scroll_state.timer_id = 0;
|
||||
_GLFWwindow *w = _glfwWindowForId(x11_momentum_scroll_state.window_id);
|
||||
if (w) {
|
||||
glfw_handle_scroll_event_for_momentum(
|
||||
w, &x11_momentum_scroll_state.last_event, true, x11_momentum_scroll_state.is_finger_based);
|
||||
x11_momentum_scroll_state.last_event.y_offset = 0; x11_momentum_scroll_state.last_event.x_offset = 0;
|
||||
x11_momentum_scroll_state.last_event.unscaled.x = 0; x11_momentum_scroll_state.last_event.unscaled.y = 0;
|
||||
glfw_handle_scroll_event_for_momentum(w, &x11_momentum_scroll_state.last_event, true, true);
|
||||
} else {
|
||||
// Window no longer exists, cancel any ongoing momentum
|
||||
glfw_cancel_momentum_scroll();
|
||||
}
|
||||
x11_momentum_scroll_state.window_id = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1375,16 +1374,16 @@ handle_xi_motion_event(_GLFWwindow *window, XIDeviceEvent *de) {
|
|||
if (d->is_highres && d->is_finger_based && type == GLFW_SCROLL_OFFEST_HIGHRES) {
|
||||
// Reset the timer on each scroll event
|
||||
x11_cancel_momentum_scroll_timer();
|
||||
|
||||
|
||||
// Store the event for later use when timer fires
|
||||
x11_momentum_scroll_state.window_id = window->id;
|
||||
x11_momentum_scroll_state.is_finger_based = true;
|
||||
x11_momentum_scroll_state.last_event = ev;
|
||||
|
||||
// Start timer (100ms after last scroll event)
|
||||
|
||||
// Start timer
|
||||
x11_momentum_scroll_state.timer_id = glfwAddTimer(
|
||||
ms_to_monotonic_t(100), false, x11_scroll_stop_timer_callback, NULL, NULL);
|
||||
|
||||
ms_to_monotonic_t(momentum_scroll_gesture_detection_timeout_ms), false,
|
||||
x11_scroll_stop_timer_callback, NULL, NULL);
|
||||
|
||||
// Send the scroll event through momentum handler
|
||||
glfw_handle_scroll_event_for_momentum(window, &ev, false, true);
|
||||
} else {
|
||||
|
|
@ -1613,16 +1612,18 @@ static void processEvent(XEvent *event)
|
|||
{
|
||||
const int mods = translateState(event->xbutton.state);
|
||||
|
||||
// Cancel momentum scrolling on any button press
|
||||
x11_cancel_momentum_scroll_timer();
|
||||
glfw_cancel_momentum_scroll();
|
||||
#define cancel_momentum() x11_cancel_momentum_scroll_timer(); glfw_cancel_momentum_scroll()
|
||||
|
||||
if (event->xbutton.button == Button1)
|
||||
if (event->xbutton.button == Button1) {
|
||||
cancel_momentum();
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS, mods);
|
||||
else if (event->xbutton.button == Button2)
|
||||
} else if (event->xbutton.button == Button2) {
|
||||
cancel_momentum();
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS, mods);
|
||||
else if (event->xbutton.button == Button3)
|
||||
} else if (event->xbutton.button == Button3) {
|
||||
cancel_momentum();
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS, mods);
|
||||
}
|
||||
|
||||
// Modern X provides scroll events as mouse button presses
|
||||
// Only use these if smooth scrolling is not available
|
||||
|
|
@ -1649,6 +1650,7 @@ static void processEvent(XEvent *event)
|
|||
|
||||
else
|
||||
{
|
||||
cancel_momentum();
|
||||
// Additional buttons after 7 are treated as regular buttons
|
||||
// We subtract 4 to fill the gap left by scroll input above
|
||||
_glfwInputMouseClick(window,
|
||||
|
|
@ -1664,12 +1666,10 @@ static void processEvent(XEvent *event)
|
|||
{
|
||||
const int mods = translateState(event->xbutton.state);
|
||||
|
||||
// Cancel momentum scrolling on any button release
|
||||
x11_cancel_momentum_scroll_timer();
|
||||
glfw_cancel_momentum_scroll();
|
||||
|
||||
if (event->xbutton.button == Button1)
|
||||
{
|
||||
cancel_momentum();
|
||||
_glfwInputMouseClick(window,
|
||||
GLFW_MOUSE_BUTTON_LEFT,
|
||||
GLFW_RELEASE,
|
||||
|
|
@ -1677,6 +1677,7 @@ static void processEvent(XEvent *event)
|
|||
}
|
||||
else if (event->xbutton.button == Button2)
|
||||
{
|
||||
cancel_momentum();
|
||||
_glfwInputMouseClick(window,
|
||||
GLFW_MOUSE_BUTTON_MIDDLE,
|
||||
GLFW_RELEASE,
|
||||
|
|
@ -1684,6 +1685,7 @@ static void processEvent(XEvent *event)
|
|||
}
|
||||
else if (event->xbutton.button == Button3)
|
||||
{
|
||||
cancel_momentum();
|
||||
_glfwInputMouseClick(window,
|
||||
GLFW_MOUSE_BUTTON_RIGHT,
|
||||
GLFW_RELEASE,
|
||||
|
|
@ -1691,6 +1693,7 @@ static void processEvent(XEvent *event)
|
|||
}
|
||||
else if (event->xbutton.button > Button7)
|
||||
{
|
||||
cancel_momentum();
|
||||
// Additional buttons after 7 are treated as regular buttons
|
||||
// We subtract 4 to fill the gap left by scroll input above
|
||||
_glfwInputMouseClick(window,
|
||||
|
|
@ -1700,6 +1703,7 @@ static void processEvent(XEvent *event)
|
|||
}
|
||||
|
||||
return;
|
||||
#undef cancel_momentum
|
||||
}
|
||||
|
||||
case EnterNotify:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue