Overhaul Azoteq IQS5XX touchpad scroll and drag behavior#8
Open
rnewman wants to merge 6 commits into
Open
Conversation
Increased HOLD_TIME from aggressive 20ms, to more forgiving 150ms. Since TAP_TIME default, without defining, is 150ms, also decrease this appropriately. Before, they were confusing each other.
Removed TAP_TIME and HOLD_TIME definitions to return behavior to baseline, longer 300ms hold-to-tap for dragging/selecting is the price for a consistent and intuitive interface.
Increased HOLD_TIME from aggressive 20ms, to more forgiving 150ms. Since TAP_TIME (when default/without defining), is 150ms, also decrease this appropriately. Before, they were confusing each other.
AZOTEQ config.h changes: TAP_TIME = 100ms (default 150ms) HOLD_TIME = 200ms (default 300ms)
It is, in general, impossible for a QMK keyboard to implement smooth touchpad
scrolling on macOS: it ignores supplied resolution multipliers, doesn't ask for
reports, and seemingly only allows Magic Touchpads to deliver a good
experience. The recommended configuration is to use an app like SmoothScroll or
Mos to convert mouse wheel-style scrolls into smooth scroll; the work expected
of the firmware itself is to supply a reasonable range of scroll values.
This commit does so, though you might still wish to adjust configured values.
It includes three major changes to improve touchpad usability on macOS:
1. Configurable scroll speed reduction via `axis_scale`: replace naive integer
division (which truncated small per-report values to zero, causing a
"dead zone then jump" effect) with a remainder-preserving accumulator.
Uses `CONSTRAIN_HID_HV` (new macro) instead of `CONSTRAIN_HID`: clamps to the
proper HV range (`int16` when `WHEEL_EXTENDED_REPORT` is defined, `int8` otherwise).
2. Natural scrolling by default: invert the Y axis for two-finger scroll gestures
so that content follows finger direction (swipe down = scroll down),
matching macOS trackpad convention.
3. Replace press_and_hold drag with tap-to-drag:
Problem: press_and_hold fired BUTTON1 whenever a finger lingered on
the pad beyond HOLD_TIME, making it impossible to move the cursor
without accidentally drag-selecting. Disabling press_and_hold at the
IQS5XX hardware level caused the gesture engine to stall and stop
detecting taps entirely.
Solution (two parts):
a) Decouple hardware gesture detection from click behavior. A new
`AZOTEQ_IQS5XX_PRESS_AND_HOLD_AS_CLICK` define (defaulting to
`PRESS_AND_HOLD_ENABLE` for backward compat) controls whether
press_and_hold events produce BUTTON1 in the report handler.
The hardware gesture stays enabled so the IQS5XX state machine
remains healthy, but we simply ignore the event.
b) Implement macOS-style tap-to-drag: after a single_tap, BUTTON1
is held continuously for a configurable window (`TAP_DRAG_WINDOW_MS`,
default 200ms). If a finger touches the pad again within that
window, drag mode engages and BUTTON1 remains held until the
finger lifts. The continuous hold during the window is critical —
an earlier implementation that released BUTTON1 between tap and
drag worked for text selection but failed for macOS window
dragging, which requires an unbroken button press from the
initial click on the title bar.
`TAP_TIME` raised from 100ms to 200ms since there is no longer a need
to keep it short to disambiguate taps from press_and_hold.
`HOLD_TIME` remains at default 300ms.
New configurable defines (all with backward-compatible defaults):
- AZOTEQ_IQS5XX_SCROLL_DIVISOR (default 1, configured to 8 for Svalboard)
- AZOTEQ_IQS5XX_PRESS_AND_HOLD_AS_CLICK (default matches ENABLE)
- AZOTEQ_IQS5XX_TAP_DRAG_ENABLE (default false)
- AZOTEQ_IQS5XX_TAP_DRAG_WINDOW_MS (default 200)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
It is, in general, impossible for a QMK keyboard to implement smooth touchpad
scrolling on macOS: it ignores supplied resolution multipliers, doesn't ask for
reports, and seemingly only allows Magic Touchpads to deliver a good
experience. The recommended configuration is to use an app like SmoothScroll or
Mos to convert mouse wheel-style scrolls into smooth scroll; the work expected
of the firmware itself is to supply a reasonable range of scroll values.
This commit does so, though you might still wish to adjust configured values.
It includes three major changes to improve touchpad usability on macOS:
Configurable scroll speed reduction via
axis_scale: replace naive integerdivision (which truncated small per-report values to zero, causing a
"dead zone then jump" effect) with a remainder-preserving accumulator.
Uses
CONSTRAIN_HID_HV(new macro) instead ofCONSTRAIN_HID: clamps to theproper HV range (
int16whenWHEEL_EXTENDED_REPORTis defined,int8otherwise).Natural scrolling by default: invert the Y axis for two-finger scroll gestures
so that content follows finger direction (swipe down = scroll down),
matching macOS trackpad convention.
Replace press_and_hold drag with tap-to-drag:
Problem: press_and_hold fired BUTTON1 whenever a finger lingered on
the pad beyond HOLD_TIME, making it impossible to move the cursor
without accidentally drag-selecting. Disabling press_and_hold at the
IQS5XX hardware level caused the gesture engine to stall and stop
detecting taps entirely.
Solution (two parts):
a) Decouple hardware gesture detection from click behavior. A new
AZOTEQ_IQS5XX_PRESS_AND_HOLD_AS_CLICKdefine (defaulting toPRESS_AND_HOLD_ENABLEfor backward compat) controls whetherpress_and_hold events produce BUTTON1 in the report handler.
The hardware gesture stays enabled so the IQS5XX state machine
remains healthy, but we simply ignore the event.
b) Implement macOS-style tap-to-drag: after a single_tap, BUTTON1
is held continuously for a configurable window (
TAP_DRAG_WINDOW_MS,default 200ms). If a finger touches the pad again within that
window, drag mode engages and BUTTON1 remains held until the
finger lifts. The continuous hold during the window is critical —
an earlier implementation that released BUTTON1 between tap and
drag worked for text selection but failed for macOS window
dragging, which requires an unbroken button press from the
initial click on the title bar.
TAP_TIMEraised from 100ms to 200ms since there is no longer a needto keep it short to disambiguate taps from press_and_hold.
HOLD_TIMEremains at default 300ms.New configurable defines (all with backward-compatible defaults):