Skip to content

Fix lightweight Picker traversal controls when non-traversable#5091

Merged
shai-almog merged 1 commit into
codenameone:masterfrom
jsfan3:codex/fix-picker-lightweight-traversal-buttons
May 29, 2026
Merged

Fix lightweight Picker traversal controls when non-traversable#5091
shai-almog merged 1 commit into
codenameone:masterfrom
jsfan3:codex/fix-picker-lightweight-traversal-buttons

Conversation

@jsfan3
Copy link
Copy Markdown
Contributor

@jsfan3 jsfan3 commented May 29, 2026

Summary

  • Hide lightweight Picker next/previous controls when the picker itself is not traversable.
  • Prevent lightweight picker next/previous commands from moving focus out of a non-traversable picker.
  • Keep the lightweight popup behavior aligned with Component#setTraversable(false) / preferred tab index traversal.

Problem

Picker defaults into the focus traversal order by setting a preferred tab index in its constructor. Applications can opt a picker out of traversal via setTraversable(false), which makes the component absent from the form's tab iterator.

The lightweight picker popup still calls Form#getTabIterator(Picker.this) to decide whether to show previous/next buttons. When the picker has been made non-traversable, the tab iterator cannot find it and initializes its current position to -1. In that state hasNext() may still return the first traversable component in the form, and hasPrevious() may return the last traversable component. As a result, the lightweight popup can display traversal controls even though the picker opted out of traversal.

Pressing one of those controls then calls getNextComponent(Picker.this) / getPreviousComponent(Picker.this), requests focus on an unrelated component, and starts editing it. On Android this can surface as an unexpected native text editor appearing for a later TextField immediately after the picker closes.

Fix

Gate both sides of the lightweight picker traversal behavior on Picker.this.isTraversable():

  • the previous/next buttons are only created for traversable pickers;
  • COMMAND_NEXT / COMMAND_PREV only attempt focus transfer for traversable pickers.

This preserves the existing traversal behavior for normal traversable pickers while respecting applications that explicitly call setTraversable(false).

Verification

  • Reproduced in an Android app with a lightweight string Picker followed by numeric TextFields.
  • Before this patch: picker.setTraversable(false) still shows the previous/next arrow buttons; pressing an arrow closes the picker and starts editing a numeric text field.
  • With this patch: non-traversable lightweight pickers do not expose or execute previous/next traversal controls.
  • Ran git diff --check on the branch.

@jsfan3 jsfan3 force-pushed the codex/fix-picker-lightweight-traversal-buttons branch from acae645 to c10183e Compare May 29, 2026 13:26
@jsfan3
Copy link
Copy Markdown
Contributor Author

jsfan3 commented May 29, 2026

@shai-almog I used generative AI to create this pull request, which addresses a real-world problem on my Android device. The fix seems reasonable and straightforward, and I don't think testing it locally by recompiling CN1 is necessary. However, if you would like me to do so, I can.

@shai-almog shai-almog merged commit 5864445 into codenameone:master May 29, 2026
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