mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-06-28 22:12:10 -04:00
feat(bar): separate workspace appearance for unfocused displays (#2687)
* feat(bar): separate workspace appearance for unfocused displays Add a toggle in the Workspace Appearance card to style workspace indicators independently on displays that aren't currently focused. The card is split into Focused Display and Unfocused Display(s) tabs. When the new master toggle is off (default), unfocused displays inherit the focused settings, preserving existing behavior. When on, unfocused displays use their own colors (focused/occupied/unfocused/urgent) and focused border (enable, color, thickness). WorkspaceSwitcher resolves the focused monitor per compositor and routes color/border resolution through isFocusedMonitor/useUnfocusedAppearance. * refactor(bar): address review feedback for unfocused workspace appearance - Consolidate focused-monitor lookup into BarWidgetService.getFocusedScreenName(), adding Mango support, and drop the duplicate compositor switches in WorkspaceSwitcher (effectiveScreenName + isFocusedMonitor now use the helper). - Extract the shared color and border options into reusable WorkspaceAppearanceColorOptions and WorkspaceAppearanceBorderFields components so the focused and unfocused tabs no longer duplicate the layout. - Gate the unfocused-display options on BarWidgetService.focusedScreenDetectionSupported and show an explanatory note on compositors without focus detection (e.g. labwc), instead of silently no-opping.
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user