feat(trackpad): macos scroll resolution hid descriptor
Some checks failed
Build firmware / build-firmware (default) (push) Failing after 2s
Build firmware / build-firmware (oryx) (push) Failing after 2s

This commit is contained in:
Florian
2025-12-05 16:37:56 +07:00
parent b246a7de74
commit 29ee055e25
4 changed files with 61 additions and 65 deletions

View File

@@ -357,36 +357,19 @@ report_mouse_t navigator_trackpad_get_report(report_mouse_t mouse_report) {
scroll_inertia.vy -= friction_y;
// Convert Q8 velocity to scroll value
# ifdef NAVIGATOR_TRACKPAD_MACOS_SCROLLING
// macOS mode: send raw velocity deltas (descriptor tells macOS the resolution)
int16_t scroll_x = scroll_inertia.vx / 256;
int16_t scroll_y = scroll_inertia.vy / 256;
# else
// Hi-res mode: apply multiplier for Windows/Linux
int16_t scroll_x = (scroll_inertia.vx * NAVIGATOR_TRACKPAD_SCROLL_MULTIPLIER) / 256;
int16_t scroll_y = (scroll_inertia.vy * NAVIGATOR_TRACKPAD_SCROLL_MULTIPLIER) / 256;
# endif
# ifdef NAVIGATOR_TRACKPAD_MACOS_SCROLLING
// macOS mode: accumulate scroll and only output when threshold is crossed
macos_scroll_accumulated_h += (float)scroll_x / NAVIGATOR_TRACKPAD_MACOS_SCROLL_DIVIDER;
macos_scroll_accumulated_v += (float)scroll_y / NAVIGATOR_TRACKPAD_MACOS_SCROLL_DIVIDER;
float abs_h = (macos_scroll_accumulated_h < 0) ? -macos_scroll_accumulated_h : macos_scroll_accumulated_h;
float abs_v = (macos_scroll_accumulated_v < 0) ? -macos_scroll_accumulated_v : macos_scroll_accumulated_v;
// Only output scroll when accumulated value crosses 1.0
if (abs_h >= 1.0f) {
scroll_x = (macos_scroll_accumulated_h > 0) ? 1 : -1;
macos_scroll_accumulated_h -= (macos_scroll_accumulated_h > 0) ? 1.0f : -1.0f;
} else {
scroll_x = 0;
}
if (abs_v >= 1.0f) {
scroll_y = (macos_scroll_accumulated_v > 0) ? 1 : -1;
macos_scroll_accumulated_v -= (macos_scroll_accumulated_v > 0) ? 1.0f : -1.0f;
} else {
scroll_y = 0;
}
# else
// Hi-res mode: clamp to int8_t range
// Clamp to int8_t range
scroll_x = (scroll_x > 127) ? 127 : ((scroll_x < -127) ? -127 : scroll_x);
scroll_y = (scroll_y > 127) ? 127 : ((scroll_y < -127) ? -127 : scroll_y);
# endif
// Check if velocity is too low to continue
int16_t abs_vx = scroll_inertia.vx < 0 ? -scroll_inertia.vx : scroll_inertia.vx;
@@ -604,11 +587,17 @@ report_mouse_t navigator_trackpad_get_report(report_mouse_t mouse_report) {
if (delta_x != 0 || delta_y != 0) {
# ifdef NAVIGATOR_TRACKPAD_SCROLL_WITH_TWO_FINGERS
if (gesture.state == TP_SCROLLING) {
// Two-finger scroll: output directly to h/v for high-res scrolling
// With high-res scrolling enabled, the OS divides by 120 to get ticks
// Apply multiplier to adjust scroll speed
# ifdef NAVIGATOR_TRACKPAD_MACOS_SCROLLING
// macOS mode: send raw deltas, macOS handles scaling via HIDScrollResolution
// Apple trackpads report raw sensor deltas and let macOS apply acceleration
int16_t scroll_x = delta_x;
int16_t scroll_y = delta_y;
# else
// Hi-res mode: apply multiplier for Windows/Linux
// These OSes divide by the Resolution Multiplier (120)
int16_t scroll_x = delta_x * NAVIGATOR_TRACKPAD_SCROLL_MULTIPLIER;
int16_t scroll_y = delta_y * NAVIGATOR_TRACKPAD_SCROLL_MULTIPLIER;
# endif
# ifdef NAVIGATOR_TRACKPAD_SCROLL_INERTIA_ENABLE
// Track velocity for inertia using exponential smoothing (Q8 fixed point)
@@ -638,34 +627,9 @@ report_mouse_t navigator_trackpad_get_report(report_mouse_t mouse_report) {
}
# endif
# ifdef NAVIGATOR_TRACKPAD_MACOS_SCROLLING
// macOS mode: accumulate scroll and only output when threshold is crossed
// This provides fine-grained speed control via the divider
macos_scroll_accumulated_h += (float)scroll_x / NAVIGATOR_TRACKPAD_MACOS_SCROLL_DIVIDER;
macos_scroll_accumulated_v += (float)scroll_y / NAVIGATOR_TRACKPAD_MACOS_SCROLL_DIVIDER;
float abs_h = (macos_scroll_accumulated_h < 0) ? -macos_scroll_accumulated_h : macos_scroll_accumulated_h;
float abs_v = (macos_scroll_accumulated_v < 0) ? -macos_scroll_accumulated_v : macos_scroll_accumulated_v;
// Only output scroll when accumulated value crosses 1.0
if (abs_h >= 1.0f) {
scroll_x = (macos_scroll_accumulated_h > 0) ? 1 : -1;
macos_scroll_accumulated_h -= (macos_scroll_accumulated_h > 0) ? 1.0f : -1.0f;
} else {
scroll_x = 0;
}
if (abs_v >= 1.0f) {
scroll_y = (macos_scroll_accumulated_v > 0) ? 1 : -1;
macos_scroll_accumulated_v -= (macos_scroll_accumulated_v > 0) ? 1.0f : -1.0f;
} else {
scroll_y = 0;
}
# else
// Hi-res mode: clamp to int8_t range for the report
// Clamp to int8_t range for the report
scroll_x = (scroll_x > 127) ? 127 : ((scroll_x < -127) ? -127 : scroll_x);
scroll_y = (scroll_y > 127) ? 127 : ((scroll_y < -127) ? -127 : scroll_y);
# endif
// Apply scroll inversion if configured
# ifdef NAVIGATOR_SCROLL_INVERT_X

View File

@@ -88,19 +88,12 @@
// #define NAVIGATOR_TRACKPAD_SCROLL_WITH_TWO_FINGERS
// macOS scrolling mode (define to enable)
// macOS doesn't respect the HID Resolution Multiplier descriptor and expects
// small 1/-1 scroll reports instead. Enable this for macOS compatibility.
// When enabled, scroll values are normalized to 1/-1 with accumulation for smooth control.
// When disabled (default), uses hi-res scrolling with POINTING_DEVICE_HIRES_SCROLL_ENABLE
// macOS doesn't respect the HID Resolution Multiplier descriptor.
// When enabled, sends raw scroll deltas without the multiplier (like Apple trackpads).
// macOS applies its own HIDScrollResolution (400 DPI) and acceleration curves.
// When disabled (default), applies multiplier for Windows/Linux hi-res scrolling.
// #define NAVIGATOR_TRACKPAD_MACOS_SCROLLING
// macOS scroll speed divider (higher = slower, default: 60)
// Only used when NAVIGATOR_TRACKPAD_MACOS_SCROLLING is enabled
// Adjust this value to control scroll speed on macOS
#ifndef NAVIGATOR_TRACKPAD_MACOS_SCROLL_DIVIDER
# define NAVIGATOR_TRACKPAD_MACOS_SCROLL_DIVIDER 60
#endif
// Scroll inversion configuration
// Define these to invert scroll direction on respective axes
// #define NAVIGATOR_SCROLL_INVERT_X

View File

@@ -195,6 +195,20 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
HID_RI_LOGICAL_MAXIMUM(16, 32767),
HID_RI_REPORT_COUNT(8, 0x01),
HID_RI_REPORT_SIZE(8, 0x10),
# endif
# ifdef POINTING_DEVICE_MACOS_SCROLL_RESOLUTION
// Add physical units for macOS scrolling
HID_RI_UNIT(8, 0x13), // English Linear (inches)
HID_RI_UNIT_EXPONENT(8, -4), // 10^-4 scale
# ifndef WHEEL_EXTENDED_REPORT
// Calculate: (127 / UNITS_PER_INCH) * 10000 for 10^-4 scale
HID_RI_PHYSICAL_MINIMUM(16, -(1270000 / POINTING_DEVICE_MACOS_SCROLL_UNITS_PER_INCH)),
HID_RI_PHYSICAL_MAXIMUM(16, (1270000 / POINTING_DEVICE_MACOS_SCROLL_UNITS_PER_INCH)),
# else
// Calculate: (32767 / UNITS_PER_INCH) * 10000 for 10^-4 scale
HID_RI_PHYSICAL_MINIMUM(16, -(327670000 / POINTING_DEVICE_MACOS_SCROLL_UNITS_PER_INCH)),
HID_RI_PHYSICAL_MAXIMUM(16, (327670000 / POINTING_DEVICE_MACOS_SCROLL_UNITS_PER_INCH)),
# endif
# endif
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
@@ -211,6 +225,20 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
HID_RI_LOGICAL_MAXIMUM(16, 32767),
HID_RI_REPORT_COUNT(8, 0x01),
HID_RI_REPORT_SIZE(8, 0x10),
# endif
# ifdef POINTING_DEVICE_MACOS_SCROLL_RESOLUTION
// Add physical units for macOS scrolling
HID_RI_UNIT(8, 0x13), // English Linear (inches)
HID_RI_UNIT_EXPONENT(8, -4), // 10^-4 scale
# ifndef WHEEL_EXTENDED_REPORT
// Calculate: (127 / UNITS_PER_INCH) * 10000 for 10^-4 scale
HID_RI_PHYSICAL_MINIMUM(16, -(1270000 / POINTING_DEVICE_MACOS_SCROLL_UNITS_PER_INCH)),
HID_RI_PHYSICAL_MAXIMUM(16, (1270000 / POINTING_DEVICE_MACOS_SCROLL_UNITS_PER_INCH)),
# else
// Calculate: (32767 / UNITS_PER_INCH) * 10000 for 10^-4 scale
HID_RI_PHYSICAL_MINIMUM(16, -(327670000 / POINTING_DEVICE_MACOS_SCROLL_UNITS_PER_INCH)),
HID_RI_PHYSICAL_MAXIMUM(16, (327670000 / POINTING_DEVICE_MACOS_SCROLL_UNITS_PER_INCH)),
# endif
# endif
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),

View File

@@ -33,6 +33,17 @@
# define RAW_USAGE_ID 0x61
#endif
/////////////////////
// macOS Scroll Resolution (units per inch)
// Lower value = more sensitive scrolling (default: 200 for 2x Apple sensitivity)
// Apple trackpads use 400, but smaller trackpads need lower values
#ifdef POINTING_DEVICE_MACOS_SCROLL_RESOLUTION
# ifndef POINTING_DEVICE_MACOS_SCROLL_UNITS_PER_INCH
# define POINTING_DEVICE_MACOS_SCROLL_UNITS_PER_INCH 200
# endif
#endif
/////////////////////
// Hires Scroll Defaults