mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-06-08 04:09:15 -04:00
feat(settings): add compositor section & restructured settings
- add dedicated Compositor pages for comp specifc features - add Dank Bar Appearance subsection - improve lazy loading, caching, search routing, & IPC navigation - standardized responsive Setting categories from global animations
This commit is contained in:
@@ -0,0 +1,324 @@
|
||||
import QtQuick
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
import qs.Modules.Settings.Widgets
|
||||
|
||||
Item {
|
||||
DankFlickable {
|
||||
anchors.fill: parent
|
||||
clip: true
|
||||
contentHeight: layoutColumn.height + Theme.spacingXL
|
||||
contentWidth: width
|
||||
|
||||
Column {
|
||||
id: layoutColumn
|
||||
|
||||
topPadding: Theme.spacingXL
|
||||
bottomPadding: Theme.spacingXL
|
||||
width: Math.min(550, parent.width - Theme.spacingL * 2)
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
spacing: Theme.spacingXL
|
||||
|
||||
SettingsCard {
|
||||
width: parent.width
|
||||
tags: ["niri", "layout", "gaps", "radius", "window", "border"]
|
||||
title: I18n.tr("Niri Layout Overrides").replace("Niri", "niri")
|
||||
settingKey: "niriLayout"
|
||||
iconName: "crop_square"
|
||||
visible: CompositorService.isNiri
|
||||
|
||||
SettingsToggleRow {
|
||||
tags: ["niri", "gaps", "override"]
|
||||
settingKey: "niriLayoutGapsOverrideEnabled"
|
||||
text: I18n.tr("Override Gaps")
|
||||
description: I18n.tr("Use custom gaps instead of bar spacing")
|
||||
checked: SettingsData.niriLayoutGapsOverride >= 0
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
const currentGaps = Math.max(4, (SettingsData.barConfigs[0]?.spacing ?? 4));
|
||||
SettingsData.set("niriLayoutGapsOverride", currentGaps);
|
||||
return;
|
||||
}
|
||||
SettingsData.set("niriLayoutGapsOverride", -1);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tags: ["niri", "gaps", "override"]
|
||||
settingKey: "niriLayoutGapsOverride"
|
||||
text: I18n.tr("Window Gaps")
|
||||
description: I18n.tr("Space between windows")
|
||||
visible: SettingsData.niriLayoutGapsOverride >= 0
|
||||
value: Math.max(0, SettingsData.niriLayoutGapsOverride)
|
||||
minimum: 0
|
||||
maximum: 50
|
||||
unit: "px"
|
||||
defaultValue: Math.max(4, (SettingsData.barConfigs[0]?.spacing ?? 4))
|
||||
onSliderValueChanged: newValue => SettingsData.set("niriLayoutGapsOverride", newValue)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tags: ["niri", "radius", "override"]
|
||||
settingKey: "niriLayoutRadiusOverrideEnabled"
|
||||
text: I18n.tr("Override Corner Radius")
|
||||
description: I18n.tr("Use custom window radius instead of theme radius")
|
||||
checked: SettingsData.niriLayoutRadiusOverride >= 0
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
SettingsData.set("niriLayoutRadiusOverride", SettingsData.cornerRadius);
|
||||
return;
|
||||
}
|
||||
SettingsData.set("niriLayoutRadiusOverride", -1);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tags: ["niri", "radius", "override"]
|
||||
settingKey: "niriLayoutRadiusOverride"
|
||||
text: I18n.tr("Window Corner Radius")
|
||||
description: I18n.tr("Rounded corners for windows")
|
||||
visible: SettingsData.niriLayoutRadiusOverride >= 0
|
||||
value: Math.max(0, SettingsData.niriLayoutRadiusOverride)
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
unit: "px"
|
||||
defaultValue: SettingsData.cornerRadius
|
||||
onSliderValueChanged: newValue => SettingsData.set("niriLayoutRadiusOverride", newValue)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tags: ["niri", "border", "override"]
|
||||
settingKey: "niriLayoutBorderSizeEnabled"
|
||||
text: I18n.tr("Override Border Size")
|
||||
description: I18n.tr("Use custom border/focus-ring width")
|
||||
checked: SettingsData.niriLayoutBorderSize >= 0
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
SettingsData.set("niriLayoutBorderSize", 2);
|
||||
return;
|
||||
}
|
||||
SettingsData.set("niriLayoutBorderSize", -1);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tags: ["niri", "border", "override"]
|
||||
settingKey: "niriLayoutBorderSize"
|
||||
text: I18n.tr("Border Size")
|
||||
description: I18n.tr("Width of window border and focus ring")
|
||||
visible: SettingsData.niriLayoutBorderSize >= 0
|
||||
value: Math.max(0, SettingsData.niriLayoutBorderSize)
|
||||
minimum: 0
|
||||
maximum: 10
|
||||
unit: "px"
|
||||
defaultValue: 2
|
||||
onSliderValueChanged: newValue => SettingsData.set("niriLayoutBorderSize", newValue)
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
width: parent.width
|
||||
tags: ["hyprland", "layout", "gaps", "radius", "window", "border", "rounding"]
|
||||
title: I18n.tr("Hyprland Layout Overrides")
|
||||
settingKey: "hyprlandLayout"
|
||||
iconName: "crop_square"
|
||||
visible: CompositorService.isHyprland
|
||||
|
||||
SettingsToggleRow {
|
||||
tags: ["hyprland", "gaps", "override"]
|
||||
settingKey: "hyprlandLayoutGapsOverrideEnabled"
|
||||
text: I18n.tr("Override Gaps")
|
||||
description: I18n.tr("Use custom gaps instead of bar spacing")
|
||||
checked: SettingsData.hyprlandLayoutGapsOverride >= 0
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
const currentGaps = Math.max(4, (SettingsData.barConfigs[0]?.spacing ?? 4));
|
||||
SettingsData.set("hyprlandLayoutGapsOverride", currentGaps);
|
||||
return;
|
||||
}
|
||||
SettingsData.set("hyprlandLayoutGapsOverride", -1);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tags: ["hyprland", "gaps", "override"]
|
||||
settingKey: "hyprlandLayoutGapsOverride"
|
||||
text: I18n.tr("Window Gaps")
|
||||
description: I18n.tr("Space between windows (gaps_in and gaps_out)")
|
||||
visible: SettingsData.hyprlandLayoutGapsOverride >= 0
|
||||
value: Math.max(0, SettingsData.hyprlandLayoutGapsOverride)
|
||||
minimum: 0
|
||||
maximum: 50
|
||||
unit: "px"
|
||||
defaultValue: Math.max(4, (SettingsData.barConfigs[0]?.spacing ?? 4))
|
||||
onSliderValueChanged: newValue => SettingsData.set("hyprlandLayoutGapsOverride", newValue)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tags: ["hyprland", "radius", "override", "rounding"]
|
||||
settingKey: "hyprlandLayoutRadiusOverrideEnabled"
|
||||
text: I18n.tr("Override Corner Radius")
|
||||
description: I18n.tr("Use custom window rounding instead of theme radius")
|
||||
checked: SettingsData.hyprlandLayoutRadiusOverride >= 0
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
SettingsData.set("hyprlandLayoutRadiusOverride", SettingsData.cornerRadius);
|
||||
return;
|
||||
}
|
||||
SettingsData.set("hyprlandLayoutRadiusOverride", -1);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tags: ["hyprland", "radius", "override", "rounding"]
|
||||
settingKey: "hyprlandLayoutRadiusOverride"
|
||||
text: I18n.tr("Window Rounding")
|
||||
description: I18n.tr("Rounded corners for windows (decoration.rounding)")
|
||||
visible: SettingsData.hyprlandLayoutRadiusOverride >= 0
|
||||
value: Math.max(0, SettingsData.hyprlandLayoutRadiusOverride)
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
unit: "px"
|
||||
defaultValue: SettingsData.cornerRadius
|
||||
onSliderValueChanged: newValue => SettingsData.set("hyprlandLayoutRadiusOverride", newValue)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tags: ["hyprland", "border", "override"]
|
||||
settingKey: "hyprlandLayoutBorderSizeEnabled"
|
||||
text: I18n.tr("Override Border Size")
|
||||
description: I18n.tr("Use custom border size")
|
||||
checked: SettingsData.hyprlandLayoutBorderSize >= 0
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
SettingsData.set("hyprlandLayoutBorderSize", 2);
|
||||
return;
|
||||
}
|
||||
SettingsData.set("hyprlandLayoutBorderSize", -1);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tags: ["hyprland", "border", "override"]
|
||||
settingKey: "hyprlandLayoutBorderSize"
|
||||
text: I18n.tr("Border Size")
|
||||
description: I18n.tr("Width of window border (general.border_size)")
|
||||
visible: SettingsData.hyprlandLayoutBorderSize >= 0
|
||||
value: Math.max(0, SettingsData.hyprlandLayoutBorderSize)
|
||||
minimum: 0
|
||||
maximum: 10
|
||||
unit: "px"
|
||||
defaultValue: 2
|
||||
onSliderValueChanged: newValue => SettingsData.set("hyprlandLayoutBorderSize", newValue)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tags: ["hyprland", "resize", "border", "mouse", "drag"]
|
||||
settingKey: "hyprlandResizeOnBorder"
|
||||
text: I18n.tr("Resize on Border")
|
||||
description: I18n.tr("Resize windows by dragging their edges with the mouse")
|
||||
checked: SettingsData.hyprlandResizeOnBorder
|
||||
onToggled: checked => SettingsData.set("hyprlandResizeOnBorder", checked)
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
width: parent.width
|
||||
tags: ["mangowc", "mango", "dwl", "layout", "gaps", "radius", "window", "border"]
|
||||
title: I18n.tr("MangoWC Layout Overrides")
|
||||
settingKey: "mangoLayout"
|
||||
iconName: "crop_square"
|
||||
visible: CompositorService.isDwl || CompositorService.isMango
|
||||
|
||||
SettingsToggleRow {
|
||||
tags: ["mangowc", "mango", "gaps", "override"]
|
||||
settingKey: "mangoLayoutGapsOverrideEnabled"
|
||||
text: I18n.tr("Override Gaps")
|
||||
description: I18n.tr("Use custom gaps instead of bar spacing")
|
||||
checked: SettingsData.mangoLayoutGapsOverride >= 0
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
const currentGaps = Math.max(4, (SettingsData.barConfigs[0]?.spacing ?? 4));
|
||||
SettingsData.set("mangoLayoutGapsOverride", currentGaps);
|
||||
return;
|
||||
}
|
||||
SettingsData.set("mangoLayoutGapsOverride", -1);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tags: ["mangowc", "mango", "gaps", "override"]
|
||||
settingKey: "mangoLayoutGapsOverride"
|
||||
text: I18n.tr("Window Gaps")
|
||||
description: I18n.tr("Space between windows (gappih/gappiv/gappoh/gappov)")
|
||||
visible: SettingsData.mangoLayoutGapsOverride >= 0
|
||||
value: Math.max(0, SettingsData.mangoLayoutGapsOverride)
|
||||
minimum: 0
|
||||
maximum: 50
|
||||
unit: "px"
|
||||
defaultValue: Math.max(4, (SettingsData.barConfigs[0]?.spacing ?? 4))
|
||||
onSliderValueChanged: newValue => SettingsData.set("mangoLayoutGapsOverride", newValue)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tags: ["mangowc", "mango", "radius", "override"]
|
||||
settingKey: "mangoLayoutRadiusOverrideEnabled"
|
||||
text: I18n.tr("Override Corner Radius")
|
||||
description: I18n.tr("Use custom window radius instead of theme radius")
|
||||
checked: SettingsData.mangoLayoutRadiusOverride >= 0
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
SettingsData.set("mangoLayoutRadiusOverride", SettingsData.cornerRadius);
|
||||
return;
|
||||
}
|
||||
SettingsData.set("mangoLayoutRadiusOverride", -1);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tags: ["mangowc", "mango", "radius", "override"]
|
||||
settingKey: "mangoLayoutRadiusOverride"
|
||||
text: I18n.tr("Window Corner Radius")
|
||||
description: I18n.tr("Rounded corners for windows (border_radius)")
|
||||
visible: SettingsData.mangoLayoutRadiusOverride >= 0
|
||||
value: Math.max(0, SettingsData.mangoLayoutRadiusOverride)
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
unit: "px"
|
||||
defaultValue: SettingsData.cornerRadius
|
||||
onSliderValueChanged: newValue => SettingsData.set("mangoLayoutRadiusOverride", newValue)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tags: ["mangowc", "mango", "border", "override"]
|
||||
settingKey: "mangoLayoutBorderSizeEnabled"
|
||||
text: I18n.tr("Override Border Size")
|
||||
description: I18n.tr("Use custom border size")
|
||||
checked: SettingsData.mangoLayoutBorderSize >= 0
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
SettingsData.set("mangoLayoutBorderSize", 2);
|
||||
return;
|
||||
}
|
||||
SettingsData.set("mangoLayoutBorderSize", -1);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tags: ["mangowc", "mango", "border", "override"]
|
||||
settingKey: "mangoLayoutBorderSize"
|
||||
text: I18n.tr("Border Size")
|
||||
description: I18n.tr("Width of window border (borderpx)")
|
||||
visible: SettingsData.mangoLayoutBorderSize >= 0
|
||||
value: Math.max(0, SettingsData.mangoLayoutBorderSize)
|
||||
minimum: 0
|
||||
maximum: 10
|
||||
unit: "px"
|
||||
defaultValue: 2
|
||||
onSliderValueChanged: newValue => SettingsData.set("mangoLayoutBorderSize", newValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
LayoutMirroring.enabled: I18n.isRtl
|
||||
LayoutMirroring.childrenInherit: true
|
||||
|
||||
property int subTabIndex: 0
|
||||
|
||||
readonly property var workspaceSections: ({
|
||||
"workspaceSettings": true,
|
||||
"showWorkspaceIndex": true,
|
||||
"showWorkspaceName": true,
|
||||
"showWorkspacePadding": true,
|
||||
"showWorkspaceApps": true,
|
||||
"groupWorkspaceApps": true,
|
||||
"groupActiveWorkspaceApps": true,
|
||||
"workspaceActiveAppHighlightEnabled": true,
|
||||
"workspaceFollowFocus": true,
|
||||
"showOccupiedWorkspacesOnly": true,
|
||||
"reverseScrolling": true,
|
||||
"workspaceDragReorder": true,
|
||||
"dwlShowAllTags": true,
|
||||
"workspaceIcons": true
|
||||
})
|
||||
readonly property var layoutSections: ({
|
||||
"niriLayout": true,
|
||||
"niriLayoutGapsOverrideEnabled": true,
|
||||
"niriLayoutGapsOverride": true,
|
||||
"niriLayoutRadiusOverrideEnabled": true,
|
||||
"niriLayoutRadiusOverride": true,
|
||||
"niriLayoutBorderSizeEnabled": true,
|
||||
"niriLayoutBorderSize": true,
|
||||
"hyprlandLayout": true,
|
||||
"hyprlandLayoutGapsOverrideEnabled": true,
|
||||
"hyprlandLayoutGapsOverride": true,
|
||||
"hyprlandLayoutRadiusOverrideEnabled": true,
|
||||
"hyprlandLayoutRadiusOverride": true,
|
||||
"hyprlandLayoutBorderSizeEnabled": true,
|
||||
"hyprlandLayoutBorderSize": true,
|
||||
"hyprlandResizeOnBorder": true,
|
||||
"mangoLayout": true,
|
||||
"mangoLayoutGapsOverrideEnabled": true,
|
||||
"mangoLayoutGapsOverride": true,
|
||||
"mangoLayoutRadiusOverrideEnabled": true,
|
||||
"mangoLayoutRadiusOverride": true,
|
||||
"mangoLayoutBorderSizeEnabled": true,
|
||||
"mangoLayoutBorderSize": true
|
||||
})
|
||||
|
||||
function routeSearchTarget(target) {
|
||||
if (!target)
|
||||
return;
|
||||
if (workspaceSections[target]) {
|
||||
subTabIndex = 0;
|
||||
} else if (layoutSections[target]) {
|
||||
subTabIndex = 1;
|
||||
} else if (target === "windowRules" || target.startsWith("windowRule")) {
|
||||
subTabIndex = 2;
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: routeSearchTarget(SettingsSearchService.targetSection)
|
||||
|
||||
Connections {
|
||||
target: SettingsSearchService
|
||||
|
||||
function onTargetSectionChanged() {
|
||||
root.routeSearchTarget(SettingsSearchService.targetSection);
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
spacing: 0
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 60
|
||||
color: "transparent"
|
||||
|
||||
DankTabBar {
|
||||
id: compositorTabBar
|
||||
|
||||
width: Math.min(500, parent.width - Theme.spacingL * 2)
|
||||
height: 45
|
||||
anchors.centerIn: parent
|
||||
model: [
|
||||
{
|
||||
"text": I18n.tr("Workspaces"),
|
||||
"icon": "view_module"
|
||||
},
|
||||
{
|
||||
"text": I18n.tr("Window Layout"),
|
||||
"icon": "crop_square"
|
||||
},
|
||||
{
|
||||
"text": I18n.tr("Window Rules"),
|
||||
"icon": "select_window"
|
||||
}
|
||||
]
|
||||
currentIndex: root.subTabIndex
|
||||
onTabClicked: index => root.subTabIndex = index
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
y: compositorTabBar.y + compositorTabBar.height + 10
|
||||
width: compositorTabBar.width
|
||||
height: 1
|
||||
color: Theme.surface
|
||||
opacity: 0.56
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
clip: true
|
||||
|
||||
Loader {
|
||||
anchors.fill: parent
|
||||
active: root.subTabIndex === 0
|
||||
visible: active
|
||||
sourceComponent: WorkspacesTab {}
|
||||
}
|
||||
|
||||
Loader {
|
||||
anchors.fill: parent
|
||||
active: root.subTabIndex === 1
|
||||
visible: active
|
||||
sourceComponent: CompositorLayoutTab {}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: windowRulesLoader
|
||||
|
||||
property bool loadedOnce: false
|
||||
|
||||
anchors.fill: parent
|
||||
active: root.subTabIndex === 2 || loadedOnce
|
||||
visible: root.subTabIndex === 2 && status === Loader.Ready
|
||||
asynchronous: true
|
||||
sourceComponent: WindowRulesTab {
|
||||
pageActive: root.subTabIndex === 2
|
||||
}
|
||||
|
||||
onLoaded: loadedOnce = true
|
||||
}
|
||||
|
||||
StyledText {
|
||||
anchors.centerIn: parent
|
||||
visible: root.subTabIndex === 2 && windowRulesLoader.status === Loader.Loading
|
||||
text: I18n.tr("Loading...", "loading indicator")
|
||||
color: Theme.surfaceVariantText
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import QtQuick
|
||||
|
||||
DankBarTab {
|
||||
appearanceOnly: true
|
||||
}
|
||||
@@ -13,7 +13,22 @@ Item {
|
||||
LayoutMirroring.childrenInherit: true
|
||||
|
||||
property var parentModal: null
|
||||
property string selectedBarId: "default"
|
||||
property bool appearanceOnly: false
|
||||
property string selectedBarId: SettingsUiState.selectedBarId
|
||||
|
||||
onSelectedBarIdChanged: {
|
||||
if (SettingsUiState.selectedBarId !== selectedBarId)
|
||||
SettingsUiState.selectedBarId = selectedBarId;
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: SettingsUiState
|
||||
|
||||
function onSelectedBarIdChanged() {
|
||||
if (dankBarTab.selectedBarId !== SettingsUiState.selectedBarId)
|
||||
dankBarTab.selectedBarId = SettingsUiState.selectedBarId;
|
||||
}
|
||||
}
|
||||
|
||||
property var selectedBarConfig: {
|
||||
selectedBarId;
|
||||
@@ -21,6 +36,14 @@ Item {
|
||||
const index = SettingsData.barConfigs.findIndex(cfg => cfg.id === selectedBarId);
|
||||
return index !== -1 ? SettingsData.barConfigs[index] : SettingsData.barConfigs[0];
|
||||
}
|
||||
readonly property string selectedBarName: {
|
||||
selectedBarId;
|
||||
SettingsData.barConfigs;
|
||||
const index = SettingsData.barConfigs.findIndex(config => config.id === selectedBarId);
|
||||
if (index < 0)
|
||||
return I18n.tr("Bar");
|
||||
return SettingsData.barConfigs[index].name || I18n.tr("Bar %1").arg(index + 1);
|
||||
}
|
||||
|
||||
property bool selectedBarIsVertical: {
|
||||
selectedBarId;
|
||||
@@ -210,10 +233,33 @@ Item {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
spacing: Theme.spacingXL
|
||||
|
||||
SettingsCard {
|
||||
tab: "appearance"
|
||||
iconName: "toolbar"
|
||||
title: I18n.tr("Dank Bar")
|
||||
settingKey: "barAppearance"
|
||||
visible: dankBarTab.appearanceOnly
|
||||
|
||||
SettingsButtonGroupRow {
|
||||
text: I18n.tr("Editing changes on %1").arg(dankBarTab.selectedBarName)
|
||||
model: SettingsData.barConfigs.map((config, index) => config.name || I18n.tr("Bar %1").arg(index + 1))
|
||||
currentIndex: {
|
||||
const index = SettingsData.barConfigs.findIndex(config => config.id === dankBarTab.selectedBarId);
|
||||
return Math.max(0, index);
|
||||
}
|
||||
onSelectionChanged: (index, selected) => {
|
||||
if (!selected || index < 0 || index >= SettingsData.barConfigs.length)
|
||||
return;
|
||||
dankBarTab.selectedBarId = SettingsData.barConfigs[index].id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
iconName: "dashboard"
|
||||
title: I18n.tr("Bar Configurations")
|
||||
settingKey: "barConfigurations"
|
||||
visible: !dankBarTab.appearanceOnly
|
||||
|
||||
RowLayout {
|
||||
width: parent.width
|
||||
@@ -410,7 +456,7 @@ Item {
|
||||
SettingsCard {
|
||||
iconName: selectedBarConfig?.enabled ? "visibility" : "visibility_off"
|
||||
title: I18n.tr("Enable Bar")
|
||||
visible: selectedBarId !== "default"
|
||||
visible: !dankBarTab.appearanceOnly && selectedBarId !== "default"
|
||||
|
||||
SettingsToggleRow {
|
||||
text: I18n.tr("Toggle visibility of this bar configuration")
|
||||
@@ -426,7 +472,7 @@ Item {
|
||||
iconName: "vertical_align_center"
|
||||
title: I18n.tr("Position")
|
||||
settingKey: "barPosition"
|
||||
visible: selectedBarConfig?.enabled
|
||||
visible: !dankBarTab.appearanceOnly && selectedBarConfig?.enabled
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
@@ -486,7 +532,7 @@ Item {
|
||||
settingKey: "barDisplay"
|
||||
collapsible: true
|
||||
expanded: false
|
||||
visible: selectedBarConfig?.enabled
|
||||
visible: !dankBarTab.appearanceOnly && selectedBarConfig?.enabled
|
||||
|
||||
StyledText {
|
||||
width: parent.width
|
||||
@@ -588,12 +634,12 @@ Item {
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
iconName: "visibility_off"
|
||||
iconName: "visibility"
|
||||
title: I18n.tr("Visibility")
|
||||
settingKey: "barVisibility"
|
||||
collapsible: true
|
||||
expanded: false
|
||||
visible: selectedBarConfig?.enabled
|
||||
expanded: true
|
||||
visible: !dankBarTab.appearanceOnly && selectedBarConfig?.enabled
|
||||
|
||||
SettingsToggleRow {
|
||||
text: I18n.tr("Auto-hide")
|
||||
@@ -751,7 +797,7 @@ Item {
|
||||
}
|
||||
|
||||
SettingsControlledByFrame {
|
||||
visible: SettingsData.frameEnabled
|
||||
visible: !dankBarTab.appearanceOnly && SettingsData.frameEnabled
|
||||
parentModal: dankBarTab.parentModal
|
||||
settingLabel: I18n.tr("Bar spacing and size")
|
||||
reason: I18n.tr("Managed by Frame")
|
||||
@@ -761,7 +807,7 @@ Item {
|
||||
iconName: "space_bar"
|
||||
title: I18n.tr("Spacing")
|
||||
settingKey: "barSpacing"
|
||||
visible: (selectedBarConfig?.enabled ?? false) && !SettingsData.frameEnabled
|
||||
visible: !dankBarTab.appearanceOnly && (selectedBarConfig?.enabled ?? false) && !SettingsData.frameEnabled
|
||||
|
||||
SettingsSliderRow {
|
||||
id: edgeSpacingSlider
|
||||
@@ -911,10 +957,11 @@ Item {
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
tab: "appearance"
|
||||
iconName: "opacity"
|
||||
title: I18n.tr("Transparency")
|
||||
settingKey: "barTransparency"
|
||||
visible: selectedBarConfig?.enabled
|
||||
visible: dankBarTab.appearanceOnly && selectedBarConfig?.enabled
|
||||
|
||||
SettingsSliderRow {
|
||||
id: barTransparencySlider
|
||||
@@ -973,10 +1020,12 @@ Item {
|
||||
|
||||
SettingsSliderCard {
|
||||
id: fontScaleSliderCard
|
||||
tab: "appearance"
|
||||
settingKey: "barFontScale"
|
||||
iconName: "text_fields"
|
||||
title: I18n.tr("Font Scale")
|
||||
description: I18n.tr("Scale DankBar font sizes independently")
|
||||
visible: selectedBarConfig?.enabled
|
||||
visible: dankBarTab.appearanceOnly && selectedBarConfig?.enabled
|
||||
minimum: 50
|
||||
maximum: 200
|
||||
value: Math.round((selectedBarConfig?.fontScale ?? 1.0) * 100)
|
||||
@@ -998,10 +1047,12 @@ Item {
|
||||
|
||||
SettingsSliderCard {
|
||||
id: iconScaleSliderCard
|
||||
tab: "appearance"
|
||||
settingKey: "barIconScale"
|
||||
iconName: "interests"
|
||||
title: I18n.tr("Icon Scale")
|
||||
description: I18n.tr("Scale DankBar icon sizes independently")
|
||||
visible: selectedBarConfig?.enabled
|
||||
visible: dankBarTab.appearanceOnly && selectedBarConfig?.enabled
|
||||
minimum: 50
|
||||
maximum: 200
|
||||
value: Math.round((selectedBarConfig?.iconScale ?? 1.0) * 100)
|
||||
@@ -1021,13 +1072,18 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
WorkspaceAppearanceCard {
|
||||
visible: dankBarTab.appearanceOnly
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
tab: "appearance"
|
||||
iconName: "rounded_corner"
|
||||
title: I18n.tr("Corners & Background")
|
||||
settingKey: "barCorners"
|
||||
collapsible: true
|
||||
expanded: false
|
||||
visible: selectedBarConfig?.enabled
|
||||
expanded: true
|
||||
visible: dankBarTab.appearanceOnly && selectedBarConfig?.enabled
|
||||
|
||||
SettingsControlledByFrame {
|
||||
visible: SettingsData.frameEnabled
|
||||
@@ -1144,7 +1200,7 @@ Item {
|
||||
iconName: "fit_screen"
|
||||
title: I18n.tr("Maximize Detection")
|
||||
description: I18n.tr("Remove gaps and border when windows are maximized")
|
||||
visible: selectedBarConfig?.enabled && (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango)
|
||||
visible: !dankBarTab.appearanceOnly && selectedBarConfig?.enabled && (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango)
|
||||
checked: selectedBarConfig?.maximizeDetection ?? true
|
||||
onToggled: checked => SettingsData.updateBarConfig(selectedBarId, {
|
||||
maximizeDetection: checked
|
||||
@@ -1152,10 +1208,11 @@ Item {
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
tab: "appearance"
|
||||
iconName: "filter_b_and_w"
|
||||
title: I18n.tr("System Tray Icon Tint")
|
||||
settingKey: "trayIconTint"
|
||||
visible: selectedBarConfig?.enabled
|
||||
visible: dankBarTab.appearanceOnly && selectedBarConfig?.enabled
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Choose monochrome or a theme color tint for system tray icons")
|
||||
@@ -1251,9 +1308,11 @@ Item {
|
||||
}
|
||||
|
||||
SettingsToggleCard {
|
||||
tab: "appearance"
|
||||
settingKey: "barBorder"
|
||||
iconName: "border_style"
|
||||
title: I18n.tr("Border")
|
||||
visible: selectedBarConfig?.enabled
|
||||
visible: dankBarTab.appearanceOnly && selectedBarConfig?.enabled && !dankBarTab.connectedFrameModeActive
|
||||
checked: selectedBarConfig?.borderEnabled ?? false
|
||||
onToggled: checked => SettingsData.updateBarConfig(selectedBarId, {
|
||||
borderEnabled: checked
|
||||
@@ -1344,9 +1403,11 @@ Item {
|
||||
}
|
||||
|
||||
SettingsToggleCard {
|
||||
tab: "appearance"
|
||||
settingKey: "barWidgetOutline"
|
||||
iconName: "highlight"
|
||||
title: I18n.tr("Widget Outline")
|
||||
visible: selectedBarConfig?.enabled
|
||||
visible: dankBarTab.appearanceOnly && selectedBarConfig?.enabled
|
||||
checked: selectedBarConfig?.widgetOutlineEnabled ?? false
|
||||
onToggled: checked => SettingsData.updateBarConfig(selectedBarId, {
|
||||
widgetOutlineEnabled: checked
|
||||
@@ -1437,7 +1498,7 @@ Item {
|
||||
}
|
||||
|
||||
SettingsControlledByFrame {
|
||||
visible: dankBarTab.connectedFrameModeActive
|
||||
visible: dankBarTab.appearanceOnly && dankBarTab.connectedFrameModeActive
|
||||
parentModal: dankBarTab.parentModal
|
||||
settingLabel: I18n.tr("Bar shadow, border, and corners")
|
||||
reason: I18n.tr("Managed by Frame in Connected Mode")
|
||||
@@ -1445,12 +1506,13 @@ Item {
|
||||
|
||||
SettingsCard {
|
||||
id: shadowCard
|
||||
tab: "appearance"
|
||||
iconName: "layers"
|
||||
title: I18n.tr("Shadow Override", "bar shadow settings card")
|
||||
settingKey: "barShadow"
|
||||
collapsible: true
|
||||
expanded: false
|
||||
visible: (selectedBarConfig?.enabled ?? false) && !dankBarTab.connectedFrameModeActive
|
||||
visible: dankBarTab.appearanceOnly && (selectedBarConfig?.enabled ?? false) && !dankBarTab.connectedFrameModeActive
|
||||
|
||||
readonly property bool shadowActive: (selectedBarConfig?.shadowIntensity ?? 0) > 0
|
||||
readonly property bool isCustomColor: (selectedBarConfig?.shadowColorMode ?? "default") === "custom"
|
||||
@@ -1512,6 +1574,7 @@ Item {
|
||||
}
|
||||
|
||||
SettingsDropdownRow {
|
||||
tab: "appearance"
|
||||
visible: shadowCard.shadowActive
|
||||
text: I18n.tr("Direction Source", "bar shadow direction source")
|
||||
description: I18n.tr("Choose how this bar resolves shadow direction")
|
||||
@@ -1545,6 +1608,7 @@ Item {
|
||||
}
|
||||
|
||||
SettingsDropdownRow {
|
||||
tab: "appearance"
|
||||
visible: shadowCard.shadowActive && shadowCard.directionSource === "manual"
|
||||
text: I18n.tr("Manual Direction", "bar manual shadow direction")
|
||||
description: I18n.tr("Use a fixed shadow direction for this bar")
|
||||
@@ -1680,7 +1744,7 @@ Item {
|
||||
iconName: "mouse"
|
||||
title: I18n.tr("Scroll Wheel")
|
||||
description: I18n.tr("Control workspaces and columns by scrolling on the bar")
|
||||
visible: selectedBarConfig?.enabled
|
||||
visible: !dankBarTab.appearanceOnly && selectedBarConfig?.enabled
|
||||
checked: selectedBarConfig?.scrollEnabled ?? true
|
||||
onToggled: checked => SettingsData.updateBarConfig(selectedBarId, {
|
||||
scrollEnabled: checked
|
||||
|
||||
@@ -1640,7 +1640,7 @@ Item {
|
||||
SettingsControlledByFrame {
|
||||
visible: themeColorsTab.connectedFrameModeActive
|
||||
parentModal: themeColorsTab.parentModal
|
||||
settingLabel: I18n.tr("Surface Opacity")
|
||||
settingLabel: I18n.tr("Transparency")
|
||||
reason: I18n.tr("Managed by Frame in Connected Mode")
|
||||
}
|
||||
|
||||
@@ -1648,7 +1648,7 @@ Item {
|
||||
tab: "theme"
|
||||
tags: ["surface", "popup", "transparency", "opacity", "modal"]
|
||||
settingKey: "popupTransparency"
|
||||
text: I18n.tr("Surface Opacity")
|
||||
text: I18n.tr("Transparency")
|
||||
description: I18n.tr("Controls opacity of all popouts, modals, and their content layers")
|
||||
visible: !themeColorsTab.connectedFrameModeActive
|
||||
value: Math.round(SettingsData.popupTransparency * 100)
|
||||
@@ -1956,325 +1956,6 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
tab: "theme"
|
||||
tags: ["niri", "layout", "gaps", "radius", "window", "border"]
|
||||
title: I18n.tr("Niri Layout Overrides").replace("Niri", "niri")
|
||||
settingKey: "niriLayout"
|
||||
iconName: "crop_square"
|
||||
visible: CompositorService.isNiri
|
||||
|
||||
SettingsToggleRow {
|
||||
tab: "theme"
|
||||
tags: ["niri", "gaps", "override"]
|
||||
settingKey: "niriLayoutGapsOverrideEnabled"
|
||||
text: I18n.tr("Override Gaps")
|
||||
description: I18n.tr("Use custom gaps instead of bar spacing")
|
||||
checked: SettingsData.niriLayoutGapsOverride >= 0
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
const currentGaps = Math.max(4, (SettingsData.barConfigs[0]?.spacing ?? 4));
|
||||
SettingsData.set("niriLayoutGapsOverride", currentGaps);
|
||||
return;
|
||||
}
|
||||
SettingsData.set("niriLayoutGapsOverride", -1);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tab: "theme"
|
||||
tags: ["niri", "gaps", "override"]
|
||||
settingKey: "niriLayoutGapsOverride"
|
||||
text: I18n.tr("Window Gaps")
|
||||
description: I18n.tr("Space between windows")
|
||||
visible: SettingsData.niriLayoutGapsOverride >= 0
|
||||
value: Math.max(0, SettingsData.niriLayoutGapsOverride)
|
||||
minimum: 0
|
||||
maximum: 50
|
||||
unit: "px"
|
||||
defaultValue: Math.max(4, (SettingsData.barConfigs[0]?.spacing ?? 4))
|
||||
onSliderValueChanged: newValue => SettingsData.set("niriLayoutGapsOverride", newValue)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tab: "theme"
|
||||
tags: ["niri", "radius", "override"]
|
||||
settingKey: "niriLayoutRadiusOverrideEnabled"
|
||||
text: I18n.tr("Override Corner Radius")
|
||||
description: I18n.tr("Use custom window radius instead of theme radius")
|
||||
checked: SettingsData.niriLayoutRadiusOverride >= 0
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
SettingsData.set("niriLayoutRadiusOverride", SettingsData.cornerRadius);
|
||||
return;
|
||||
}
|
||||
SettingsData.set("niriLayoutRadiusOverride", -1);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tab: "theme"
|
||||
tags: ["niri", "radius", "override"]
|
||||
settingKey: "niriLayoutRadiusOverride"
|
||||
text: I18n.tr("Window Corner Radius")
|
||||
description: I18n.tr("Rounded corners for windows")
|
||||
visible: SettingsData.niriLayoutRadiusOverride >= 0
|
||||
value: Math.max(0, SettingsData.niriLayoutRadiusOverride)
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
unit: "px"
|
||||
defaultValue: SettingsData.cornerRadius
|
||||
onSliderValueChanged: newValue => SettingsData.set("niriLayoutRadiusOverride", newValue)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tab: "theme"
|
||||
tags: ["niri", "border", "override"]
|
||||
settingKey: "niriLayoutBorderSizeEnabled"
|
||||
text: I18n.tr("Override Border Size")
|
||||
description: I18n.tr("Use custom border/focus-ring width")
|
||||
checked: SettingsData.niriLayoutBorderSize >= 0
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
SettingsData.set("niriLayoutBorderSize", 2);
|
||||
return;
|
||||
}
|
||||
SettingsData.set("niriLayoutBorderSize", -1);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tab: "theme"
|
||||
tags: ["niri", "border", "override"]
|
||||
settingKey: "niriLayoutBorderSize"
|
||||
text: I18n.tr("Border Size")
|
||||
description: I18n.tr("Width of window border and focus ring")
|
||||
visible: SettingsData.niriLayoutBorderSize >= 0
|
||||
value: Math.max(0, SettingsData.niriLayoutBorderSize)
|
||||
minimum: 0
|
||||
maximum: 10
|
||||
unit: "px"
|
||||
defaultValue: 2
|
||||
onSliderValueChanged: newValue => SettingsData.set("niriLayoutBorderSize", newValue)
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
tab: "theme"
|
||||
tags: ["hyprland", "layout", "gaps", "radius", "window", "border", "rounding"]
|
||||
title: I18n.tr("Hyprland Layout Overrides")
|
||||
settingKey: "hyprlandLayout"
|
||||
iconName: "crop_square"
|
||||
visible: CompositorService.isHyprland
|
||||
|
||||
SettingsToggleRow {
|
||||
tab: "theme"
|
||||
tags: ["hyprland", "gaps", "override"]
|
||||
settingKey: "hyprlandLayoutGapsOverrideEnabled"
|
||||
text: I18n.tr("Override Gaps")
|
||||
description: I18n.tr("Use custom gaps instead of bar spacing")
|
||||
checked: SettingsData.hyprlandLayoutGapsOverride >= 0
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
const currentGaps = Math.max(4, (SettingsData.barConfigs[0]?.spacing ?? 4));
|
||||
SettingsData.set("hyprlandLayoutGapsOverride", currentGaps);
|
||||
return;
|
||||
}
|
||||
SettingsData.set("hyprlandLayoutGapsOverride", -1);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tab: "theme"
|
||||
tags: ["hyprland", "gaps", "override"]
|
||||
settingKey: "hyprlandLayoutGapsOverride"
|
||||
text: I18n.tr("Window Gaps")
|
||||
description: I18n.tr("Space between windows (gaps_in and gaps_out)")
|
||||
visible: SettingsData.hyprlandLayoutGapsOverride >= 0
|
||||
value: Math.max(0, SettingsData.hyprlandLayoutGapsOverride)
|
||||
minimum: 0
|
||||
maximum: 50
|
||||
unit: "px"
|
||||
defaultValue: Math.max(4, (SettingsData.barConfigs[0]?.spacing ?? 4))
|
||||
onSliderValueChanged: newValue => SettingsData.set("hyprlandLayoutGapsOverride", newValue)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tab: "theme"
|
||||
tags: ["hyprland", "radius", "override", "rounding"]
|
||||
settingKey: "hyprlandLayoutRadiusOverrideEnabled"
|
||||
text: I18n.tr("Override Corner Radius")
|
||||
description: I18n.tr("Use custom window rounding instead of theme radius")
|
||||
checked: SettingsData.hyprlandLayoutRadiusOverride >= 0
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
SettingsData.set("hyprlandLayoutRadiusOverride", SettingsData.cornerRadius);
|
||||
return;
|
||||
}
|
||||
SettingsData.set("hyprlandLayoutRadiusOverride", -1);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tab: "theme"
|
||||
tags: ["hyprland", "radius", "override", "rounding"]
|
||||
settingKey: "hyprlandLayoutRadiusOverride"
|
||||
text: I18n.tr("Window Rounding")
|
||||
description: I18n.tr("Rounded corners for windows (decoration.rounding)")
|
||||
visible: SettingsData.hyprlandLayoutRadiusOverride >= 0
|
||||
value: Math.max(0, SettingsData.hyprlandLayoutRadiusOverride)
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
unit: "px"
|
||||
defaultValue: SettingsData.cornerRadius
|
||||
onSliderValueChanged: newValue => SettingsData.set("hyprlandLayoutRadiusOverride", newValue)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tab: "theme"
|
||||
tags: ["hyprland", "border", "override"]
|
||||
settingKey: "hyprlandLayoutBorderSizeEnabled"
|
||||
text: I18n.tr("Override Border Size")
|
||||
description: I18n.tr("Use custom border size")
|
||||
checked: SettingsData.hyprlandLayoutBorderSize >= 0
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
SettingsData.set("hyprlandLayoutBorderSize", 2);
|
||||
return;
|
||||
}
|
||||
SettingsData.set("hyprlandLayoutBorderSize", -1);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tab: "theme"
|
||||
tags: ["hyprland", "border", "override"]
|
||||
settingKey: "hyprlandLayoutBorderSize"
|
||||
text: I18n.tr("Border Size")
|
||||
description: I18n.tr("Width of window border (general.border_size)")
|
||||
visible: SettingsData.hyprlandLayoutBorderSize >= 0
|
||||
value: Math.max(0, SettingsData.hyprlandLayoutBorderSize)
|
||||
minimum: 0
|
||||
maximum: 10
|
||||
unit: "px"
|
||||
defaultValue: 2
|
||||
onSliderValueChanged: newValue => SettingsData.set("hyprlandLayoutBorderSize", newValue)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tab: "theme"
|
||||
tags: ["hyprland", "resize", "border", "mouse", "drag"]
|
||||
settingKey: "hyprlandResizeOnBorder"
|
||||
text: I18n.tr("Resize on Border")
|
||||
description: I18n.tr("Resize windows by dragging their edges with the mouse")
|
||||
checked: SettingsData.hyprlandResizeOnBorder
|
||||
onToggled: checked => SettingsData.set("hyprlandResizeOnBorder", checked)
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
tab: "theme"
|
||||
tags: ["mangowc", "mango", "dwl", "layout", "gaps", "radius", "window", "border"]
|
||||
title: I18n.tr("MangoWC Layout Overrides")
|
||||
settingKey: "mangoLayout"
|
||||
iconName: "crop_square"
|
||||
visible: CompositorService.isDwl || CompositorService.isMango
|
||||
|
||||
SettingsToggleRow {
|
||||
tab: "theme"
|
||||
tags: ["mangowc", "mango", "gaps", "override"]
|
||||
settingKey: "mangoLayoutGapsOverrideEnabled"
|
||||
text: I18n.tr("Override Gaps")
|
||||
description: I18n.tr("Use custom gaps instead of bar spacing")
|
||||
checked: SettingsData.mangoLayoutGapsOverride >= 0
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
const currentGaps = Math.max(4, (SettingsData.barConfigs[0]?.spacing ?? 4));
|
||||
SettingsData.set("mangoLayoutGapsOverride", currentGaps);
|
||||
return;
|
||||
}
|
||||
SettingsData.set("mangoLayoutGapsOverride", -1);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tab: "theme"
|
||||
tags: ["mangowc", "mango", "gaps", "override"]
|
||||
settingKey: "mangoLayoutGapsOverride"
|
||||
text: I18n.tr("Window Gaps")
|
||||
description: I18n.tr("Space between windows (gappih/gappiv/gappoh/gappov)")
|
||||
visible: SettingsData.mangoLayoutGapsOverride >= 0
|
||||
value: Math.max(0, SettingsData.mangoLayoutGapsOverride)
|
||||
minimum: 0
|
||||
maximum: 50
|
||||
unit: "px"
|
||||
defaultValue: Math.max(4, (SettingsData.barConfigs[0]?.spacing ?? 4))
|
||||
onSliderValueChanged: newValue => SettingsData.set("mangoLayoutGapsOverride", newValue)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tab: "theme"
|
||||
tags: ["mangowc", "mango", "radius", "override"]
|
||||
settingKey: "mangoLayoutRadiusOverrideEnabled"
|
||||
text: I18n.tr("Override Corner Radius")
|
||||
description: I18n.tr("Use custom window radius instead of theme radius")
|
||||
checked: SettingsData.mangoLayoutRadiusOverride >= 0
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
SettingsData.set("mangoLayoutRadiusOverride", SettingsData.cornerRadius);
|
||||
return;
|
||||
}
|
||||
SettingsData.set("mangoLayoutRadiusOverride", -1);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tab: "theme"
|
||||
tags: ["mangowc", "mango", "radius", "override"]
|
||||
settingKey: "mangoLayoutRadiusOverride"
|
||||
text: I18n.tr("Window Corner Radius")
|
||||
description: I18n.tr("Rounded corners for windows (border_radius)")
|
||||
visible: SettingsData.mangoLayoutRadiusOverride >= 0
|
||||
value: Math.max(0, SettingsData.mangoLayoutRadiusOverride)
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
unit: "px"
|
||||
defaultValue: SettingsData.cornerRadius
|
||||
onSliderValueChanged: newValue => SettingsData.set("mangoLayoutRadiusOverride", newValue)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tab: "theme"
|
||||
tags: ["mangowc", "mango", "border", "override"]
|
||||
settingKey: "mangoLayoutBorderSizeEnabled"
|
||||
text: I18n.tr("Override Border Size")
|
||||
description: I18n.tr("Use custom border size")
|
||||
checked: SettingsData.mangoLayoutBorderSize >= 0
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
SettingsData.set("mangoLayoutBorderSize", 2);
|
||||
return;
|
||||
}
|
||||
SettingsData.set("mangoLayoutBorderSize", -1);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tab: "theme"
|
||||
tags: ["mangowc", "mango", "border", "override"]
|
||||
settingKey: "mangoLayoutBorderSize"
|
||||
text: I18n.tr("Border Size")
|
||||
description: I18n.tr("Width of window border (borderpx)")
|
||||
visible: SettingsData.mangoLayoutBorderSize >= 0
|
||||
value: Math.max(0, SettingsData.mangoLayoutBorderSize)
|
||||
minimum: 0
|
||||
maximum: 10
|
||||
unit: "px"
|
||||
defaultValue: 2
|
||||
onSliderValueChanged: newValue => SettingsData.set("mangoLayoutBorderSize", newValue)
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
tab: "theme"
|
||||
tags: ["modal", "darken", "background", "overlay"]
|
||||
|
||||
@@ -2,6 +2,7 @@ pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
StyledRect {
|
||||
@@ -12,6 +13,7 @@ StyledRect {
|
||||
|
||||
property string tab: ""
|
||||
property var tags: []
|
||||
property string settingKey: ""
|
||||
|
||||
property string title: ""
|
||||
property string description: ""
|
||||
@@ -29,6 +31,34 @@ StyledRect {
|
||||
radius: Theme.cornerRadius
|
||||
color: Theme.surfaceContainerHigh
|
||||
|
||||
function findParentFlickable() {
|
||||
let p = root.parent;
|
||||
while (p) {
|
||||
if (p.hasOwnProperty("contentY") && p.hasOwnProperty("contentItem"))
|
||||
return p;
|
||||
p = p.parent;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (!settingKey)
|
||||
return;
|
||||
const key = settingKey;
|
||||
Qt.callLater(() => {
|
||||
if (!root.parent)
|
||||
return;
|
||||
const flickable = findParentFlickable();
|
||||
if (flickable)
|
||||
SettingsSearchService.registerCard(key, root, flickable);
|
||||
});
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
if (settingKey)
|
||||
SettingsSearchService.unregisterCard(settingKey);
|
||||
}
|
||||
|
||||
Column {
|
||||
id: contentColumn
|
||||
anchors.left: parent.left
|
||||
|
||||
@@ -2,6 +2,7 @@ pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
StyledRect {
|
||||
@@ -12,6 +13,7 @@ StyledRect {
|
||||
|
||||
property string tab: ""
|
||||
property var tags: []
|
||||
property string settingKey: ""
|
||||
|
||||
property string title: ""
|
||||
property string description: ""
|
||||
@@ -28,6 +30,34 @@ StyledRect {
|
||||
radius: Theme.cornerRadius
|
||||
color: Theme.surfaceContainerHigh
|
||||
|
||||
function findParentFlickable() {
|
||||
let p = root.parent;
|
||||
while (p) {
|
||||
if (p.hasOwnProperty("contentY") && p.hasOwnProperty("contentItem"))
|
||||
return p;
|
||||
p = p.parent;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (!settingKey)
|
||||
return;
|
||||
const key = settingKey;
|
||||
Qt.callLater(() => {
|
||||
if (!root.parent)
|
||||
return;
|
||||
const flickable = findParentFlickable();
|
||||
if (flickable)
|
||||
SettingsSearchService.registerCard(key, root, flickable);
|
||||
});
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
if (settingKey)
|
||||
SettingsSearchService.unregisterCard(settingKey);
|
||||
}
|
||||
|
||||
Column {
|
||||
id: mainColumn
|
||||
anchors.left: parent.left
|
||||
|
||||
@@ -25,12 +25,14 @@ Item {
|
||||
}
|
||||
|
||||
property bool hasMultipleBars: SettingsData.barConfigs.length > 1
|
||||
property int pluginCatalogRevision: 0
|
||||
|
||||
DankTooltipV2 {
|
||||
id: sharedTooltip
|
||||
}
|
||||
|
||||
property var baseWidgetDefinitions: {
|
||||
pluginCatalogRevision;
|
||||
var coreWidgets = [
|
||||
{
|
||||
"id": "layout",
|
||||
@@ -274,6 +276,30 @@ Item {
|
||||
return coreWidgets;
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: PluginService
|
||||
|
||||
function onPluginDataChanged() {
|
||||
widgetsTab.pluginCatalogRevision++;
|
||||
}
|
||||
|
||||
function onPluginListUpdated() {
|
||||
widgetsTab.pluginCatalogRevision++;
|
||||
}
|
||||
|
||||
function onPluginLoaded() {
|
||||
widgetsTab.pluginCatalogRevision++;
|
||||
}
|
||||
|
||||
function onPluginStateChanged() {
|
||||
widgetsTab.pluginCatalogRevision++;
|
||||
}
|
||||
|
||||
function onPluginUnloaded() {
|
||||
widgetsTab.pluginCatalogRevision++;
|
||||
}
|
||||
}
|
||||
|
||||
property var defaultLeftWidgets: [
|
||||
{
|
||||
"id": "launcherButton",
|
||||
|
||||
@@ -17,6 +17,8 @@ Item {
|
||||
LayoutMirroring.childrenInherit: true
|
||||
|
||||
property var parentModal: null
|
||||
property bool pageActive: true
|
||||
property bool componentReady: false
|
||||
property var windowRulesIncludeStatus: ({
|
||||
"exists": false,
|
||||
"included": false,
|
||||
@@ -32,6 +34,13 @@ Item {
|
||||
property string expandedExternalId: ""
|
||||
readonly property string dmsRulesFileName: CompositorService.isNiri ? "dms/windowrules.kdl" : CompositorService.isMango ? "dms/windowrules.conf" : "dms/windowrules.lua"
|
||||
|
||||
Component.onDestruction: SettingsSearchService.unregisterCard("windowRules")
|
||||
|
||||
onPageActiveChanged: {
|
||||
if (componentReady && pageActive)
|
||||
loadWindowRules();
|
||||
}
|
||||
|
||||
readonly property var matchLabels: ({
|
||||
"appId": I18n.tr("App ID"),
|
||||
"title": I18n.tr("Title"),
|
||||
@@ -182,12 +191,15 @@ Item {
|
||||
function loadWindowRules() {
|
||||
const compositor = CompositorService.compositor;
|
||||
if (compositor !== "niri" && compositor !== "hyprland" && compositor !== "mango") {
|
||||
checkingInclude = false;
|
||||
windowRules = [];
|
||||
externalRules = [];
|
||||
return;
|
||||
}
|
||||
|
||||
checkingInclude = true;
|
||||
Proc.runCommand("load-windowrules", ["dms", "config", "windowrules", "list", compositor], (output, exitCode) => {
|
||||
checkingInclude = false;
|
||||
if (exitCode !== 0) {
|
||||
windowRules = [];
|
||||
externalRules = [];
|
||||
@@ -258,44 +270,6 @@ Item {
|
||||
});
|
||||
}
|
||||
|
||||
function checkWindowRulesIncludeStatus() {
|
||||
const compositor = CompositorService.compositor;
|
||||
if (compositor !== "niri" && compositor !== "hyprland" && compositor !== "mango") {
|
||||
windowRulesIncludeStatus = {
|
||||
"exists": false,
|
||||
"included": false,
|
||||
"configFormat": "",
|
||||
"readOnly": false
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
const filename = (compositor === "niri") ? "windowrules.kdl" : (compositor === "mango") ? "windowrules.conf" : "windowrules.lua";
|
||||
checkingInclude = true;
|
||||
Proc.runCommand("check-windowrules-include", ["dms", "config", "resolve-include", compositor, filename], (output, exitCode) => {
|
||||
checkingInclude = false;
|
||||
if (exitCode !== 0) {
|
||||
windowRulesIncludeStatus = {
|
||||
"exists": false,
|
||||
"included": false,
|
||||
"configFormat": "",
|
||||
"readOnly": false
|
||||
};
|
||||
return;
|
||||
}
|
||||
try {
|
||||
windowRulesIncludeStatus = JSON.parse(output.trim());
|
||||
} catch (e) {
|
||||
windowRulesIncludeStatus = {
|
||||
"exists": false,
|
||||
"included": false,
|
||||
"configFormat": "",
|
||||
"readOnly": false
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function fixWindowRulesInclude() {
|
||||
if (readOnly) {
|
||||
showHyprlandReadOnlyWarning();
|
||||
@@ -320,7 +294,6 @@ Item {
|
||||
return;
|
||||
if (CompositorService.isMango)
|
||||
MangoService.reloadConfig();
|
||||
checkWindowRulesIncludeStatus();
|
||||
loadWindowRules();
|
||||
});
|
||||
}
|
||||
@@ -372,10 +345,12 @@ Item {
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango) {
|
||||
checkWindowRulesIncludeStatus();
|
||||
loadWindowRules();
|
||||
}
|
||||
componentReady = true;
|
||||
Qt.callLater(() => {
|
||||
SettingsSearchService.registerCard("windowRules", headerSection, flickable);
|
||||
if (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango)
|
||||
loadWindowRules();
|
||||
});
|
||||
}
|
||||
|
||||
DankFlickable {
|
||||
|
||||
@@ -0,0 +1,230 @@
|
||||
import QtQuick
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
import qs.Modules.Settings.Widgets
|
||||
|
||||
SettingsCard {
|
||||
iconName: "palette"
|
||||
title: I18n.tr("Workspace Appearance")
|
||||
settingKey: "workspaceAppearance"
|
||||
collapsible: true
|
||||
expanded: false
|
||||
|
||||
SettingsButtonGroupRow {
|
||||
text: I18n.tr("Focused Color")
|
||||
model: ["pri", "s", "sc", "sch", "none"]
|
||||
buttonHeight: 22
|
||||
minButtonWidth: 36
|
||||
buttonPadding: Theme.spacingS
|
||||
checkIconSize: Theme.iconSizeSmall - 2
|
||||
textSize: Theme.fontSizeSmall - 1
|
||||
spacing: 1
|
||||
currentIndex: {
|
||||
switch (SettingsData.workspaceColorMode) {
|
||||
case "s":
|
||||
return 1;
|
||||
case "sc":
|
||||
return 2;
|
||||
case "sch":
|
||||
return 3;
|
||||
case "none":
|
||||
return 4;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
onSelectionChanged: (index, selected) => {
|
||||
if (!selected)
|
||||
return;
|
||||
const modes = ["default", "s", "sc", "sch", "none"];
|
||||
SettingsData.set("workspaceColorMode", modes[index]);
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 1
|
||||
color: Theme.outline
|
||||
opacity: 0.15
|
||||
}
|
||||
|
||||
SettingsButtonGroupRow {
|
||||
text: I18n.tr("Occupied Color")
|
||||
model: ["none", "sec", "s", "sc", "sch", "schh"]
|
||||
visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isMango
|
||||
buttonHeight: 22
|
||||
minButtonWidth: 36
|
||||
buttonPadding: Theme.spacingS
|
||||
checkIconSize: Theme.iconSizeSmall - 2
|
||||
textSize: Theme.fontSizeSmall - 1
|
||||
spacing: 1
|
||||
currentIndex: {
|
||||
switch (SettingsData.workspaceOccupiedColorMode) {
|
||||
case "sec":
|
||||
return 1;
|
||||
case "s":
|
||||
return 2;
|
||||
case "sc":
|
||||
return 3;
|
||||
case "sch":
|
||||
return 4;
|
||||
case "schh":
|
||||
return 5;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
onSelectionChanged: (index, selected) => {
|
||||
if (!selected)
|
||||
return;
|
||||
const modes = ["none", "sec", "s", "sc", "sch", "schh"];
|
||||
SettingsData.set("workspaceOccupiedColorMode", modes[index]);
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 1
|
||||
color: Theme.outline
|
||||
opacity: 0.15
|
||||
visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isMango
|
||||
}
|
||||
|
||||
SettingsButtonGroupRow {
|
||||
text: I18n.tr("Unfocused Color")
|
||||
model: ["def", "s", "sc", "sch"]
|
||||
buttonHeight: 22
|
||||
minButtonWidth: 36
|
||||
buttonPadding: Theme.spacingS
|
||||
checkIconSize: Theme.iconSizeSmall - 2
|
||||
textSize: Theme.fontSizeSmall - 1
|
||||
spacing: 1
|
||||
currentIndex: {
|
||||
switch (SettingsData.workspaceUnfocusedColorMode) {
|
||||
case "s":
|
||||
return 1;
|
||||
case "sc":
|
||||
return 2;
|
||||
case "sch":
|
||||
return 3;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
onSelectionChanged: (index, selected) => {
|
||||
if (!selected)
|
||||
return;
|
||||
const modes = ["default", "s", "sc", "sch"];
|
||||
SettingsData.set("workspaceUnfocusedColorMode", modes[index]);
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 1
|
||||
color: Theme.outline
|
||||
opacity: 0.15
|
||||
visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isMango || CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle
|
||||
}
|
||||
|
||||
SettingsButtonGroupRow {
|
||||
text: I18n.tr("Urgent Color")
|
||||
visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isMango || CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle
|
||||
model: ["err", "pri", "sec", "s", "sc"]
|
||||
buttonHeight: 22
|
||||
minButtonWidth: 36
|
||||
buttonPadding: Theme.spacingS
|
||||
checkIconSize: Theme.iconSizeSmall - 2
|
||||
textSize: Theme.fontSizeSmall - 1
|
||||
spacing: 1
|
||||
currentIndex: {
|
||||
switch (SettingsData.workspaceUrgentColorMode) {
|
||||
case "primary":
|
||||
return 1;
|
||||
case "secondary":
|
||||
return 2;
|
||||
case "s":
|
||||
return 3;
|
||||
case "sc":
|
||||
return 4;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
onSelectionChanged: (index, selected) => {
|
||||
if (!selected)
|
||||
return;
|
||||
const modes = ["default", "primary", "secondary", "s", "sc"];
|
||||
SettingsData.set("workspaceUrgentColorMode", modes[index]);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingS
|
||||
visible: SettingsData.workspaceFocusedBorderEnabled
|
||||
leftPadding: Theme.spacingM
|
||||
|
||||
SettingsButtonGroupRow {
|
||||
width: parent.width - parent.leftPadding
|
||||
text: I18n.tr("Border Color")
|
||||
model: [I18n.tr("Surface"), I18n.tr("Secondary"), I18n.tr("Primary")]
|
||||
currentIndex: {
|
||||
switch (SettingsData.workspaceFocusedBorderColor) {
|
||||
case "surfaceText":
|
||||
return 0;
|
||||
case "secondary":
|
||||
return 1;
|
||||
case "primary":
|
||||
return 2;
|
||||
default:
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
onSelectionChanged: (index, selected) => {
|
||||
if (!selected)
|
||||
return;
|
||||
let newColor = "primary";
|
||||
switch (index) {
|
||||
case 0:
|
||||
newColor = "surfaceText";
|
||||
break;
|
||||
case 1:
|
||||
newColor = "secondary";
|
||||
break;
|
||||
case 2:
|
||||
newColor = "primary";
|
||||
break;
|
||||
}
|
||||
SettingsData.set("workspaceFocusedBorderColor", newColor);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,9 @@ Item {
|
||||
|
||||
Column {
|
||||
id: mainColumn
|
||||
topPadding: 4
|
||||
|
||||
topPadding: Theme.spacingXL
|
||||
bottomPadding: Theme.spacingXL
|
||||
width: Math.min(550, parent.width - Theme.spacingL * 2)
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
spacing: Theme.spacingXL
|
||||
@@ -196,231 +198,6 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
width: parent.width
|
||||
iconName: "palette"
|
||||
title: I18n.tr("Workspace Appearance")
|
||||
settingKey: "workspaceAppearance"
|
||||
|
||||
SettingsButtonGroupRow {
|
||||
text: I18n.tr("Focused Color")
|
||||
model: ["pri", "s", "sc", "sch", "none"]
|
||||
buttonHeight: 22
|
||||
minButtonWidth: 36
|
||||
buttonPadding: Theme.spacingS
|
||||
checkIconSize: Theme.iconSizeSmall - 2
|
||||
textSize: Theme.fontSizeSmall - 1
|
||||
spacing: 1
|
||||
currentIndex: {
|
||||
switch (SettingsData.workspaceColorMode) {
|
||||
case "s":
|
||||
return 1;
|
||||
case "sc":
|
||||
return 2;
|
||||
case "sch":
|
||||
return 3;
|
||||
case "none":
|
||||
return 4;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
onSelectionChanged: (index, selected) => {
|
||||
if (!selected)
|
||||
return;
|
||||
const modes = ["default", "s", "sc", "sch", "none"];
|
||||
SettingsData.set("workspaceColorMode", modes[index]);
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 1
|
||||
color: Theme.outline
|
||||
opacity: 0.15
|
||||
}
|
||||
|
||||
SettingsButtonGroupRow {
|
||||
text: I18n.tr("Occupied Color")
|
||||
model: ["none", "sec", "s", "sc", "sch", "schh"]
|
||||
visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isMango
|
||||
buttonHeight: 22
|
||||
minButtonWidth: 36
|
||||
buttonPadding: Theme.spacingS
|
||||
checkIconSize: Theme.iconSizeSmall - 2
|
||||
textSize: Theme.fontSizeSmall - 1
|
||||
spacing: 1
|
||||
currentIndex: {
|
||||
switch (SettingsData.workspaceOccupiedColorMode) {
|
||||
case "sec":
|
||||
return 1;
|
||||
case "s":
|
||||
return 2;
|
||||
case "sc":
|
||||
return 3;
|
||||
case "sch":
|
||||
return 4;
|
||||
case "schh":
|
||||
return 5;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
onSelectionChanged: (index, selected) => {
|
||||
if (!selected)
|
||||
return;
|
||||
const modes = ["none", "sec", "s", "sc", "sch", "schh"];
|
||||
SettingsData.set("workspaceOccupiedColorMode", modes[index]);
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 1
|
||||
color: Theme.outline
|
||||
opacity: 0.15
|
||||
visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isMango
|
||||
}
|
||||
|
||||
SettingsButtonGroupRow {
|
||||
text: I18n.tr("Unfocused Color")
|
||||
model: ["def", "s", "sc", "sch"]
|
||||
buttonHeight: 22
|
||||
minButtonWidth: 36
|
||||
buttonPadding: Theme.spacingS
|
||||
checkIconSize: Theme.iconSizeSmall - 2
|
||||
textSize: Theme.fontSizeSmall - 1
|
||||
spacing: 1
|
||||
currentIndex: {
|
||||
switch (SettingsData.workspaceUnfocusedColorMode) {
|
||||
case "s":
|
||||
return 1;
|
||||
case "sc":
|
||||
return 2;
|
||||
case "sch":
|
||||
return 3;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
onSelectionChanged: (index, selected) => {
|
||||
if (!selected)
|
||||
return;
|
||||
const modes = ["default", "s", "sc", "sch"];
|
||||
SettingsData.set("workspaceUnfocusedColorMode", modes[index]);
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 1
|
||||
color: Theme.outline
|
||||
opacity: 0.15
|
||||
visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isMango || CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle
|
||||
}
|
||||
|
||||
SettingsButtonGroupRow {
|
||||
text: I18n.tr("Urgent Color")
|
||||
visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isMango || CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle
|
||||
model: ["err", "pri", "sec", "s", "sc"]
|
||||
buttonHeight: 22
|
||||
minButtonWidth: 36
|
||||
buttonPadding: Theme.spacingS
|
||||
checkIconSize: Theme.iconSizeSmall - 2
|
||||
textSize: Theme.fontSizeSmall - 1
|
||||
spacing: 1
|
||||
currentIndex: {
|
||||
switch (SettingsData.workspaceUrgentColorMode) {
|
||||
case "primary":
|
||||
return 1;
|
||||
case "secondary":
|
||||
return 2;
|
||||
case "s":
|
||||
return 3;
|
||||
case "sc":
|
||||
return 4;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
onSelectionChanged: (index, selected) => {
|
||||
if (!selected)
|
||||
return;
|
||||
const modes = ["default", "primary", "secondary", "s", "sc"];
|
||||
SettingsData.set("workspaceUrgentColorMode", modes[index]);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingS
|
||||
visible: SettingsData.workspaceFocusedBorderEnabled
|
||||
leftPadding: Theme.spacingM
|
||||
|
||||
SettingsButtonGroupRow {
|
||||
width: parent.width - parent.leftPadding
|
||||
text: I18n.tr("Border Color")
|
||||
model: [I18n.tr("Surface"), I18n.tr("Secondary"), I18n.tr("Primary")]
|
||||
currentIndex: {
|
||||
switch (SettingsData.workspaceFocusedBorderColor) {
|
||||
case "surfaceText":
|
||||
return 0;
|
||||
case "secondary":
|
||||
return 1;
|
||||
case "primary":
|
||||
return 2;
|
||||
default:
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
onSelectionChanged: (index, selected) => {
|
||||
if (!selected)
|
||||
return;
|
||||
let newColor = "primary";
|
||||
switch (index) {
|
||||
case 0:
|
||||
newColor = "surfaceText";
|
||||
break;
|
||||
case 1:
|
||||
newColor = "secondary";
|
||||
break;
|
||||
case 2:
|
||||
newColor = "primary";
|
||||
break;
|
||||
}
|
||||
SettingsData.set("workspaceFocusedBorderColor", newColor);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
width: parent.width
|
||||
iconName: "label"
|
||||
|
||||
Reference in New Issue
Block a user