Skip to content

fix: Recognize every input callbacks mixin when hit testing - #3994

Open
luanpotter wants to merge 2 commits into
mainfrom
luan.input-callbacks
Open

fix: Recognize every input callbacks mixin when hit testing#3994
luanpotter wants to merge 2 commits into
mainfrom
luan.input-callbacks

Conversation

@luanpotter

Copy link
Copy Markdown
Member

Description

Follow up from #3986 (comment)

FlameGame.containsEventHandlerAt backs GameRenderBox.hitTestSelf, which decides (for now) whether the game takes part in the hit test when the GameWidget uses a HitTestBehavior other than opaque. It enumerated some callbacks mixins and was missing five others: LongPressCallbacks, TertiaryTapCallbacks, ScrollCallbacks, PointerMoveCallbacks and HoverCallbacks.

Before, components using any of those would silently received no events under deferToChild or translucent.

Rather than extending the list and the problem, this adds two marker interfaces:

  • InputCallbacks: anchors the whole family, much like Event does for the event classes.
  • PointerInputCallbacks implements InputCallbacks: the positional/pointer subset, i.e. the mixins whose events carry a position and can therefore take part in hit testing.

This serves this and other future purposes, and is public API for users to access and write generic code on top.

I will still explore (after this) following the direction I proposed in #3982: FlameGame stops overriding containsEventHandlerAt altogether - the game reports a hit anywhere within its bounds, and per-component transparency becomes an explicit opt-in user override written against PointerInputCallbacks using this interface:

@override
bool containsEventHandlerAt(Vector2 position) =>
    componentsAtPoint(position).any((c) => c is PointerInputCallbacks);

Regardless, this is a great shape to have the callbacks in, so I am extracting this first.

Checklist

  • I have followed the Contributor Guide when preparing my PR.
  • I have updated/added tests for ALL new/updated/fixed functionality.
  • I have updated/added relevant documentation in docs and added dartdoc comments with ///.
  • I have updated/added relevant examples in examples or docs.

Breaking Change?

  • Yes, this PR is a breaking change.
  • No, this PR is not a breaking change.

component is DoubleTapCallbacks ||
component is ScaleCallbacks ||
component is SecondaryTapCallbacks) {
if (component is PointerInputCallbacks) {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

this is the fix

@luanpotter
luanpotter marked this pull request as ready for review August 12, 2026 02:41
@luanpotter
luanpotter requested review from spydon and a lite review from Copilot August 12, 2026 02:46

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.

Pull request overview

This PR fixes FlameGame.containsEventHandlerAt / GameWidget hit-testing under HitTestBehavior.deferToChild and translucent by introducing marker interfaces for input-callback mixins and using them for pointer-position-aware hit testing.

Changes:

  • Add InputCallbacks and PointerInputCallbacks marker interfaces and export them as public API.
  • Update pointer/positional callback mixins to implement PointerInputCallbacks, and simplify FlameGame.containsEventHandlerAt to check for that marker.
  • Add regression tests and update GameWidget documentation to reflect the new behavior.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/flame/test/game/contains_event_handler_at_test.dart Adds regression coverage for containsEventHandlerAt and GameWidget hit-testing (including LongPressCallbacks under deferToChild).
packages/flame/lib/src/game/flame_game.dart Replaces a hard-coded list of callback mixins with a PointerInputCallbacks marker check for hit testing.
packages/flame/lib/src/events/callbacks/input_callbacks.dart Introduces the root marker interface for all input callback mixins.
packages/flame/lib/src/events/callbacks/pointer_input_callbacks.dart Introduces the positional/pointer subset marker used for hit testing.
packages/flame/lib/src/events/callbacks/tap_callbacks.dart Implements PointerInputCallbacks on TapCallbacks.
packages/flame/lib/src/events/callbacks/secondary_tap_callbacks.dart Implements PointerInputCallbacks on SecondaryTapCallbacks.
packages/flame/lib/src/events/callbacks/tertiary_tap_callbacks.dart Implements PointerInputCallbacks on TertiaryTapCallbacks.
packages/flame/lib/src/events/callbacks/drag_callbacks.dart Implements PointerInputCallbacks on DragCallbacks.
packages/flame/lib/src/events/callbacks/double_tap_callbacks.dart Implements PointerInputCallbacks on DoubleTapCallbacks.
packages/flame/lib/src/events/callbacks/scale_callbacks.dart Implements PointerInputCallbacks on ScaleCallbacks.
packages/flame/lib/src/events/callbacks/scroll_callbacks.dart Implements PointerInputCallbacks on ScrollCallbacks.
packages/flame/lib/src/events/callbacks/pointer_move_callbacks.dart Implements PointerInputCallbacks on PointerMoveCallbacks (covering HoverCallbacks transitively).
packages/flame/lib/src/events/callbacks/long_press_callbacks.dart Implements PointerInputCallbacks on LongPressCallbacks.
packages/flame/lib/events.dart Exports the new marker interfaces as part of the public events.dart surface.
doc/flame/game_widget.md Documents that pointer hit-testing treats PointerInputCallbacks components as interactive.

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

Comment thread packages/flame/lib/src/events/callbacks/input_callbacks.dart
@luanpotter
luanpotter force-pushed the luan.input-callbacks branch from 9df50d6 to 0e402c1 Compare August 12, 2026 03:00

@erickzanardo erickzanardo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Left a question, but LGTM either way

/// Marker interface implemented by every input callbacks mixin.
///
/// See `PointerInputCallbacks` for the positional subset.
abstract interface class InputCallbacks {}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Shouldn't this and the other interface define methods?

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