Skip to content

[Android] Reset the native DOWN flag for unmanaged buttons - #4590

Merged
m-bert merged 1 commit into
mainfrom
@mbert/button-native-down-reset
Oct 13, 2026
Merged

m-bert merged 1 commit into
mainfrom
@mbert/button-native-down-reset

Conversation

@m-bert

@m-bert m-bert commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator

Description

ButtonViewGroup tracks whether the native dispatch delivered DOWN for the current gesture and resets it when the handler goes BEGAN. The reset sat behind the managedHandlerTag guard, so it only ran for buttons that manage their own handler (Touchable, Pressable). A button attached through a detector, like RectButton with useNativeGesture, set the flag on its first touch and never cleared it. From then on the #4441 rule degraded to the mid-gesture check only, and a fling caught on such a button was not cancelled.

The reset now runs before the guard, so every handler on the view gets the per-gesture rule. Since #4582 the detector rule already covers this case for detector-attached buttons, so there is no visible change today; this fixes the stale state so the hook's rule holds on its own.

Test plan

Repro
import { useState } from 'react';
import { FlatList, StyleSheet, Text, View } from 'react-native';
import { GestureHandlerRootView, RectButton } from 'react-native-gesture-handler';

export default function App() {
  const [presses, setPresses] = useState(0);

  return (
    <GestureHandlerRootView style={styles.flex}>
      <Text style={styles.counter}>{`presses=${presses}`}</Text>
      <FlatList
        data={Array.from({ length: 500 }, (_, i) => i)}
        keyExtractor={(item) => String(item)}
        renderItem={({ item }) => (
          <RectButton style={styles.row} onPress={() => setPresses((count) => count + 1)}>
            <Text>Row {item}</Text>
          </RectButton>
        )}
      />
    </GestureHandlerRootView>
  );
}

const styles = StyleSheet.create({
  flex: { flex: 1 },
  counter: { padding: 16, paddingTop: 48, fontFamily: 'monospace' },
  row: { height: 80, justifyContent: 'center', paddingLeft: 16, borderBottomWidth: 1 },
});

Copilot AI balanced review requested due to automatic review settings October 12, 2026 14:40
@coderabbitai

coderabbitai Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: eff9ba3b-f8ba-42be-a294-91204dbb5e85

📥 Commits

Reviewing files that changed from the base of the PR and between 0f8b2ba and e88a5e7.


📒 Files selected for processing (1)
  • packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 6 remain after this review.



📝 Summary

Summary by CodeRabbit

  • Bug Fixes
    • Unmanaged buttons now correctly reset their touch state when a gesture begins.

Walkthrough

The Android button state-change handler now resets receivedNativeDown at the start of STATE_BEGAN, before checking for a managed handler.

Changes

Button press state

Layer / File(s) Summary
Reset native-down state
packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt
The STATE_BEGAN path resets receivedNativeDown before the managed-handler check. The reset below that check was removed.

Suggested reviewers: j-piasecki


Priority: ⬇️ Low

Merge Risk: ⚪ Minimal · up to e88a5

The change extends the per-gesture reset to buttons without a managed handler, while preserving the existing managed-button event order. No actionable merge-blocking risk is established.

Pre-merge checks | Passed 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main Android change: resetting the native DOWN flag for unmanaged buttons.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The focused state-reset relocation correctly addresses unmanaged buttons without altering managed-handler behavior.

0 open findings

What changed in this PR

Moves Android’s per-gesture native DOWN reset so unmanaged detector-attached buttons also receive correct cancellation behavior.

Changes:

  • Resets receivedNativeDown on STATE_BEGAN before the managed-handler guard.
  • Preserves managed button press-state handling.
File Description
RNGestureHandlerButtonViewManager.kt Applies DOWN-state reset to managed and unmanaged buttons.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@m-bert
m-bert requested review from bartlomiejbloniarz and j-piasecki and removed request for bartlomiejbloniarz October 12, 2026 15:04
@m-bert
m-bert merged commit 2b23b88 into main Oct 13, 2026
6 checks passed
@m-bert
m-bert deleted the @mbert/button-native-down-reset branch October 13, 2026 11:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants