refactor: centralize gesture state reset in useTrackpadGesture#334
refactor: centralize gesture state reset in useTrackpadGesture#334upendra512 wants to merge 1 commit intoAOSSIE-Org:mainfrom
Conversation
…E-Org#281) Gesture state was reset in multiple scattered places across the hook, making it easy to miss a ref when adding new gesture state in the future. Introduce resetGestureState() which clears all gesture refs in one place: ongoingTouches, moved, releasedCount, dragging, lastPinchDist, pinching, and any pending draggingTimeout. Refactor handleTouchEnd to capture needed state before calling resetGestureState(), then dispatch drag release and tap events after. This keeps the same external behavior while making the reset path clear. Add handleTouchCancel that calls setIsTracking(false) + resetGestureState() as a clean handler for interrupted gestures (phone call, system interrupt). Expose onTouchCancel in the returned handlers object. Fixes AOSSIE-Org#281 Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
WalkthroughThe changes introduce a Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/hooks/useTrackpadGesture.ts`:
- Around line 270-273: handleTouchCancel currently only resets local state via
setIsTracking and resetGestureState, but if a drag was active it never notifies
the remote side that the button was released; update handleTouchCancel to detect
an active drag/pressed state and send the equivalent "press: false" remote event
before clearing local state. Use the same helper the touchend/touchup flow uses
to send button events (the function that emits mouse/press events in this
module) so the remote button state is cleared, then call setIsTracking(false)
and resetGestureState().
- Line 281: The hook useTrackpadGesture now returns onTouchCancel but
TouchArea.tsx still only types and binds onTouchStart/onTouchMove/onTouchEnd;
update the TouchArea component to include the onTouchCancel prop in its props
interface and JSX event bindings (add onTouchCancel={props.onTouchCancel} or
equivalent) and ensure any internal handler references (e.g., handleTouchStart,
handleTouchMove, handleTouchEnd) are extended to accept/call the provided
onTouchCancel so touch-cancel events trigger the same reset/cleanup logic as end
events.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 664dfd07-be05-496f-8985-64bc5e15152b
📒 Files selected for processing (1)
src/hooks/useTrackpadGesture.ts
| const handleTouchCancel = () => { | ||
| setIsTracking(false) | ||
| resetGestureState() | ||
| } |
There was a problem hiding this comment.
Touch-cancel can leave remote drag/button state stuck.
If cancellation happens during an active drag, state is reset locally but no press: false event is sent. That can leave the remote side thinking left button is still down.
🐛 Proposed fix
const handleTouchCancel = () => {
+ const wasDragging = dragging.current
setIsTracking(false)
resetGestureState()
+ if (wasDragging) {
+ send({ type: "click", button: "left", press: false })
+ }
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const handleTouchCancel = () => { | |
| setIsTracking(false) | |
| resetGestureState() | |
| } | |
| const handleTouchCancel = () => { | |
| const wasDragging = dragging.current | |
| setIsTracking(false) | |
| resetGestureState() | |
| if (wasDragging) { | |
| send({ type: "click", button: "left", press: false }) | |
| } | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/hooks/useTrackpadGesture.ts` around lines 270 - 273, handleTouchCancel
currently only resets local state via setIsTracking and resetGestureState, but
if a drag was active it never notifies the remote side that the button was
released; update handleTouchCancel to detect an active drag/pressed state and
send the equivalent "press: false" remote event before clearing local state. Use
the same helper the touchend/touchup flow uses to send button events (the
function that emits mouse/press events in this module) so the remote button
state is cleared, then call setIsTracking(false) and resetGestureState().
| onTouchStart: handleTouchStart, | ||
| onTouchMove: handleTouchMove, | ||
| onTouchEnd: handleTouchEnd, | ||
| onTouchCancel: handleTouchCancel, |
There was a problem hiding this comment.
onTouchCancel exposure is not fully integrated in all consumers.
This hook now returns onTouchCancel, but src/components/Trackpad/TouchArea.tsx still types and binds only start/move/end handlers. In that path, cancel events will still bypass this reset logic.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/hooks/useTrackpadGesture.ts` at line 281, The hook useTrackpadGesture now
returns onTouchCancel but TouchArea.tsx still only types and binds
onTouchStart/onTouchMove/onTouchEnd; update the TouchArea component to include
the onTouchCancel prop in its props interface and JSX event bindings (add
onTouchCancel={props.onTouchCancel} or equivalent) and ensure any internal
handler references (e.g., handleTouchStart, handleTouchMove, handleTouchEnd) are
extended to accept/call the provided onTouchCancel so touch-cancel events
trigger the same reset/cleanup logic as end events.
Closes #281
Gesture state was reset in multiple scattered places, making it easy to miss a ref when adding new gesture state.
Changes:
Checklist:
Summary by CodeRabbit