Skip to content

fix(taskbar): focus Niri windows by compositor ID - #3705

Open
eaceaser wants to merge 1 commit into
noctalia-dev:mainfrom
eaceaser:fix/niri-taskbar-window-focus
Open

fix(taskbar): focus Niri windows by compositor ID#3705
eaceaser wants to merge 1 commit into
noctalia-dev:mainfrom
eaceaser:fix/niri-taskbar-window-focus

Conversation

@eaceaser

Copy link
Copy Markdown
Contributor

Summary

Use Niri’s compositor window IDs to give each taskbar entry a stable identity for ordering, focus state, and window actions.

On main, the taskbar builds its window list from the generic foreign-toplevel interface and reconciles those entries with compositor workspace data separately. This works when a foreign-toplevel handle is sufficient, but Niri’s workspace layout and focus operations are addressed by numeric window ID. Multiple windows from the same application can therefore be assigned by less-specific metadata such as app ID and title.

This change adds a Niri-specific taskbar path that:

  • Reads exact window IDs, workspace placement, focus state, and layout coordinates from Niri IPC.
  • Uses the matching ext-foreign-toplevel identifier as the immutable identity stored by each task.
  • Filters taskbar windows to the IDs reported for the bar’s output.
  • Orders tasks from Niri’s current workspace and layout positions.
  • Activates and closes Niri windows by compositor ID.
  • Selects the focused-window indicator using Niri’s focused window ID.
  • Recomputes the model when Niri reports window layout changes.
  • Keeps foreign-toplevel property updates pending until the protocol’s done event, so the taskbar only consumes complete records.

When the exact Niri association is temporarily unavailable, the taskbar waits for the next IPC or foreign-toplevel update instead of assigning the window through app/title matching. Other compositors retain the existing generic behavior.

Motivation

On Niri, clicking a taskbar entry does not always focus the window represented by that entry. The problem is most noticeable with several windows from the same application and with windows on secondary monitors or other workspaces.

For example, two Ghostty windows can appear in one left-to-right order while clicking their taskbar entries focuses them in the opposite order. The focused-window indicator can consequently appear under the wrong entry as well.

Niri exposes the information needed to avoid this ambiguity:

  • A stable numeric ID for every window.
  • The focused window’s ID.
  • Each window’s workspace and position in the scrolling layout.
  • An equivalent identifier through ext-foreign-toplevel.

Using that ID throughout the taskbar model ensures that displayed position, focused state, and click target all refer to the same compositor window.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Refactoring
  • Build / packaging

Related Issue

N/A

Testing

  • meson test -C build-debug --print-errorlogs — 64/64 tests passed
  • meson compile -C build-debug noctalia
  • Formatting validated with clang-format 22.1.8 using --dry-run --Werror
  • Added regression coverage for:
    • Niri window identity and workspace assignment
    • Layout-position updates
    • Exact compositor-ID preservation during reconciliation
    • Focus changes based on compositor window ID
    • Multiple windows with identical app IDs and titles
    • Atomic foreign-toplevel property publication on done
    • Pending and committed foreign-toplevel removal

Manual Coverage

  • Tested on Niri
  • Tested on Hyprland
  • Tested on Sway
  • Tested on another compositor:
  • Tested with different bar positions and density settings
  • Tested at different interface scaling values
  • Tested with multiple monitors

Screenshots / Videos

N/A — this changes taskbar window association and interaction behavior without changing its visual design.

Checklist

  • This PR is ready for review, or it is marked as Draft.
  • I read and followed the relevant guidance in CONTRIBUTING.md.
  • Formatting was validated with clang-format v22.
  • I ran the relevant build and test commands.
  • I self-reviewed the changes.
  • I checked for new warnings or errors.
  • This PR does not require end-user documentation changes.
  • This PR adds no new user-facing strings.
  • I did not edit non-English translation files.
  • I used the existing canonical names for config keys, IPC names, paths, and identifiers.

Additional Notes

gpt-5.6-sol was used extensively in debugging and implementation. I reviewed + iterated on the implementation to try to not overcomplicate this patch, but I did some digging around how other bars with Niri-specific behavior manage this, and they seem to just rely on Niri's specific IPC interface vs. using Wayland's generic interface. This avoids all ambiguity and issues with joining the Wayland vs. Niri representations together. I don't have enough context on the direction Noctalia is trying to take to know if that's a refactor worth exploring, but it does seem to be cleaner as far as the data model is concerned when using Niri.

Use Niri's ext-foreign-toplevel identifier to tie taskbar entries to numeric IPC window IDs, and prefer FocusWindow for activation. This avoids ambiguous app/title association and unreliable foreign-toplevel activation.

Keep focus and close behavior keyed by the same IDs, with tests for activation precedence, stale IDs, focus events, and close requests.
@eaceaser
eaceaser force-pushed the fix/niri-taskbar-window-focus branch from e6582ba to 1dad3fb Compare July 30, 2026 05:24
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