mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-24 21:42:51 -05:00
displays: add configurator for niri, Hyprland, and MangoWC
- Configure position, VRR, orientation, resolution, refresh rate - Split Display section into Configuration, Gamma, and Widgets - MangoWC omits VRR because it doesnt have per-display VRR - HDR configuration not present for Hyprland
This commit is contained in:
125
quickshell/Services/HyprlandService.qml
Normal file
125
quickshell/Services/HyprlandService.qml
Normal file
@@ -0,0 +1,125 @@
|
||||
pragma Singleton
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtCore
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import qs.Common
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
readonly property string configDir: Paths.strip(StandardPaths.writableLocation(StandardPaths.ConfigLocation))
|
||||
readonly property string hyprDmsDir: configDir + "/hypr/dms"
|
||||
readonly property string outputsPath: hyprDmsDir + "/outputs.conf"
|
||||
|
||||
function getOutputIdentifier(output, outputName) {
|
||||
if (SettingsData.displayNameMode === "model" && output.make && output.model) {
|
||||
return "desc:" + output.make + " " + output.model;
|
||||
}
|
||||
return outputName;
|
||||
}
|
||||
|
||||
function generateOutputsConfig(outputsData) {
|
||||
if (!outputsData || Object.keys(outputsData).length === 0)
|
||||
return;
|
||||
let lines = ["# Auto-generated by DMS - do not edit manually", ""];
|
||||
|
||||
for (const outputName in outputsData) {
|
||||
const output = outputsData[outputName];
|
||||
if (!output)
|
||||
continue;
|
||||
let resolution = "preferred";
|
||||
if (output.modes && output.current_mode !== undefined) {
|
||||
const mode = output.modes[output.current_mode];
|
||||
if (mode)
|
||||
resolution = mode.width + "x" + mode.height + "@" + (mode.refresh_rate / 1000).toFixed(3);
|
||||
}
|
||||
|
||||
const x = output.logical?.x ?? 0;
|
||||
const y = output.logical?.y ?? 0;
|
||||
const position = x + "x" + y;
|
||||
|
||||
const scale = output.logical?.scale ?? 1.0;
|
||||
|
||||
const identifier = getOutputIdentifier(output, outputName);
|
||||
let monitorLine = "monitor = " + identifier + ", " + resolution + ", " + position + ", " + scale;
|
||||
|
||||
const transform = transformToHyprland(output.logical?.transform ?? "Normal");
|
||||
if (transform !== 0)
|
||||
monitorLine += ", transform, " + transform;
|
||||
|
||||
if (output.vrr_supported && output.vrr_enabled)
|
||||
monitorLine += ", vrr, 1";
|
||||
|
||||
lines.push(monitorLine);
|
||||
}
|
||||
|
||||
lines.push("");
|
||||
|
||||
const content = lines.join("\n");
|
||||
|
||||
Proc.runCommand("hypr-write-outputs", ["sh", "-c", `mkdir -p "${hyprDmsDir}" && cat > "${outputsPath}" << 'EOF'\n${content}EOF`], (output, exitCode) => {
|
||||
if (exitCode !== 0) {
|
||||
console.warn("HyprlandService: Failed to write outputs config:", output);
|
||||
return;
|
||||
}
|
||||
console.info("HyprlandService: Generated outputs config at", outputsPath);
|
||||
if (CompositorService.isHyprland)
|
||||
reloadConfig();
|
||||
});
|
||||
}
|
||||
|
||||
function reloadConfig() {
|
||||
Proc.runCommand("hyprctl-reload", ["hyprctl", "reload"], (output, exitCode) => {
|
||||
if (exitCode !== 0)
|
||||
console.warn("HyprlandService: hyprctl reload failed:", output);
|
||||
});
|
||||
}
|
||||
|
||||
function transformToHyprland(transform) {
|
||||
switch (transform) {
|
||||
case "Normal":
|
||||
return 0;
|
||||
case "90":
|
||||
return 1;
|
||||
case "180":
|
||||
return 2;
|
||||
case "270":
|
||||
return 3;
|
||||
case "Flipped":
|
||||
return 4;
|
||||
case "Flipped90":
|
||||
return 5;
|
||||
case "Flipped180":
|
||||
return 6;
|
||||
case "Flipped270":
|
||||
return 7;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
function hyprlandToTransform(value) {
|
||||
switch (value) {
|
||||
case 0:
|
||||
return "Normal";
|
||||
case 1:
|
||||
return "90";
|
||||
case 2:
|
||||
return "180";
|
||||
case 3:
|
||||
return "270";
|
||||
case 4:
|
||||
return "Flipped";
|
||||
case 5:
|
||||
return "Flipped90";
|
||||
case 6:
|
||||
return "Flipped180";
|
||||
case 7:
|
||||
return "Flipped270";
|
||||
default:
|
||||
return "Normal";
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user