mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-08-02 03:28:28 -04:00
31efe9b385
fixes #2047
675 lines
31 KiB
QML
675 lines
31 KiB
QML
import QtCore
|
|
import QtQuick
|
|
import qs.Common
|
|
import qs.Services
|
|
import qs.Widgets
|
|
import qs.Modules.Settings.Widgets
|
|
import "../../Common/ConfigIncludeResolve.js" as ConfigIncludeResolve
|
|
|
|
Item {
|
|
id: root
|
|
|
|
LayoutMirroring.enabled: I18n.isRtl
|
|
LayoutMirroring.childrenInherit: true
|
|
|
|
property var layoutIncludeStatus: ({
|
|
"exists": false,
|
|
"included": false,
|
|
"configFormat": "",
|
|
"readOnly": false
|
|
})
|
|
readonly property bool readOnly: CompositorService.isHyprland && layoutIncludeStatus.readOnly === true
|
|
property bool checkingInclude: false
|
|
property bool fixingInclude: false
|
|
property string xrayConflictSource: ""
|
|
|
|
function getLayoutConfigPaths() {
|
|
const configDir = Paths.strip(StandardPaths.writableLocation(StandardPaths.ConfigLocation));
|
|
switch (CompositorService.compositor) {
|
|
case "niri":
|
|
return {
|
|
"configFile": configDir + "/niri/config.kdl",
|
|
"layoutFile": configDir + "/niri/dms/layout.kdl",
|
|
"grepPattern": 'include.*"dms/layout.kdl"',
|
|
"includeLine": 'include "dms/layout.kdl"'
|
|
};
|
|
case "hyprland":
|
|
return {
|
|
"configFile": configDir + "/hypr/hyprland.lua",
|
|
"layoutFile": configDir + "/hypr/dms/layout.lua",
|
|
"grepPattern": "dms.layout",
|
|
"includeLine": "require(\"dms.layout\")"
|
|
};
|
|
case "mango":
|
|
return {
|
|
"configFile": configDir + "/mango/config.conf",
|
|
"layoutFile": configDir + "/mango/dms/layout.conf",
|
|
"grepPattern": "source.*dms/layout.conf",
|
|
"includeLine": "source=./dms/layout.conf"
|
|
};
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function checkLayoutIncludeStatus() {
|
|
const compositor = CompositorService.compositor;
|
|
if (compositor !== "niri" && compositor !== "hyprland" && compositor !== "mango") {
|
|
layoutIncludeStatus = {
|
|
"exists": false,
|
|
"included": false,
|
|
"configFormat": "",
|
|
"readOnly": false
|
|
};
|
|
return;
|
|
}
|
|
|
|
const filename = compositor === "niri" ? "layout.kdl" : (compositor === "hyprland" ? "layout.lua" : "layout.conf");
|
|
const compositorArg = compositor === "mango" ? "mangowc" : compositor;
|
|
|
|
checkingInclude = true;
|
|
Proc.runCommand("check-layout-include", ["dms", "config", "resolve-include", compositorArg, filename], (output, exitCode) => {
|
|
checkingInclude = false;
|
|
if (exitCode !== 0) {
|
|
layoutIncludeStatus = {
|
|
"exists": false,
|
|
"included": false,
|
|
"configFormat": "",
|
|
"readOnly": false
|
|
};
|
|
return;
|
|
}
|
|
try {
|
|
layoutIncludeStatus = JSON.parse(output.trim());
|
|
} catch (e) {
|
|
layoutIncludeStatus = {
|
|
"exists": false,
|
|
"included": false,
|
|
"configFormat": "",
|
|
"readOnly": false
|
|
};
|
|
}
|
|
});
|
|
}
|
|
|
|
function fixLayoutInclude() {
|
|
if (readOnly) {
|
|
ToastService.showWarning(I18n.tr("Hyprland conf mode"), I18n.tr("This install is still using hyprland.conf. Run dms setup to migrate before editing layout settings."), "dms setup", "hyprland-migration");
|
|
return;
|
|
}
|
|
const paths = getLayoutConfigPaths();
|
|
if (!paths)
|
|
return;
|
|
|
|
fixingInclude = true;
|
|
const unixTime = Math.floor(Date.now() / 1000);
|
|
const backupFile = paths.configFile + ".backup" + unixTime;
|
|
const script = ConfigIncludeResolve.buildRepairScript({
|
|
configFile: paths.configFile,
|
|
backupFile: backupFile,
|
|
fragmentFile: paths.layoutFile,
|
|
grepPattern: paths.grepPattern,
|
|
includeLine: paths.includeLine
|
|
});
|
|
Proc.runCommand("fix-layout-include", ["sh", "-c", script], (output, exitCode) => {
|
|
fixingInclude = false;
|
|
if (exitCode !== 0)
|
|
return;
|
|
checkLayoutIncludeStatus();
|
|
SettingsData.updateCompositorLayout();
|
|
});
|
|
}
|
|
|
|
function checkXrayConflicts() {
|
|
if (!CompositorService.isNiri)
|
|
return;
|
|
const configDir = Paths.strip(StandardPaths.writableLocation(StandardPaths.ConfigLocation));
|
|
const script = `cd "${configDir}/niri" 2>/dev/null || exit 0
|
|
files="config.kdl"
|
|
for f in $(sed -nE 's/^[[:space:]]*include[[:space:]]+"([^"]+)".*/\\1/p' config.kdl 2>/dev/null); do
|
|
case "$f" in dms/*|/*dms/*) continue ;; esac
|
|
[ -f "$f" ] && files="$files $f"
|
|
done
|
|
awk '$1 == "xray" { print FILENAME ":" FNR; exit }' $files 2>/dev/null`;
|
|
|
|
Proc.runCommand("check-xray-conflict", ["sh", "-c", script], (output, exitCode) => {
|
|
xrayConflictSource = exitCode === 0 ? output.trim() : "";
|
|
});
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
if (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango) {
|
|
checkLayoutIncludeStatus();
|
|
checkXrayConflicts();
|
|
}
|
|
}
|
|
|
|
DankFlickable {
|
|
anchors.fill: parent
|
|
clip: true
|
|
contentHeight: layoutColumn.height + Theme.spacingXL
|
|
contentWidth: width
|
|
|
|
Column {
|
|
id: layoutColumn
|
|
|
|
topPadding: 4
|
|
width: Math.min(550, parent.width - Theme.spacingL * 2)
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
spacing: Theme.spacingXL
|
|
|
|
StyledRect {
|
|
id: warningBox
|
|
width: parent.width
|
|
height: warningContent.implicitHeight + Theme.spacingL * 2
|
|
radius: Theme.cornerRadius
|
|
|
|
readonly property bool showLegacy: root.readOnly
|
|
readonly property bool showSetup: !showLegacy && !root.layoutIncludeStatus.included
|
|
|
|
color: (showLegacy || showSetup) ? Theme.withAlpha(Theme.primary, 0.15) : Theme.withAlpha(Theme.primary, 0)
|
|
border.color: (showLegacy || showSetup) ? Theme.withAlpha(Theme.primary, 0.3) : Theme.withAlpha(Theme.primary, 0)
|
|
border.width: 1
|
|
visible: (showLegacy || showSetup) && !root.checkingInclude && (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango)
|
|
|
|
Row {
|
|
id: warningContent
|
|
anchors.fill: parent
|
|
anchors.margins: Theme.spacingL
|
|
spacing: Theme.spacingM
|
|
|
|
DankIcon {
|
|
name: "warning"
|
|
size: Theme.iconSize
|
|
color: Theme.primary
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
|
|
Column {
|
|
width: parent.width - Theme.iconSize - (fixButton.visible ? fixButton.width + Theme.spacingM : 0) - Theme.spacingM
|
|
spacing: Theme.spacingXS
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
|
|
StyledText {
|
|
text: {
|
|
if (warningBox.showLegacy)
|
|
return I18n.tr("Hyprland conf mode");
|
|
if (warningBox.showSetup)
|
|
return I18n.tr("First Time Setup");
|
|
return "";
|
|
}
|
|
font.pixelSize: Theme.fontSizeMedium
|
|
font.weight: Font.Medium
|
|
color: Theme.primary
|
|
width: parent.width
|
|
horizontalAlignment: Text.AlignLeft
|
|
}
|
|
|
|
StyledText {
|
|
text: {
|
|
if (warningBox.showLegacy)
|
|
return I18n.tr("This install is still using hyprland.conf. Run dms setup to migrate before editing layout settings.");
|
|
if (warningBox.showSetup)
|
|
return I18n.tr("Click 'Setup' to create %1 and add include to your compositor config.").arg("dms/layout");
|
|
return "";
|
|
}
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
color: Theme.surfaceVariantText
|
|
wrapMode: Text.WordWrap
|
|
width: parent.width
|
|
horizontalAlignment: Text.AlignLeft
|
|
}
|
|
}
|
|
|
|
DankButton {
|
|
id: fixButton
|
|
visible: !warningBox.showLegacy && warningBox.showSetup
|
|
text: root.fixingInclude ? I18n.tr("Setting up...") : I18n.tr("Setup")
|
|
backgroundColor: Theme.primary
|
|
textColor: Theme.primaryText
|
|
enabled: !root.fixingInclude
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
onClicked: root.fixLayoutInclude()
|
|
}
|
|
}
|
|
}
|
|
|
|
StyledRect {
|
|
width: parent.width
|
|
height: xrayConflictRow.implicitHeight + Theme.spacingL * 2
|
|
radius: Theme.cornerRadius
|
|
color: Theme.withAlpha(Theme.primary, 0.15)
|
|
border.color: Theme.withAlpha(Theme.primary, 0.3)
|
|
border.width: 1
|
|
visible: root.xrayConflictSource !== ""
|
|
|
|
Row {
|
|
id: xrayConflictRow
|
|
anchors.fill: parent
|
|
anchors.margins: Theme.spacingL
|
|
spacing: Theme.spacingM
|
|
|
|
DankIcon {
|
|
name: "warning"
|
|
size: Theme.iconSize
|
|
color: Theme.primary
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
|
|
StyledText {
|
|
width: parent.width - Theme.iconSize - Theme.spacingM
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
text: I18n.tr("An xray rule at %1 may conflict with the Xray settings below").arg(root.xrayConflictSource)
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
color: Theme.surfaceVariantText
|
|
wrapMode: Text.WordWrap
|
|
}
|
|
}
|
|
}
|
|
|
|
SettingsCard {
|
|
width: parent.width
|
|
tags: ["niri", "layout", "gaps", "radius", "window", "border"]
|
|
title: I18n.tr("Niri Layout Overrides")
|
|
settingKey: "niriLayout"
|
|
iconName: "layers"
|
|
visible: CompositorService.isNiri
|
|
|
|
SettingsButtonGroupRow {
|
|
tags: ["niri", "gaps", "override", "unmanaged"]
|
|
settingKey: "niriLayoutGapsMode"
|
|
text: I18n.tr("Gaps")
|
|
description: I18n.tr("Auto matches bar spacing; Off leaves gaps to your niri config")
|
|
model: [I18n.tr("Auto"), I18n.tr("Custom"), I18n.tr("Off")]
|
|
currentIndex: {
|
|
if (SettingsData.niriLayoutGapsOverride === -2)
|
|
return 2;
|
|
return SettingsData.niriLayoutGapsOverride >= 0 ? 1 : 0;
|
|
}
|
|
onSelectionChanged: (index, selected) => {
|
|
if (!selected)
|
|
return;
|
|
switch (index) {
|
|
case 1:
|
|
SettingsData.set("niriLayoutGapsOverride", Math.max(4, (SettingsData.barConfigs[0]?.spacing ?? 4)));
|
|
return;
|
|
case 2:
|
|
SettingsData.set("niriLayoutGapsOverride", -2);
|
|
return;
|
|
default:
|
|
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)
|
|
}
|
|
|
|
SettingsToggleRow {
|
|
visible: CompositorService.isNiri
|
|
tags: ["niri", "xray", "blur", "background-effect", "performance"]
|
|
settingKey: "niriLayoutXrayEnabled"
|
|
text: I18n.tr("Xray Blur Effect")
|
|
description: I18n.tr("Blurred surfaces show the wallpaper instead of the content beneath")
|
|
checked: NiriService.layoutXrayEnabled
|
|
onToggled: checked => NiriService.setLayoutXray(checked)
|
|
}
|
|
|
|
SettingsToggleRow {
|
|
// Hidden in Frame Connected mode, where it has no target
|
|
visible: CompositorService.isNiri && !SettingsData.connectedFrameModeActive
|
|
tags: ["niri", "xray", "bar", "frame", "performance"]
|
|
settingKey: "niriLayoutBarXrayEnabled"
|
|
text: SettingsData.frameEnabled ? I18n.tr("Frame Xray") : I18n.tr("Dank Bar Xray")
|
|
description: I18n.tr("Always blur against the wallpaper, even with Xray off")
|
|
checked: NiriService.layoutBarXrayEnabled
|
|
onToggled: checked => NiriService.setLayoutBarXray(checked)
|
|
}
|
|
}
|
|
|
|
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
|
|
|
|
SettingsButtonGroupRow {
|
|
tags: ["hyprland", "gaps", "override", "inner", "outer", "unmanaged"]
|
|
settingKey: "hyprlandLayoutGapsMode"
|
|
text: I18n.tr("Gaps")
|
|
description: I18n.tr("Auto matches bar spacing; Off leaves gaps to your Hyprland config")
|
|
model: [I18n.tr("Auto"), I18n.tr("Custom"), I18n.tr("Off")]
|
|
currentIndex: {
|
|
if (SettingsData.hyprlandLayoutGapsOverride === -2)
|
|
return 2;
|
|
return SettingsData.hyprlandLayoutGapsOverride >= 0 ? 1 : 0;
|
|
}
|
|
onSelectionChanged: (index, selected) => {
|
|
if (!selected)
|
|
return;
|
|
switch (index) {
|
|
case 1:
|
|
SettingsData.set("hyprlandLayoutGapsOverride", Math.max(4, (SettingsData.barConfigs[0]?.spacing ?? 4)));
|
|
return;
|
|
case 2:
|
|
SettingsData.set("hyprlandLayoutGapsOverride", -2);
|
|
return;
|
|
default:
|
|
SettingsData.set("hyprlandLayoutGapsOverride", -1);
|
|
}
|
|
}
|
|
}
|
|
|
|
SettingsSliderRow {
|
|
tags: ["hyprland", "gaps", "override", "inner"]
|
|
settingKey: "hyprlandLayoutGapsOverride"
|
|
text: I18n.tr("Inner Gaps")
|
|
description: I18n.tr("Space between windows") + " (gaps_in)"
|
|
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)
|
|
}
|
|
|
|
SettingsSliderRow {
|
|
tags: ["hyprland", "gaps", "override", "outer", "edge"]
|
|
settingKey: "hyprlandLayoutGapsOutOverride"
|
|
text: I18n.tr("Outer Gaps")
|
|
description: I18n.tr("Space between windows and screen edges") + " (gaps_out)"
|
|
visible: SettingsData.hyprlandLayoutGapsOverride >= 0
|
|
value: SettingsData.hyprlandLayoutGapsOutOverride >= 0 ? SettingsData.hyprlandLayoutGapsOutOverride : Math.max(0, SettingsData.hyprlandLayoutGapsOverride)
|
|
minimum: 0
|
|
maximum: 50
|
|
unit: "px"
|
|
defaultValue: Math.max(0, SettingsData.hyprlandLayoutGapsOverride)
|
|
onSliderValueChanged: newValue => SettingsData.set("hyprlandLayoutGapsOutOverride", newValue)
|
|
}
|
|
|
|
SettingsToggleRow {
|
|
tags: ["hyprland", "radius", "override", "rounding"]
|
|
settingKey: "hyprlandLayoutRadiusOverrideEnabled"
|
|
text: I18n.tr("Override Corner Radius")
|
|
description: I18n.tr("Use custom window radius 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 Corner Radius")
|
|
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)
|
|
}
|
|
|
|
SettingsToggleRow {
|
|
visible: CompositorService.isHyprland
|
|
tags: ["hyprland", "xray", "blur", "background-effect", "performance"]
|
|
settingKey: "hyprlandLayoutXrayEnabled"
|
|
text: I18n.tr("Xray Blur Effect")
|
|
description: I18n.tr("Blurred surfaces show the wallpaper instead of the content beneath")
|
|
checked: HyprlandService.layoutXrayEnabled
|
|
onToggled: checked => HyprlandService.setLayoutXray(checked)
|
|
}
|
|
|
|
SettingsToggleRow {
|
|
// Hidden in Frame Connected mode, where it has no target
|
|
visible: CompositorService.isHyprland && !SettingsData.connectedFrameModeActive
|
|
tags: ["hyprland", "xray", "bar", "frame", "performance"]
|
|
settingKey: "hyprlandLayoutBarXrayEnabled"
|
|
text: SettingsData.frameEnabled ? I18n.tr("Frame Xray") : I18n.tr("Dank Bar Xray")
|
|
description: I18n.tr("Always blur against the wallpaper, even with Xray off")
|
|
checked: HyprlandService.layoutBarXrayEnabled
|
|
onToggled: checked => HyprlandService.setLayoutBarXray(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.isMango
|
|
|
|
SettingsButtonGroupRow {
|
|
tags: ["mangowc", "mango", "gaps", "override", "inner", "outer", "unmanaged"]
|
|
settingKey: "mangoLayoutGapsMode"
|
|
text: I18n.tr("Gaps")
|
|
description: I18n.tr("Auto matches bar spacing; Off leaves gaps to your MangoWC config")
|
|
model: [I18n.tr("Auto"), I18n.tr("Custom"), I18n.tr("Off")]
|
|
currentIndex: {
|
|
if (SettingsData.mangoLayoutGapsOverride === -2)
|
|
return 2;
|
|
return SettingsData.mangoLayoutGapsOverride >= 0 ? 1 : 0;
|
|
}
|
|
onSelectionChanged: (index, selected) => {
|
|
if (!selected)
|
|
return;
|
|
switch (index) {
|
|
case 1:
|
|
SettingsData.set("mangoLayoutGapsOverride", Math.max(4, (SettingsData.barConfigs[0]?.spacing ?? 4)));
|
|
return;
|
|
case 2:
|
|
SettingsData.set("mangoLayoutGapsOverride", -2);
|
|
return;
|
|
default:
|
|
SettingsData.set("mangoLayoutGapsOverride", -1);
|
|
}
|
|
}
|
|
}
|
|
|
|
SettingsSliderRow {
|
|
tags: ["mangowc", "mango", "gaps", "override", "inner"]
|
|
settingKey: "mangoLayoutGapsOverride"
|
|
text: I18n.tr("Inner Gaps")
|
|
description: I18n.tr("Space between windows") + " (gappih/gappiv)"
|
|
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)
|
|
}
|
|
|
|
SettingsSliderRow {
|
|
tags: ["mangowc", "mango", "gaps", "override", "outer", "edge"]
|
|
settingKey: "mangoLayoutGapsOutOverride"
|
|
text: I18n.tr("Outer Gaps")
|
|
description: I18n.tr("Space between windows and screen edges") + " (gappoh/gappov)"
|
|
visible: SettingsData.mangoLayoutGapsOverride >= 0
|
|
value: SettingsData.mangoLayoutGapsOutOverride >= 0 ? SettingsData.mangoLayoutGapsOutOverride : Math.max(0, SettingsData.mangoLayoutGapsOverride)
|
|
minimum: 0
|
|
maximum: 50
|
|
unit: "px"
|
|
defaultValue: Math.max(0, SettingsData.mangoLayoutGapsOverride)
|
|
onSliderValueChanged: newValue => SettingsData.set("mangoLayoutGapsOutOverride", 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)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|