From c6b9b3656649e12b4e40b3e6c99fa183c78989bc Mon Sep 17 00:00:00 2001 From: Vladimir Date: Wed, 11 Mar 2026 15:57:05 +0100 Subject: [PATCH] feat: highlight active workspace app tiles (#1957) * feat: highlight active workspace app tiles * feat: add workspace active-app highlight toggle --- quickshell/Common/SettingsData.qml | 1 + quickshell/Common/settings/SettingsSpec.js | 1 + .../DankBar/Widgets/WorkspaceSwitcher.qml | 62 ++++++++++++++----- quickshell/Modules/Settings/WorkspacesTab.qml | 10 +++ 4 files changed, 58 insertions(+), 16 deletions(-) diff --git a/quickshell/Common/SettingsData.qml b/quickshell/Common/SettingsData.qml index 0c2d0485..44523253 100644 --- a/quickshell/Common/SettingsData.qml +++ b/quickshell/Common/SettingsData.qml @@ -280,6 +280,7 @@ Singleton { property bool showOccupiedWorkspacesOnly: false property bool reverseScrolling: false property bool dwlShowAllTags: false + property bool workspaceActiveAppHighlightEnabled: false property string workspaceColorMode: "default" property string workspaceOccupiedColorMode: "none" property string workspaceUnfocusedColorMode: "default" diff --git a/quickshell/Common/settings/SettingsSpec.js b/quickshell/Common/settings/SettingsSpec.js index f5e2a068..69bfd909 100644 --- a/quickshell/Common/settings/SettingsSpec.js +++ b/quickshell/Common/settings/SettingsSpec.js @@ -123,6 +123,7 @@ var SPEC = { showOccupiedWorkspacesOnly: { def: false }, reverseScrolling: { def: false }, dwlShowAllTags: { def: false }, + workspaceActiveAppHighlightEnabled: { def: false }, workspaceColorMode: { def: "default" }, workspaceOccupiedColorMode: { def: "none" }, workspaceUnfocusedColorMode: { def: "default" }, diff --git a/quickshell/Modules/DankBar/Widgets/WorkspaceSwitcher.qml b/quickshell/Modules/DankBar/Widgets/WorkspaceSwitcher.qml index 02094b79..0314c68c 100644 --- a/quickshell/Modules/DankBar/Widgets/WorkspaceSwitcher.qml +++ b/quickshell/Modules/DankBar/Widgets/WorkspaceSwitcher.qml @@ -1470,6 +1470,10 @@ Item { delegate: Item { width: root.appIconSize height: root.appIconSize + readonly property bool appHighlightActive: SettingsData.workspaceActiveAppHighlightEnabled && modelData.active + readonly property color appBorderColor: appHighlightActive ? focusedBorderColor : Theme.primarySelected + readonly property color appGlyphColor: appHighlightActive ? focusedBorderColor : Theme.primary + readonly property real appOpacity: (modelData.active || isActive) ? 1.0 : rowAppMouseArea.containsMouse ? 0.8 : 0.6 IconImage { id: rowAppIcon @@ -1485,14 +1489,14 @@ Item { color: Theme.surfaceContainer radius: Theme.cornerRadius * (root.appIconSize / 40) border.width: 1 - border.color: Theme.primarySelected - opacity: (modelData.active || isActive) ? 1.0 : rowAppMouseArea.containsMouse ? 0.8 : 0.6 + border.color: appBorderColor + opacity: appOpacity StyledText { anchors.centerIn: parent text: (modelData.fallbackText || "?").charAt(0).toUpperCase() font.pixelSize: parent.width * 0.45 - color: Theme.primary + color: appGlyphColor font.weight: Font.Bold } } @@ -1503,14 +1507,14 @@ Item { color: Theme.surfaceContainer radius: Theme.cornerRadius * (root.appIconSize / 40) border.width: 1 - border.color: Theme.primarySelected - opacity: (modelData.active || isActive) ? 1.0 : rowAppMouseArea.containsMouse ? 0.8 : 0.6 + border.color: appBorderColor + opacity: appOpacity DankIcon { anchors.centerIn: parent size: parent.width * 0.7 name: "sports_esports" - color: Theme.primary + color: appGlyphColor } } @@ -1523,11 +1527,12 @@ Item { layer.effect: MultiEffect { saturation: 0 colorization: 1 - colorizationColor: isActive ? quickshellIconActiveColor : quickshellIconInactiveColor + colorizationColor: appHighlightActive ? focusedBorderColor : (isActive ? quickshellIconActiveColor : quickshellIconInactiveColor) } } IconImage { + id: rowSteamIcon anchors.fill: parent source: modelData.icon opacity: modelData.active ? 1.0 : rowAppMouseArea.containsMouse ? 0.8 : 0.6 @@ -1538,11 +1543,21 @@ Item { anchors.centerIn: parent size: root.appIconSize name: "sports_esports" - color: Theme.widgetTextColor + color: appHighlightActive ? focusedBorderColor : Theme.widgetTextColor opacity: modelData.active ? 1.0 : rowAppMouseArea.containsMouse ? 0.8 : 0.6 visible: modelData.isSteamApp && !modelData.icon } + Rectangle { + anchors.fill: parent + visible: (rowAppIcon.visible || rowSteamIcon.visible || modelData.isQuickshell) && appHighlightActive + color: "transparent" + radius: Theme.cornerRadius * (root.appIconSize / 40) + border.width: 1 + border.color: focusedBorderColor + z: 1 + } + MouseArea { id: rowAppMouseArea anchors.fill: parent @@ -1624,6 +1639,10 @@ Item { delegate: Item { width: root.appIconSize height: root.appIconSize + readonly property bool appHighlightActive: SettingsData.workspaceActiveAppHighlightEnabled && modelData.active + readonly property color appBorderColor: appHighlightActive ? focusedBorderColor : Theme.primarySelected + readonly property color appGlyphColor: appHighlightActive ? focusedBorderColor : Theme.primary + readonly property real appOpacity: (modelData.active || isActive) ? 1.0 : colAppMouseArea.containsMouse ? 0.8 : 0.6 IconImage { id: colAppIcon @@ -1639,14 +1658,14 @@ Item { color: Theme.surfaceContainer radius: Theme.cornerRadius * (root.appIconSize / 40) border.width: 1 - border.color: Theme.primarySelected - opacity: (modelData.active || isActive) ? 1.0 : colAppMouseArea.containsMouse ? 0.8 : 0.6 + border.color: appBorderColor + opacity: appOpacity StyledText { anchors.centerIn: parent text: (modelData.fallbackText || "?").charAt(0).toUpperCase() font.pixelSize: parent.width * 0.45 - color: Theme.primary + color: appGlyphColor font.weight: Font.Bold } } @@ -1657,14 +1676,14 @@ Item { color: Theme.surfaceContainer radius: Theme.cornerRadius * (root.appIconSize / 40) border.width: 1 - border.color: Theme.primarySelected - opacity: (modelData.active || isActive) ? 1.0 : colAppMouseArea.containsMouse ? 0.8 : 0.6 + border.color: appBorderColor + opacity: appOpacity DankIcon { anchors.centerIn: parent size: parent.width * 0.7 name: "sports_esports" - color: Theme.primary + color: appGlyphColor } } @@ -1677,11 +1696,12 @@ Item { layer.effect: MultiEffect { saturation: 0 colorization: 1 - colorizationColor: isActive ? quickshellIconActiveColor : quickshellIconInactiveColor + colorizationColor: appHighlightActive ? focusedBorderColor : (isActive ? quickshellIconActiveColor : quickshellIconInactiveColor) } } IconImage { + id: colSteamIcon anchors.fill: parent source: modelData.icon opacity: modelData.active ? 1.0 : colAppMouseArea.containsMouse ? 0.8 : 0.6 @@ -1692,11 +1712,21 @@ Item { anchors.centerIn: parent size: root.appIconSize name: "sports_esports" - color: Theme.widgetTextColor + color: appHighlightActive ? focusedBorderColor : Theme.widgetTextColor opacity: modelData.active ? 1.0 : colAppMouseArea.containsMouse ? 0.8 : 0.6 visible: modelData.isSteamApp && !modelData.icon } + Rectangle { + anchors.fill: parent + visible: (colAppIcon.visible || colSteamIcon.visible || modelData.isQuickshell) && appHighlightActive + color: "transparent" + radius: Theme.cornerRadius * (root.appIconSize / 40) + border.width: 1 + border.color: focusedBorderColor + z: 1 + } + MouseArea { id: colAppMouseArea anchors.fill: parent diff --git a/quickshell/Modules/Settings/WorkspacesTab.qml b/quickshell/Modules/Settings/WorkspacesTab.qml index 8c0e4da3..99955fd6 100644 --- a/quickshell/Modules/Settings/WorkspacesTab.qml +++ b/quickshell/Modules/Settings/WorkspacesTab.qml @@ -125,6 +125,16 @@ Item { onToggled: checked => SettingsData.set("groupWorkspaceApps", checked) } + SettingsToggleRow { + settingKey: "workspaceActiveAppHighlightEnabled" + tags: ["workspace", "apps", "icons", "highlight", "active", "focused"] + text: I18n.tr("Highlight Active Workspace App") + description: I18n.tr("Highlight the currently focused app inside workspace indicators") + checked: SettingsData.workspaceActiveAppHighlightEnabled + visible: SettingsData.showWorkspaceApps + onToggled: checked => SettingsData.set("workspaceActiveAppHighlightEnabled", checked) + } + SettingsToggleRow { settingKey: "workspaceFollowFocus" tags: ["workspace", "focus", "follow", "monitor"]