Skip to content

feat(bar): add bar.screens to restrict the bar to specific monitors - #6501

Open
fivves wants to merge 2 commits into
basecamp:quattrofrom
fivves:feat/bar-screens
Open

feat(bar): add bar.screens to restrict the bar to specific monitors#6501
fivves wants to merge 2 commits into
basecamp:quattrofrom
fivves:feat/bar-screens

Conversation

@fivves

@fivves fivves commented Aug 2, 2026

Copy link
Copy Markdown

Summary

The bar currently creates a panel on every connected screen (Variants { model: Quickshell.screens }). On multi-monitor setups there's no way to keep the bar on just one monitor — the only workaround is editing Bar.qml directly, which gets clobbered on every omarchy update. Waybar solved this years ago with a per-output config; this brings the same idea to shell.json.

Adds an optional bar.screens key: a list of Wayland output names the bar should be created on. Empty or omitted keeps the current behavior (bar on every screen).

{
  "bar": {
    "position": "top",
    "screens": ["DP-1"]
  }
}

Changes

  • shell/plugins/bar/Bar.qml: new screenFilter/barScreens properties; all three per-screen Variants (BarPanel, DragGhostPanel, BarMoveGhostPanel) now bind to barScreens instead of Quickshell.screens directly
  • shell/shell.qml: screens: [] in the builtin fallback config
  • config/omarchy/shell.json: "screens": [] in the default config
  • Docs updated in docs/omarchy-shell.md and shell/plugins/bar/README.md

Behavior

  • Default: unchanged, one bar per screen
  • "screens": ["DP-1"]: only DP-1 gets a bar; names match hyprctl monitors output
  • Reactive: re-evaluates when screens hotplug or shell.json reloads, so changing the value moves the bar live without a shell restart

Testing

  • qmllint passes on both modified QML files
  • The filter expression is the same one I've been running on a dual-monitor setup (bar on DP-1 only, drag/move ghosts filtered too), verified working across shell restarts

Adds an optional screens list to the bar: section of shell.json.
When set to output names like ["DP-1"], only those screens get a bar
panel plus the drag/move ghost panels. Empty or unset keeps the
default of one bar per screen.

The bar was hardcoded to create a panel on every screen via
Variants { model: Quickshell.screens } with no config option, so a
single-monitor bar required editing Bar.qml, which gets clobbered on
every omarchy update.

- shell/plugins/bar/Bar.qml: screenFilter/barScreens properties; all
  three Variants bind to barScreens
- shell/shell.qml: screens: [] in the builtin fallback config
- config/omarchy/shell.json: screens: [] in the default config
- docs/omarchy-shell.md and shell/plugins/bar/README.md: document the key
Copilot AI review requested due to automatic review settings August 2, 2026 05:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds monitor-specific filtering for the built-in bar while preserving all-screen defaults.

Changes:

  • Filters bar and ghost panels by configured output names.
  • Adds default screens: [] configuration.
  • Documents bar.screens.

Tip

If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
shell/plugins/bar/Bar.qml Implements reactive screen filtering.
shell/shell.qml Adds the fallback default.
config/omarchy/shell.json Adds the shipped default.
shell/plugins/bar/README.md Documents bar configuration.
docs/omarchy-shell.md Documents the shell-level setting.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread shell/plugins/bar/Bar.qml Outdated
Comment on lines +61 to +63
readonly property var barScreens: root.screenFilter.length > 0
? Quickshell.screens.filter(s => root.screenFilter.indexOf(s.name) !== -1)
: Quickshell.screens

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Addressed in 78a688c. Moved the filter logic from Bar.qml into BarModel.js (screenNames/screensFor) so it runs in the existing node harness, and added 11 assertions to test/shell.d/bar-test.sh covering omitted/empty filters, matching and non-matching output names, non-array tolerance, and all three per-screen Variants binding the configured filter. Caveat: this harness cannot execute QML, so live hotplug re-evaluation is not directly testable here — the barScreens binding references Quickshell.screens and barConfig directly, so it re-evaluates on screen changes and config reloads, and the structural wiring is now guarded by the suite.

Comment thread docs/omarchy-shell.md Outdated
Comment on lines +156 to +158
9. `bar.screens` is an optional list of Wayland output names that limits
which monitors get a bar (e.g. `["DP-1"]`). Empty or omitted means every
screen gets a bar.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in 78a688c. Rule 9 now scopes bar.screens to the built-in bar (omarchy.bar) and notes that replacement bar plugins receive barConfig but must implement the filtering themselves.

- Move the screen filter logic from Bar.qml into BarModel.js
  (screenNames/screensFor) so it is unit-testable in the existing
  node harness
- bar-test.sh: 11 new assertions covering omitted/empty filters,
  matching and non-matching output names, non-array tolerance, and
  all three per-screen Variants binding the configured filter
- docs/omarchy-shell.md: scope rule 9 to the built-in bar; replacement
  bar plugins receive barConfig but must implement filtering themselves
Copilot AI review requested due to automatic review settings August 2, 2026 05:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (1)

shell/plugins/bar/Bar.qml:56

  • The filter only changes the three bar Variants, but the notification service still creates a popup on every Quickshell.screens output and always calls popupPlacement with the global bar clearance (shell/plugins/notifications/Service.qml:788-804). With screens: ["DP-1"], notifications on every other output remain displaced as though a top/right bar existed. Please expose/check whether modelData is included in the bar screen filter and use only the outer gap when that output has no bar.
  readonly property var barScreens: BarModel.screensFor(barConfig, Quickshell.screens)

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