Skip to content

Conversation

@dustinmcafee
Copy link
Contributor

RCA:
For Android devices older than version 14, the application was attempting to handle DPAD (remote control directional pad) inputs by moving a text cursor, which is incorrect for navigating a TV user interface.

To fix this, I made the following changes to app/src/main/java/net/christianbeier/droidvnc_ng/InputService.java:

Added context-aware navigation: When the user has a text field (including standard EditText and TextView) in focus, the D-pad now functions as a text cursor.
View Navigation: If the focused element is not a text field, the D-pad retains its original behavior, shifting the focus between different UI components.

Also attempts to attain focus when user presses on DPAD, and there is no focus available. This allows user to have better control in the edge-case where device doesn't consider any particular view in focus.

On a TV Device (running Android < 14):
Effect: This is a critical fix. DPAD navigation with a remote control will now work correctly, allowing users to navigate between buttons, menus, and other UI elements. The application is now usable on these devices.
Risk: None. This change corrects the behavior to match user expectations for a TV app.
On a non-TV Device (Phone/Tablet, running Android < 14):
Effect: This change is also an improvement. If a user has an external keyboard connected, the arrow keys will now properly navigate between focusable elements in the app (like buttons or input fields), which is standard behavior. The previous text-cursor logic was less useful and only worked inside text boxes.
Risk: Very low. The new behavior is more consistent with standard Android keyboard navigation and is unlikely to cause any issues.

On Any Device (TV or non-TV, running Android 14+):
Effect: None. These devices use a more modern input handling method that was already working correctly. The code I modified is part of a fallback for older Android versions and is not executed on newer ones.
Risk: None.

Video of test run on Sony TV running Android 9:
https://drive.google.com/file/d/1gjjfkjSKLxkCvSKM51FbqrCtp24S7ygE/view?usp=sharing

@bk138 bk138 self-assigned this Oct 12, 2025
Objects.requireNonNull(currentFocusNode).performAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_NEXT_AT_MOVEMENT_GRANULARITY.getId(), action);
if ((keysym == 0xff51 || keysym == 0xff52 || keysym == 0xff53 || keysym == 0xff54) && down != 0) {

if (currentFocusNode == null) {
Copy link
Owner

Choose a reason for hiding this comment

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

the indentation seems off here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should be resolved

supportsTextTraversal = className.equals("android.widget.EditText") || className.contains("TextField");
}

if (supportsTextTraversal) {
Copy link
Owner

Choose a reason for hiding this comment

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

how would we be able to focus-traverse out of a text field?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

With this current implementation, it won't traverse out.

I need to add something to check if the cursor is at the edge of the text (beginning, end, top, or bottom), and allow traversal in that case.

@dustinmcafee
Copy link
Contributor Author

Sorry -- I have not forgotten about this -- I will find some time this weekend and update!

@bk138
Copy link
Owner

bk138 commented Oct 15, 2025

Sorry -- I have not forgotten about this -- I will find some time this weekend and update!

No problem; I know exactly how this is...

@bk138
Copy link
Owner

bk138 commented Oct 21, 2025

@dustinmcafee you don't have to invest time on this, I've taken your PR and reworked it a bit in the light of shortcomings in my code that I need to fix. I will commit your change, preserving your authorship, when done.

…AT_MOVEMENT_GRANULARITY is actually commonly used on Android Google TV homescreen. Also, if currentFocusNode is null, then try to attain focus on some node to prevent forcing user to use mouse
@dustinmcafee
Copy link
Contributor Author

dustinmcafee commented Oct 21, 2025

@bk138 Sorry -- I actually was taking another look, today.

I fixed indentation issues, and re-added the comment.

I am going to try to test this commit out sometime today for the traversing out of text fields:
ce16411

Also, I needed to do some force-pushes -- because I didn't realize I was using the wrong SSH keys to push some commits, and I needed to make sure it specified my current email address.

@andresberge
Copy link

How can I test this bug fix? The DPAD issue would be a fantastic fix!

@bk138 bk138 merged commit 80a7cc3 into bk138:master Dec 8, 2025
1 check passed
@andresberge
Copy link

How can I test this bug fix? The DPAD issue would be a fantastic fix!

Thanks! I'll give it a go tonight!

@bk138
Copy link
Owner

bk138 commented Dec 8, 2025

@andresberge this is still a bit rough (focus sometimes lost on app change) but the basics do work.

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