Skip to content

Improve Android mouse event handling, especially relative mode. - #16538

Merged
slouken merged 3 commits into
libsdl-org:mainfrom
Packetdancer:android-mouse
Oct 19, 2026
Merged

slouken merged 3 commits into
libsdl-org:mainfrom
Packetdancer:android-mouse

Conversation

@Packetdancer

Copy link
Copy Markdown
Contributor
  • I confirm that I am the author of this code and release it to the SDL project under the zlib license. This contribution does not contain code from other sources, including code generated by a Large Language Model ("AI").

Description

So it turns out that Android has some interestingly varied ways of handling mouse events.

Some devices will send ACTION_DOWN and ACTION_UP for clicks. Some will send ACTION_BUTTON_PRESS and ACTION_BUTTON_RELEASE. Some will send ACTION_BUTTON_PRESS for the click, and then ACTION_CANCEL for the release. Some will use ACTION_HOVER_EXIT for the button press, and ACTION_HOVER_ENTER for the button release.

Some will include a button release for one button and a button press for another in the same message, only changing the button state field. Switching from absolute to relative mouse on some Android variants generates a spurious ACTION_CANCEL event for mouse via the onTouch handler. Etc.

In an effort to make mouse behavior consistent everywhere, these changes:

  • Use OnCapturedPointerListener on API 26+, so that we don't have shenanigans with relative versus absolute mouse mode
  • Watch for changes to button state in a number of action messages
  • Filter out the ACTION_CANCEL in onTouch

As a side benefit, now that we are handling all the messages, we can get rid of the block of logic throwing out fallback key events in the key dispatcher.

These have been tested on Samsung Galaxy S21 and Amazon Fire TV Stick 4K Max so far. I'm going to do some further testing at home (Nvidia Shield TV, Wacom Movinkpad Pro, etc.) over the weekend, but I'm throwing this pull request in so that @slouken has time to review/request any changes.

default:
break;
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change

int action = event.getActionMasked();

SDLActivity.onNativeMouse(buttonState, action, x, y, true);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change

Comment thread src/video/android/SDL_androidmouse.c Outdated
default:
break;
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change

Comment thread src/video/android/SDL_androidmouse.c Outdated
SDL_SendMouseMotion(0, window, SDL_DEFAULT_MOUSE_ID, relative, x, y);

if (changes_press) {
button = TranslateButton(changes_press);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Do you need to potentially handle multiple button state changes here?

@Packetdancer Packetdancer Oct 17, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Hypothetically, yes, but nothing I've tested on so far groups more than two button changes into a single event.

Still, probably not the worst idea to handle it just in case... I'll tweak that this weekend.

@Packetdancer

Copy link
Copy Markdown
Contributor Author

Okay. I have now tested this with four different mice, across every Android device I could get my hands on this weekend. At this point, mouse buttons now work consistently across every combination in that matrix, so I think we're good to go!

@slouken
slouken merged commit d356368 into libsdl-org:main Oct 19, 2026
10 checks passed
@slouken

slouken commented Oct 19, 2026

Copy link
Copy Markdown
Collaborator

Merged, thanks!

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.

2 participants