Skip to content

Fix BaseButton input when enable_long_press_as_right_click is true - #120962

Merged
Repiteo merged 1 commit into
godotengine:masterfrom
syntaxerror247:base-button
Jul 10, 2026
Merged

Fix BaseButton input when enable_long_press_as_right_click is true#120962
Repiteo merged 1 commit into
godotengine:masterfrom
syntaxerror247:base-button

Conversation

@syntaxerror247

@syntaxerror247 syntaxerror247 commented Jul 5, 2026

Copy link
Copy Markdown
Member

This PR fixes a touch behavior issue that occurs when enable_long_press_as_right_click is enabled.
regression from #110893

The following describes the behavior before and after this change. A normal tap always generates a press event.

When Action Mode = Button Release and Button Mask = Mouse Left

  • Before this PR: A long press triggers a button press action even though the button has not been released yet.
  • After this PR: A long press does not trigger any action. When a long press is detected, the original touch is canceled and enable_long_press_as_right_click generates a Mouse Right event instead. Since the button is configured for Mouse Left, no action is triggered.

When Action Mode = Button Release and Button Mask = Mouse Right

  • Before this PR: A long press triggers a button press action before the touch is released, and another press action is triggered when the touch is released.
  • After this PR: A long press triggers a single button press action when the touch is released.

When Action Mode = Button Press, the behavior remains unchanged:

  • Button Mask = Mouse Left: A press action is triggered immediately on touch.
  • Button Mask = Mouse Right: A press action is triggered immediately on touch. If the touch is held long enough to become a long press, an additional press action is triggered for the right-click event.

@syntaxerror247
syntaxerror247 requested a review from a team as a code owner July 5, 2026 11:35
@syntaxerror247 syntaxerror247 added this to the 4.8 milestone Jul 5, 2026
@syntaxerror247 syntaxerror247 added cherrypick:4.7 Considered for cherry-picking into a future 4.7.x release bug topic:input topic:gui labels Jul 5, 2026
@syntaxerror247
syntaxerror247 requested a review from a team July 5, 2026 11:36
@Nintorch
Nintorch self-requested a review July 5, 2026 11:41
@syntaxerror247

Copy link
Copy Markdown
Member Author

cc @Alex2782 @Kazox61

@ace24713

ace24713 commented Jul 5, 2026

Copy link
Copy Markdown

I'm curious about how some of this works...

When a long press is detected, the original touch is canceled

How does that work? I see InputEventScreenTouch has a "canceled" property, but I don't see anywhere in base_button where it's actually checked, so I find it hard to believe it handles everything intently and is left in a good state in all cases. Call it a hunch.

When Action Mode = Button Release and Button Mask = Mouse Right ... A long press triggers a single button press action when the touch is released.

That's also curious. If it ignores emulated events, how does it even respond to the emulated right click? Are emulated right-click events not set as DEVICE_ID_EMULATION? I mean I guess that'd be fine as long as it works, it's just unexpected.

A normal tap always generates a press event.

If "always" in this context means even when Button Mask = Mouse Right, that sounds like another regression too. Before multitouch support, a button with Mouse Right would not respond to short taps, but would respond to long presses. (worth noting I didn't explicitly verify that, but it's sensible)

Button Mask = Mouse Right: A press action is triggered immediately on touch. If the touch is held long enough to become a long press, an additional press action is triggered for the right-click event.

Similarly to the above, this is probably not how it would have behaved before multitouch support.

@syntaxerror247

Copy link
Copy Markdown
Member Author

When a long press is detected, the original touch is canceled

How does that work? I see InputEventScreenTouch has a "canceled" property, but I don't see anywhere in base_button where it's actually checked, so I find it hard to believe it handles everything intently and is left in a good state in all cases. Call it a hunch.

Code checks for !event->is_pressed() which also handles canceled event. As you can see in the changes, where press action is triggered, I've now updated the check to event->is_released(), so it doesn't trigger a press for canceled events.

When Action Mode = Button Release and Button Mask = Mouse Right ... A long press triggers a single button press action when the touch is released.

That's also curious. If it ignores emulated events, how does it even respond to the emulated right click? Are emulated right-click events not set as DEVICE_ID_EMULATION? I mean I guess that'd be fine as long as it works, it's just unexpected.

Yes, right click generated by enable_long_press_as_right_click setting, does not have DEVICE_ID_EMULATION. These are like regular mouse click. DEVICE_ID_EMULATION is only being used for emulate_touch_from_mouse and emulate_mouse_from_touch setting.

A normal tap always generates a press event.

If "always" in this context means even when Button Mask = Mouse Right, that sounds like another regression too. Before multitouch support, a button with Mouse Right would not respond to short taps, but would respond to long presses. (worth noting I didn't explicitly verify that, but it's sensible)

Button Mask = Mouse Right: A press action is triggered immediately on touch. If the touch is held long enough to become a long press, an additional press action is triggered for the right-click event.

Similarly to the above, this is probably not how it would have behaved before multitouch support.

Yes, button mask is ignored for touch input. This does sounds like a regression but I'm not sure what we can do here, you know touch have no concept of button mask.

@ace24713

ace24713 commented Jul 6, 2026

Copy link
Copy Markdown

Code checks for !event->is_pressed() which also handles canceled event. As you can see in the changes, where press action is triggered, I've now updated the check to event->is_released(), so it doesn't trigger a press for canceled events.

Ohh that makes sense, I was not aware that is_released is cancel aware. 👍

Yes, button mask is ignored for touch input. This does sounds like a regression but I'm not sure what we can do here, you know touch have no concept of button mask.

If I were to make a proposal...

In terms of regression minimization, I think treating touch inputs as left mouse events would be simple. That would be intuitive enough, I certainly wouldn't expect a touch input to be able to press a button coded to respond only to right mouse.

Alternatively...

What about adding "touch" as a potential mask option? That way buttons can be individually set to respond to whatever sorts of inputs the user wants. For example I could set a button to respond to mouse events only (which also works as a compatibility setting) or respond to touch and right mouse, touch and right and left mouse, or any combination.

@m4gr3d m4gr3d 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.

The code change looks good.

@syntaxerror247

Copy link
Copy Markdown
Member Author

What about adding "touch" as a potential mask option? That way buttons can be individually set to respond to whatever sorts of inputs the user wants. For example I could set a button to respond to mouse events only (which also works as a compatibility setting) or respond to touch and right mouse, touch and right and left mouse, or any combination.

I personally like this option, but final call on this would be from Input or GUI team. It would be great if you can make a proposal with both of your suggestions.

@ace24713

Copy link
Copy Markdown

I personally like this option, but final call on this would be from Input or GUI team. It would be great if you can make a proposal with both of your suggestions.

Gotcha, proposal opened here:
godotengine/godot-proposals#15163

@Repiteo
Repiteo merged commit 91cb8e9 into godotengine:master Jul 10, 2026
20 checks passed
@Repiteo

Repiteo commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Thanks!

@syntaxerror247
syntaxerror247 deleted the base-button branch July 10, 2026 19:31
@Repiteo

Repiteo commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Cherry-picked for 4.7.2.

@Repiteo Repiteo removed the cherrypick:4.7 Considered for cherry-picking into a future 4.7.x release label Jul 24, 2026
BendyLand pushed a commit to BendyLand/voltaire that referenced this pull request Aug 2, 2026
Fix `BaseButton` input when `enable_long_press_as_right_click` is true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants