mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-06-13 14:36:32 -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:
@@ -11,6 +11,10 @@ Singleton {
|
|||||||
readonly property int durMed: 450
|
readonly property int durMed: 450
|
||||||
readonly property int durLong: 600
|
readonly property int durLong: 600
|
||||||
|
|
||||||
|
// Navigation feedback stays responsive even when ambient shell motion is slow.
|
||||||
|
readonly property int settingsNavigationStateDuration: 180
|
||||||
|
readonly property int settingsNavigationRippleDuration: 200
|
||||||
|
|
||||||
readonly property int slidePx: 80
|
readonly property int slidePx: 80
|
||||||
|
|
||||||
readonly property var emphasized: [0.05, 0.00, 0.133333, 0.06, 0.166667, 0.40, 0.208333, 0.82, 0.25, 1.00, 1.00, 1.00]
|
readonly property var emphasized: [0.05, 0.00, 0.133333, 0.06, 0.166667, 0.40, 0.208333, 0.82, 0.25, 1.00, 1.00, 1.00]
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
pragma Singleton
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import qs.Common
|
||||||
|
|
||||||
|
Singleton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property string selectedBarId: "default"
|
||||||
|
|
||||||
|
function normalizeSelectedBar() {
|
||||||
|
if (SettingsData.getBarConfig(selectedBarId))
|
||||||
|
return;
|
||||||
|
selectedBarId = SettingsData.barConfigs[0]?.id ?? "default";
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: SettingsData
|
||||||
|
|
||||||
|
function onBarConfigsChanged() {
|
||||||
|
root.normalizeSelectedBar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -947,7 +947,7 @@ Item {
|
|||||||
|
|
||||||
function tabs(): string {
|
function tabs(): string {
|
||||||
if (!PopoutService.settingsModal)
|
if (!PopoutService.settingsModal)
|
||||||
return "wallpaper\ntheme\ntypography\ntime_weather\nsounds\ndankbar\ndankbar_settings\ndankbar_widgets\nworkspaces\nmedia_player\nnotifications\nosd\nrunning_apps\nupdater\ndock\nlauncher\nkeybinds\ndisplays\nnetwork\nprinters\nlock_screen\npower_sleep\nplugins\nabout";
|
return "wallpaper\ntheme\ntypography\ntime_weather\nsounds\ndankbar\ndankbar_settings\ndankbar_appearance\ndankbar_widgets\nframe\nworkspaces\ncompositor\nmedia_player\nnotifications\nosd\nrunning_apps\nupdater\ndock\nlauncher\nkeybinds\ndisplays\nnetwork\nprinters\nlock_screen\npower_sleep\nplugins\nabout";
|
||||||
var modal = PopoutService.settingsModal;
|
var modal = PopoutService.settingsModal;
|
||||||
var ids = [];
|
var ids = [];
|
||||||
var structure = modal.sidebar?.categoryStructure ?? [];
|
var structure = modal.sidebar?.categoryStructure ?? [];
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import qs.Common
|
import qs.Common
|
||||||
import qs.Modules.Settings
|
import qs.Modules.Settings
|
||||||
|
import qs.Widgets
|
||||||
|
|
||||||
FocusScope {
|
FocusScope {
|
||||||
id: root
|
id: root
|
||||||
@@ -97,7 +98,24 @@ FocusScope {
|
|||||||
visible: active
|
visible: active
|
||||||
focus: active
|
focus: active
|
||||||
|
|
||||||
sourceComponent: WorkspacesTab {}
|
sourceComponent: CompositorTab {}
|
||||||
|
|
||||||
|
onActiveChanged: {
|
||||||
|
if (active && item)
|
||||||
|
Qt.callLater(() => item.forceActiveFocus());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: dankBarAppearanceLoader
|
||||||
|
anchors.fill: parent
|
||||||
|
active: root.currentIndex === 6
|
||||||
|
visible: active
|
||||||
|
focus: active
|
||||||
|
|
||||||
|
sourceComponent: DankBarAppearanceTab {
|
||||||
|
parentModal: root.parentModal
|
||||||
|
}
|
||||||
|
|
||||||
onActiveChanged: {
|
onActiveChanged: {
|
||||||
if (active && item)
|
if (active && item)
|
||||||
@@ -432,19 +450,36 @@ FocusScope {
|
|||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: widgetsLoader
|
id: widgetsLoader
|
||||||
|
|
||||||
|
property bool loadedOnce: false
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
active: root.currentIndex === 22
|
active: root.currentIndex === 22 || loadedOnce
|
||||||
visible: active
|
visible: root.currentIndex === 22 && status === Loader.Ready
|
||||||
focus: active
|
focus: visible
|
||||||
|
asynchronous: true
|
||||||
|
|
||||||
sourceComponent: WidgetsTab {
|
sourceComponent: WidgetsTab {
|
||||||
parentModal: root.parentModal
|
parentModal: root.parentModal
|
||||||
}
|
}
|
||||||
|
|
||||||
onActiveChanged: {
|
onLoaded: {
|
||||||
if (active && item)
|
loadedOnce = true;
|
||||||
|
if (visible && item)
|
||||||
Qt.callLater(() => item.forceActiveFocus());
|
Qt.callLater(() => item.forceActiveFocus());
|
||||||
}
|
}
|
||||||
|
onVisibleChanged: {
|
||||||
|
if (visible && item)
|
||||||
|
Qt.callLater(() => item.forceActiveFocus());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
visible: root.currentIndex === 22 && widgetsLoader.status === Loader.Loading
|
||||||
|
text: I18n.tr("Loading...", "loading indicator")
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
@@ -479,23 +514,6 @@ FocusScope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: windowRulesLoader
|
|
||||||
anchors.fill: parent
|
|
||||||
active: root.currentIndex === 28
|
|
||||||
visible: active
|
|
||||||
focus: active
|
|
||||||
|
|
||||||
sourceComponent: WindowRulesTab {
|
|
||||||
parentModal: root.parentModal
|
|
||||||
}
|
|
||||||
|
|
||||||
onActiveChanged: {
|
|
||||||
if (active && item)
|
|
||||||
Qt.callLater(() => item.forceActiveFocus());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: audioLoader
|
id: audioLoader
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ Rectangle {
|
|||||||
property bool searchActive: searchField.text.length > 0
|
property bool searchActive: searchField.text.length > 0
|
||||||
property int searchSelectedIndex: 0
|
property int searchSelectedIndex: 0
|
||||||
property int keyboardHighlightIndex: -1
|
property int keyboardHighlightIndex: -1
|
||||||
|
readonly property int navigationStateDuration: Theme.currentAnimationSpeed === SettingsData.AnimationSpeed.None ? 0 : Anims.settingsNavigationStateDuration
|
||||||
|
|
||||||
function focusSearch() {
|
function focusSearch() {
|
||||||
searchField.forceActiveFocus();
|
searchField.forceActiveFocus();
|
||||||
@@ -115,6 +116,12 @@ Rectangle {
|
|||||||
"icon": "tune",
|
"icon": "tune",
|
||||||
"tabIndex": 3
|
"tabIndex": 3
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "dankbar_appearance",
|
||||||
|
"text": I18n.tr("Appearance"),
|
||||||
|
"icon": "palette",
|
||||||
|
"tabIndex": 6
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "dankbar_widgets",
|
"id": "dankbar_widgets",
|
||||||
"text": I18n.tr("Widgets"),
|
"text": I18n.tr("Widgets"),
|
||||||
@@ -131,16 +138,10 @@ Rectangle {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "workspaces_widgets",
|
"id": "workspaces_widgets",
|
||||||
"text": I18n.tr("Workspaces & Widgets"),
|
"text": I18n.tr("Widgets & Notifications"),
|
||||||
"icon": "dashboard",
|
"icon": "dashboard",
|
||||||
"collapsedByDefault": true,
|
"collapsedByDefault": true,
|
||||||
"children": [
|
"children": [
|
||||||
{
|
|
||||||
"id": "workspaces",
|
|
||||||
"text": I18n.tr("Workspaces"),
|
|
||||||
"icon": "view_module",
|
|
||||||
"tabIndex": 4
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "media_player",
|
"id": "media_player",
|
||||||
"text": I18n.tr("Media Player"),
|
"text": I18n.tr("Media Player"),
|
||||||
@@ -187,6 +188,12 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "compositor",
|
||||||
|
"text": I18n.tr("Compositor"),
|
||||||
|
"icon": "layers",
|
||||||
|
"tabIndex": 4
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "keybinds",
|
"id": "keybinds",
|
||||||
"text": I18n.tr("Keyboard Shortcuts"),
|
"text": I18n.tr("Keyboard Shortcuts"),
|
||||||
@@ -305,13 +312,6 @@ Rectangle {
|
|||||||
"text": I18n.tr("Users"),
|
"text": I18n.tr("Users"),
|
||||||
"icon": "manage_accounts",
|
"icon": "manage_accounts",
|
||||||
"tabIndex": 35
|
"tabIndex": 35
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "window_rules",
|
|
||||||
"text": I18n.tr("Window Rules"),
|
|
||||||
"icon": "select_window",
|
|
||||||
"tabIndex": 28,
|
|
||||||
"windowRulesCapable": true
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -544,6 +544,8 @@ Rectangle {
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
var normalized = name.toLowerCase().replace(/[_\-\s]/g, "");
|
var normalized = name.toLowerCase().replace(/[_\-\s]/g, "");
|
||||||
|
if (normalized === "workspaces")
|
||||||
|
normalized = "compositor";
|
||||||
|
|
||||||
for (var i = 0; i < categoryStructure.length; i++) {
|
for (var i = 0; i < categoryStructure.length; i++) {
|
||||||
var cat = categoryStructure[i];
|
var cat = categoryStructure[i];
|
||||||
@@ -588,7 +590,7 @@ Rectangle {
|
|||||||
id: __m1
|
id: __m1
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
text: I18n.tr("Workspaces & Widgets")
|
text: I18n.tr("Widgets & Notifications")
|
||||||
}
|
}
|
||||||
StyledTextMetrics {
|
StyledTextMetrics {
|
||||||
id: __m2
|
id: __m2
|
||||||
@@ -782,6 +784,7 @@ Rectangle {
|
|||||||
id: resultRipple
|
id: resultRipple
|
||||||
rippleColor: root.searchSelectedIndex === resultDelegate.index ? Theme.buttonText : Theme.surfaceText
|
rippleColor: root.searchSelectedIndex === resultDelegate.index ? Theme.buttonText : Theme.surfaceText
|
||||||
cornerRadius: resultDelegate.radius
|
cornerRadius: resultDelegate.radius
|
||||||
|
animationDuration: Anims.settingsNavigationRippleDuration
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
@@ -837,8 +840,9 @@ Rectangle {
|
|||||||
|
|
||||||
Behavior on color {
|
Behavior on color {
|
||||||
ColorAnimation {
|
ColorAnimation {
|
||||||
duration: Theme.shortDuration
|
duration: root.navigationStateDuration
|
||||||
easing.type: Theme.standardEasing
|
easing.type: Easing.BezierSpline
|
||||||
|
easing.bezierCurve: Anims.expressiveEffects
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -912,6 +916,7 @@ Rectangle {
|
|||||||
id: categoryRipple
|
id: categoryRipple
|
||||||
rippleColor: categoryRow.isActive ? Theme.buttonText : Theme.surfaceText
|
rippleColor: categoryRow.isActive ? Theme.buttonText : Theme.surfaceText
|
||||||
cornerRadius: categoryRow.radius
|
cornerRadius: categoryRow.radius
|
||||||
|
animationDuration: Anims.settingsNavigationRippleDuration
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
@@ -967,8 +972,9 @@ Rectangle {
|
|||||||
|
|
||||||
Behavior on color {
|
Behavior on color {
|
||||||
ColorAnimation {
|
ColorAnimation {
|
||||||
duration: Theme.shortDuration
|
duration: root.navigationStateDuration
|
||||||
easing.type: Theme.standardEasing
|
easing.type: Easing.BezierSpline
|
||||||
|
easing.bezierCurve: Anims.expressiveEffects
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1009,6 +1015,7 @@ Rectangle {
|
|||||||
id: childRipple
|
id: childRipple
|
||||||
rippleColor: childDelegate.isActive ? Theme.buttonText : Theme.surfaceText
|
rippleColor: childDelegate.isActive ? Theme.buttonText : Theme.surfaceText
|
||||||
cornerRadius: childDelegate.radius
|
cornerRadius: childDelegate.radius
|
||||||
|
animationDuration: Anims.settingsNavigationRippleDuration
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
@@ -1049,8 +1056,9 @@ Rectangle {
|
|||||||
|
|
||||||
Behavior on color {
|
Behavior on color {
|
||||||
ColorAnimation {
|
ColorAnimation {
|
||||||
duration: Theme.shortDuration
|
duration: root.navigationStateDuration
|
||||||
easing.type: Theme.standardEasing
|
easing.type: Easing.BezierSpline
|
||||||
|
easing.bezierCurve: Anims.expressiveEffects
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
LayoutMirroring.childrenInherit: true
|
||||||
|
|
||||||
property var parentModal: null
|
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: {
|
property var selectedBarConfig: {
|
||||||
selectedBarId;
|
selectedBarId;
|
||||||
@@ -21,6 +36,14 @@ Item {
|
|||||||
const index = SettingsData.barConfigs.findIndex(cfg => cfg.id === selectedBarId);
|
const index = SettingsData.barConfigs.findIndex(cfg => cfg.id === selectedBarId);
|
||||||
return index !== -1 ? SettingsData.barConfigs[index] : SettingsData.barConfigs[0];
|
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: {
|
property bool selectedBarIsVertical: {
|
||||||
selectedBarId;
|
selectedBarId;
|
||||||
@@ -210,10 +233,33 @@ Item {
|
|||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
spacing: Theme.spacingXL
|
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 {
|
SettingsCard {
|
||||||
iconName: "dashboard"
|
iconName: "dashboard"
|
||||||
title: I18n.tr("Bar Configurations")
|
title: I18n.tr("Bar Configurations")
|
||||||
settingKey: "barConfigurations"
|
settingKey: "barConfigurations"
|
||||||
|
visible: !dankBarTab.appearanceOnly
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@@ -410,7 +456,7 @@ Item {
|
|||||||
SettingsCard {
|
SettingsCard {
|
||||||
iconName: selectedBarConfig?.enabled ? "visibility" : "visibility_off"
|
iconName: selectedBarConfig?.enabled ? "visibility" : "visibility_off"
|
||||||
title: I18n.tr("Enable Bar")
|
title: I18n.tr("Enable Bar")
|
||||||
visible: selectedBarId !== "default"
|
visible: !dankBarTab.appearanceOnly && selectedBarId !== "default"
|
||||||
|
|
||||||
SettingsToggleRow {
|
SettingsToggleRow {
|
||||||
text: I18n.tr("Toggle visibility of this bar configuration")
|
text: I18n.tr("Toggle visibility of this bar configuration")
|
||||||
@@ -426,7 +472,7 @@ Item {
|
|||||||
iconName: "vertical_align_center"
|
iconName: "vertical_align_center"
|
||||||
title: I18n.tr("Position")
|
title: I18n.tr("Position")
|
||||||
settingKey: "barPosition"
|
settingKey: "barPosition"
|
||||||
visible: selectedBarConfig?.enabled
|
visible: !dankBarTab.appearanceOnly && selectedBarConfig?.enabled
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@@ -486,7 +532,7 @@ Item {
|
|||||||
settingKey: "barDisplay"
|
settingKey: "barDisplay"
|
||||||
collapsible: true
|
collapsible: true
|
||||||
expanded: false
|
expanded: false
|
||||||
visible: selectedBarConfig?.enabled
|
visible: !dankBarTab.appearanceOnly && selectedBarConfig?.enabled
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@@ -588,12 +634,12 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SettingsCard {
|
SettingsCard {
|
||||||
iconName: "visibility_off"
|
iconName: "visibility"
|
||||||
title: I18n.tr("Visibility")
|
title: I18n.tr("Visibility")
|
||||||
settingKey: "barVisibility"
|
settingKey: "barVisibility"
|
||||||
collapsible: true
|
collapsible: true
|
||||||
expanded: false
|
expanded: true
|
||||||
visible: selectedBarConfig?.enabled
|
visible: !dankBarTab.appearanceOnly && selectedBarConfig?.enabled
|
||||||
|
|
||||||
SettingsToggleRow {
|
SettingsToggleRow {
|
||||||
text: I18n.tr("Auto-hide")
|
text: I18n.tr("Auto-hide")
|
||||||
@@ -751,7 +797,7 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SettingsControlledByFrame {
|
SettingsControlledByFrame {
|
||||||
visible: SettingsData.frameEnabled
|
visible: !dankBarTab.appearanceOnly && SettingsData.frameEnabled
|
||||||
parentModal: dankBarTab.parentModal
|
parentModal: dankBarTab.parentModal
|
||||||
settingLabel: I18n.tr("Bar spacing and size")
|
settingLabel: I18n.tr("Bar spacing and size")
|
||||||
reason: I18n.tr("Managed by Frame")
|
reason: I18n.tr("Managed by Frame")
|
||||||
@@ -761,7 +807,7 @@ Item {
|
|||||||
iconName: "space_bar"
|
iconName: "space_bar"
|
||||||
title: I18n.tr("Spacing")
|
title: I18n.tr("Spacing")
|
||||||
settingKey: "barSpacing"
|
settingKey: "barSpacing"
|
||||||
visible: (selectedBarConfig?.enabled ?? false) && !SettingsData.frameEnabled
|
visible: !dankBarTab.appearanceOnly && (selectedBarConfig?.enabled ?? false) && !SettingsData.frameEnabled
|
||||||
|
|
||||||
SettingsSliderRow {
|
SettingsSliderRow {
|
||||||
id: edgeSpacingSlider
|
id: edgeSpacingSlider
|
||||||
@@ -911,10 +957,11 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SettingsCard {
|
SettingsCard {
|
||||||
|
tab: "appearance"
|
||||||
iconName: "opacity"
|
iconName: "opacity"
|
||||||
title: I18n.tr("Transparency")
|
title: I18n.tr("Transparency")
|
||||||
settingKey: "barTransparency"
|
settingKey: "barTransparency"
|
||||||
visible: selectedBarConfig?.enabled
|
visible: dankBarTab.appearanceOnly && selectedBarConfig?.enabled
|
||||||
|
|
||||||
SettingsSliderRow {
|
SettingsSliderRow {
|
||||||
id: barTransparencySlider
|
id: barTransparencySlider
|
||||||
@@ -973,10 +1020,12 @@ Item {
|
|||||||
|
|
||||||
SettingsSliderCard {
|
SettingsSliderCard {
|
||||||
id: fontScaleSliderCard
|
id: fontScaleSliderCard
|
||||||
|
tab: "appearance"
|
||||||
|
settingKey: "barFontScale"
|
||||||
iconName: "text_fields"
|
iconName: "text_fields"
|
||||||
title: I18n.tr("Font Scale")
|
title: I18n.tr("Font Scale")
|
||||||
description: I18n.tr("Scale DankBar font sizes independently")
|
description: I18n.tr("Scale DankBar font sizes independently")
|
||||||
visible: selectedBarConfig?.enabled
|
visible: dankBarTab.appearanceOnly && selectedBarConfig?.enabled
|
||||||
minimum: 50
|
minimum: 50
|
||||||
maximum: 200
|
maximum: 200
|
||||||
value: Math.round((selectedBarConfig?.fontScale ?? 1.0) * 100)
|
value: Math.round((selectedBarConfig?.fontScale ?? 1.0) * 100)
|
||||||
@@ -998,10 +1047,12 @@ Item {
|
|||||||
|
|
||||||
SettingsSliderCard {
|
SettingsSliderCard {
|
||||||
id: iconScaleSliderCard
|
id: iconScaleSliderCard
|
||||||
|
tab: "appearance"
|
||||||
|
settingKey: "barIconScale"
|
||||||
iconName: "interests"
|
iconName: "interests"
|
||||||
title: I18n.tr("Icon Scale")
|
title: I18n.tr("Icon Scale")
|
||||||
description: I18n.tr("Scale DankBar icon sizes independently")
|
description: I18n.tr("Scale DankBar icon sizes independently")
|
||||||
visible: selectedBarConfig?.enabled
|
visible: dankBarTab.appearanceOnly && selectedBarConfig?.enabled
|
||||||
minimum: 50
|
minimum: 50
|
||||||
maximum: 200
|
maximum: 200
|
||||||
value: Math.round((selectedBarConfig?.iconScale ?? 1.0) * 100)
|
value: Math.round((selectedBarConfig?.iconScale ?? 1.0) * 100)
|
||||||
@@ -1021,13 +1072,18 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WorkspaceAppearanceCard {
|
||||||
|
visible: dankBarTab.appearanceOnly
|
||||||
|
}
|
||||||
|
|
||||||
SettingsCard {
|
SettingsCard {
|
||||||
|
tab: "appearance"
|
||||||
iconName: "rounded_corner"
|
iconName: "rounded_corner"
|
||||||
title: I18n.tr("Corners & Background")
|
title: I18n.tr("Corners & Background")
|
||||||
settingKey: "barCorners"
|
settingKey: "barCorners"
|
||||||
collapsible: true
|
collapsible: true
|
||||||
expanded: false
|
expanded: true
|
||||||
visible: selectedBarConfig?.enabled
|
visible: dankBarTab.appearanceOnly && selectedBarConfig?.enabled
|
||||||
|
|
||||||
SettingsControlledByFrame {
|
SettingsControlledByFrame {
|
||||||
visible: SettingsData.frameEnabled
|
visible: SettingsData.frameEnabled
|
||||||
@@ -1144,7 +1200,7 @@ Item {
|
|||||||
iconName: "fit_screen"
|
iconName: "fit_screen"
|
||||||
title: I18n.tr("Maximize Detection")
|
title: I18n.tr("Maximize Detection")
|
||||||
description: I18n.tr("Remove gaps and border when windows are maximized")
|
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
|
checked: selectedBarConfig?.maximizeDetection ?? true
|
||||||
onToggled: checked => SettingsData.updateBarConfig(selectedBarId, {
|
onToggled: checked => SettingsData.updateBarConfig(selectedBarId, {
|
||||||
maximizeDetection: checked
|
maximizeDetection: checked
|
||||||
@@ -1152,10 +1208,11 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SettingsCard {
|
SettingsCard {
|
||||||
|
tab: "appearance"
|
||||||
iconName: "filter_b_and_w"
|
iconName: "filter_b_and_w"
|
||||||
title: I18n.tr("System Tray Icon Tint")
|
title: I18n.tr("System Tray Icon Tint")
|
||||||
settingKey: "trayIconTint"
|
settingKey: "trayIconTint"
|
||||||
visible: selectedBarConfig?.enabled
|
visible: dankBarTab.appearanceOnly && selectedBarConfig?.enabled
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: I18n.tr("Choose monochrome or a theme color tint for system tray icons")
|
text: I18n.tr("Choose monochrome or a theme color tint for system tray icons")
|
||||||
@@ -1251,9 +1308,11 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SettingsToggleCard {
|
SettingsToggleCard {
|
||||||
|
tab: "appearance"
|
||||||
|
settingKey: "barBorder"
|
||||||
iconName: "border_style"
|
iconName: "border_style"
|
||||||
title: I18n.tr("Border")
|
title: I18n.tr("Border")
|
||||||
visible: selectedBarConfig?.enabled
|
visible: dankBarTab.appearanceOnly && selectedBarConfig?.enabled && !dankBarTab.connectedFrameModeActive
|
||||||
checked: selectedBarConfig?.borderEnabled ?? false
|
checked: selectedBarConfig?.borderEnabled ?? false
|
||||||
onToggled: checked => SettingsData.updateBarConfig(selectedBarId, {
|
onToggled: checked => SettingsData.updateBarConfig(selectedBarId, {
|
||||||
borderEnabled: checked
|
borderEnabled: checked
|
||||||
@@ -1344,9 +1403,11 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SettingsToggleCard {
|
SettingsToggleCard {
|
||||||
|
tab: "appearance"
|
||||||
|
settingKey: "barWidgetOutline"
|
||||||
iconName: "highlight"
|
iconName: "highlight"
|
||||||
title: I18n.tr("Widget Outline")
|
title: I18n.tr("Widget Outline")
|
||||||
visible: selectedBarConfig?.enabled
|
visible: dankBarTab.appearanceOnly && selectedBarConfig?.enabled
|
||||||
checked: selectedBarConfig?.widgetOutlineEnabled ?? false
|
checked: selectedBarConfig?.widgetOutlineEnabled ?? false
|
||||||
onToggled: checked => SettingsData.updateBarConfig(selectedBarId, {
|
onToggled: checked => SettingsData.updateBarConfig(selectedBarId, {
|
||||||
widgetOutlineEnabled: checked
|
widgetOutlineEnabled: checked
|
||||||
@@ -1437,7 +1498,7 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SettingsControlledByFrame {
|
SettingsControlledByFrame {
|
||||||
visible: dankBarTab.connectedFrameModeActive
|
visible: dankBarTab.appearanceOnly && dankBarTab.connectedFrameModeActive
|
||||||
parentModal: dankBarTab.parentModal
|
parentModal: dankBarTab.parentModal
|
||||||
settingLabel: I18n.tr("Bar shadow, border, and corners")
|
settingLabel: I18n.tr("Bar shadow, border, and corners")
|
||||||
reason: I18n.tr("Managed by Frame in Connected Mode")
|
reason: I18n.tr("Managed by Frame in Connected Mode")
|
||||||
@@ -1445,12 +1506,13 @@ Item {
|
|||||||
|
|
||||||
SettingsCard {
|
SettingsCard {
|
||||||
id: shadowCard
|
id: shadowCard
|
||||||
|
tab: "appearance"
|
||||||
iconName: "layers"
|
iconName: "layers"
|
||||||
title: I18n.tr("Shadow Override", "bar shadow settings card")
|
title: I18n.tr("Shadow Override", "bar shadow settings card")
|
||||||
settingKey: "barShadow"
|
settingKey: "barShadow"
|
||||||
collapsible: true
|
collapsible: true
|
||||||
expanded: false
|
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 shadowActive: (selectedBarConfig?.shadowIntensity ?? 0) > 0
|
||||||
readonly property bool isCustomColor: (selectedBarConfig?.shadowColorMode ?? "default") === "custom"
|
readonly property bool isCustomColor: (selectedBarConfig?.shadowColorMode ?? "default") === "custom"
|
||||||
@@ -1512,6 +1574,7 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SettingsDropdownRow {
|
SettingsDropdownRow {
|
||||||
|
tab: "appearance"
|
||||||
visible: shadowCard.shadowActive
|
visible: shadowCard.shadowActive
|
||||||
text: I18n.tr("Direction Source", "bar shadow direction source")
|
text: I18n.tr("Direction Source", "bar shadow direction source")
|
||||||
description: I18n.tr("Choose how this bar resolves shadow direction")
|
description: I18n.tr("Choose how this bar resolves shadow direction")
|
||||||
@@ -1545,6 +1608,7 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SettingsDropdownRow {
|
SettingsDropdownRow {
|
||||||
|
tab: "appearance"
|
||||||
visible: shadowCard.shadowActive && shadowCard.directionSource === "manual"
|
visible: shadowCard.shadowActive && shadowCard.directionSource === "manual"
|
||||||
text: I18n.tr("Manual Direction", "bar manual shadow direction")
|
text: I18n.tr("Manual Direction", "bar manual shadow direction")
|
||||||
description: I18n.tr("Use a fixed shadow direction for this bar")
|
description: I18n.tr("Use a fixed shadow direction for this bar")
|
||||||
@@ -1680,7 +1744,7 @@ Item {
|
|||||||
iconName: "mouse"
|
iconName: "mouse"
|
||||||
title: I18n.tr("Scroll Wheel")
|
title: I18n.tr("Scroll Wheel")
|
||||||
description: I18n.tr("Control workspaces and columns by scrolling on the bar")
|
description: I18n.tr("Control workspaces and columns by scrolling on the bar")
|
||||||
visible: selectedBarConfig?.enabled
|
visible: !dankBarTab.appearanceOnly && selectedBarConfig?.enabled
|
||||||
checked: selectedBarConfig?.scrollEnabled ?? true
|
checked: selectedBarConfig?.scrollEnabled ?? true
|
||||||
onToggled: checked => SettingsData.updateBarConfig(selectedBarId, {
|
onToggled: checked => SettingsData.updateBarConfig(selectedBarId, {
|
||||||
scrollEnabled: checked
|
scrollEnabled: checked
|
||||||
|
|||||||
@@ -1640,7 +1640,7 @@ Item {
|
|||||||
SettingsControlledByFrame {
|
SettingsControlledByFrame {
|
||||||
visible: themeColorsTab.connectedFrameModeActive
|
visible: themeColorsTab.connectedFrameModeActive
|
||||||
parentModal: themeColorsTab.parentModal
|
parentModal: themeColorsTab.parentModal
|
||||||
settingLabel: I18n.tr("Surface Opacity")
|
settingLabel: I18n.tr("Transparency")
|
||||||
reason: I18n.tr("Managed by Frame in Connected Mode")
|
reason: I18n.tr("Managed by Frame in Connected Mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1648,7 +1648,7 @@ Item {
|
|||||||
tab: "theme"
|
tab: "theme"
|
||||||
tags: ["surface", "popup", "transparency", "opacity", "modal"]
|
tags: ["surface", "popup", "transparency", "opacity", "modal"]
|
||||||
settingKey: "popupTransparency"
|
settingKey: "popupTransparency"
|
||||||
text: I18n.tr("Surface Opacity")
|
text: I18n.tr("Transparency")
|
||||||
description: I18n.tr("Controls opacity of all popouts, modals, and their content layers")
|
description: I18n.tr("Controls opacity of all popouts, modals, and their content layers")
|
||||||
visible: !themeColorsTab.connectedFrameModeActive
|
visible: !themeColorsTab.connectedFrameModeActive
|
||||||
value: Math.round(SettingsData.popupTransparency * 100)
|
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 {
|
SettingsCard {
|
||||||
tab: "theme"
|
tab: "theme"
|
||||||
tags: ["modal", "darken", "background", "overlay"]
|
tags: ["modal", "darken", "background", "overlay"]
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ pragma ComponentBehavior: Bound
|
|||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
@@ -12,6 +13,7 @@ StyledRect {
|
|||||||
|
|
||||||
property string tab: ""
|
property string tab: ""
|
||||||
property var tags: []
|
property var tags: []
|
||||||
|
property string settingKey: ""
|
||||||
|
|
||||||
property string title: ""
|
property string title: ""
|
||||||
property string description: ""
|
property string description: ""
|
||||||
@@ -29,6 +31,34 @@ StyledRect {
|
|||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Theme.surfaceContainerHigh
|
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 {
|
Column {
|
||||||
id: contentColumn
|
id: contentColumn
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ pragma ComponentBehavior: Bound
|
|||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
@@ -12,6 +13,7 @@ StyledRect {
|
|||||||
|
|
||||||
property string tab: ""
|
property string tab: ""
|
||||||
property var tags: []
|
property var tags: []
|
||||||
|
property string settingKey: ""
|
||||||
|
|
||||||
property string title: ""
|
property string title: ""
|
||||||
property string description: ""
|
property string description: ""
|
||||||
@@ -28,6 +30,34 @@ StyledRect {
|
|||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Theme.surfaceContainerHigh
|
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 {
|
Column {
|
||||||
id: mainColumn
|
id: mainColumn
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|||||||
@@ -25,12 +25,14 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
property bool hasMultipleBars: SettingsData.barConfigs.length > 1
|
property bool hasMultipleBars: SettingsData.barConfigs.length > 1
|
||||||
|
property int pluginCatalogRevision: 0
|
||||||
|
|
||||||
DankTooltipV2 {
|
DankTooltipV2 {
|
||||||
id: sharedTooltip
|
id: sharedTooltip
|
||||||
}
|
}
|
||||||
|
|
||||||
property var baseWidgetDefinitions: {
|
property var baseWidgetDefinitions: {
|
||||||
|
pluginCatalogRevision;
|
||||||
var coreWidgets = [
|
var coreWidgets = [
|
||||||
{
|
{
|
||||||
"id": "layout",
|
"id": "layout",
|
||||||
@@ -274,6 +276,30 @@ Item {
|
|||||||
return coreWidgets;
|
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: [
|
property var defaultLeftWidgets: [
|
||||||
{
|
{
|
||||||
"id": "launcherButton",
|
"id": "launcherButton",
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ Item {
|
|||||||
LayoutMirroring.childrenInherit: true
|
LayoutMirroring.childrenInherit: true
|
||||||
|
|
||||||
property var parentModal: null
|
property var parentModal: null
|
||||||
|
property bool pageActive: true
|
||||||
|
property bool componentReady: false
|
||||||
property var windowRulesIncludeStatus: ({
|
property var windowRulesIncludeStatus: ({
|
||||||
"exists": false,
|
"exists": false,
|
||||||
"included": false,
|
"included": false,
|
||||||
@@ -32,6 +34,13 @@ Item {
|
|||||||
property string expandedExternalId: ""
|
property string expandedExternalId: ""
|
||||||
readonly property string dmsRulesFileName: CompositorService.isNiri ? "dms/windowrules.kdl" : CompositorService.isMango ? "dms/windowrules.conf" : "dms/windowrules.lua"
|
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: ({
|
readonly property var matchLabels: ({
|
||||||
"appId": I18n.tr("App ID"),
|
"appId": I18n.tr("App ID"),
|
||||||
"title": I18n.tr("Title"),
|
"title": I18n.tr("Title"),
|
||||||
@@ -182,12 +191,15 @@ Item {
|
|||||||
function loadWindowRules() {
|
function loadWindowRules() {
|
||||||
const compositor = CompositorService.compositor;
|
const compositor = CompositorService.compositor;
|
||||||
if (compositor !== "niri" && compositor !== "hyprland" && compositor !== "mango") {
|
if (compositor !== "niri" && compositor !== "hyprland" && compositor !== "mango") {
|
||||||
|
checkingInclude = false;
|
||||||
windowRules = [];
|
windowRules = [];
|
||||||
externalRules = [];
|
externalRules = [];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkingInclude = true;
|
||||||
Proc.runCommand("load-windowrules", ["dms", "config", "windowrules", "list", compositor], (output, exitCode) => {
|
Proc.runCommand("load-windowrules", ["dms", "config", "windowrules", "list", compositor], (output, exitCode) => {
|
||||||
|
checkingInclude = false;
|
||||||
if (exitCode !== 0) {
|
if (exitCode !== 0) {
|
||||||
windowRules = [];
|
windowRules = [];
|
||||||
externalRules = [];
|
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() {
|
function fixWindowRulesInclude() {
|
||||||
if (readOnly) {
|
if (readOnly) {
|
||||||
showHyprlandReadOnlyWarning();
|
showHyprlandReadOnlyWarning();
|
||||||
@@ -320,7 +294,6 @@ Item {
|
|||||||
return;
|
return;
|
||||||
if (CompositorService.isMango)
|
if (CompositorService.isMango)
|
||||||
MangoService.reloadConfig();
|
MangoService.reloadConfig();
|
||||||
checkWindowRulesIncludeStatus();
|
|
||||||
loadWindowRules();
|
loadWindowRules();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -372,10 +345,12 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango) {
|
componentReady = true;
|
||||||
checkWindowRulesIncludeStatus();
|
Qt.callLater(() => {
|
||||||
loadWindowRules();
|
SettingsSearchService.registerCard("windowRules", headerSection, flickable);
|
||||||
}
|
if (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango)
|
||||||
|
loadWindowRules();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
DankFlickable {
|
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 {
|
Column {
|
||||||
id: mainColumn
|
id: mainColumn
|
||||||
topPadding: 4
|
|
||||||
|
topPadding: Theme.spacingXL
|
||||||
|
bottomPadding: Theme.spacingXL
|
||||||
width: Math.min(550, parent.width - Theme.spacingL * 2)
|
width: Math.min(550, parent.width - Theme.spacingL * 2)
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
spacing: Theme.spacingXL
|
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 {
|
SettingsCard {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
iconName: "label"
|
iconName: "label"
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Item {
|
|||||||
property color rippleColor: Theme.primary
|
property color rippleColor: Theme.primary
|
||||||
property real cornerRadius: 0
|
property real cornerRadius: 0
|
||||||
property bool enableRipple: typeof SettingsData !== "undefined" ? (SettingsData.enableRippleEffects ?? true) : true
|
property bool enableRipple: typeof SettingsData !== "undefined" ? (SettingsData.enableRippleEffects ?? true) : true
|
||||||
|
property int animationDuration: Theme.expressiveDurations.expressiveDefaultSpatial
|
||||||
|
|
||||||
property real _rippleX: 0
|
property real _rippleX: 0
|
||||||
property real _rippleY: 0
|
property real _rippleY: 0
|
||||||
@@ -58,18 +59,18 @@ Item {
|
|||||||
property: "rippleRadius"
|
property: "rippleRadius"
|
||||||
from: 0
|
from: 0
|
||||||
to: root._rippleMaxRadius
|
to: root._rippleMaxRadius
|
||||||
duration: Theme.expressiveDurations.expressiveDefaultSpatial
|
duration: root.animationDuration
|
||||||
easing.bezierCurve: Theme.expressiveCurves.standardDecel
|
easing.bezierCurve: Theme.expressiveCurves.standardDecel
|
||||||
}
|
}
|
||||||
SequentialAnimation {
|
SequentialAnimation {
|
||||||
PauseAnimation {
|
PauseAnimation {
|
||||||
duration: Math.round(Theme.expressiveDurations.expressiveDefaultSpatial * 0.6)
|
duration: Math.round(root.animationDuration * 0.6)
|
||||||
}
|
}
|
||||||
DankAnim {
|
DankAnim {
|
||||||
target: rippleFx
|
target: rippleFx
|
||||||
property: "rippleOpacity"
|
property: "rippleOpacity"
|
||||||
to: 0
|
to: 0
|
||||||
duration: Theme.expressiveDurations.expressiveDefaultSpatial
|
duration: root.animationDuration
|
||||||
easing.bezierCurve: Theme.expressiveCurves.standard
|
easing.bezierCurve: Theme.expressiveCurves.standard
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,20 @@ CATEGORY_KEYWORDS = {
|
|||||||
"Time & Weather": ["clock", "forecast", "date"],
|
"Time & Weather": ["clock", "forecast", "date"],
|
||||||
"Keyboard Shortcuts": ["keys", "bindings", "hotkey"],
|
"Keyboard Shortcuts": ["keys", "bindings", "hotkey"],
|
||||||
"Dank Bar": ["panel", "topbar", "statusbar"],
|
"Dank Bar": ["panel", "topbar", "statusbar"],
|
||||||
"Workspaces": ["virtual desktops", "spaces"],
|
"Compositor": [
|
||||||
|
"virtual desktops",
|
||||||
|
"spaces",
|
||||||
|
"window",
|
||||||
|
"rules",
|
||||||
|
"matching",
|
||||||
|
"floating",
|
||||||
|
"fullscreen",
|
||||||
|
"opacity",
|
||||||
|
"gaps",
|
||||||
|
"borders",
|
||||||
|
"corner rounding",
|
||||||
|
"overrides",
|
||||||
|
],
|
||||||
"Dock": ["taskbar", "launcher bar"],
|
"Dock": ["taskbar", "launcher bar"],
|
||||||
"Network": ["connectivity", "online"],
|
"Network": ["connectivity", "online"],
|
||||||
"System": ["os", "linux"],
|
"System": ["os", "linux"],
|
||||||
@@ -82,14 +95,6 @@ CATEGORY_KEYWORDS = {
|
|||||||
"Displays": ["monitor", "screen", "resolution"],
|
"Displays": ["monitor", "screen", "resolution"],
|
||||||
"Desktop Widgets": ["conky", "desktop clock"],
|
"Desktop Widgets": ["conky", "desktop clock"],
|
||||||
"Audio": ["sound", "volume", "speaker", "microphone", "headphones", "pipewire"],
|
"Audio": ["sound", "volume", "speaker", "microphone", "headphones", "pipewire"],
|
||||||
"Window Rules": [
|
|
||||||
"window",
|
|
||||||
"rules",
|
|
||||||
"matching",
|
|
||||||
"floating",
|
|
||||||
"fullscreen",
|
|
||||||
"opacity",
|
|
||||||
],
|
|
||||||
"Locale": ["locale", "language", "country"],
|
"Locale": ["locale", "language", "country"],
|
||||||
"Greeter": ["login", "greetd", "display manager"],
|
"Greeter": ["login", "greetd", "display manager"],
|
||||||
"Multiplexers": ["tmux", "zellij", "terminal"],
|
"Multiplexers": ["tmux", "zellij", "terminal"],
|
||||||
@@ -104,8 +109,13 @@ TAB_INDEX_MAP = {
|
|||||||
"TimeWeatherTab.qml": 1,
|
"TimeWeatherTab.qml": 1,
|
||||||
"KeybindsTab.qml": 2,
|
"KeybindsTab.qml": 2,
|
||||||
"DankBarTab.qml": 3,
|
"DankBarTab.qml": 3,
|
||||||
|
"CompositorTab.qml": 4,
|
||||||
|
"CompositorLayoutTab.qml": 4,
|
||||||
"WorkspacesTab.qml": 4,
|
"WorkspacesTab.qml": 4,
|
||||||
|
"WindowRulesTab.qml": 4,
|
||||||
"DockTab.qml": 5,
|
"DockTab.qml": 5,
|
||||||
|
"DankBarAppearanceTab.qml": 6,
|
||||||
|
"WorkspaceAppearanceCard.qml": 6,
|
||||||
"NetworkTab.qml": 7,
|
"NetworkTab.qml": 7,
|
||||||
"PrinterTab.qml": 8,
|
"PrinterTab.qml": 8,
|
||||||
"LauncherTab.qml": 9,
|
"LauncherTab.qml": 9,
|
||||||
@@ -127,7 +137,6 @@ TAB_INDEX_MAP = {
|
|||||||
"GammaControlTab.qml": 25,
|
"GammaControlTab.qml": 25,
|
||||||
"DisplayWidgetsTab.qml": 26,
|
"DisplayWidgetsTab.qml": 26,
|
||||||
"DesktopWidgetsTab.qml": 27,
|
"DesktopWidgetsTab.qml": 27,
|
||||||
"WindowRulesTab.qml": 28,
|
|
||||||
"AudioTab.qml": 29,
|
"AudioTab.qml": 29,
|
||||||
"LocaleTab.qml": 30,
|
"LocaleTab.qml": 30,
|
||||||
"GreeterTab.qml": 31,
|
"GreeterTab.qml": 31,
|
||||||
@@ -143,8 +152,9 @@ TAB_CATEGORY_MAP = {
|
|||||||
1: "Time & Weather",
|
1: "Time & Weather",
|
||||||
2: "Keyboard Shortcuts",
|
2: "Keyboard Shortcuts",
|
||||||
3: "Dank Bar",
|
3: "Dank Bar",
|
||||||
4: "Workspaces",
|
4: "Compositor",
|
||||||
5: "Dock",
|
5: "Dock",
|
||||||
|
6: "Dank Bar",
|
||||||
7: "Network",
|
7: "Network",
|
||||||
8: "System",
|
8: "System",
|
||||||
9: "Launcher",
|
9: "Launcher",
|
||||||
@@ -166,7 +176,6 @@ TAB_CATEGORY_MAP = {
|
|||||||
25: "Displays",
|
25: "Displays",
|
||||||
26: "Displays",
|
26: "Displays",
|
||||||
27: "Desktop Widgets",
|
27: "Desktop Widgets",
|
||||||
28: "Window Rules",
|
|
||||||
29: "Audio",
|
29: "Audio",
|
||||||
30: "Locale",
|
30: "Locale",
|
||||||
31: "Greeter",
|
31: "Greeter",
|
||||||
@@ -302,9 +311,9 @@ def extract_property(block, prop_name):
|
|||||||
|
|
||||||
def find_settings_components(content, filename):
|
def find_settings_components(content, filename):
|
||||||
results = []
|
results = []
|
||||||
tab_index = TAB_INDEX_MAP.get(filename, -1)
|
file_tab_index = TAB_INDEX_MAP.get(filename, -1)
|
||||||
|
|
||||||
if tab_index == -1:
|
if file_tab_index == -1:
|
||||||
return results
|
return results
|
||||||
|
|
||||||
for component in SEARCHABLE_COMPONENTS:
|
for component in SEARCHABLE_COMPONENTS:
|
||||||
@@ -321,6 +330,11 @@ def find_settings_components(content, filename):
|
|||||||
if not setting_key:
|
if not setting_key:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
tab_index = file_tab_index
|
||||||
|
tab_raw = extract_property(block, "tab")
|
||||||
|
if tab_raw and tab_raw.strip("\"'") == "appearance":
|
||||||
|
tab_index = 6
|
||||||
|
|
||||||
title_raw = extract_property(block, "title")
|
title_raw = extract_property(block, "title")
|
||||||
text_raw = extract_property(block, "text")
|
text_raw = extract_property(block, "text")
|
||||||
label = None
|
label = None
|
||||||
@@ -489,7 +503,7 @@ def extract_settings_index(root_dir):
|
|||||||
seen_keys = set()
|
seen_keys = set()
|
||||||
|
|
||||||
for qml_file in settings_dir.glob("*.qml"):
|
for qml_file in settings_dir.glob("*.qml"):
|
||||||
if not qml_file.name.endswith("Tab.qml"):
|
if qml_file.name not in TAB_INDEX_MAP:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
with open(qml_file, "r", encoding="utf-8") as f:
|
with open(qml_file, "r", encoding="utf-8") as f:
|
||||||
@@ -502,6 +516,24 @@ def extract_settings_index(root_dir):
|
|||||||
seen_keys.add(key)
|
seen_keys.add(key)
|
||||||
all_entries.append(entry)
|
all_entries.append(entry)
|
||||||
|
|
||||||
|
if "windowRules" not in seen_keys:
|
||||||
|
all_entries.append(
|
||||||
|
{
|
||||||
|
"section": "windowRules",
|
||||||
|
"label": "Window Rules",
|
||||||
|
"tabIndex": 4,
|
||||||
|
"category": "Compositor",
|
||||||
|
"keywords": enrich_keywords(
|
||||||
|
"Window Rules",
|
||||||
|
"Define compositor rules for window behavior",
|
||||||
|
"Compositor",
|
||||||
|
["matching", "floating", "fullscreen", "opacity"],
|
||||||
|
),
|
||||||
|
"icon": "select_window",
|
||||||
|
"description": "Define compositor rules for window behavior",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
return all_entries
|
return all_entries
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user