mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-08-01 19:18:28 -04:00
refactor(include): Add missing layout include & normalize config banners
- The Display config process ID now includes the output name in NiriService
This commit is contained in:
@@ -37,9 +37,11 @@ var resolveIncludeCmd = &cobra.Command{
|
|||||||
"cursor.lua",
|
"cursor.lua",
|
||||||
"windowrules.lua",
|
"windowrules.lua",
|
||||||
"cursor.kdl",
|
"cursor.kdl",
|
||||||
|
"layout.kdl",
|
||||||
"outputs.kdl",
|
"outputs.kdl",
|
||||||
"binds.kdl",
|
"binds.kdl",
|
||||||
"cursor.conf",
|
"cursor.conf",
|
||||||
|
"layout.conf",
|
||||||
"outputs.conf",
|
"outputs.conf",
|
||||||
"binds.conf",
|
"binds.conf",
|
||||||
}, cobra.ShellCompDirectiveNoFileComp
|
}, cobra.ShellCompDirectiveNoFileComp
|
||||||
|
|||||||
@@ -7,6 +7,24 @@ function dirname(path) {
|
|||||||
return idx > 0 ? path.substring(0, idx) : ".";
|
return idx > 0 ? path.substring(0, idx) : ".";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sectionHeaderFor(includeLine) {
|
||||||
|
const line = String(includeLine ?? "").trim();
|
||||||
|
if (line.startsWith("require"))
|
||||||
|
return "-- DMS Include Configs";
|
||||||
|
if (line.startsWith("source"))
|
||||||
|
return "# DMS Include Configs";
|
||||||
|
return "// DMS Include Configs";
|
||||||
|
}
|
||||||
|
|
||||||
|
function managedIncludePatternFor(includeLine) {
|
||||||
|
const line = String(includeLine ?? "").trim();
|
||||||
|
if (line.startsWith("require"))
|
||||||
|
return "require.*dms[.]";
|
||||||
|
if (line.startsWith("source"))
|
||||||
|
return "source.*dms/";
|
||||||
|
return "include.*dms/";
|
||||||
|
}
|
||||||
|
|
||||||
function buildRepairScript(options) {
|
function buildRepairScript(options) {
|
||||||
const configFile = options.configFile;
|
const configFile = options.configFile;
|
||||||
const backupFile = options.backupFile;
|
const backupFile = options.backupFile;
|
||||||
@@ -31,7 +49,9 @@ function buildRepairScript(options) {
|
|||||||
for (const include of includes) {
|
for (const include of includes) {
|
||||||
if (!include.grepPattern || !include.includeLine)
|
if (!include.grepPattern || !include.includeLine)
|
||||||
continue;
|
continue;
|
||||||
commands.push(`if ! grep -v '^[[:space:]]*\\(//\\|#\\|--\\)' ${shQuote(configFile)} 2>/dev/null | grep -q ${shQuote(include.grepPattern)}; then echo '' >> ${shQuote(configFile)} && printf '%s\\n' ${shQuote(include.includeLine)} >> ${shQuote(configFile)}; fi`);
|
const sectionHeader = options.sectionHeader || sectionHeaderFor(include.includeLine);
|
||||||
|
const managedIncludePattern = managedIncludePatternFor(include.includeLine);
|
||||||
|
commands.push(`if ! grep -v '^[[:space:]]*\\(//\\|#\\|--\\)' ${shQuote(configFile)} 2>/dev/null | grep -q ${shQuote(include.grepPattern)}; then if grep -Fqx ${shQuote(sectionHeader)} ${shQuote(configFile)} 2>/dev/null || grep -v '^[[:space:]]*\\(//\\|#\\|--\\)' ${shQuote(configFile)} 2>/dev/null | grep -q ${shQuote(managedIncludePattern)}; then printf '%s\\n' ${shQuote(include.includeLine)} >> ${shQuote(configFile)}; elif [ -s ${shQuote(configFile)} ]; then printf '\\n%s\\n%s\\n' ${shQuote(sectionHeader)} ${shQuote(include.includeLine)} >> ${shQuote(configFile)}; else printf '%s\\n%s\\n' ${shQuote(sectionHeader)} ${shQuote(include.includeLine)} >> ${shQuote(configFile)}; fi; fi`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return commands.join("; ");
|
return commands.join("; ");
|
||||||
|
|||||||
@@ -1,10 +1,130 @@
|
|||||||
|
import QtCore
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
import qs.Common
|
import qs.Common
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
import qs.Modules.Settings.Widgets
|
import qs.Modules.Settings.Widgets
|
||||||
|
import "../../Common/ConfigIncludeResolve.js" as ConfigIncludeResolve
|
||||||
|
|
||||||
Item {
|
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
|
||||||
|
|
||||||
|
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();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango)
|
||||||
|
checkLayoutIncludeStatus();
|
||||||
|
}
|
||||||
|
|
||||||
DankFlickable {
|
DankFlickable {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
clip: true
|
clip: true
|
||||||
@@ -19,6 +139,82 @@ Item {
|
|||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
spacing: Theme.spacingXL
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SettingsCard {
|
SettingsCard {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
tags: ["niri", "layout", "gaps", "radius", "window", "border"]
|
tags: ["niri", "layout", "gaps", "radius", "window", "border"]
|
||||||
|
|||||||
@@ -847,6 +847,14 @@ Singleton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: NiriService
|
||||||
|
enabled: CompositorService.isNiri
|
||||||
|
function onConfigReloaded() {
|
||||||
|
root.checkIncludeStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
outputs = buildOutputsMap();
|
outputs = buildOutputsMap();
|
||||||
reloadSavedOutputs();
|
reloadSavedOutputs();
|
||||||
|
|||||||
@@ -13,13 +13,12 @@ StyledRect {
|
|||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
|
|
||||||
readonly property bool showLegacy: DisplayConfigState.readOnly
|
readonly property bool showLegacy: DisplayConfigState.readOnly
|
||||||
readonly property bool showError: !showLegacy && DisplayConfigState.includeStatus.exists && !DisplayConfigState.includeStatus.included
|
readonly property bool showSetup: !showLegacy && !DisplayConfigState.includeStatus.included
|
||||||
readonly property bool showSetup: !showLegacy && !DisplayConfigState.includeStatus.exists && !DisplayConfigState.includeStatus.included
|
|
||||||
|
|
||||||
color: (showLegacy || showError || showSetup) ? Theme.withAlpha(Theme.primary, 0.15) : Theme.withAlpha(Theme.primary, 0)
|
color: (showLegacy || showSetup) ? Theme.withAlpha(Theme.primary, 0.15) : Theme.withAlpha(Theme.primary, 0)
|
||||||
border.color: (showLegacy || showError || showSetup) ? Theme.withAlpha(Theme.primary, 0.3) : Theme.withAlpha(Theme.primary, 0)
|
border.color: (showLegacy || showSetup) ? Theme.withAlpha(Theme.primary, 0.3) : Theme.withAlpha(Theme.primary, 0)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
visible: (showLegacy || showError || showSetup) && DisplayConfigState.hasOutputBackend && !DisplayConfigState.checkingInclude
|
visible: (showLegacy || showSetup) && DisplayConfigState.hasOutputBackend && !DisplayConfigState.checkingInclude
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: warningContent
|
id: warningContent
|
||||||
@@ -49,8 +48,6 @@ StyledRect {
|
|||||||
return I18n.tr("Hyprland conf mode");
|
return I18n.tr("Hyprland conf mode");
|
||||||
if (root.showSetup)
|
if (root.showSetup)
|
||||||
return I18n.tr("First Time Setup");
|
return I18n.tr("First Time Setup");
|
||||||
if (root.showError)
|
|
||||||
return I18n.tr("Outputs Include Missing");
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
@@ -66,8 +63,6 @@ StyledRect {
|
|||||||
return I18n.tr("This install is still using hyprland.conf. Run dms setup to migrate before editing display settings.");
|
return I18n.tr("This install is still using hyprland.conf. Run dms setup to migrate before editing display settings.");
|
||||||
if (root.showSetup)
|
if (root.showSetup)
|
||||||
return I18n.tr("Click 'Setup' to create the outputs config and add include to your compositor config.");
|
return I18n.tr("Click 'Setup' to create the outputs config and add include to your compositor config.");
|
||||||
if (root.showError)
|
|
||||||
return I18n.tr("dms/outputs config exists but is not included in your compositor config. Display changes won't persist.");
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
@@ -80,14 +75,8 @@ StyledRect {
|
|||||||
|
|
||||||
DankButton {
|
DankButton {
|
||||||
id: fixButton
|
id: fixButton
|
||||||
visible: !root.showLegacy && (root.showError || root.showSetup)
|
visible: !root.showLegacy && root.showSetup
|
||||||
text: {
|
text: DisplayConfigState.fixingInclude ? I18n.tr("Setting up...") : I18n.tr("Setup")
|
||||||
if (DisplayConfigState.fixingInclude)
|
|
||||||
return I18n.tr("Fixing...");
|
|
||||||
if (root.showSetup)
|
|
||||||
return I18n.tr("Setup");
|
|
||||||
return I18n.tr("Fix Now");
|
|
||||||
}
|
|
||||||
backgroundColor: Theme.primary
|
backgroundColor: Theme.primary
|
||||||
textColor: Theme.primaryText
|
textColor: Theme.primaryText
|
||||||
enabled: !DisplayConfigState.fixingInclude
|
enabled: !DisplayConfigState.fixingInclude
|
||||||
|
|||||||
@@ -347,14 +347,13 @@ Item {
|
|||||||
|
|
||||||
readonly property var status: KeybindsService.dmsStatus
|
readonly property var status: KeybindsService.dmsStatus
|
||||||
readonly property bool showLegacy: KeybindsService.readOnly
|
readonly property bool showLegacy: KeybindsService.readOnly
|
||||||
readonly property bool showError: !showLegacy && !status.included && status.exists
|
|
||||||
readonly property bool showWarning: !showLegacy && status.included && status.overriddenBy > 0
|
readonly property bool showWarning: !showLegacy && status.included && status.overriddenBy > 0
|
||||||
readonly property bool showSetup: !showLegacy && !status.exists
|
readonly property bool showSetup: !showLegacy && !status.included
|
||||||
|
|
||||||
color: (showLegacy || showError || showWarning || showSetup) ? Theme.withAlpha(Theme.primary, 0.15) : Theme.withAlpha(Theme.primary, 0)
|
color: (showLegacy || showWarning || showSetup) ? Theme.withAlpha(Theme.primary, 0.15) : Theme.withAlpha(Theme.primary, 0)
|
||||||
border.color: (showLegacy || showError || showWarning || showSetup) ? Theme.withAlpha(Theme.primary, 0.3) : Theme.withAlpha(Theme.primary, 0)
|
border.color: (showLegacy || showWarning || showSetup) ? Theme.withAlpha(Theme.primary, 0.3) : Theme.withAlpha(Theme.primary, 0)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
visible: (showLegacy || showError || showWarning || showSetup) && !KeybindsService.loading
|
visible: (showLegacy || showWarning || showSetup) && !KeybindsService.loading
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: warningSection
|
id: warningSection
|
||||||
@@ -384,8 +383,6 @@ Item {
|
|||||||
return I18n.tr("Hyprland conf mode");
|
return I18n.tr("Hyprland conf mode");
|
||||||
if (warningBox.showSetup)
|
if (warningBox.showSetup)
|
||||||
return I18n.tr("First Time Setup");
|
return I18n.tr("First Time Setup");
|
||||||
if (warningBox.showError)
|
|
||||||
return I18n.tr("Binds Include Missing");
|
|
||||||
if (warningBox.showWarning)
|
if (warningBox.showWarning)
|
||||||
return I18n.tr("Possible Override Conflicts");
|
return I18n.tr("Possible Override Conflicts");
|
||||||
return "";
|
return "";
|
||||||
@@ -393,17 +390,16 @@ Item {
|
|||||||
font.pixelSize: Theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
color: Theme.primary
|
color: Theme.primary
|
||||||
|
width: parent.width
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
readonly property string bindsFile: KeybindsService.currentProvider === "niri" ? "dms/binds.kdl" : KeybindsService.currentProvider === "hyprland" ? "dms/binds-user.lua" : "dms/binds.conf"
|
|
||||||
text: {
|
text: {
|
||||||
if (warningBox.showLegacy)
|
if (warningBox.showLegacy)
|
||||||
return I18n.tr("This install is still using hyprland.conf. Run dms setup to migrate before editing shortcuts in Settings.");
|
return I18n.tr("This install is still using hyprland.conf. Run dms setup to migrate before editing shortcuts in Settings.");
|
||||||
if (warningBox.showSetup)
|
if (warningBox.showSetup)
|
||||||
return I18n.tr("Click 'Setup' to create %1 and add include to config.").arg(bindsFile);
|
return I18n.tr("Click 'Setup' to create %1 and add include to your compositor config.").arg("dms/binds");
|
||||||
if (warningBox.showError)
|
|
||||||
return I18n.tr("%1 exists but is not included in config. Custom keybinds will not work until this is fixed.").arg(bindsFile);
|
|
||||||
if (warningBox.showWarning) {
|
if (warningBox.showWarning) {
|
||||||
const count = warningBox.status.overriddenBy;
|
const count = warningBox.status.overriddenBy;
|
||||||
return I18n.ntr("%1 DMS bind may be overridden by config binds that come after the include.", "%1 DMS binds may be overridden by config binds that come after the include.", count).arg(count);
|
return I18n.ntr("%1 DMS bind may be overridden by config binds that come after the include.", "%1 DMS binds may be overridden by config binds that come after the include.", count).arg(count);
|
||||||
@@ -420,14 +416,8 @@ Item {
|
|||||||
|
|
||||||
DankButton {
|
DankButton {
|
||||||
id: fixButton
|
id: fixButton
|
||||||
visible: !warningBox.showLegacy && (warningBox.showError || warningBox.showSetup)
|
visible: !warningBox.showLegacy && warningBox.showSetup
|
||||||
text: {
|
text: KeybindsService.fixing ? I18n.tr("Setting up...") : I18n.tr("Setup")
|
||||||
if (KeybindsService.fixing)
|
|
||||||
return I18n.tr("Fixing...");
|
|
||||||
if (warningBox.showSetup)
|
|
||||||
return I18n.tr("Setup");
|
|
||||||
return I18n.tr("Fix Now");
|
|
||||||
}
|
|
||||||
backgroundColor: Theme.primary
|
backgroundColor: Theme.primary
|
||||||
textColor: Theme.primaryText
|
textColor: Theme.primaryText
|
||||||
enabled: !KeybindsService.fixing
|
enabled: !KeybindsService.fixing
|
||||||
|
|||||||
@@ -2078,27 +2078,27 @@ Item {
|
|||||||
StyledRect {
|
StyledRect {
|
||||||
id: cursorWarningBox
|
id: cursorWarningBox
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: cursorWarningContent.implicitHeight + Theme.spacingM * 2
|
height: cursorWarningContent.implicitHeight + Theme.spacingL * 2
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
|
|
||||||
readonly property bool showError: themeColorsTab.cursorIncludeStatus.exists && !themeColorsTab.cursorIncludeStatus.included
|
readonly property bool showLegacy: themeColorsTab.cursorReadOnly
|
||||||
readonly property bool showSetup: !themeColorsTab.cursorIncludeStatus.exists && !themeColorsTab.cursorIncludeStatus.included
|
readonly property bool showSetup: !showLegacy && !themeColorsTab.cursorIncludeStatus.included
|
||||||
|
|
||||||
color: (showError || showSetup) ? Theme.withAlpha(Theme.warning, 0.15) : Theme.withAlpha(Theme.warning, 0)
|
color: (showLegacy || showSetup) ? Theme.withAlpha(Theme.primary, 0.15) : Theme.withAlpha(Theme.primary, 0)
|
||||||
border.color: (showError || showSetup) ? Theme.withAlpha(Theme.warning, 0.3) : Theme.withAlpha(Theme.warning, 0)
|
border.color: (showLegacy || showSetup) ? Theme.withAlpha(Theme.primary, 0.3) : Theme.withAlpha(Theme.primary, 0)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
visible: (showError || showSetup) && !themeColorsTab.checkingCursorInclude
|
visible: (showLegacy || showSetup) && !themeColorsTab.checkingCursorInclude
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
id: cursorWarningContent
|
id: cursorWarningContent
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Theme.spacingM
|
anchors.margins: Theme.spacingL
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
name: "warning"
|
name: "warning"
|
||||||
size: Theme.iconSize
|
size: Theme.iconSize
|
||||||
color: Theme.warning
|
color: Theme.primary
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2108,27 +2108,42 @@ Item {
|
|||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: cursorWarningBox.showSetup ? I18n.tr("Cursor Config Not Configured") : I18n.tr("Cursor Include Missing")
|
text: {
|
||||||
|
if (cursorWarningBox.showLegacy)
|
||||||
|
return I18n.tr("Hyprland conf mode");
|
||||||
|
if (cursorWarningBox.showSetup)
|
||||||
|
return I18n.tr("First Time Setup");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
color: Theme.warning
|
color: Theme.primary
|
||||||
|
width: parent.width
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: cursorWarningBox.showSetup ? I18n.tr("Click 'Setup' to create cursor config and add include to your compositor config.") : I18n.tr("dms/cursor config exists but is not included. Cursor settings won't apply.")
|
text: {
|
||||||
|
if (cursorWarningBox.showLegacy)
|
||||||
|
return I18n.tr("This install is still using hyprland.conf. Run dms setup to migrate before editing cursor settings.");
|
||||||
|
if (cursorWarningBox.showSetup)
|
||||||
|
return I18n.tr("Click 'Setup' to create %1 and add include to your compositor config.").arg("dms/cursor");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: Theme.surfaceVariantText
|
color: Theme.surfaceVariantText
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankButton {
|
DankButton {
|
||||||
id: cursorFixButton
|
id: cursorFixButton
|
||||||
visible: cursorWarningBox.showError || cursorWarningBox.showSetup
|
visible: !cursorWarningBox.showLegacy && cursorWarningBox.showSetup
|
||||||
text: themeColorsTab.fixingCursorInclude ? I18n.tr("Fixing...") : (cursorWarningBox.showSetup ? I18n.tr("Setup") : I18n.tr("Fix Now"))
|
text: themeColorsTab.fixingCursorInclude ? I18n.tr("Setting up...") : I18n.tr("Setup")
|
||||||
backgroundColor: Theme.warning
|
backgroundColor: Theme.primary
|
||||||
textColor: Theme.background
|
textColor: Theme.primaryText
|
||||||
enabled: !themeColorsTab.fixingCursorInclude
|
enabled: !themeColorsTab.fixingCursorInclude
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
onClicked: themeColorsTab.fixCursorInclude()
|
onClicked: themeColorsTab.fixCursorInclude()
|
||||||
|
|||||||
@@ -472,13 +472,12 @@ Item {
|
|||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
|
|
||||||
readonly property bool showLegacy: root.readOnly
|
readonly property bool showLegacy: root.readOnly
|
||||||
readonly property bool showError: !showLegacy && root.windowRulesIncludeStatus.exists && !root.windowRulesIncludeStatus.included
|
readonly property bool showSetup: !showLegacy && !root.windowRulesIncludeStatus.included
|
||||||
readonly property bool showSetup: !showLegacy && !root.windowRulesIncludeStatus.exists && !root.windowRulesIncludeStatus.included
|
|
||||||
|
|
||||||
color: (showLegacy || showError || showSetup) ? Theme.withAlpha(Theme.warning, 0.15) : Theme.withAlpha(Theme.warning, 0)
|
color: (showLegacy || showSetup) ? Theme.withAlpha(Theme.primary, 0.15) : Theme.withAlpha(Theme.primary, 0)
|
||||||
border.color: (showLegacy || showError || showSetup) ? Theme.withAlpha(Theme.warning, 0.3) : Theme.withAlpha(Theme.warning, 0)
|
border.color: (showLegacy || showSetup) ? Theme.withAlpha(Theme.primary, 0.3) : Theme.withAlpha(Theme.primary, 0)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
visible: (showLegacy || showError || showSetup) && !root.checkingInclude && (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango)
|
visible: (showLegacy || showSetup) && !root.checkingInclude && (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango)
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
id: warningSection
|
id: warningSection
|
||||||
@@ -489,7 +488,7 @@ Item {
|
|||||||
DankIcon {
|
DankIcon {
|
||||||
name: "warning"
|
name: "warning"
|
||||||
size: Theme.iconSize
|
size: Theme.iconSize
|
||||||
color: Theme.warning
|
color: Theme.primary
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,17 +498,16 @@ Item {
|
|||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: warningBox.showLegacy ? I18n.tr("Hyprland conf mode") : (warningBox.showSetup ? I18n.tr("Window Rules Not Configured") : I18n.tr("Window Rules Include Missing"))
|
text: warningBox.showLegacy ? I18n.tr("Hyprland conf mode") : I18n.tr("First Time Setup")
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
color: Theme.warning
|
color: Theme.primary
|
||||||
width: parent.width
|
width: parent.width
|
||||||
horizontalAlignment: Text.AlignLeft
|
horizontalAlignment: Text.AlignLeft
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
readonly property string rulesFile: root.dmsRulesFileName
|
text: warningBox.showLegacy ? I18n.tr("This install is still using hyprland.conf. Run dms setup to migrate before editing window rules in Settings.") : I18n.tr("Click 'Setup' to create %1 and add include to your compositor config.").arg("dms/windowrules")
|
||||||
text: warningBox.showLegacy ? I18n.tr("This install is still using hyprland.conf. Run dms setup to migrate before editing window rules in Settings.") : (warningBox.showSetup ? I18n.tr("Click 'Setup' to create %1 and add include to your compositor config.").arg(rulesFile) : I18n.tr("%1 exists but is not included. Window rules won't apply.").arg(rulesFile))
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: Theme.surfaceVariantText
|
color: Theme.surfaceVariantText
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
@@ -520,10 +518,10 @@ Item {
|
|||||||
|
|
||||||
DankButton {
|
DankButton {
|
||||||
id: fixButton
|
id: fixButton
|
||||||
visible: !warningBox.showLegacy && (warningBox.showError || warningBox.showSetup)
|
visible: !warningBox.showLegacy && warningBox.showSetup
|
||||||
text: root.fixingInclude ? I18n.tr("Fixing...") : (warningBox.showSetup ? I18n.tr("Setup") : I18n.tr("Fix Now"))
|
text: root.fixingInclude ? I18n.tr("Setting up...") : I18n.tr("Setup")
|
||||||
backgroundColor: Theme.warning
|
backgroundColor: Theme.primary
|
||||||
textColor: Theme.background
|
textColor: Theme.primaryText
|
||||||
enabled: !root.fixingInclude
|
enabled: !root.fixingInclude
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
onClicked: root.fixWindowRulesInclude()
|
onClicked: root.fixWindowRulesInclude()
|
||||||
|
|||||||
@@ -1252,7 +1252,7 @@ Singleton {
|
|||||||
commands.push(`niri msg output "${outputName}" ${config.disabled ? "off" : "on"}`);
|
commands.push(`niri msg output "${outputName}" ${config.disabled ? "off" : "on"}`);
|
||||||
if (config.disabled) {
|
if (config.disabled) {
|
||||||
const fullDisableCommand = "{ " + commands.join(" && ") + "; } 2>&1";
|
const fullDisableCommand = "{ " + commands.join(" && ") + "; } 2>&1";
|
||||||
Proc.runCommand("niri-output-config", ["sh", "-c", fullDisableCommand], (output, exitCode) => {
|
Proc.runCommand("niri-output-config-" + outputName, ["sh", "-c", fullDisableCommand], (output, exitCode) => {
|
||||||
if (exitCode !== 0) {
|
if (exitCode !== 0) {
|
||||||
log.warn("Failed to apply output config:", outputName, "exit:", exitCode, output);
|
log.warn("Failed to apply output config:", outputName, "exit:", exitCode, output);
|
||||||
if (callback)
|
if (callback)
|
||||||
@@ -1296,7 +1296,7 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const fullCommand = "{ " + commands.join(" && ") + "; } 2>&1";
|
const fullCommand = "{ " + commands.join(" && ") + "; } 2>&1";
|
||||||
Proc.runCommand("niri-output-config", ["sh", "-c", fullCommand], (output, exitCode) => {
|
Proc.runCommand("niri-output-config-" + outputName, ["sh", "-c", fullCommand], (output, exitCode) => {
|
||||||
if (exitCode !== 0) {
|
if (exitCode !== 0) {
|
||||||
log.warn("Failed to apply output config:", outputName, "exit:", exitCode, output);
|
log.warn("Failed to apply output config:", outputName, "exit:", exitCode, output);
|
||||||
if (callback)
|
if (callback)
|
||||||
|
|||||||
Reference in New Issue
Block a user