feat(trackpad): add safeguards to prevent cursor jumping

This commit is contained in:
Florian Didron
2025-12-04 15:04:12 +07:00
parent 28aae38c6b
commit fa4f335051
2 changed files with 25 additions and 12 deletions

View File

@@ -426,15 +426,18 @@ report_mouse_t navigator_trackpad_get_report(report_mouse_t mouse_report) {
#endif #endif
#if defined(NAVIGATOR_TRACKPAD_PTP_MODE) #if defined(NAVIGATOR_TRACKPAD_PTP_MODE)
uint8_t fingers = finger_count(&ptp_report); // Create local snapshot to avoid race condition with callback updating ptp_report
bool is_touching = ptp_report.fingers[0].tip; cgen6_report_t local_report = ptp_report;
uint8_t fingers = finger_count(&local_report);
bool is_touching = local_report.fingers[0].tip;
bool was_idle = (gesture.state == TP_IDLE); bool was_idle = (gesture.state == TP_IDLE);
// Handle finger down - record start position (regardless of current state) // Handle finger down - record start position (regardless of current state)
if (is_touching && was_idle) { if (is_touching && was_idle) {
gesture.touch_start_time = timer_read(); gesture.touch_start_time = timer_read();
gesture.prev_x = ptp_report.fingers[0].x; gesture.prev_x = local_report.fingers[0].x;
gesture.prev_y = ptp_report.fingers[0].y; gesture.prev_y = local_report.fingers[0].y;
gesture.settled_x = 0; // Will be set after settle time gesture.settled_x = 0; // Will be set after settle time
gesture.settled_y = 0; gesture.settled_y = 0;
gesture.settled = false; gesture.settled = false;
@@ -523,15 +526,15 @@ report_mouse_t navigator_trackpad_get_report(report_mouse_t mouse_report) {
// Record settled position once settle time elapses // Record settled position once settle time elapses
if (!gesture.settled && duration >= NAVIGATOR_TRACKPAD_TAP_SETTLE_TIME) { if (!gesture.settled && duration >= NAVIGATOR_TRACKPAD_TAP_SETTLE_TIME) {
gesture.settled = true; gesture.settled = true;
gesture.settled_x = ptp_report.fingers[0].x; gesture.settled_x = local_report.fingers[0].x;
gesture.settled_y = ptp_report.fingers[0].y; gesture.settled_y = local_report.fingers[0].y;
} }
// Check if we should suppress movement (might still be a tap) // Check if we should suppress movement (might still be a tap)
int32_t dist_sq = 0; int32_t dist_sq = 0;
if (gesture.settled) { if (gesture.settled) {
int16_t dx = ptp_report.fingers[0].x - gesture.settled_x; int16_t dx = local_report.fingers[0].x - gesture.settled_x;
int16_t dy = ptp_report.fingers[0].y - gesture.settled_y; int16_t dy = local_report.fingers[0].y - gesture.settled_y;
dist_sq = (int32_t)dx * dx + (int32_t)dy * dy; dist_sq = (int32_t)dx * dx + (int32_t)dy * dy;
} }
@@ -540,8 +543,14 @@ report_mouse_t navigator_trackpad_get_report(report_mouse_t mouse_report) {
(gesture.settled && dist_sq > NAVIGATOR_TRACKPAD_TAP_MOVE_THRESHOLD); (gesture.settled && dist_sq > NAVIGATOR_TRACKPAD_TAP_MOVE_THRESHOLD);
if (should_move) { if (should_move) {
int16_t delta_x = ptp_report.fingers[0].x - gesture.prev_x; int16_t delta_x = local_report.fingers[0].x - gesture.prev_x;
int16_t delta_y = ptp_report.fingers[0].y - gesture.prev_y; int16_t delta_y = local_report.fingers[0].y - gesture.prev_y;
// Clamp deltas to prevent jumps from bad data
if (delta_x > NAVIGATOR_TRACKPAD_MAX_DELTA) delta_x = NAVIGATOR_TRACKPAD_MAX_DELTA;
if (delta_x < -NAVIGATOR_TRACKPAD_MAX_DELTA) delta_x = -NAVIGATOR_TRACKPAD_MAX_DELTA;
if (delta_y > NAVIGATOR_TRACKPAD_MAX_DELTA) delta_y = NAVIGATOR_TRACKPAD_MAX_DELTA;
if (delta_y < -NAVIGATOR_TRACKPAD_MAX_DELTA) delta_y = -NAVIGATOR_TRACKPAD_MAX_DELTA;
if (delta_x != 0 || delta_y != 0) { if (delta_x != 0 || delta_y != 0) {
# ifdef NAVIGATOR_TRACKPAD_SCROLL_WITH_TWO_FINGERS # ifdef NAVIGATOR_TRACKPAD_SCROLL_WITH_TWO_FINGERS
@@ -607,8 +616,8 @@ report_mouse_t navigator_trackpad_get_report(report_mouse_t mouse_report) {
} }
} }
gesture.prev_x = ptp_report.fingers[0].x; gesture.prev_x = local_report.fingers[0].x;
gesture.prev_y = ptp_report.fingers[0].y; gesture.prev_y = local_report.fingers[0].y;
} }
#endif #endif

View File

@@ -43,6 +43,10 @@
# define NAVIGATOR_TRACKPAD_TAP_SETTLE_TIME 30 // Ignore movement during initial contact (ms) # define NAVIGATOR_TRACKPAD_TAP_SETTLE_TIME 30 // Ignore movement during initial contact (ms)
#endif #endif
#ifndef NAVIGATOR_TRACKPAD_MAX_DELTA
# define NAVIGATOR_TRACKPAD_MAX_DELTA 250 // Max allowed delta per frame to prevent jumps
#endif
#ifndef NAVIGATOR_TRACKPAD_ADDRESS #ifndef NAVIGATOR_TRACKPAD_ADDRESS
# define NAVIGATOR_TRACKPAD_ADDRESS 0x58 # define NAVIGATOR_TRACKPAD_ADDRESS 0x58
#endif #endif