Skip to content

[bug] FocusManager loses current focus after dynamic registration reorder #1759

Description

@ZainabTravadi

Which package?

@termuijs/core

What happened?

FocusManager can lose the currently focused widget when a new focusable is registered and the internal focusable list is reordered by tabIndex.

During registration, the new focusable is inserted and the internal _focusables array is sorted. However, the current focus is tracked using _currentIndex, which is not updated after reordering.

As a result, _currentIndex may end up pointing to a different widget than the one that was previously focused.

Expected behavior

The same widget should remain focused after registration, even if the internal list is reordered.

Actual behavior

Registering a new focusable with a lower tabIndex can unexpectedly change the currently focused widget.

Steps to reproduce

const manager = new FocusManager();

// Register focusables
manager.register({ id: 'a', tabIndex: 10, focusable: true });
manager.register({ id: 'b', tabIndex: 20, focusable: true });

// Focus b
manager.focus('b');

// Register a new focusable that sorts before existing entries
manager.register({ id: 'c', tabIndex: 5, focusable: true });

// Expected: currentId === 'b'
// Actual: currentId === 'a'

Environment

  • Bun version: 1.x
  • OS: Linux (WSL)
  • Terminal emulator: Windows Terminal
  • TermUI version: Latest main

Screenshots or terminal output

Observed state:

Before registration:
focusables = [a, b]
currentId = b

After registering c(tabIndex=5):
focusables = [c, a, b]
currentId = a

Expected:

Before registration:
currentId = b

After registering c(tabIndex=5):
currentId = b

GSSoC contributor?

  • Yes. You contribute under GSSoC 2026.
  • No.

Metadata

Metadata

Assignees

Labels

assignedIssue claimed by a contributor.type:bug+10 pts. Bug fix.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions