1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-08-08 06:28:27 -04:00

feat(theme/settings): dedicated floating window styling with shared chrome

- Refactor Widget Styling into Surface Styling & Floating
  Windows
- New sync per-host opacity & foreground layer control
- Shared DankFloatingWindow chrome
- Settings fix to destroy Settings window on-hide so niri floating
  rules match subsequent runs
Related: #2709
This commit is contained in:
purian23
2026-08-06 20:52:14 -04:00
parent dade416ca0
commit 9013464312
50 changed files with 810 additions and 420 deletions
+6
View File
@@ -164,6 +164,11 @@ Singleton {
property string matugenTargetMonitor: ""
property real popupTransparency: 1.0
property real dockTransparency: 1
property bool floatingWindowSyncGlobal: true
property real floatingWindowTransparency: 1.0
property bool floatingWindowForegroundLayers: true
property real floatingWindowForegroundTransparency: 1.0
property bool dmsWindowsFloating: true
property string widgetBackgroundColor: "sch"
property string widgetBackgroundCustomColor: "#6750A4"
property real widgetBackgroundCustomStrength: 0.50
@@ -264,6 +269,7 @@ Singleton {
onBlurEnabledChanged: saveSettings()
property bool blurForegroundLayers: true
onBlurForegroundLayersChanged: saveSettings()
property real foregroundLayerTransparency: 1.0
property real blurLayerOutlineOpacity: 0.12
onBlurLayerOutlineOpacityChanged: saveSettings()
property bool blurBorderEnabled: true
+33 -2
View File
@@ -345,11 +345,28 @@ Singleton {
readonly property bool foregroundLayers: typeof SettingsData === "undefined" || (SettingsData.blurForegroundLayers ?? true)
readonly property bool blurForegroundLayers: blurLayersActive && foregroundLayers
readonly property bool transparentBlurLayers: blurLayersActive && !foregroundLayers
readonly property real foregroundLayerTransparency: typeof SettingsData === "undefined" ? 1.0 : (SettingsData.foregroundLayerTransparency ?? 1.0)
readonly property bool notificationForegroundLayers: typeof SettingsData === "undefined" || (SettingsData.notificationForegroundLayers ?? true)
readonly property color readableSurface: withAlpha(surfaceContainer, popupTransparency)
readonly property color readableSurfaceHigh: withAlpha(surfaceContainerHigh, popupTransparency)
readonly property color floatingSurface: foregroundLayers ? readableSurface : withAlpha(readableSurface, 0)
readonly property color floatingSurfaceHigh: foregroundLayers ? readableSurfaceHigh : withAlpha(readableSurfaceHigh, 0)
readonly property color floatingSurfaceHigh: foregroundLayers ? withAlpha(surfaceContainerHigh, foregroundLayerTransparency) : withAlpha(surfaceContainerHigh, 0)
readonly property bool floatingWindowSynced: typeof SettingsData === "undefined" || (SettingsData.floatingWindowSyncGlobal ?? true)
readonly property real floatingWindowTransparency: {
if (typeof SettingsData === "undefined" || floatingWindowSynced)
return popupTransparency;
return SettingsData.floatingWindowTransparency ?? 1.0;
}
readonly property bool floatingWindowForegroundLayers: floatingWindowSynced ? foregroundLayers : (SettingsData.floatingWindowForegroundLayers ?? true)
readonly property real floatingWindowForegroundTransparency: {
if (typeof SettingsData === "undefined" || floatingWindowSynced)
return foregroundLayerTransparency;
return SettingsData.floatingWindowForegroundTransparency ?? 1.0;
}
readonly property color floatingWindowSurface: withAlpha(surfaceContainer, floatingWindowTransparency)
readonly property color floatingWindowSurfaceHigh: floatingWindowForegroundLayers ? withAlpha(surfaceContainerHigh, floatingWindowForegroundTransparency) : withAlpha(surfaceContainerHigh, 0)
readonly property color floatingWindowNestedSurface: floatingWindowSurfaceHigh
readonly property color notepadWindowSurface: withAlpha(surfaceContainer, notepadTransparency)
readonly property color nestedSurface: floatingSurfaceHigh
readonly property color notificationFloatingSurface: notificationForegroundLayers ? readableSurface : withAlpha(readableSurface, 0)
readonly property color notificationFloatingSurfaceHigh: notificationForegroundLayers ? readableSurfaceHigh : withAlpha(readableSurfaceHigh, 0)
@@ -357,6 +374,20 @@ Singleton {
readonly property real blurLayerOutlineOpacity: Math.max(0, Math.min(1, typeof SettingsData === "undefined" ? 0.12 : (SettingsData.blurLayerOutlineOpacity ?? 0.12)))
readonly property real layerOutlineOpacity: blurLayerOutlineOpacity
readonly property int layerOutlineWidth: layerOutlineOpacity > 0 ? 1 : 0
readonly property real floatingWindowFieldAlpha: floatingWindowTransparency
readonly property color floatingWindowFieldColor: withAlpha(surfaceContainerHigh, floatingWindowFieldAlpha)
readonly property real popupFieldAlpha: {
if (transparentBlurLayers)
return 0.28;
if (blurForegroundLayers)
return Math.max(foregroundLayerTransparency, 0.62);
return popupTransparency;
}
readonly property color popupFieldColor: withAlpha(surfaceContainerHigh, popupFieldAlpha)
readonly property color popupFieldBorderColor: withAlpha(outline, blurLayersActive ? 0.16 : layerOutlineOpacity)
readonly property color popupFieldFocusedBorderColor: withAlpha(primary, blurLayersActive ? 0.72 : 1.0)
readonly property color floatingWindowFieldBorderColor: popupFieldBorderColor
readonly property color floatingWindowFieldFocusedBorderColor: popupFieldFocusedBorderColor
property color surfaceTextHover: withAlpha(surfaceText, 0.08)
property color surfaceTextAlpha: withAlpha(surfaceText, 0.3)
@@ -1194,7 +1225,7 @@ Singleton {
readonly property var _availableThemeNames: StockThemes.getAllThemeNames()
property string currentThemeName: currentTheme
property real notepadTransparency: SettingsData.notepadTransparencyOverride >= 0 ? SettingsData.notepadTransparencyOverride : popupTransparency
property real notepadTransparency: SettingsData.notepadTransparencyOverride >= 0 ? SettingsData.notepadTransparencyOverride : floatingWindowTransparency
property bool widgetBackgroundHasAlpha: {
const colorMode = typeof SettingsData !== "undefined" ? SettingsData.widgetBackgroundColor : "sch";
@@ -17,6 +17,11 @@ var SPEC = {
popupTransparency: { def: 1.0, coerce: percentToUnit },
dockTransparency: { def: 1.0, coerce: percentToUnit },
floatingWindowSyncGlobal: { def: true },
floatingWindowTransparency: { def: 1.0, coerce: percentToUnit },
floatingWindowForegroundLayers: { def: true },
floatingWindowForegroundTransparency: { def: 1.0, coerce: percentToUnit },
dmsWindowsFloating: { def: true },
widgetBackgroundColor: { def: "sch" },
widgetBackgroundCustomColor: { def: "#6750A4" },
@@ -97,6 +102,7 @@ var SPEC = {
barElevationEnabled: { def: true },
blurEnabled: { def: false },
blurForegroundLayers: { def: true },
foregroundLayerTransparency: { def: 1.0, coerce: percentToUnit },
blurLayerOutlineOpacity: { def: 0.12, coerce: percentToUnit },
blurBorderEnabled: { def: true },
blurBorderColor: { def: "outline" },
+2 -1
View File
@@ -635,7 +635,7 @@ Item {
if (visible) {
wasShown = true;
} else if (wasShown) {
PopoutService.unloadSettings();
Qt.callLater(() => PopoutService.unloadSettingsNow());
}
}
}
@@ -940,6 +940,7 @@ Item {
expandedWidthValue: 960
edgeGap: SettingsData.notepadEffectiveEdgeGap
slideEdge: SettingsData.notepadSlideoutSide
customTransparency: Theme.notepadTransparency
onIsVisibleChanged: {
if (isVisible)
-4
View File
@@ -318,10 +318,6 @@ DankModal {
width: parent.width - Theme.spacingS * 2
anchors.horizontalCenter: parent.horizontalCenter
height: 52
cornerRadius: Theme.cornerRadius
backgroundColor: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
normalBorderColor: Theme.outlineMedium
focusedBorderColor: Theme.primary
leftIconName: "search"
leftIconSize: Theme.iconSize
leftIconColor: Theme.surfaceVariantText
@@ -15,7 +15,7 @@ Rectangle {
height: Math.round(Theme.fontSizeMedium * 4.2)
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
color: Theme.floatingWindowNestedSurface
Rectangle {
anchors.fill: parent
@@ -4,10 +4,9 @@ import qs.Common
import qs.Services
import qs.Widgets
FloatingWindow {
DankFloatingWindow {
id: root
property bool disablePopupTransparency: true
readonly property int modalWidth: 680
readonly property int modalHeight: screen ? Math.min(720, screen.height - 80) : 720
@@ -21,7 +20,6 @@ FloatingWindow {
title: i18n("What's New")
minimumSize: Qt.size(modalWidth, modalHeight)
maximumSize: Qt.size(modalWidth, modalHeight)
color: Theme.surfaceContainer
visible: false
onClosed: visible = false
@@ -112,7 +110,7 @@ FloatingWindow {
anchors.right: parent.right
anchors.bottom: parent.bottom
height: Math.round(Theme.fontSizeMedium * 4.5)
color: Theme.surfaceContainerHigh
color: Theme.floatingWindowNestedSurface
Rectangle {
anchors.top: parent.top
@@ -23,17 +23,6 @@ FocusScope {
property bool editMode: false
property var editingApp: null
property string editAppId: ""
readonly property bool _blurActive: Theme.blurForegroundLayers || Theme.transparentBlurLayers
readonly property real _launcherFieldAlpha: {
if (Theme.transparentBlurLayers)
return 0.28;
if (Theme.blurForegroundLayers)
return Math.max(Theme.popupTransparency, 0.62);
return Theme.popupTransparency;
}
readonly property color _launcherSearchFieldColor: Theme.withAlpha(Theme.surfaceContainerHigh, _launcherFieldAlpha)
readonly property color _launcherSearchBorderColor: Theme.withAlpha(Theme.outline, _blurActive ? 0.16 : Theme.layerOutlineOpacity)
readonly property color _launcherSearchFocusedBorderColor: Theme.withAlpha(Theme.primary, _blurActive ? 0.72 : 1.0)
function resetScroll() {
resultsList.resetScroll();
@@ -314,7 +303,7 @@ FocusScope {
anchors.fill: parent
anchors.topMargin: -Theme.cornerRadius
// In connected mode the launcher provides the surface so update the toolbar for arcs
visible: !(root.parentModal?.frameOwnsConnectedChrome ?? false) && !root._blurActive
visible: !(root.parentModal?.frameOwnsConnectedChrome ?? false) && !Theme.blurLayersActive
color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
radius: Theme.cornerRadius
}
@@ -472,12 +461,6 @@ FocusScope {
DankTextField {
id: searchField
width: parent.width - (pluginBadge.visible ? pluginBadge.width + Theme.spacingS : 0)
cornerRadius: Theme.cornerRadius
backgroundColor: root._launcherSearchFieldColor
normalBorderColor: root._launcherSearchBorderColor
focusedBorderColor: root._launcherSearchFocusedBorderColor
borderWidth: 1
focusedBorderWidth: 2
leftIconName: controller.activePluginId ? "extension" : controller.searchQuery.startsWith("/") ? "folder" : "search"
leftIconSize: Theme.iconSize
leftIconColor: Theme.surfaceVariantText
@@ -146,7 +146,7 @@ Item {
width: parent.width
height: keybindsGrid.height + Theme.spacingM * 2
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
color: Theme.floatingWindowNestedSurface
readonly property bool useTwoColumns: width > 500
readonly property int columnCount: useTwoColumns ? 2 : 1
@@ -240,7 +240,7 @@ Item {
width: parent.width
height: noKeybindsColumn.height + Theme.spacingM * 2
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
color: Theme.floatingWindowNestedSurface
visible: !root.hasKeybinds
Column {
@@ -291,7 +291,7 @@ Item {
anchors.leftMargin: Theme.spacingXL
anchors.rightMargin: Theme.spacingXL
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
color: Theme.floatingWindowNestedSurface
clip: true
Column {
@@ -15,7 +15,7 @@ Rectangle {
height: Math.round(Theme.fontSizeMedium * 6.4)
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
color: Theme.floatingWindowNestedSurface
Rectangle {
anchors.fill: parent
+3 -5
View File
@@ -5,11 +5,10 @@ import qs.Common
import qs.Services
import qs.Widgets
FloatingWindow {
DankFloatingWindow {
id: root
readonly property var log: Log.scoped("GreeterModal")
property bool disablePopupTransparency: true
property int currentPage: 0
readonly property int totalPages: 3
readonly property var pageComponents: [welcomePage, doctorPage, completePage]
@@ -90,7 +89,6 @@ FloatingWindow {
title: I18n.tr("Welcome", "greeter modal window title")
minimumSize: Qt.size(modalWidth, modalHeight)
maximumSize: Qt.size(modalWidth, modalHeight)
color: Theme.surfaceContainer
visible: false
onClosed: visible = false
@@ -173,7 +171,7 @@ FloatingWindow {
width: pageIndicatorRow.width + Theme.spacingM * 2
height: indicatorHeight
radius: indicatorHeight / 2
color: Theme.surfaceContainerHigh
color: Theme.floatingWindowNestedSurface
Row {
id: pageIndicatorRow
@@ -259,7 +257,7 @@ FloatingWindow {
anchors.right: parent.right
anchors.bottom: parent.bottom
height: Math.round(Theme.fontSizeMedium * 4.5)
color: Theme.surfaceContainerHigh
color: Theme.floatingWindowNestedSurface
Rectangle {
anchors.top: parent.top
@@ -13,7 +13,7 @@ Rectangle {
height: Math.round(Theme.fontSizeMedium * 3.1)
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
color: Theme.floatingWindowNestedSurface
Rectangle {
anchors.fill: parent
@@ -15,7 +15,7 @@ Rectangle {
height: Math.round(Theme.fontSizeMedium * 4.5)
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
color: Theme.floatingWindowNestedSurface
Rectangle {
anchors.fill: parent
@@ -9,7 +9,7 @@ Rectangle {
property string label: ""
property string iconName: ""
property color iconColor: Theme.surfaceText
property color bgColor: Theme.surfaceContainerHigh
property color bgColor: Theme.floatingWindowNestedSurface
property bool selected: false
signal clicked
+1 -9
View File
@@ -5,10 +5,9 @@ import qs.Modals
import qs.Services
import qs.Widgets
FloatingWindow {
DankFloatingWindow {
id: win
property bool disablePopupTransparency: true
property alias shouldBeVisible: win.visible
signal floatingToggleRequested
@@ -30,7 +29,6 @@ FloatingWindow {
minimumSize: Qt.size(Math.min(560, Screen.width), Math.min(400, Screen.height))
implicitWidth: 1000
implicitHeight: screen ? Math.min(820, screen.height - 100) : 820
color: Theme.surfaceContainer
visible: false
onVisibleChanged: {
@@ -61,12 +59,6 @@ FloatingWindow {
onDoubleClicked: windowControls.tryToggleMaximize()
}
Rectangle {
anchors.fill: parent
color: Theme.surfaceContainer
opacity: 0.5
}
Row {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingL
-4
View File
@@ -313,10 +313,6 @@ DankModal {
width: parent.width
height: 48
cornerRadius: Theme.cornerRadius
backgroundColor: Theme.surfaceContainerHigh
normalBorderColor: Theme.outlineMedium
focusedBorderColor: Theme.primary
leftIconName: "search"
leftIconSize: Theme.iconSize
leftIconColor: Theme.surfaceVariantText
+2 -7
View File
@@ -202,7 +202,7 @@ FocusScope {
StyledText {
text: root.currentFlow?.message ?? ""
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceTextMedium
color: Theme.surfaceText
width: parent.width
wrapMode: Text.Wrap
maximumLineCount: 2
@@ -272,11 +272,6 @@ FocusScope {
width: parent.width
height: root.inputFieldHeight
backgroundColor: Theme.surfaceHover
normalBorderColor: Theme.outlineStrong
focusedBorderColor: Theme.primary
borderWidth: 1
focusedBorderWidth: 2
leftIconName: root.polkitPamHasFprint ? "fingerprint" : ""
leftIconSize: 20
leftIconColor: Theme.primary
@@ -352,7 +347,7 @@ FocusScope {
anchors.centerIn: parent
text: I18n.tr("Authenticate")
font.pixelSize: Theme.fontSizeMedium
color: Theme.background
color: Theme.primaryText
font.weight: Font.Medium
}
+1 -4
View File
@@ -4,11 +4,9 @@ import qs.Common
import qs.Services
import qs.Widgets
FloatingWindow {
DankFloatingWindow {
id: root
property bool disablePopupTransparency: true
function show() {
if (contentLoader.item)
contentLoader.item.reset();
@@ -29,7 +27,6 @@ FloatingWindow {
title: I18n.tr("Authentication")
minimumSize: Qt.size(460, 220)
maximumSize: Qt.size(460, 220)
color: Theme.surfaceContainer
visible: false
onClosed: hide()
+2 -4
View File
@@ -8,11 +8,10 @@ import qs.Services
import qs.Widgets
import "../Common/Format.js" as Format
FloatingWindow {
DankFloatingWindow {
id: processListModal
readonly property var log: Log.scoped("ProcessListModal")
property bool disablePopupTransparency: true
property int currentTab: 0
property string searchText: ""
property string expandedPid: ""
@@ -81,7 +80,6 @@ FloatingWindow {
minimumSize: Qt.size(Math.min(Math.round(Theme.fontSizeMedium * 48), Screen.width), Math.min(Math.round(Theme.fontSizeMedium * 34), Screen.height))
implicitWidth: Math.round(Theme.fontSizeMedium * 71)
implicitHeight: Math.round(Theme.fontSizeMedium * 51)
color: Theme.surfaceContainer
visible: false
onClosed: hide()
@@ -420,7 +418,7 @@ FloatingWindow {
Layout.margins: Theme.spacingL
Layout.topMargin: Theme.spacingM
radius: Theme.cornerRadius
color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
color: Theme.floatingWindowNestedSurface
border.color: Theme.outlineLight
border.width: 1
clip: true
+2 -11
View File
@@ -5,7 +5,7 @@ import qs.Modals.FileBrowser
import qs.Services
import qs.Widgets
FloatingWindow {
DankFloatingWindow {
id: settingsModal
property var profileBrowser: profileBrowserLoader.item
@@ -95,7 +95,6 @@ FloatingWindow {
minimumSize: Qt.size(500, 400)
implicitWidth: 900
implicitHeight: screen ? Math.min(940, screen.height - 100) : 940
color: Theme.surfaceContainer
visible: false
onClosed: hide()
@@ -180,8 +179,6 @@ FloatingWindow {
FocusScope {
id: contentFocusScope
property bool disablePopupTransparency: true
LayoutMirroring.enabled: I18n.isRtl
LayoutMirroring.childrenInherit: true
@@ -203,12 +200,6 @@ FloatingWindow {
onDoubleClicked: windowControls.tryToggleMaximize()
}
Rectangle {
anchors.fill: parent
color: Theme.surfaceContainer
opacity: 0.5
}
Row {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingL
@@ -276,7 +267,7 @@ FloatingWindow {
width: parent.width
height: showBanner ? bannerContent.implicitHeight + Theme.spacingM * 2 : 0
color: Theme.surfaceContainerHigh
color: Theme.floatingWindowNestedSurface
visible: showBanner
clip: true
@@ -648,7 +648,7 @@ Rectangle {
implicitWidth: __calculatedWidth
width: __calculatedWidth
height: parent.height
color: Theme.surfaceContainer
color: "transparent"
radius: Theme.cornerRadius
Component.onCompleted: {
@@ -749,12 +749,9 @@ Rectangle {
id: searchField
width: parent.width - parent.leftPadding - parent.rightPadding
placeholderText: I18n.tr("Search...")
normalBorderColor: Theme.outlineMedium
focusedBorderColor: Theme.primary
leftIconName: "search"
leftIconSize: Theme.iconSize - 4
showClearButton: text.length > 0
usePopupTransparency: false
onTextChanged: {
SettingsSearchService.search(text);
root.searchSelectedIndex = 0;
+1 -3
View File
@@ -4,10 +4,9 @@ import qs.Common
import qs.Services
import qs.Widgets
FloatingWindow {
DankFloatingWindow {
id: root
property bool disablePopupTransparency: true
property var editingRule: null
property bool isEditMode: editingRule !== null
property bool isNiri: CompositorService.isNiri
@@ -29,7 +28,6 @@ FloatingWindow {
title: isEditMode ? I18n.tr("Edit Window Rule") : I18n.tr("Create Window Rule")
minimumSize: Qt.size(500, 600)
maximumSize: Qt.size(500, 600)
color: Theme.surfaceContainer
visible: false
onClosed: hide()
+1 -3
View File
@@ -4,18 +4,16 @@ import qs.Common
import qs.Services
import qs.Widgets
FloatingWindow {
DankFloatingWindow {
id: root
readonly property var log: Log.scoped("WorkspaceRenameModal")
property bool disablePopupTransparency: true
readonly property int inputFieldHeight: Theme.fontSizeMedium + Theme.spacingL * 2
objectName: "workspaceRenameModal"
title: I18n.tr("Rename Workspace")
minimumSize: Qt.size(400, 160)
maximumSize: Qt.size(400, 160)
color: Theme.surfaceContainer
visible: false
onClosed: hide()
@@ -5,7 +5,7 @@ import qs.Services
import qs.Widgets
import qs.Modules.Notepad
FloatingWindow {
DankFloatingWindow {
id: win
property alias shouldBeVisible: win.visible
@@ -27,7 +27,7 @@ FloatingWindow {
minimumSize: Qt.size(360, 320)
implicitWidth: 640
implicitHeight: 760
color: Theme.surfaceContainer
surfaceColor: Theme.notepadWindowSurface
visible: false
onVisibleChanged: {
@@ -38,7 +38,6 @@ FloatingWindow {
}
}
// A compositor close (e.g. niri close-window)
onClosed: win.visible = false
Item {
@@ -58,12 +57,6 @@ FloatingWindow {
onDoubleClicked: windowControls.tryToggleMaximize()
}
Rectangle {
anchors.fill: parent
color: Theme.surfaceContainerHigh
opacity: 0.5
}
Row {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingM
@@ -353,7 +353,7 @@ Item {
anchors.leftMargin: -Theme.spacingM
width: parent.width + Theme.spacingM
text: I18n.tr("Surface Opacity")
description: I18n.tr("Override global transparency for Notepad")
description: I18n.tr("Override floating window transparency for Notepad")
checked: SettingsData.notepadTransparencyOverride >= 0
onToggled: checked => {
if (checked) {
@@ -370,7 +370,7 @@ Item {
width: parent.width + Theme.spacingM
height: 24
visible: SettingsData.notepadTransparencyOverride >= 0
value: Math.round((SettingsData.notepadTransparencyOverride >= 0 ? SettingsData.notepadTransparencyOverride : SettingsData.popupTransparency) * 100)
value: Math.round(Theme.notepadTransparency * 100)
minimum: 0
maximum: 100
unit: ""
@@ -364,7 +364,7 @@ Column {
height: 48
visible: searchVisible
opacity: searchVisible ? 1 : 0
color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
color: Theme.floatingWindowNestedSurface
border.color: searchField.activeFocus ? Theme.primary : Theme.outlineMedium
border.width: searchField.activeFocus ? 2 : 1
radius: Theme.cornerRadius
@@ -941,7 +941,7 @@ Column {
width: Math.min(root.width, 360)
height: pathInfoRow.implicitHeight + Theme.spacingS * 2
radius: Theme.cornerRadius
color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
color: Theme.floatingWindowNestedSurface
border.color: Theme.outlineMedium
border.width: 1
z: 10
@@ -118,7 +118,9 @@ Column {
width: parent.width
height: 56
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
color: Theme.floatingWindowFieldColor
border.color: Theme.floatingWindowFieldBorderColor
border.width: 1
Row {
anchors.fill: parent
@@ -6,10 +6,9 @@ import qs.Common
import qs.Services
import qs.Widgets
FloatingWindow {
DankFloatingWindow {
id: root
property bool disablePopupTransparency: true
property string searchQuery: ""
property var filteredWidgets: []
property int selectedIndex: -1
@@ -107,7 +106,6 @@ FloatingWindow {
minimumSize: Qt.size(400, 350)
implicitWidth: 500
implicitHeight: 550
color: Theme.surfaceContainer
visible: false
onClosed: hide()
@@ -276,10 +274,6 @@ FloatingWindow {
id: searchField
width: parent.width
height: 48
cornerRadius: Theme.cornerRadius
backgroundColor: Theme.surfaceContainerHigh
normalBorderColor: Theme.outlineMedium
focusedBorderColor: Theme.primary
leftIconName: "search"
leftIconSize: Theme.iconSize
leftIconColor: Theme.surfaceVariantText
@@ -465,7 +465,6 @@ Item {
iconName: "restart_alt"
iconSize: 20
visible: JSON.stringify(SettingsData.notificationRules) !== JSON.stringify(SettingsData.getDefaultNotificationRules())
backgroundColor: Theme.surfaceContainer
iconColor: Theme.surfaceVariantText
onClicked: SettingsData.resetNotificationRules()
},
@@ -473,7 +472,6 @@ Item {
buttonSize: 36
iconName: "add"
iconSize: 20
backgroundColor: Theme.surfaceContainer
iconColor: Theme.primary
onClicked: {
SettingsData.addNotificationRule();
@@ -723,7 +721,7 @@ Item {
}
Item {
width: Math.max(0, parent.width - parent.spacing - mutedAppLabel.width - unmuteBtn.width - deleteBtn.width - Theme.spacingS * 5)
width: Math.max(0, parent.width - parent.spacing - mutedAppLabel.width - unmuteBtn.width - mutedDeleteBtn.width - Theme.spacingS * 5)
height: 1
}
@@ -736,7 +734,7 @@ Item {
}
Item {
id: deleteBtn
id: mutedDeleteBtn
width: 28
height: 28
anchors.verticalCenter: parent.verticalCenter
@@ -744,18 +742,18 @@ Item {
Rectangle {
anchors.fill: parent
radius: Theme.cornerRadius
color: deleteArea.containsMouse ? Theme.withAlpha(Theme.error, 0.2) : Theme.withAlpha(Theme.error, 0)
color: mutedDeleteArea.containsMouse ? Theme.withAlpha(Theme.error, 0.2) : Theme.withAlpha(Theme.error, 0)
}
DankIcon {
anchors.centerIn: parent
name: "delete"
size: 18
color: deleteArea.containsMouse ? Theme.error : Theme.surfaceVariantText
color: mutedDeleteArea.containsMouse ? Theme.error : Theme.surfaceVariantText
}
MouseArea {
id: deleteArea
id: mutedDeleteArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
+5 -13
View File
@@ -7,10 +7,9 @@ import qs.Modals.Common
import qs.Services
import qs.Widgets
FloatingWindow {
DankFloatingWindow {
id: root
property bool disablePopupTransparency: true
property var allPlugins: []
property string searchQuery: ""
property var filteredPlugins: []
@@ -608,7 +607,6 @@ FloatingWindow {
return Math.round(Math.min(maxHeight, Math.max(540, parentModal.height * 0.8)));
return Math.min(maxHeight, 760);
}
color: Theme.surfaceContainer
visible: false
onClosed: hide()
@@ -838,10 +836,6 @@ FloatingWindow {
anchors.top: headerArea.bottom
anchors.topMargin: Theme.spacingM
height: 48
cornerRadius: Theme.cornerRadius
backgroundColor: Theme.surfaceContainerHigh
normalBorderColor: Theme.outlineMedium
focusedBorderColor: Theme.primary
leftIconName: "search"
leftIconSize: Theme.iconSize
leftIconColor: Theme.surfaceVariantText
@@ -1102,7 +1096,7 @@ FloatingWindow {
ClippingRectangle {
anchors.fill: parent
radius: Theme.cornerRadius - 2
color: Theme.surfaceContainerHigh
color: Theme.floatingWindowNestedSurface
CachingImage {
id: cardPreview
@@ -1362,7 +1356,7 @@ FloatingWindow {
anchors.topMargin: Theme.spacingM
anchors.bottom: parent.bottom
z: 10
color: Theme.surfaceContainer
color: Theme.floatingWindowSurface
opacity: root.detailPluginId !== "" ? 1 : 0
visible: opacity > 0
@@ -1555,7 +1549,7 @@ FloatingWindow {
width: parent.width
height: Math.round(width * 0.52)
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
color: Theme.floatingWindowNestedSurface
border.color: Theme.withAlpha(Theme.outline, 0.2)
border.width: 1
@@ -1829,10 +1823,9 @@ FloatingWindow {
id: thirdPartyConfirmLoader
active: false
FloatingWindow {
DankFloatingWindow {
id: thirdPartyConfirmModal
property bool disablePopupTransparency: true
parentWindow: root
function show() {
@@ -1847,7 +1840,6 @@ FloatingWindow {
title: I18n.tr("Third-Party Plugin Warning")
implicitWidth: 500
implicitHeight: 350
color: Theme.surfaceContainer
visible: false
FocusScope {
@@ -32,7 +32,6 @@ Item {
iconName: "restart_alt"
iconSize: 20
visible: JSON.stringify(SettingsData.appIdSubstitutions) !== JSON.stringify(SettingsData.getDefaultAppIdSubstitutions())
backgroundColor: Theme.surfaceContainer
iconColor: Theme.surfaceVariantText
onClicked: SettingsData.resetAppIdSubstitutions()
},
@@ -40,7 +39,6 @@ Item {
buttonSize: 36
iconName: "add"
iconSize: 20
backgroundColor: Theme.surfaceContainer
iconColor: Theme.primary
onClicked: SettingsData.addAppIdSubstitution("", "", "exact")
}
+3 -9
View File
@@ -6,10 +6,9 @@ import qs.Modals.Common
import qs.Services
import qs.Widgets
FloatingWindow {
DankFloatingWindow {
id: root
property bool disablePopupTransparency: true
property var allThemes: []
property string searchQuery: ""
property var filteredThemes: []
@@ -148,7 +147,6 @@ FloatingWindow {
minimumSize: Qt.size(550, 450)
implicitWidth: 700
implicitHeight: 700
color: Theme.surfaceContainer
visible: false
onVisibleChanged: {
@@ -301,10 +299,6 @@ FloatingWindow {
anchors.top: descriptionText.bottom
anchors.topMargin: Theme.spacingM
height: 48
cornerRadius: Theme.cornerRadius
backgroundColor: Theme.surfaceContainerHigh
normalBorderColor: Theme.outlineMedium
focusedBorderColor: Theme.primary
leftIconName: "search"
leftIconSize: Theme.iconSize
leftIconColor: Theme.surfaceVariantText
@@ -401,7 +395,7 @@ FloatingWindow {
width: hasPreview ? 180 : 0
height: parent.height
radius: Theme.cornerRadius - 2
color: Theme.surfaceContainerHigh
color: Theme.floatingWindowNestedSurface
visible: hasPreview
Image {
@@ -596,7 +590,7 @@ FloatingWindow {
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
background: Rectangle {
color: Theme.surfaceContainerHigh
color: Theme.floatingWindowNestedSurface
radius: Theme.cornerRadius
border.width: 1
border.color: Theme.outlineMedium
+363 -172
View File
@@ -65,112 +65,173 @@ Item {
"label": I18n.tr("Custom", "widget background color option")
})]
property var cursorIncludeStatus: ({
"exists": false,
"included": false,
"configFormat": "",
"readOnly": false
})
property var cursorIncludeStatus: defaultIncludeStatus()
readonly property bool cursorReadOnly: CompositorService.isHyprland && cursorIncludeStatus.readOnly === true
property bool checkingCursorInclude: false
property bool fixingCursorInclude: false
function getCursorConfigPaths() {
const configDir = Paths.strip(StandardPaths.writableLocation(StandardPaths.ConfigLocation));
switch (CompositorService.compositor) {
case "niri":
return {
"configFile": configDir + "/niri/config.kdl",
"cursorFile": configDir + "/niri/dms/cursor.kdl",
"grepPattern": 'include.*"dms/cursor.kdl"',
"includeLine": 'include "dms/cursor.kdl"'
};
case "hyprland":
return {
"configFile": configDir + "/hypr/hyprland.lua",
"cursorFile": configDir + "/hypr/dms/cursor.lua",
"grepPattern": "dms.cursor",
"includeLine": "require(\"dms.cursor\")"
};
case "mango":
return {
"configFile": configDir + "/mango/config.conf",
"cursorFile": configDir + "/mango/dms/cursor.conf",
"grepPattern": 'source.*dms/cursor.conf',
"includeLine": "source=./dms/cursor.conf"
};
default:
return null;
}
property var windowRulesIncludeStatus: defaultIncludeStatus()
readonly property bool windowRulesReadOnly: CompositorService.isHyprland && windowRulesIncludeStatus.readOnly === true
property bool checkingWindowRulesInclude: false
property bool fixingWindowRulesInclude: false
readonly property var includeConfigSpecs: ({
"cursor": ({
"niri": {
"configName": "config.kdl",
"fragmentName": "cursor.kdl",
"grepPattern": 'include.*"dms/cursor.kdl"',
"includeLine": 'include "dms/cursor.kdl"'
},
"hyprland": {
"configName": "hyprland.lua",
"fragmentName": "cursor.lua",
"grepPattern": "dms.cursor",
"includeLine": "require(\"dms.cursor\")"
},
"mango": {
"configName": "config.conf",
"fragmentName": "cursor.conf",
"grepPattern": "source.*dms/cursor.conf",
"includeLine": "source=./dms/cursor.conf"
}
}),
"windowrules": ({
"niri": {
"configName": "config.kdl",
"fragmentName": "windowrules.kdl",
"grepPattern": 'include.*"dms/windowrules.kdl"',
"includeLine": 'include "dms/windowrules.kdl"'
},
"hyprland": {
"configName": "hyprland.lua",
"fragmentName": "windowrules.lua",
"grepPattern": "dms.windowrules",
"includeLine": "require(\"dms.windowrules\")"
},
"mango": {
"configName": "config.conf",
"fragmentName": "windowrules.conf",
"grepPattern": "dms/windowrules.conf",
"includeLine": "source=./dms/windowrules.conf"
}
})
})
function defaultIncludeStatus() {
return {
"exists": false,
"included": false,
"configFormat": "",
"readOnly": false
};
}
function checkCursorIncludeStatus() {
const compositor = CompositorService.compositor;
if (compositor !== "niri" && compositor !== "hyprland" && compositor !== "mango") {
cursorIncludeStatus = {
"exists": false,
"included": false,
"configFormat": "",
"readOnly": false
};
function getIncludeConfigPaths(includeKind) {
const spec = includeConfigSpecs[includeKind]?.[CompositorService.compositor];
if (!spec)
return null;
const configDir = Paths.strip(StandardPaths.writableLocation(StandardPaths.ConfigLocation)) + "/" + CompositorService.compositor;
return {
"configFile": configDir + "/" + spec.configName,
"fragmentFile": configDir + "/dms/" + spec.fragmentName,
"grepPattern": spec.grepPattern,
"includeLine": spec.includeLine
};
}
function checkIncludeStatus(includeKind, procTag, onFinished) {
const spec = includeConfigSpecs[includeKind]?.[CompositorService.compositor];
if (!spec) {
onFinished(defaultIncludeStatus());
return;
}
const filename = (compositor === "niri") ? "cursor.kdl" : ((compositor === "hyprland") ? "cursor.lua" : "cursor.conf");
const compositor = CompositorService.compositor;
const compositorArg = (compositor === "mango") ? "mangowc" : compositor;
checkingCursorInclude = true;
Proc.runCommand("check-cursor-include", [Proc.dmsBin, "config", "resolve-include", compositorArg, filename], (output, exitCode) => {
checkingCursorInclude = false;
Proc.runCommand(procTag, [Proc.dmsBin, "config", "resolve-include", compositorArg, spec.fragmentName], (output, exitCode) => {
if (exitCode !== 0) {
cursorIncludeStatus = {
"exists": false,
"included": false,
"configFormat": "",
"readOnly": false
};
onFinished(defaultIncludeStatus());
return;
}
try {
cursorIncludeStatus = JSON.parse(output.trim());
onFinished(JSON.parse(output.trim()));
} catch (e) {
cursorIncludeStatus = {
"exists": false,
"included": false,
"configFormat": "",
"readOnly": false
};
onFinished(defaultIncludeStatus());
}
});
}
function fixCursorInclude() {
if (cursorReadOnly) {
function checkCursorIncludeStatus() {
checkingCursorInclude = true;
checkIncludeStatus("cursor", "check-cursor-include", status => {
checkingCursorInclude = false;
cursorIncludeStatus = status;
});
}
function checkWindowRulesIncludeStatus() {
checkingWindowRulesInclude = true;
checkIncludeStatus("windowrules", "check-windowrules-include-theme", status => {
checkingWindowRulesInclude = false;
windowRulesIncludeStatus = status;
});
}
function fixInclude(includeKind, procTag, readOnly, onFinished) {
if (readOnly) {
ToastService.showWarning(I18n.tr("Hyprland conf mode"), I18n.tr("This install is still using hyprland.conf. Run dms setup to migrate before changing these settings."), "dms setup", "hyprland-migration");
onFinished(false);
return;
}
const paths = getCursorConfigPaths();
if (!paths)
const paths = getIncludeConfigPaths(includeKind);
if (!paths) {
onFinished(false);
return;
fixingCursorInclude = true;
}
const unixTime = Math.floor(Date.now() / 1000);
const backupFile = paths.configFile + ".backup" + unixTime;
const script = ConfigIncludeResolve.buildRepairScript({
configFile: paths.configFile,
backupFile: backupFile,
fragmentFile: paths.cursorFile,
backupFile: paths.configFile + ".backup" + unixTime,
fragmentFile: paths.fragmentFile,
grepPattern: paths.grepPattern,
includeLine: paths.includeLine
});
Proc.runCommand("fix-cursor-include", ["sh", "-c", script], (output, exitCode) => {
Proc.runCommand(procTag, ["sh", "-c", script], (output, exitCode) => onFinished(exitCode === 0));
}
function fixCursorInclude() {
fixingCursorInclude = true;
fixInclude("cursor", "fix-cursor-include", cursorReadOnly, success => {
fixingCursorInclude = false;
if (exitCode !== 0)
if (!success)
return;
checkCursorIncludeStatus();
SettingsData.updateCompositorCursor();
});
}
function fixWindowRulesInclude() {
fixingWindowRulesInclude = true;
fixInclude("windowrules", "fix-windowrules-include-theme", windowRulesReadOnly, success => {
fixingWindowRulesInclude = false;
if (!success)
return;
if (CompositorService.isMango)
MangoService.reloadConfig();
checkWindowRulesIncludeStatus();
CompositorService.applyDmsWindowFloatingRule();
});
}
function unsyncFloatingWindowSettings() {
if (!SettingsData.floatingWindowSyncGlobal)
return;
SettingsData.set("floatingWindowTransparency", SettingsData.popupTransparency);
SettingsData.set("floatingWindowForegroundLayers", SettingsData.blurForegroundLayers ?? true);
SettingsData.set("floatingWindowForegroundTransparency", SettingsData.foregroundLayerTransparency ?? 1.0);
SettingsData.set("floatingWindowSyncGlobal", false);
}
function isTemplateDetected(templateId) {
if (!templateDetection || templateDetection.length === 0)
return true;
@@ -259,8 +320,10 @@ Item {
themeColorsTab.templateDetection = JSON.parse(output.trim());
} catch (e) {}
});
if (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango)
if (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango) {
checkCursorIncludeStatus();
checkWindowRulesIncludeStatus();
}
refreshMatugenSchemePreviews();
}
@@ -296,6 +359,78 @@ Item {
}
}
component IncludeWarningBox: StyledRect {
id: includeWarningBox
property bool checking: false
property bool fixing: false
property bool includeReadOnly: false
property bool alreadyIncluded: false
property bool visibleCondition: true
property string fragmentPath: ""
property var onSetup: function () {}
readonly property bool showLegacy: includeReadOnly
readonly property bool showSetup: !showLegacy && !alreadyIncluded
width: parent.width
height: includeWarningContent.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadius
color: Theme.withAlpha(Theme.primary, 0.15)
border.color: Theme.withAlpha(Theme.primary, 0.3)
border.width: 1
visible: visibleCondition && (showLegacy || showSetup) && !checking
Row {
id: includeWarningContent
anchors.fill: parent
anchors.margins: Theme.spacingL
spacing: Theme.spacingM
DankIcon {
name: "warning"
size: Theme.iconSize
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
Column {
width: parent.width - Theme.iconSize - (includeFixButton.visible ? includeFixButton.width + Theme.spacingM : 0) - Theme.spacingM
spacing: Theme.spacingXS
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: includeWarningBox.showLegacy ? I18n.tr("Hyprland conf mode") : I18n.tr("First Time Setup")
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.primary
width: parent.width
horizontalAlignment: Text.AlignLeft
}
StyledText {
text: includeWarningBox.showLegacy ? I18n.tr("This install is still using hyprland.conf. Run dms setup to migrate before changing these settings.") : I18n.tr("Click 'Setup' to create %1 and add include to your compositor config.").arg(includeWarningBox.fragmentPath)
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
width: parent.width
horizontalAlignment: Text.AlignLeft
}
}
DankButton {
id: includeFixButton
visible: !includeWarningBox.showLegacy && includeWarningBox.showSetup
text: includeWarningBox.fixing ? I18n.tr("Setting up...") : I18n.tr("Setup")
backgroundColor: Theme.primary
textColor: Theme.primaryText
enabled: !includeWarningBox.fixing
anchors.verticalCenter: parent.verticalCenter
onClicked: includeWarningBox.onSetup()
}
}
}
DankFlickable {
anchors.fill: parent
clip: true
@@ -1137,15 +1272,28 @@ Item {
SettingsCard {
tab: "theme"
tags: ["automatic", "color", "mode", "schedule", "sunrise", "sunset"]
title: I18n.tr("Automatic Color Mode")
settingKey: "automaticColorMode"
iconName: "schedule"
tags: ["light", "dark", "mode", "appearance", "automatic", "color", "schedule", "sunrise", "sunset"]
title: I18n.tr("Color Mode")
settingKey: "colorMode"
iconName: "contrast"
Column {
width: parent.width
spacing: Theme.spacingM
SettingsToggleRow {
tab: "theme"
tags: ["light", "dark", "mode"]
settingKey: "isLightMode"
text: I18n.tr("Light Mode")
description: I18n.tr("Use light theme instead of dark theme")
checked: SessionData.isLightMode
onToggled: checked => {
Theme.screenTransition();
Theme.setLightMode(checked);
}
}
DankToggle {
id: themeModeAutoToggle
width: parent.width
@@ -1568,27 +1716,6 @@ Item {
}
}
SettingsCard {
tab: "theme"
tags: ["light", "dark", "mode", "appearance"]
title: I18n.tr("Color Mode")
settingKey: "colorMode"
iconName: "contrast"
SettingsToggleRow {
tab: "theme"
tags: ["light", "dark", "mode"]
settingKey: "isLightMode"
text: I18n.tr("Light Mode")
description: I18n.tr("Use light theme instead of dark theme")
checked: SessionData.isLightMode
onToggled: checked => {
Theme.screenTransition();
Theme.setLightMode(checked);
}
}
}
SettingsCard {
tab: "theme"
tags: ["transparency", "opacity", "widget", "styling"]
@@ -1723,12 +1850,21 @@ Item {
}
}
}
}
SettingsCard {
tab: "theme"
tags: ["surface", "popup", "transparency", "opacity", "modal", "border", "outline", "corner", "radius"]
title: I18n.tr("Surface Styling")
settingKey: "surfaceStyling"
iconName: "layers"
SettingsSliderRow {
tab: "theme"
tags: ["surface", "popup", "transparency", "opacity", "modal"]
settingKey: "popupTransparency"
text: I18n.tr("Surface Opacity")
description: I18n.tr("Controls opacity of shell surfaces, popouts, and modals")
description: I18n.tr("Controls opacity of shell surfaces, popouts, and modals", "Surface Opacity setting description")
visible: !themeColorsTab.connectedFrameModeActive
value: Math.round(SettingsData.popupTransparency * 100)
minimum: 0
@@ -1748,6 +1884,21 @@ Item {
onToggled: checked => SettingsData.set("blurForegroundLayers", checked)
}
SettingsSliderRow {
tab: "theme"
tags: ["foreground", "layers", "opacity", "transparency", "contrast", "cards"]
settingKey: "foregroundLayerTransparency"
text: I18n.tr("Foreground Opacity")
description: I18n.tr("Opacity of foreground cards and nested surfaces on shell panels")
visible: SettingsData.blurForegroundLayers ?? true
value: Math.round((SettingsData.foregroundLayerTransparency ?? 1.0) * 100)
minimum: 0
maximum: 100
unit: "%"
defaultValue: 100
onSliderValueChanged: newValue => SettingsData.set("foregroundLayerTransparency", newValue / 100)
}
SettingsSliderRow {
tab: "theme"
tags: ["foreground", "layers", "outline", "border", "cards", "widgets", "notifications", "control center"]
@@ -1854,6 +2005,113 @@ Item {
}
}
SettingsCard {
tab: "theme"
tags: ["floating", "window", "settings", "notepad", "authentication", "polkit", "opacity", "transparency", "foreground", "tile", "tiling"]
title: I18n.tr("Floating Windows")
settingKey: "floatingWindows"
iconName: "open_in_new"
SettingsToggleRow {
tab: "theme"
tags: ["floating", "window", "sync", "global", "surface", "opacity"]
settingKey: "floatingWindowSyncGlobal"
text: I18n.tr("Sync with Global Settings")
description: I18n.tr("Floating windows follow Surface Styling settings")
checked: SettingsData.floatingWindowSyncGlobal ?? true
onToggled: checked => SettingsData.set("floatingWindowSyncGlobal", checked)
}
SettingsSliderRow {
id: floatingWindowOpacitySlider
tab: "theme"
tags: ["floating", "window", "opacity", "transparency"]
settingKey: "floatingWindowTransparency"
text: I18n.tr("Window Opacity")
description: I18n.tr("Opacity of floating DMS windows like Settings, Notepad, and authentication prompts")
value: Math.round(Theme.floatingWindowTransparency * 100)
minimum: 0
maximum: 100
unit: "%"
defaultValue: 100
onSliderValueChanged: newValue => {
themeColorsTab.unsyncFloatingWindowSettings();
SettingsData.set("floatingWindowTransparency", newValue / 100);
}
Binding {
target: floatingWindowOpacitySlider
property: "value"
value: Math.round(Theme.floatingWindowTransparency * 100)
restoreMode: Binding.RestoreBinding
}
}
SettingsToggleRow {
tab: "theme"
tags: ["floating", "window", "foreground", "layers", "contrast", "cards", "blur", "glass"]
settingKey: "floatingWindowForegroundLayers"
text: I18n.tr("Foreground Layers")
description: I18n.tr("Show foreground surfaces on cards inside floating windows")
checked: Theme.floatingWindowForegroundLayers
onToggled: checked => {
themeColorsTab.unsyncFloatingWindowSettings();
SettingsData.set("floatingWindowForegroundLayers", checked);
}
}
SettingsSliderRow {
id: floatingWindowForegroundOpacitySlider
tab: "theme"
tags: ["floating", "window", "foreground", "layers", "opacity", "transparency", "cards"]
settingKey: "floatingWindowForegroundTransparency"
text: I18n.tr("Foreground Opacity")
description: I18n.tr("Opacity of cards and nested surfaces inside floating windows")
visible: Theme.floatingWindowForegroundLayers
value: Math.round(Theme.floatingWindowForegroundTransparency * 100)
minimum: 0
maximum: 100
unit: "%"
defaultValue: 100
onSliderValueChanged: newValue => {
themeColorsTab.unsyncFloatingWindowSettings();
SettingsData.set("floatingWindowForegroundTransparency", newValue / 100);
}
Binding {
target: floatingWindowForegroundOpacitySlider
property: "value"
value: Math.round(Theme.floatingWindowForegroundTransparency * 100)
restoreMode: Binding.RestoreBinding
}
}
SettingsToggleRow {
tab: "theme"
tags: ["floating", "window", "tile", "tiling", "compositor", "rule", "niri", "hyprland", "mango"]
settingKey: "dmsWindowsFloating"
text: I18n.tr("Open Windows Floating")
description: I18n.tr("Open DMS windows floating instead of tiled")
visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango
checked: SettingsData.dmsWindowsFloating ?? true
onToggled: checked => {
SettingsData.set("dmsWindowsFloating", checked);
if (checked)
themeColorsTab.checkWindowRulesIncludeStatus();
}
}
IncludeWarningBox {
visibleCondition: (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango) && (SettingsData.dmsWindowsFloating ?? true)
checking: themeColorsTab.checkingWindowRulesInclude
fixing: themeColorsTab.fixingWindowRulesInclude
includeReadOnly: themeColorsTab.windowRulesReadOnly
alreadyIncluded: themeColorsTab.windowRulesIncludeStatus.included
fragmentPath: "dms/windowrules"
onSetup: themeColorsTab.fixWindowRulesInclude
}
}
SettingsCard {
tab: "theme"
tags: ["blur", "background", "transparency", "glass", "frosted"]
@@ -2144,80 +2402,13 @@ Item {
width: parent.width
spacing: Theme.spacingM
StyledRect {
id: cursorWarningBox
width: parent.width
height: cursorWarningContent.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadius
readonly property bool showLegacy: themeColorsTab.cursorReadOnly
readonly property bool showSetup: !showLegacy && !themeColorsTab.cursorIncludeStatus.included
color: (showLegacy || showSetup) ? Theme.withAlpha(Theme.primary, 0.15) : Theme.withAlpha(Theme.primary, 0)
border.color: (showLegacy || showSetup) ? Theme.withAlpha(Theme.primary, 0.3) : Theme.withAlpha(Theme.primary, 0)
border.width: 1
visible: (showLegacy || showSetup) && !themeColorsTab.checkingCursorInclude
Row {
id: cursorWarningContent
anchors.fill: parent
anchors.margins: Theme.spacingL
spacing: Theme.spacingM
DankIcon {
name: "warning"
size: Theme.iconSize
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
Column {
width: parent.width - Theme.iconSize - (cursorFixButton.visible ? cursorFixButton.width + Theme.spacingM : 0) - Theme.spacingM
spacing: Theme.spacingXS
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: {
if (cursorWarningBox.showLegacy)
return I18n.tr("Hyprland conf mode");
if (cursorWarningBox.showSetup)
return I18n.tr("First Time Setup");
return "";
}
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.primary
width: parent.width
horizontalAlignment: Text.AlignLeft
}
StyledText {
text: {
if (cursorWarningBox.showLegacy)
return I18n.tr("This install is still using hyprland.conf. Run dms setup to migrate before changing these settings.");
if (cursorWarningBox.showSetup)
return I18n.tr("Click 'Setup' to create %1 and add include to your compositor config.").arg("dms/cursor");
return "";
}
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
width: parent.width
horizontalAlignment: Text.AlignLeft
}
}
DankButton {
id: cursorFixButton
visible: !cursorWarningBox.showLegacy && cursorWarningBox.showSetup
text: themeColorsTab.fixingCursorInclude ? I18n.tr("Setting up...") : I18n.tr("Setup")
backgroundColor: Theme.primary
textColor: Theme.primaryText
enabled: !themeColorsTab.fixingCursorInclude
anchors.verticalCenter: parent.verticalCenter
onClicked: themeColorsTab.fixCursorInclude()
}
}
IncludeWarningBox {
checking: themeColorsTab.checkingCursorInclude
fixing: themeColorsTab.fixingCursorInclude
includeReadOnly: themeColorsTab.cursorReadOnly
alreadyIncluded: themeColorsTab.cursorIncludeStatus.included
fragmentPath: "dms/cursor"
onSetup: themeColorsTab.fixCursorInclude
}
SettingsDropdownRow {
@@ -3,10 +3,9 @@ import Quickshell
import qs.Common
import qs.Widgets
FloatingWindow {
DankFloatingWindow {
id: root
property bool disablePopupTransparency: true
property var allWidgets: []
property string targetSection: ""
property string searchQuery: ""
@@ -15,10 +14,10 @@ FloatingWindow {
property bool keyboardNavigationActive: false
property var parentModal: null
parentWindow: parentModal
readonly property bool blurActive: Theme.blurForegroundLayers || Theme.transparentBlurLayers
readonly property real surfaceAlpha: blurActive ? Math.min(Theme.popupTransparency, Theme.transparentBlurLayers ? 0.36 : 0.78) : 1.0
readonly property real fieldAlpha: blurActive ? Math.min(Theme.popupTransparency, Theme.transparentBlurLayers ? 0.18 : 0.62) : 1.0
readonly property real rowAlpha: blurActive ? Math.min(Theme.popupTransparency, Theme.transparentBlurLayers ? 0.12 : 0.52) : 0.30
readonly property bool blurActive: Theme.blurLayersActive
readonly property bool floatingForegroundLayers: Theme.floatingWindowForegroundLayers
readonly property bool transparentBlurLayers: Theme.blurLayersActive && !floatingForegroundLayers
readonly property real rowAlpha: blurActive ? Math.min(Theme.floatingWindowTransparency, transparentBlurLayers ? 0.12 : 0.52) : 0.30
signal widgetSelected(string widgetId, string targetSection)
@@ -112,7 +111,6 @@ FloatingWindow {
minimumSize: Qt.size(400, 350)
implicitWidth: 500
implicitHeight: 550
color: blurActive ? Theme.withAlpha(Theme.surfaceContainer, 0) : Theme.surfaceContainer
visible: false
onClosed: hide()
@@ -139,24 +137,6 @@ FloatingWindow {
});
}
WindowBlur {
targetWindow: root
blurX: 0
blurY: 0
blurWidth: root.visible ? root.width : 0
blurHeight: root.visible ? root.height : 0
blurRadius: Theme.cornerRadius
}
Rectangle {
anchors.fill: parent
radius: Theme.cornerRadius
color: Theme.withAlpha(Theme.surfaceContainer, root.surfaceAlpha)
border.color: root.blurActive ? Theme.outlineMedium : Theme.withAlpha(Theme.outlineMedium, 0)
border.width: root.blurActive ? Theme.layerOutlineWidth : 0
antialiasing: true
}
FocusScope {
id: widgetKeyHandler
@@ -294,10 +274,6 @@ FloatingWindow {
id: searchField
width: parent.width
height: 48
cornerRadius: Theme.cornerRadius
backgroundColor: Theme.withAlpha(Theme.surfaceContainerHigh, root.fieldAlpha)
normalBorderColor: Theme.outlineMedium
focusedBorderColor: Theme.primary
leftIconName: "search"
leftIconSize: Theme.iconSize
leftIconColor: Theme.surfaceVariantText
@@ -1,13 +1,11 @@
import QtQuick
import Quickshell
import qs.Common
import qs.Services
import qs.Widgets
FloatingWindow {
DankFloatingWindow {
id: root
property bool disablePopupTransparency: true
property string searchQuery: ""
property var filteredApps: []
property int selectedIndex: -1
@@ -23,28 +21,10 @@ FloatingWindow {
minimumSize: Qt.size(400, 350)
implicitWidth: 500
implicitHeight: 550
color: "transparent"
visible: false
onClosed: hide()
WindowBlur {
targetWindow: root
blurX: 0
blurY: 0
blurWidth: root.visible ? root.width : 0
blurHeight: root.visible ? root.height : 0
blurRadius: Theme.cornerRadius
}
Rectangle {
anchors.fill: parent
radius: Theme.cornerRadius
color: Theme.withAlpha(Theme.surfaceContainer, 0.95)
border.color: Theme.outlineMedium
border.width: Theme.layerOutlineWidth
}
FocusScope {
anchors.fill: parent
focus: true
@@ -143,10 +123,6 @@ FloatingWindow {
id: searchField
width: parent.width
height: 48
cornerRadius: Theme.cornerRadius
backgroundColor: Theme.withAlpha(Theme.surfaceContainerHigh, 0.8)
normalBorderColor: Theme.outlineMedium
focusedBorderColor: Theme.primary
leftIconName: "search"
leftIconSize: Theme.iconSize
leftIconColor: Theme.surfaceVariantText
@@ -122,7 +122,6 @@ Rectangle {
buttonSize: 36
iconName: "restart_alt"
iconSize: 20
backgroundColor: Theme.surfaceContainerHigh
iconColor: Theme.surfaceVariantText
tooltipText: I18n.tr("Reset to default name")
anchors.verticalCenter: parent.verticalCenter
@@ -137,7 +136,6 @@ Rectangle {
buttonSize: 36
iconName: root.isHidden ? "visibility" : "visibility_off"
iconSize: 20
backgroundColor: Theme.surfaceContainerHigh
iconColor: root.isHidden ? Theme.primary : Theme.surfaceVariantText
tooltipText: root.isHidden ? I18n.tr("Show device") : I18n.tr("Hide device")
anchors.verticalCenter: parent.verticalCenter
@@ -38,7 +38,9 @@ StyledRect {
return h;
}
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
color: Theme.floatingWindowNestedSurface
border.color: Theme.outlineMedium
border.width: Theme.layerOutlineWidth
readonly property bool collapsed: collapsible && !expanded
readonly property bool hasHeader: root.title !== "" || root.iconName !== ""
@@ -20,7 +20,6 @@ DankDropdown {
width: parent?.width ?? 0
addHorizontalPadding: true
usePopupTransparency: false
Rectangle {
anchors.fill: parent
@@ -35,7 +35,9 @@ StyledRect {
width: parent?.width ?? 0
height: Theme.spacingL * 2 + contentColumn.height
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
color: Theme.floatingWindowNestedSurface
border.color: Theme.outlineMedium
border.width: Theme.layerOutlineWidth
Component.onCompleted: {
if (!settingKey)
@@ -110,7 +112,6 @@ StyledRect {
iconName: "restart_alt"
iconSize: 20
visible: root.defaultValue >= 0 && slider.value !== root.defaultValue
backgroundColor: Theme.surfaceContainerHigh
iconColor: Theme.surfaceVariantText
onClicked: {
slider.value = root.defaultValue;
@@ -124,7 +124,6 @@ Item {
iconName: "restart_alt"
iconSize: 20
visible: root.defaultValue >= 0 && slider.value !== root.defaultValue
backgroundColor: Theme.surfaceContainerHigh
iconColor: Theme.surfaceVariantText
onClicked: {
slider.value = root.defaultValue;
@@ -29,7 +29,9 @@ StyledRect {
width: parent?.width ?? 0
height: Theme.spacingL * 2 + mainColumn.height
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
color: Theme.floatingWindowNestedSurface
border.color: Theme.outlineMedium
border.width: Theme.layerOutlineWidth
Component.onCompleted: {
if (!settingKey)
@@ -27,7 +27,7 @@ Rectangle {
width: parent?.width ?? 0
height: variantColumn.height
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
color: Theme.floatingWindowNestedSurface
clip: true
Column {
+43
View File
@@ -975,6 +975,45 @@ Singleton {
compositorDetected = true;
if (isNiri)
NiriService.generateNiriBlurrule();
Qt.callLater(applyDmsWindowFloatingRule);
}
function applyDmsWindowFloatingRule() {
if (!compositorDetected || (!isNiri && !isHyprland && !isMango))
return;
const floating = typeof SettingsData === "undefined" || (SettingsData.dmsWindowsFloating ?? true);
if (!floating) {
Proc.runCommand("dms-windowrule-float-remove", [Proc.dmsBin, "config", "windowrules", "remove", compositor, "dms-floating-windows"], (output, exitCode) => {
if (exitCode !== 0) {
log.warn("failed to remove DMS floating window rule", exitCode, output);
return;
}
if (isMango)
MangoService.reloadConfig();
});
return;
}
const ruleJson = JSON.stringify({
"id": "dms-floating-windows",
"name": "DMS Floating Windows",
"enabled": true,
"matchCriteria": {
"appId": "^com.danklinux.dms$"
},
"actions": {
"openFloating": true
}
});
Proc.runCommand("dms-windowrule-float-add", [Proc.dmsBin, "config", "windowrules", "add", compositor, ruleJson], (output, exitCode) => {
if (exitCode !== 0) {
log.warn("failed to add DMS floating window rule", exitCode, output);
return;
}
if (isNiri)
NiriService.validate();
if (isMango)
MangoService.reloadConfig();
});
}
// Fallback when the socket owner can't be resolved (no ss, unrecognized
@@ -1140,5 +1179,9 @@ Singleton {
return;
}
}
function onDmsWindowsFloatingChanged() {
root.applyDmsWindowFloatingRule();
}
}
}
+7 -1
View File
@@ -1202,7 +1202,6 @@ Singleton {
if (frameEnabled && SettingsData.frameMode !== "connected")
excludeNamespaces.push("dms:frame");
// Xray is niri's default blur, so only the off state needs a rule.
let xrayRules = "";
if (!layoutXrayEnabled) {
const excludeLines = layoutBarXrayEnabled ? excludeNamespaces.map(ns => `\n exclude namespace="^${ns}$"`).join("") : "";
@@ -1212,6 +1211,13 @@ layer-rule {${excludeLines}
background-effect {
xray false
}
}
window-rule {
match app-id="^com.danklinux.dms$"
background-effect {
xray false
}
}`;
}
// Marker persists the preference even while the rule has no target
+3 -6
View File
@@ -118,7 +118,7 @@ Singleton {
"systemUpdate": () => _unloadPopoutNow("systemUpdatePopout", "systemUpdateLoader"),
"layout": () => _unloadPopoutNow("layoutPopout", "layoutPopoutLoader"),
"clipboardHistory": () => _unloadPopoutNow("clipboardHistoryPopout", "clipboardHistoryPopoutLoader"),
"settings": () => _unloadSettingsNow()
"settings": () => unloadSettingsNow()
})
function setPosition(popout, x, y, width, section, screen) {
@@ -491,15 +491,12 @@ Singleton {
openSettingsWithTab(tabName);
}
function unloadSettings() {
_scheduleUnload("settings");
}
function _unloadSettingsNow() {
function unloadSettingsNow() {
if (!settingsModalLoader)
return;
if (settingsModal && settingsModal.visible)
return;
delete _pendingUnloads["settings"];
settingsModal = null;
settingsModalLoader.active = false;
}
+49
View File
@@ -0,0 +1,49 @@
pragma ComponentBehavior: Bound
import QtQuick
import Quickshell
import qs.Common
import qs.Services
FloatingWindow {
id: root
default property alias content: contentItem.data
property color surfaceColor: Theme.floatingWindowSurface
color: "transparent"
Rectangle {
anchors.fill: parent
radius: Theme.cornerRadius
color: root.surfaceColor
}
WindowBlur {
targetWindow: root
blurX: 0
blurY: 0
blurWidth: root.visible ? root.width : 0
blurHeight: root.visible ? root.height : 0
blurRadius: Theme.cornerRadius
}
Item {
id: contentItem
property bool disablePopupTransparency: true
anchors.fill: parent
}
Rectangle {
anchors.fill: parent
radius: Theme.cornerRadius
color: "transparent"
border.color: BlurService.borderColor
border.width: BlurService.borderWidth
antialiasing: true
z: 100
}
}
@@ -397,7 +397,9 @@ def find_settings_components(content, filename, wrappers):
visible_raw = extract_property(block, "visible")
condition_key = FILE_CONDITION_MAP.get(filename)
if visible_raw:
if "CompositorService.isNiri" in visible_raw:
if all(c in visible_raw for c in ("CompositorService.isNiri", "CompositorService.isHyprland", "CompositorService.isMango")):
condition_key = "windowRulesCapable"
elif "CompositorService.isNiri" in visible_raw:
condition_key = "isNiri"
elif "CompositorService.isHyprland" in visible_raw:
condition_key = "isHyprland"
@@ -935,7 +935,7 @@
"workspace"
],
"description": "Show the bar only when no windows are open",
"conditionKey": "isNiri"
"conditionKey": "windowRulesCapable"
},
{
"section": "hoverPopouts",
@@ -1013,7 +1013,7 @@
],
"icon": "fit_screen",
"description": "Remove gaps and border when windows are maximized",
"conditionKey": "isNiri"
"conditionKey": "windowRulesCapable"
},
{
"section": "barMaximizeWidgetIcons",
@@ -1421,7 +1421,7 @@
"workspaces"
],
"description": "Show workspaces of the currently focused monitor",
"conditionKey": "isNiri"
"conditionKey": "windowRulesCapable"
},
{
"section": "workspaceSettings",
@@ -1447,7 +1447,7 @@
],
"icon": "view_module",
"description": "Show workspace index numbers in the top bar workspace switcher",
"conditionKey": "isNiri"
"conditionKey": "windowRulesCapable"
},
{
"section": "groupActiveWorkspaceApps",
@@ -1575,7 +1575,7 @@
"workspace"
],
"description": "Reverse workspace switch direction when scrolling over the bar",
"conditionKey": "isNiri"
"conditionKey": "windowRulesCapable"
},
{
"section": "workspaceUnfocusedMonitorSeparateAppearance",
@@ -1663,7 +1663,7 @@
"workspaces"
],
"description": "Display only workspaces that contain windows",
"conditionKey": "isNiri"
"conditionKey": "windowRulesCapable"
},
{
"section": "showWorkspaceApps",
@@ -1693,7 +1693,7 @@
"workspace"
],
"description": "Display application icons in workspace indicators",
"conditionKey": "isNiri"
"conditionKey": "windowRulesCapable"
},
{
"section": "showWorkspaceIndex",
@@ -1987,7 +1987,7 @@
"windows"
],
"description": "Show dock when floating windows don",
"conditionKey": "isNiri"
"conditionKey": "windowRulesCapable"
},
{
"section": "dockIsolateDisplays",
@@ -3530,30 +3530,6 @@
],
"description": "Hide cursor after inactivity (0 = disabled)"
},
{
"section": "automaticColorMode",
"label": "Automatic Color Mode",
"tabIndex": 10,
"category": "Theme & Colors",
"keywords": [
"appearance",
"automatic",
"color",
"colors",
"colour",
"hue",
"look",
"mode",
"schedule",
"scheme",
"style",
"sunrise",
"sunset",
"theme",
"tint"
],
"icon": "schedule"
},
{
"section": "blurEnabled",
"label": "Background Blur",
@@ -3638,6 +3614,7 @@
"category": "Theme & Colors",
"keywords": [
"appearance",
"automatic",
"color",
"colors",
"colour",
@@ -3650,8 +3627,11 @@
"look",
"mode",
"night",
"schedule",
"scheme",
"style",
"sunrise",
"sunset",
"theme",
"tint"
],
@@ -3745,7 +3725,7 @@
],
"icon": "mouse",
"description": "Mouse pointer appearance",
"conditionKey": "isNiri"
"conditionKey": "windowRulesCapable"
},
{
"section": "widgetBackgroundCustomStrength",
@@ -3858,6 +3838,37 @@
"theme"
]
},
{
"section": "floatingWindows",
"label": "Floating Windows",
"tabIndex": 10,
"category": "Theme & Colors",
"keywords": [
"appearance",
"authentication",
"colors",
"floating",
"follow",
"foreground",
"look",
"notepad",
"opacity",
"polkit",
"scheme",
"settings",
"style",
"styling",
"surface",
"theme",
"tile",
"tiling",
"transparency",
"window",
"windows"
],
"icon": "open_in_new",
"description": "Floating windows follow Surface Styling settings"
},
{
"section": "matugenTemplateNeovimSetBackground",
"label": "Follow DMS background color",
@@ -3909,6 +3920,84 @@
],
"description": "Show foreground surfaces on panels for stronger contrast"
},
{
"section": "floatingWindowForegroundLayers",
"label": "Foreground Layers",
"tabIndex": 10,
"category": "Theme & Colors",
"keywords": [
"appearance",
"blur",
"cards",
"colors",
"contrast",
"floating",
"foreground",
"glass",
"inside",
"layers",
"look",
"scheme",
"show",
"style",
"surfaces",
"theme",
"window",
"windows"
],
"description": "Show foreground surfaces on cards inside floating windows"
},
{
"section": "floatingWindowForegroundTransparency",
"label": "Foreground Opacity",
"tabIndex": 10,
"category": "Theme & Colors",
"keywords": [
"appearance",
"cards",
"colors",
"floating",
"foreground",
"inside",
"layers",
"look",
"nested",
"opacity",
"scheme",
"style",
"surfaces",
"theme",
"transparency",
"window",
"windows"
],
"description": "Opacity of cards and nested surfaces inside floating windows"
},
{
"section": "foregroundLayerTransparency",
"label": "Foreground Opacity",
"tabIndex": 10,
"category": "Theme & Colors",
"keywords": [
"appearance",
"cards",
"colors",
"contrast",
"foreground",
"layers",
"look",
"nested",
"opacity",
"panels",
"scheme",
"shell",
"style",
"surfaces",
"theme",
"transparency"
],
"description": "Opacity of foreground cards and nested surfaces on shell panels"
},
{
"section": "matugenTemplateGtk",
"label": "GTK",
@@ -4290,6 +4379,34 @@
"description": "Invert touchpad scroll direction",
"conditionKey": "isMango"
},
{
"section": "dmsWindowsFloating",
"label": "Open Windows Floating",
"tabIndex": 10,
"category": "Theme & Colors",
"keywords": [
"appearance",
"colors",
"compositor",
"floating",
"hyprland",
"look",
"mango",
"niri",
"open",
"rule",
"scheme",
"style",
"theme",
"tile",
"tiled",
"tiling",
"window",
"windows"
],
"description": "Open DMS windows floating instead of tiled",
"conditionKey": "windowRulesCapable"
},
{
"section": "popoutElevationEnabled",
"label": "Popout Shadows",
@@ -4579,6 +4696,37 @@
],
"description": "Controls opacity of shell surfaces, popouts, and modals"
},
{
"section": "surfaceStyling",
"label": "Surface Styling",
"tabIndex": 10,
"category": "Theme & Colors",
"keywords": [
"appearance",
"border",
"colors",
"controls",
"corner",
"look",
"modal",
"modals",
"opacity",
"outline",
"popouts",
"popup",
"radius",
"scheme",
"shell",
"style",
"styling",
"surface",
"surfaces",
"theme",
"transparency"
],
"icon": "layers",
"description": "Controls opacity of shell surfaces, popouts, and modals"
},
{
"section": "syncModeWithPortal",
"label": "Sync Mode with Portal",
@@ -4606,6 +4754,31 @@
],
"description": "Sync dark mode with settings portals for system-wide theme hints"
},
{
"section": "floatingWindowSyncGlobal",
"label": "Sync with Global Settings",
"tabIndex": 10,
"category": "Theme & Colors",
"keywords": [
"appearance",
"colors",
"floating",
"follow",
"global",
"look",
"opacity",
"scheme",
"settings",
"style",
"styling",
"surface",
"sync",
"theme",
"window",
"windows"
],
"description": "Floating windows follow Surface Styling settings"
},
{
"section": "systemAppTheming",
"label": "System App Theming",
@@ -4806,6 +4979,30 @@
],
"description": "Choose neutral or accent-colored widget text"
},
{
"section": "floatingWindowTransparency",
"label": "Window Opacity",
"tabIndex": 10,
"category": "Theme & Colors",
"keywords": [
"appearance",
"authentication",
"colors",
"floating",
"look",
"notepad",
"opacity",
"prompts",
"scheme",
"settings",
"style",
"theme",
"transparency",
"window",
"windows"
],
"description": "Opacity of floating DMS windows like Settings, Notepad, and authentication prompts"
},
{
"section": "matugenTemplateZed",
"label": "Zed",