diff --git a/quickshell/Common/SettingsData.qml b/quickshell/Common/SettingsData.qml index fad4c53c..40509645 100644 --- a/quickshell/Common/SettingsData.qml +++ b/quickshell/Common/SettingsData.qml @@ -425,6 +425,19 @@ Singleton { property string workspaceFocusedBorderColor: "primary" property string workspaceFocusedBorderCustomColor: "#6750A4" property int workspaceFocusedBorderThickness: 2 + property bool workspaceUnfocusedMonitorSeparateAppearance: false + property string workspaceUnfocusedMonitorColorMode: "default" + property string workspaceUnfocusedMonitorFocusedCustomColor: "#6750A4" + property string workspaceUnfocusedMonitorOccupiedColorMode: "none" + property string workspaceUnfocusedMonitorOccupiedCustomColor: "#625B71" + property string workspaceUnfocusedMonitorUnfocusedColorMode: "default" + property string workspaceUnfocusedMonitorUnfocusedCustomColor: "#49454E" + property string workspaceUnfocusedMonitorUrgentColorMode: "default" + property string workspaceUnfocusedMonitorUrgentCustomColor: "#B3261E" + property bool workspaceUnfocusedMonitorBorderEnabled: false + property string workspaceUnfocusedMonitorBorderColor: "primary" + property string workspaceUnfocusedMonitorBorderCustomColor: "#6750A4" + property int workspaceUnfocusedMonitorBorderThickness: 2 property var workspaceNameIcons: ({}) property bool waveProgressEnabled: true property bool scrollTitleEnabled: true diff --git a/quickshell/Common/settings/SettingsSpec.js b/quickshell/Common/settings/SettingsSpec.js index df7e0271..f137e6f7 100644 --- a/quickshell/Common/settings/SettingsSpec.js +++ b/quickshell/Common/settings/SettingsSpec.js @@ -163,6 +163,19 @@ var SPEC = { workspaceFocusedBorderColor: { def: "primary" }, workspaceFocusedBorderCustomColor: { def: "#6750A4" }, workspaceFocusedBorderThickness: { def: 2 }, + workspaceUnfocusedMonitorSeparateAppearance: { def: false }, + workspaceUnfocusedMonitorColorMode: { def: "default" }, + workspaceUnfocusedMonitorFocusedCustomColor: { def: "#6750A4" }, + workspaceUnfocusedMonitorOccupiedColorMode: { def: "none" }, + workspaceUnfocusedMonitorOccupiedCustomColor: { def: "#625B71" }, + workspaceUnfocusedMonitorUnfocusedColorMode: { def: "default" }, + workspaceUnfocusedMonitorUnfocusedCustomColor: { def: "#49454E" }, + workspaceUnfocusedMonitorUrgentColorMode: { def: "default" }, + workspaceUnfocusedMonitorUrgentCustomColor: { def: "#B3261E" }, + workspaceUnfocusedMonitorBorderEnabled: { def: false }, + workspaceUnfocusedMonitorBorderColor: { def: "primary" }, + workspaceUnfocusedMonitorBorderCustomColor: { def: "#6750A4" }, + workspaceUnfocusedMonitorBorderThickness: { def: 2 }, workspaceNameIcons: { def: {} }, waveProgressEnabled: { def: true }, scrollTitleEnabled: { def: true }, diff --git a/quickshell/Modules/DankBar/Widgets/WorkspaceSwitcher.qml b/quickshell/Modules/DankBar/Widgets/WorkspaceSwitcher.qml index 425ddb0a..cbbcd22d 100644 --- a/quickshell/Modules/DankBar/Widgets/WorkspaceSwitcher.qml +++ b/quickshell/Modules/DankBar/Widgets/WorkspaceSwitcher.qml @@ -71,25 +71,16 @@ Item { readonly property string effectiveScreenName: { if (!SettingsData.workspaceFollowFocus) return root.screenName; - - switch (CompositorService.compositor) { - case "niri": - return NiriService.currentOutput || root.screenName; - case "hyprland": - return Hyprland.focusedWorkspace?.monitor?.name || root.screenName; - case "mango": - return MangoService.activeOutput || root.screenName; - case "sway": - case "scroll": - case "miracle": - const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true); - return focusedWs?.monitor?.name || root.screenName; - default: - return root.screenName; - } + return BarWidgetService.getFocusedScreenName() || root.screenName; } readonly property bool mangoOverviewActive: CompositorService.isMango && MangoService.isOutputInOverview(effectiveScreenName) + readonly property bool isFocusedMonitor: { + const focused = BarWidgetService.getFocusedScreenName(); + return focused === "" || root.screenName === "" || focused === root.screenName; + } + readonly property bool useUnfocusedAppearance: !isFocusedMonitor && SettingsData.workspaceUnfocusedMonitorSeparateAppearance && BarWidgetService.focusedScreenDetectionSupported + readonly property var extProjection: (useExtWorkspace && parentScreen) ? WindowManager.screenProjection(parentScreen) : null readonly property bool useExtWorkspace: { if (Quickshell.env("DMS_FORCE_EXTWS") === "1") @@ -1231,23 +1222,36 @@ Item { } } - readonly property color unfocusedColor: colorFromMode(SettingsData.workspaceUnfocusedColorMode, Theme.surfaceTextAlpha, SettingsData.workspaceUnfocusedCustomColor, Theme.surfaceTextAlpha) + function effectiveColorMode(focusedMode, unfocusedMode) { + return root.useUnfocusedAppearance ? unfocusedMode : focusedMode; + } + + function effectiveCustomColor(focusedCustom, unfocusedCustom) { + return root.useUnfocusedAppearance ? unfocusedCustom : focusedCustom; + } + + readonly property color unfocusedColor: colorFromMode(effectiveColorMode(SettingsData.workspaceUnfocusedColorMode, SettingsData.workspaceUnfocusedMonitorUnfocusedColorMode), Theme.surfaceTextAlpha, effectiveCustomColor(SettingsData.workspaceUnfocusedCustomColor, SettingsData.workspaceUnfocusedMonitorUnfocusedCustomColor), Theme.surfaceTextAlpha) readonly property color activeColor: { - if (SettingsData.workspaceColorMode === "none") + const mode = effectiveColorMode(SettingsData.workspaceColorMode, SettingsData.workspaceUnfocusedMonitorColorMode); + if (mode === "none") return unfocusedColor; - return colorFromMode(SettingsData.workspaceColorMode, Theme.primary, SettingsData.workspaceFocusedCustomColor, Theme.primary); + return colorFromMode(mode, Theme.primary, effectiveCustomColor(SettingsData.workspaceFocusedCustomColor, SettingsData.workspaceUnfocusedMonitorFocusedCustomColor), Theme.primary); } readonly property color occupiedColor: { - if (SettingsData.workspaceOccupiedColorMode === "none") + const mode = effectiveColorMode(SettingsData.workspaceOccupiedColorMode, SettingsData.workspaceUnfocusedMonitorOccupiedColorMode); + if (mode === "none") return unfocusedColor; - return colorFromMode(SettingsData.workspaceOccupiedColorMode, unfocusedColor, SettingsData.workspaceOccupiedCustomColor, Theme.secondary); + return colorFromMode(mode, unfocusedColor, effectiveCustomColor(SettingsData.workspaceOccupiedCustomColor, SettingsData.workspaceUnfocusedMonitorOccupiedCustomColor), Theme.secondary); } - readonly property color urgentColor: colorFromMode(SettingsData.workspaceUrgentColorMode, Theme.error, SettingsData.workspaceUrgentCustomColor, Theme.error) + readonly property color urgentColor: colorFromMode(effectiveColorMode(SettingsData.workspaceUrgentColorMode, SettingsData.workspaceUnfocusedMonitorUrgentColorMode), Theme.error, effectiveCustomColor(SettingsData.workspaceUrgentCustomColor, SettingsData.workspaceUnfocusedMonitorUrgentCustomColor), Theme.error) - readonly property color focusedBorderColor: colorFromMode(SettingsData.workspaceFocusedBorderColor, Theme.primary, SettingsData.workspaceFocusedBorderCustomColor, Theme.primary) + readonly property color focusedBorderColor: colorFromMode(effectiveColorMode(SettingsData.workspaceFocusedBorderColor, SettingsData.workspaceUnfocusedMonitorBorderColor), Theme.primary, effectiveCustomColor(SettingsData.workspaceFocusedBorderCustomColor, SettingsData.workspaceUnfocusedMonitorBorderCustomColor), Theme.primary) + + readonly property bool focusedBorderEnabledForMonitor: root.useUnfocusedAppearance ? SettingsData.workspaceUnfocusedMonitorBorderEnabled : SettingsData.workspaceFocusedBorderEnabled + readonly property int focusedBorderThicknessForMonitor: root.useUnfocusedAppearance ? SettingsData.workspaceUnfocusedMonitorBorderThickness : SettingsData.workspaceFocusedBorderThickness function getContrastingIconColor(bgColor) { const luminance = 0.299 * bgColor.r + 0.587 * bgColor.g + 0.114 * bgColor.b; @@ -1449,17 +1453,17 @@ Item { x: root.isVertical ? (root.widgetHeight - width) / 2 : (parent.width - width) / 2 y: root.isVertical ? (parent.height - height) / 2 : (root.widgetHeight - height) / 2 width: { - const borderWidth = (SettingsData.workspaceFocusedBorderEnabled && isActive && !isPlaceholder) ? SettingsData.workspaceFocusedBorderThickness : 0; + const borderWidth = (delegateRoot.focusedBorderEnabledForMonitor && isActive && !isPlaceholder) ? delegateRoot.focusedBorderThicknessForMonitor : 0; return delegateRoot.visualWidth + borderWidth * 2; } height: { - const borderWidth = (SettingsData.workspaceFocusedBorderEnabled && isActive && !isPlaceholder) ? SettingsData.workspaceFocusedBorderThickness : 0; + const borderWidth = (delegateRoot.focusedBorderEnabledForMonitor && isActive && !isPlaceholder) ? delegateRoot.focusedBorderThicknessForMonitor : 0; return delegateRoot.visualHeight + borderWidth * 2; } radius: Theme.cornerRadius color: "transparent" - border.width: (SettingsData.workspaceFocusedBorderEnabled && isActive && !isPlaceholder) ? SettingsData.workspaceFocusedBorderThickness : 0 - border.color: (SettingsData.workspaceFocusedBorderEnabled && isActive && !isPlaceholder) ? focusedBorderColor : "transparent" + border.width: (delegateRoot.focusedBorderEnabledForMonitor && isActive && !isPlaceholder) ? delegateRoot.focusedBorderThicknessForMonitor : 0 + border.color: (delegateRoot.focusedBorderEnabledForMonitor && isActive && !isPlaceholder) ? focusedBorderColor : "transparent" Behavior on width { NumberAnimation { diff --git a/quickshell/Modules/Settings/WorkspaceAppearanceBorderFields.qml b/quickshell/Modules/Settings/WorkspaceAppearanceBorderFields.qml new file mode 100644 index 00000000..5e658798 --- /dev/null +++ b/quickshell/Modules/Settings/WorkspaceAppearanceBorderFields.qml @@ -0,0 +1,42 @@ +pragma ComponentBehavior: Bound + +import QtQuick +import qs.Common +import qs.Modules.Settings.Widgets + +Column { + id: root + + property var borderColorOptions: [] + property string borderColorKey: "" + property string borderCustomColorKey: "" + property string borderThicknessKey: "" + property var extraTags: [] + + width: parent?.width ?? 0 + spacing: Theme.spacingS + leftPadding: Theme.spacingM + + ColorDropdownRow { + width: parent.width - parent.leftPadding + text: I18n.tr("Border Color") + settingKey: root.borderColorKey + tags: ["workspace", "focused", "border", "color", "custom"].concat(root.extraTags) + options: root.borderColorOptions + currentMode: SettingsData[root.borderColorKey] + customColor: SettingsData[root.borderCustomColorKey] || "#6750A4" + onModeSelected: mode => SettingsData.set(root.borderColorKey, mode) + onCustomColorSelected: selectedColor => SettingsData.set(root.borderCustomColorKey, selectedColor.toString()) + } + + SettingsSliderRow { + width: parent.width - parent.leftPadding + text: I18n.tr("Thickness") + value: SettingsData[root.borderThicknessKey] + minimum: 1 + maximum: 6 + unit: "px" + defaultValue: 2 + onSliderValueChanged: newValue => SettingsData.set(root.borderThicknessKey, newValue) + } +} diff --git a/quickshell/Modules/Settings/WorkspaceAppearanceCard.qml b/quickshell/Modules/Settings/WorkspaceAppearanceCard.qml index 3b478382..30a13d41 100644 --- a/quickshell/Modules/Settings/WorkspaceAppearanceCard.qml +++ b/quickshell/Modules/Settings/WorkspaceAppearanceCard.qml @@ -1,6 +1,7 @@ import QtQuick import qs.Common import qs.Services +import qs.Widgets import qs.Modules.Settings.Widgets SettingsCard { @@ -9,6 +10,7 @@ SettingsCard { iconName: "palette" title: I18n.tr("Workspace Appearance") settingKey: "workspaceAppearance" + tags: ["workspace", "focused", "color", "custom"] collapsible: true expanded: false @@ -184,120 +186,182 @@ SettingsCard { readonly property bool workspaceStateColorsVisible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango readonly property bool urgentWorkspaceColorsVisible: workspaceStateColorsVisible || CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle - ColorDropdownRow { - text: I18n.tr("Focused Color") - settingKey: "workspaceColorMode" - tags: ["workspace", "focused", "color", "custom"] - options: root.focusedColorOptions - currentMode: SettingsData.workspaceColorMode - customColor: SettingsData.workspaceFocusedCustomColor || "#6750A4" - onModeSelected: mode => SettingsData.set("workspaceColorMode", mode) - onCustomColorSelected: selectedColor => SettingsData.set("workspaceFocusedCustomColor", selectedColor.toString()) + function isFocusedAppearanceSection(section) { + return ["workspaceAppearance", "workspaceColorMode", "workspaceOccupiedColorMode", "workspaceUnfocusedColorMode", "workspaceUrgentColorMode", "workspaceFocusedBorderEnabled", "workspaceFocusedBorderColor", "workspaceFocusedBorderThickness"].includes(section); } - Rectangle { + Item { width: parent.width - height: 1 - color: Theme.outline - opacity: 0.15 - } + height: workspaceTabBar.height + Theme.spacingM - ColorDropdownRow { - text: I18n.tr("Occupied Color") - settingKey: "workspaceOccupiedColorMode" - tags: ["workspace", "occupied", "color", "custom"] - visible: root.workspaceStateColorsVisible - options: root.occupiedColorOptions - currentMode: SettingsData.workspaceOccupiedColorMode - customColor: SettingsData.workspaceOccupiedCustomColor || "#625B71" - onModeSelected: mode => SettingsData.set("workspaceOccupiedColorMode", mode) - onCustomColorSelected: selectedColor => SettingsData.set("workspaceOccupiedCustomColor", selectedColor.toString()) - } + DankTabBar { + id: workspaceTabBar + width: parent.width + tabHeight: 44 + showIcons: false + model: [({ + "text": I18n.tr("Focused Display", "workspace appearance tab") + }), ({ + "text": I18n.tr("Unfocused Display(s)", "workspace appearance tab") + })] + onTabClicked: index => currentIndex = index + Component.onCompleted: Qt.callLater(updateIndicator) - Rectangle { - width: parent.width - height: 1 - color: Theme.outline - opacity: 0.15 - visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango - } + Connections { + target: SettingsSearchService - ColorDropdownRow { - text: I18n.tr("Unfocused Color") - settingKey: "workspaceUnfocusedColorMode" - tags: ["workspace", "unfocused", "color", "custom"] - options: root.unfocusedColorOptions - defaultColor: Theme.surfaceText - currentMode: SettingsData.workspaceUnfocusedColorMode - customColor: SettingsData.workspaceUnfocusedCustomColor || "#49454E" - onModeSelected: mode => SettingsData.set("workspaceUnfocusedColorMode", mode) - onCustomColorSelected: selectedColor => SettingsData.set("workspaceUnfocusedCustomColor", selectedColor.toString()) - } + function onTargetSectionChanged() { + const section = SettingsSearchService.targetSection; + if (!section) + return; - Rectangle { - width: parent.width - height: 1 - color: Theme.outline - opacity: 0.15 - visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango || CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle - } + if (section.startsWith("workspaceUnfocusedMonitor")) { + root.expanded = true; + workspaceTabBar.currentIndex = 1; + } else if (root.isFocusedAppearanceSection(section)) { + root.expanded = true; + workspaceTabBar.currentIndex = 0; + } else { + return; + } - ColorDropdownRow { - text: I18n.tr("Urgent Color") - settingKey: "workspaceUrgentColorMode" - tags: ["workspace", "urgent", "color", "custom"] - visible: root.urgentWorkspaceColorsVisible - options: root.urgentColorOptions - defaultColor: Theme.error - currentMode: SettingsData.workspaceUrgentColorMode - customColor: SettingsData.workspaceUrgentCustomColor || "#B3261E" - onModeSelected: mode => SettingsData.set("workspaceUrgentColorMode", mode) - onCustomColorSelected: selectedColor => SettingsData.set("workspaceUrgentCustomColor", selectedColor.toString()) - } - - Rectangle { - width: parent.width - height: 1 - color: Theme.outline - opacity: 0.15 - } - - SettingsToggleRow { - settingKey: "workspaceFocusedBorderEnabled" - tags: ["workspace", "border", "outline", "focused", "ring"] - text: I18n.tr("Focused Border") - description: I18n.tr("Show an outline ring around the focused workspace indicator") - checked: SettingsData.workspaceFocusedBorderEnabled - onToggled: checked => SettingsData.set("workspaceFocusedBorderEnabled", checked) + Qt.callLater(workspaceTabBar.updateIndicator); + } + } + } } Column { + id: focusedTab width: parent.width - spacing: Theme.spacingS - visible: SettingsData.workspaceFocusedBorderEnabled - leftPadding: Theme.spacingM + spacing: Theme.spacingM + visible: workspaceTabBar.currentIndex === 0 - ColorDropdownRow { - width: parent.width - parent.leftPadding - text: I18n.tr("Border Color") - settingKey: "workspaceFocusedBorderColor" - tags: ["workspace", "focused", "border", "color", "custom"] - options: root.borderColorOptions - currentMode: SettingsData.workspaceFocusedBorderColor - customColor: SettingsData.workspaceFocusedBorderCustomColor || "#6750A4" - onModeSelected: mode => SettingsData.set("workspaceFocusedBorderColor", mode) - onCustomColorSelected: selectedColor => SettingsData.set("workspaceFocusedBorderCustomColor", selectedColor.toString()) + WorkspaceAppearanceColorOptions { + focusedColorOptions: root.focusedColorOptions + occupiedColorOptions: root.occupiedColorOptions + unfocusedColorOptions: root.unfocusedColorOptions + urgentColorOptions: root.urgentColorOptions + occupiedColorVisible: root.workspaceStateColorsVisible + urgentColorVisible: root.urgentWorkspaceColorsVisible + focusedColorModeKey: "workspaceColorMode" + focusedCustomColorKey: "workspaceFocusedCustomColor" + occupiedColorModeKey: "workspaceOccupiedColorMode" + occupiedCustomColorKey: "workspaceOccupiedCustomColor" + unfocusedColorModeKey: "workspaceUnfocusedColorMode" + unfocusedCustomColorKey: "workspaceUnfocusedCustomColor" + urgentColorModeKey: "workspaceUrgentColorMode" + urgentCustomColorKey: "workspaceUrgentCustomColor" } - SettingsSliderRow { - width: parent.width - parent.leftPadding - text: I18n.tr("Thickness") - value: SettingsData.workspaceFocusedBorderThickness - minimum: 1 - maximum: 6 - unit: "px" - defaultValue: 2 - onSliderValueChanged: newValue => SettingsData.set("workspaceFocusedBorderThickness", newValue) + Rectangle { + width: parent.width + height: 1 + color: Theme.outline + opacity: 0.15 + } + + SettingsToggleRow { + settingKey: "workspaceFocusedBorderEnabled" + tags: ["workspace", "border", "outline", "focused", "ring"] + text: I18n.tr("Focused Border") + description: I18n.tr("Show an outline ring around the focused workspace indicator") + checked: SettingsData.workspaceFocusedBorderEnabled + onToggled: checked => SettingsData.set("workspaceFocusedBorderEnabled", checked) + } + + WorkspaceAppearanceBorderFields { + visible: SettingsData.workspaceFocusedBorderEnabled + borderColorOptions: root.borderColorOptions + borderColorKey: "workspaceFocusedBorderColor" + borderCustomColorKey: "workspaceFocusedBorderCustomColor" + borderThicknessKey: "workspaceFocusedBorderThickness" + } + } + + Column { + id: unfocusedTab + width: parent.width + spacing: Theme.spacingM + visible: workspaceTabBar.currentIndex === 1 + + StyledText { + width: parent.width + visible: !BarWidgetService.focusedScreenDetectionSupported + text: I18n.tr("Separate appearance for unfocused displays is not supported on this compositor.") + wrapMode: Text.WordWrap + color: Theme.surfaceVariantText + font.pixelSize: Theme.fontSizeMedium + } + + SettingsToggleRow { + visible: BarWidgetService.focusedScreenDetectionSupported + settingKey: "workspaceUnfocusedMonitorSeparateAppearance" + tags: ["workspace", "unfocused", "monitor", "display", "separate", "color"] + text: I18n.tr("Separate Appearance for Unfocused Display(s)") + description: I18n.tr("Use different workspace colors on displays that are not focused") + checked: SettingsData.workspaceUnfocusedMonitorSeparateAppearance + onToggled: checked => SettingsData.set("workspaceUnfocusedMonitorSeparateAppearance", checked) + } + + Rectangle { + width: parent.width + height: 1 + color: Theme.outline + opacity: 0.15 + visible: BarWidgetService.focusedScreenDetectionSupported + } + + Column { + id: unfocusedOptions + width: parent.width + spacing: Theme.spacingM + visible: BarWidgetService.focusedScreenDetectionSupported + enabled: SettingsData.workspaceUnfocusedMonitorSeparateAppearance + opacity: enabled ? 1 : 0.5 + + WorkspaceAppearanceColorOptions { + focusedColorOptions: root.focusedColorOptions + occupiedColorOptions: root.occupiedColorOptions + unfocusedColorOptions: root.unfocusedColorOptions + urgentColorOptions: root.urgentColorOptions + occupiedColorVisible: root.workspaceStateColorsVisible + urgentColorVisible: root.urgentWorkspaceColorsVisible + extraTags: ["unfocused", "monitor", "display"] + focusedColorModeKey: "workspaceUnfocusedMonitorColorMode" + focusedCustomColorKey: "workspaceUnfocusedMonitorFocusedCustomColor" + occupiedColorModeKey: "workspaceUnfocusedMonitorOccupiedColorMode" + occupiedCustomColorKey: "workspaceUnfocusedMonitorOccupiedCustomColor" + unfocusedColorModeKey: "workspaceUnfocusedMonitorUnfocusedColorMode" + unfocusedCustomColorKey: "workspaceUnfocusedMonitorUnfocusedCustomColor" + urgentColorModeKey: "workspaceUnfocusedMonitorUrgentColorMode" + urgentCustomColorKey: "workspaceUnfocusedMonitorUrgentCustomColor" + } + + Rectangle { + width: parent.width + height: 1 + color: Theme.outline + opacity: 0.15 + } + + SettingsToggleRow { + settingKey: "workspaceUnfocusedMonitorBorderEnabled" + tags: ["workspace", "border", "outline", "focused", "ring", "unfocused", "monitor", "display"] + text: I18n.tr("Focused Border") + description: I18n.tr("Show an outline ring around the focused workspace indicator") + checked: SettingsData.workspaceUnfocusedMonitorBorderEnabled + onToggled: checked => SettingsData.set("workspaceUnfocusedMonitorBorderEnabled", checked) + } + + WorkspaceAppearanceBorderFields { + visible: SettingsData.workspaceUnfocusedMonitorBorderEnabled + borderColorOptions: root.borderColorOptions + extraTags: ["unfocused", "monitor", "display"] + borderColorKey: "workspaceUnfocusedMonitorBorderColor" + borderCustomColorKey: "workspaceUnfocusedMonitorBorderCustomColor" + borderThicknessKey: "workspaceUnfocusedMonitorBorderThickness" + } } } } diff --git a/quickshell/Modules/Settings/WorkspaceAppearanceColorOptions.qml b/quickshell/Modules/Settings/WorkspaceAppearanceColorOptions.qml new file mode 100644 index 00000000..e5952729 --- /dev/null +++ b/quickshell/Modules/Settings/WorkspaceAppearanceColorOptions.qml @@ -0,0 +1,101 @@ +pragma ComponentBehavior: Bound + +import QtQuick +import qs.Common + +Column { + id: root + + property var focusedColorOptions: [] + property var occupiedColorOptions: [] + property var unfocusedColorOptions: [] + property var urgentColorOptions: [] + + property bool occupiedColorVisible: true + property bool urgentColorVisible: true + + property string focusedColorModeKey: "" + property string focusedCustomColorKey: "" + property string occupiedColorModeKey: "" + property string occupiedCustomColorKey: "" + property string unfocusedColorModeKey: "" + property string unfocusedCustomColorKey: "" + property string urgentColorModeKey: "" + property string urgentCustomColorKey: "" + + property var extraTags: [] + + width: parent?.width ?? 0 + spacing: Theme.spacingM + + ColorDropdownRow { + text: I18n.tr("Focused Color") + settingKey: root.focusedColorModeKey + tags: ["workspace", "focused", "color", "custom"].concat(root.extraTags) + options: root.focusedColorOptions + currentMode: SettingsData[root.focusedColorModeKey] + customColor: SettingsData[root.focusedCustomColorKey] || "#6750A4" + onModeSelected: mode => SettingsData.set(root.focusedColorModeKey, mode) + onCustomColorSelected: selectedColor => SettingsData.set(root.focusedCustomColorKey, selectedColor.toString()) + } + + Rectangle { + width: parent.width + height: 1 + color: Theme.outline + opacity: 0.15 + } + + ColorDropdownRow { + text: I18n.tr("Occupied Color") + settingKey: root.occupiedColorModeKey + tags: ["workspace", "occupied", "color", "custom"].concat(root.extraTags) + visible: root.occupiedColorVisible + options: root.occupiedColorOptions + currentMode: SettingsData[root.occupiedColorModeKey] + customColor: SettingsData[root.occupiedCustomColorKey] || "#625B71" + onModeSelected: mode => SettingsData.set(root.occupiedColorModeKey, mode) + onCustomColorSelected: selectedColor => SettingsData.set(root.occupiedCustomColorKey, selectedColor.toString()) + } + + Rectangle { + width: parent.width + height: 1 + color: Theme.outline + opacity: 0.15 + visible: root.occupiedColorVisible + } + + ColorDropdownRow { + text: I18n.tr("Unfocused Color") + settingKey: root.unfocusedColorModeKey + tags: ["workspace", "unfocused", "color", "custom"].concat(root.extraTags) + options: root.unfocusedColorOptions + defaultColor: Theme.surfaceText + currentMode: SettingsData[root.unfocusedColorModeKey] + customColor: SettingsData[root.unfocusedCustomColorKey] || "#49454E" + onModeSelected: mode => SettingsData.set(root.unfocusedColorModeKey, mode) + onCustomColorSelected: selectedColor => SettingsData.set(root.unfocusedCustomColorKey, selectedColor.toString()) + } + + Rectangle { + width: parent.width + height: 1 + color: Theme.outline + opacity: 0.15 + visible: root.urgentColorVisible + } + + ColorDropdownRow { + text: I18n.tr("Urgent Color") + settingKey: root.urgentColorModeKey + tags: ["workspace", "urgent", "color", "custom"].concat(root.extraTags) + visible: root.urgentColorVisible + options: root.urgentColorOptions + defaultColor: Theme.error + currentMode: SettingsData[root.urgentColorModeKey] + customColor: SettingsData[root.urgentCustomColorKey] || "#B3261E" + onModeSelected: mode => SettingsData.set(root.urgentColorModeKey, mode) + onCustomColorSelected: selectedColor => SettingsData.set(root.urgentCustomColorKey, selectedColor.toString()) + } +} diff --git a/quickshell/Services/BarWidgetService.qml b/quickshell/Services/BarWidgetService.qml index 66dc4e51..8ffaa02c 100644 --- a/quickshell/Services/BarWidgetService.qml +++ b/quickshell/Services/BarWidgetService.qml @@ -70,11 +70,15 @@ Singleton { return screens.length > 0 ? widgetRegistry[widgetId][screens[0]] : null; } + readonly property bool focusedScreenDetectionSupported: CompositorService.isHyprland || CompositorService.isNiri || CompositorService.isMango || CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle + function getFocusedScreenName() { if (CompositorService.isHyprland && Hyprland.focusedWorkspace?.monitor) return Hyprland.focusedWorkspace.monitor.name; if (CompositorService.isNiri && NiriService.currentOutput) return NiriService.currentOutput; + if (CompositorService.isMango && MangoService.activeOutput) + return MangoService.activeOutput; if (CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle) { const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true); return focusedWs?.monitor?.name || ""; diff --git a/quickshell/translations/settings_search_index.json b/quickshell/translations/settings_search_index.json index 4cd501ff..552b93cc 100644 --- a/quickshell/translations/settings_search_index.json +++ b/quickshell/translations/settings_search_index.json @@ -1899,6 +1899,33 @@ ], "description": "Show an outline ring around the focused workspace indicator" }, + { + "section": "workspaceUnfocusedMonitorBorderEnabled", + "label": "Focused Border", + "tabIndex": 6, + "category": "Dank Bar", + "keywords": [ + "around", + "bar", + "border", + "dank", + "desktop", + "display", + "focused", + "indicator", + "monitor", + "outline", + "panel", + "ring", + "show", + "statusbar", + "topbar", + "unfocused", + "virtual", + "workspace" + ], + "description": "Show an outline ring around the focused workspace indicator" + }, { "section": "barFontScale", "label": "Font Scale", @@ -1979,6 +2006,44 @@ "icon": "opacity", "description": "Controls opacity of the bar background" }, + { + "section": "workspaceUnfocusedMonitorSeparateAppearance", + "label": "Separate Appearance for Unfocused Display(s)", + "tabIndex": 6, + "category": "Dank Bar", + "keywords": [ + "appearance", + "bar", + "color", + "colors", + "colour", + "colours", + "dank", + "desktop", + "different", + "display", + "display(s)", + "displays", + "focused", + "hue", + "monitor", + "monitors", + "output", + "outputs", + "palette", + "panel", + "screen", + "screens", + "separate", + "statusbar", + "tint", + "topbar", + "unfocused", + "virtual", + "workspace" + ], + "description": "Use different workspace colors on displays that are not focused" + }, { "section": "barShadow", "label": "Shadow Override",