diff --git a/quickshell/Common/LayoutResolver.js b/quickshell/Common/LayoutResolver.js index 52d56bb9a..6f9b86850 100644 --- a/quickshell/Common/LayoutResolver.js +++ b/quickshell/Common/LayoutResolver.js @@ -32,6 +32,8 @@ function screenMatches(screen, preferences, screens, displayNameMode) { } function coversScreen(config, screen, screens, displayNameMode) { + if ((config?.hideOnLastDisplay ?? false) && screens.length === 1) + return false; const preferences = config?.screenPreferences || ["all"]; return preferences.includes("all") || screenMatches(screen, preferences, screens, displayNameMode) || ((config?.showOnLastDisplay ?? false) && screens.length === 1); } diff --git a/quickshell/Modules/Settings/BarHubHeader.qml b/quickshell/Modules/Settings/BarHubHeader.qml index 9bdf61146..b1eab7c7c 100644 --- a/quickshell/Modules/Settings/BarHubHeader.qml +++ b/quickshell/Modules/Settings/BarHubHeader.qml @@ -47,7 +47,8 @@ Column { enabled: true, position: freeEdge >= 0 ? freeEdge : (defaultBar.position ?? 0), screenPreferences: ["all"], - showOnLastDisplay: true + showOnLastDisplay: true, + hideOnLastDisplay: false }); delete newBar.island; delete newBar.dot; diff --git a/quickshell/Modules/Settings/DBarTab.qml b/quickshell/Modules/Settings/DBarTab.qml index 0190210d2..c8edc580e 100644 --- a/quickshell/Modules/Settings/DBarTab.qml +++ b/quickshell/Modules/Settings/DBarTab.qml @@ -32,8 +32,22 @@ Item { } function setBarShowOnLastDisplay(barId, value) { - SettingsData.updateBarConfig(barId, { - showOnLastDisplay: value + SettingsData.updateBarConfig(barId, value ? { + showOnLastDisplay: true, + hideOnLastDisplay: false + } : { + showOnLastDisplay: false + }); + if (Quickshell.screens.length === 1) + bar.notifyHorizontalBarChange(); + } + + function setBarHideOnLastDisplay(barId, value) { + SettingsData.updateBarConfig(barId, value ? { + hideOnLastDisplay: true, + showOnLastDisplay: false + } : { + hideOnLastDisplay: false }); if (Quickshell.screens.length === 1) bar.notifyHorizontalBarChange(); @@ -223,8 +237,11 @@ Item { allowEmpty: true showLastDisplay: true showOnLastDisplay: bar.selectedBarConfig?.showOnLastDisplay ?? true + allowHideOnLastDisplay: true + hideOnLastDisplay: bar.selectedBarConfig?.hideOnLastDisplay ?? false preferencesHandler: prefs => dankBarTab.setBarScreenPreferences(bar.selectedBarId, prefs) onLastDisplayToggled: checked => dankBarTab.setBarShowOnLastDisplay(bar.selectedBarId, checked) + onHideOnLastDisplayToggled: checked => dankBarTab.setBarHideOnLastDisplay(bar.selectedBarId, checked) } } diff --git a/quickshell/Modules/Settings/DisplayWidgetsTab.qml b/quickshell/Modules/Settings/DisplayWidgetsTab.qml index bb2a56c87..222467edb 100644 --- a/quickshell/Modules/Settings/DisplayWidgetsTab.qml +++ b/quickshell/Modules/Settings/DisplayWidgetsTab.qml @@ -90,8 +90,11 @@ Item { function setShowOnLastDisplay(componentId, enabled) { if (componentId.startsWith("bar:")) { const barId = componentId.substring(4); - SettingsData.updateBarConfig(barId, { - "showOnLastDisplay": enabled + SettingsData.updateBarConfig(barId, enabled ? { + "showOnLastDisplay": true, + "hideOnLastDisplay": false + } : { + "showOnLastDisplay": false }); return; } @@ -101,6 +104,25 @@ Item { SettingsData.set("showOnLastDisplay", newPrefs); } + function getHideOnLastDisplay(componentId) { + if (!componentId.startsWith("bar:")) + return false; + const barId = componentId.substring(4); + return SettingsData.getBarConfig(barId)?.hideOnLastDisplay ?? false; + } + + function setHideOnLastDisplay(componentId, enabled) { + if (!componentId.startsWith("bar:")) + return; + const barId = componentId.substring(4); + SettingsData.updateBarConfig(barId, enabled ? { + "hideOnLastDisplay": true, + "showOnLastDisplay": false + } : { + "hideOnLastDisplay": false + }); + } + SettingsPage { id: mainColumn @@ -154,8 +176,11 @@ Item { allowEmpty: true showLastDisplay: ["notifications", "osd", "toast", "notepad"].includes(componentCard.modelData.id) || componentCard.modelData.id.startsWith("bar:") showOnLastDisplay: root.getShowOnLastDisplay(componentCard.modelData.id) + allowHideOnLastDisplay: componentCard.modelData.id.startsWith("bar:") + hideOnLastDisplay: root.getHideOnLastDisplay(componentCard.modelData.id) preferencesHandler: prefs => root.setScreenPreferences(componentCard.modelData.id, prefs) onLastDisplayToggled: checked => root.setShowOnLastDisplay(componentCard.modelData.id, checked) + onHideOnLastDisplayToggled: checked => root.setHideOnLastDisplay(componentCard.modelData.id, checked) } SettingsToggleRow { diff --git a/quickshell/Modules/Settings/Widgets/BarSelectionState.qml b/quickshell/Modules/Settings/Widgets/BarSelectionState.qml index 4daa46334..db87a13a3 100644 --- a/quickshell/Modules/Settings/Widgets/BarSelectionState.qml +++ b/quickshell/Modules/Settings/Widgets/BarSelectionState.qml @@ -137,7 +137,7 @@ Item { return false; const prefs = c.screenPreferences || ["all"]; if (prefs.length > 0) - return true; + return !(c.hideOnLastDisplay ?? false) || Quickshell.screens.length !== 1; return (c.showOnLastDisplay ?? true) && Quickshell.screens.length === 1; } diff --git a/quickshell/Modules/Settings/Widgets/SettingsDisplayPicker.qml b/quickshell/Modules/Settings/Widgets/SettingsDisplayPicker.qml index b6e2a3cc6..a044383ca 100644 --- a/quickshell/Modules/Settings/Widgets/SettingsDisplayPicker.qml +++ b/quickshell/Modules/Settings/Widgets/SettingsDisplayPicker.qml @@ -12,11 +12,14 @@ Column { property bool allowEmpty: false property bool showLastDisplay: false property bool showOnLastDisplay: false + property bool allowHideOnLastDisplay: false + property bool hideOnLastDisplay: false readonly property bool localAllDisplays: !Array.isArray(displayPreferences) || displayPreferences.includes("all") || (emptyMeansAll && displayPreferences.length === 0) // A callback, not a signal: Qt 6.12 hands signal array parameters over as a V4Sequence that fails Array.isArray. property var preferencesHandler: null signal lastDisplayToggled(bool checked) + signal hideOnLastDisplayToggled(bool checked) width: parent?.width ?? 0 spacing: Theme.groupedListGap @@ -46,6 +49,13 @@ Column { onToggled: checked => root.lastDisplayToggled(checked) } + SettingsToggleRow { + text: I18n.tr("Hide on last display", "bar display assignment option") + visible: root.allowHideOnLastDisplay + checked: root.hideOnLastDisplay + onToggled: checked => root.hideOnLastDisplayToggled(checked) + } + Repeater { model: Quickshell.screens diff --git a/quickshell/tests/layout-resolver.test.mjs b/quickshell/tests/layout-resolver.test.mjs index 2cb5c48a3..2710c1232 100644 --- a/quickshell/tests/layout-resolver.test.mjs +++ b/quickshell/tests/layout-resolver.test.mjs @@ -49,6 +49,9 @@ test("absent, empty, explicit and fallback assignments remain distinct", () => { assert.equal(covers({ screenPreferences: ["DP-2"] }), false); assert.equal(covers({ screenPreferences: [], showOnLastDisplay: true }), count === 1); assert.equal(covers({ screenPreferences: ["missing"], showOnLastDisplay: true }), count === 1); + assert.equal(covers({ hideOnLastDisplay: true }), count !== 1); + assert.equal(covers({ screenPreferences: ["DP-1"], hideOnLastDisplay: true }), count !== 1); + assert.equal(covers({ screenPreferences: [], showOnLastDisplay: true, hideOnLastDisplay: true }), false); } });