Skip to content

fix(greeter): return focus to the password field after a selector menu closes - #91

Open
iwasironman wants to merge 1 commit into
noctalia-dev:mainfrom
iwasironman:fix/selector-menu-return-focus
Open

fix(greeter): return focus to the password field after a selector menu closes#91
iwasironman wants to merge 1 commit into
noctalia-dev:mainfrom
iwasironman:fix/selector-menu-return-focus

Conversation

@iwasironman

@iwasironman iwasironman commented Aug 4, 2026

Copy link
Copy Markdown

Problem

Picking a session with F3 leaves focus on the session selector. The next keystroke goes nowhere, so the password field has to be reached again with Shift+Tab before typing. F7 (color scheme) behaves the same way.

For anyone who alternates between two sessions, that makes the GUI greeter more keystrokes than tuigreet, which returns to the prompt after its session picker:

  • tuigreet: F3 → pick → type/authenticate
  • noctalia-greeter: F3 → pick → Shift+Tab → type/authenticate

It is most noticeable with allow_empty_password = true and a fingerprint reader, where the whole login is otherwise "press Enter, touch the sensor" and the stray Shift+Tab is the only manual navigation left.

Change

selectSession(), selectScheme() and closeMenusAndRestoreFocus() now prefer the password field while the password step is up, falling back to the selector that owns the menu when it is not. A small helper expresses the target:

InputArea* GreeterSurface::menuReturnFocusTarget() const {
  if (!m_passwordVisible || m_passwordField == nullptr) {
    return nullptr;
  }
  return m_passwordField->inputArea();
}

Why not restore the previously focused area

That was the first attempt, and it fails for pointer opens. A click focuses the selector before its onClick handler runs, so the "previous" focus is already the selector itself and restoring it is a no-op — keyboard opens got fixed while mouse opens did not. It also reads oddly when the menu is opened from somewhere that is not the password field.

Naming the password field outright keeps F3/F7, focus-ring activation and pointer clicks behaving identically, and needs no stored InputArea* to keep valid.

Behavior

Path Before After
F3/F7 → pick, password step selector keeps focus password field
Click selector → pick, password step selector keeps focus password field
Tab to selector → Enter → pick selector keeps focus password field
Esc out of the menu, password step selector keeps focus password field
Pick a session on the user-selection step selector keeps focus unchanged

Two consequences worth flagging, both deliberate:

  • Tab out of an open menu now steps forward from the password field (→ login button) rather than from the selector (→ scheme selector). Happy to special-case this if you would rather keep the old stepping.
  • The user menu is untouched: it only exists on the step before the password field, and enterPasswordStep() already sets focus itself.

If you would rather this were opt-in, it is a small change to gate on a greeter.toml key — say the word and I will add one.

Testing

Built and exercised on CachyOS (Arch), niri session, wlroots 0.20.2, greetd 0.10.3.

  • just build and just build-release clean, no new warnings
  • just format-check passes
  • just run-niri for the UI paths: F3/F7 via keyboard, Esc, pointer clicks on both selectors, and Tab-to-selector-then-Enter — focus lands on the password field in every password-step case, and the user-selection step is unchanged
  • Confirmed at a real login screen, not just the run-niri harness: installed to /usr/local, pointed /etc/greetd/config.toml at it, and logged in repeatedly on a stack with pam_fprintd ahead of pam_unix and allow_empty_password = true. Picking a session returns focus to the password field, so login is F3 → pick → Enter → fingerprint with no Shift+Tab.

I did not find an existing issue for this one; it is adjacent to but separate from the auth-flow work in #90.

…u closes

Picking a session with F3 left focus on the session selector, so the next
keystroke went nowhere and the password field had to be reached again with
Shift+Tab. Selecting a color scheme with F7 behaved the same way. tuigreet
returns to the prompt, so switching between two sessions regularly is more
keystrokes on the GUI greeter than on the TUI one.

selectSession(), selectScheme() and closeMenusAndRestoreFocus() now prefer
the password field while the password step is up, falling back to the
selector that owns the menu when it is not (the user-selection step keeps
its current behavior).

Restoring the previously focused area instead does not work for pointer
opens: a click focuses the selector before its onClick handler runs, so the
"previous" focus is already the selector itself. Naming the password field
outright keeps F3/F7, focus-ring activation and pointer clicks consistent.

Escape closes the menu the same way, and Tab out of an open menu now steps
forward from the password field rather than from the selector.
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.

1 participant