mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-04-03 20:32:07 -04:00
displays: add full screen only for hyprland and convert vrr to dropdown
fixes #1649 fixes #1548
This commit is contained in:
@@ -391,8 +391,12 @@ Singleton {
|
||||
const filtered = filterDisconnectedOnly(parsed);
|
||||
savedOutputs = filtered;
|
||||
|
||||
if (CompositorService.isHyprland)
|
||||
if (CompositorService.isHyprland) {
|
||||
initHyprlandSettingsFromConfig(parsed);
|
||||
syncHyprlandVrrFromConfig(parsed);
|
||||
}
|
||||
if (CompositorService.isNiri)
|
||||
syncNiriVrrFromConfig(parsed);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -431,6 +435,44 @@ Singleton {
|
||||
}
|
||||
}
|
||||
|
||||
function syncHyprlandVrrFromConfig(parsedOutputs) {
|
||||
const current = JSON.parse(JSON.stringify(SettingsData.hyprlandOutputSettings));
|
||||
let changed = false;
|
||||
for (const outputName in parsedOutputs) {
|
||||
const settings = parsedOutputs[outputName]?.hyprlandSettings;
|
||||
const fromConfig = settings?.vrrFullscreenOnly ?? false;
|
||||
const stored = current[outputName]?.vrrFullscreenOnly ?? false;
|
||||
if (fromConfig === stored)
|
||||
continue;
|
||||
if (!current[outputName])
|
||||
current[outputName] = {};
|
||||
if (fromConfig)
|
||||
current[outputName].vrrFullscreenOnly = true;
|
||||
else
|
||||
delete current[outputName].vrrFullscreenOnly;
|
||||
changed = true;
|
||||
}
|
||||
if (changed) {
|
||||
SettingsData.hyprlandOutputSettings = current;
|
||||
SettingsData.saveSettings();
|
||||
}
|
||||
}
|
||||
|
||||
function syncNiriVrrFromConfig(parsedOutputs) {
|
||||
let changed = false;
|
||||
for (const outputName in parsedOutputs) {
|
||||
const output = parsedOutputs[outputName];
|
||||
const current = SettingsData.getNiriOutputSetting(outputName, "vrrOnDemand", false);
|
||||
const fromConfig = output.vrr_on_demand ?? false;
|
||||
if (current === fromConfig)
|
||||
continue;
|
||||
SettingsData.setNiriOutputSetting(outputName, "vrrOnDemand", fromConfig || undefined);
|
||||
changed = true;
|
||||
}
|
||||
if (changed)
|
||||
SettingsData.saveSettings();
|
||||
}
|
||||
|
||||
function filterDisconnectedOnly(parsedOutputs) {
|
||||
const result = {};
|
||||
const liveNames = Object.keys(outputs);
|
||||
@@ -479,7 +521,8 @@ Singleton {
|
||||
const posMatch = body.match(/position\s+x=(-?\d+)\s+y=(-?\d+)/);
|
||||
const scaleMatch = body.match(/scale\s+([\d.]+)/);
|
||||
const transformMatch = body.match(/transform\s+"([^"]+)"/);
|
||||
const vrrMatch = body.match(/variable-refresh-rate(?:\s+on)?/);
|
||||
const vrrMatch = body.match(/variable-refresh-rate/);
|
||||
const vrrOnDemandMatch = body.match(/variable-refresh-rate\s+on-demand=true/);
|
||||
|
||||
result[name] = {
|
||||
"name": name,
|
||||
@@ -498,6 +541,7 @@ Singleton {
|
||||
] : [],
|
||||
"current_mode": 0,
|
||||
"vrr_enabled": !!vrrMatch,
|
||||
"vrr_on_demand": !!vrrOnDemandMatch,
|
||||
"vrr_supported": true
|
||||
};
|
||||
}
|
||||
@@ -535,7 +579,7 @@ Singleton {
|
||||
const name = match[1].trim();
|
||||
const rest = line.substring(line.indexOf(match[7]) + match[7].length);
|
||||
|
||||
let transform = 0, vrr = false, bitdepth = undefined, cm = undefined;
|
||||
let transform = 0, vrrMode = 0, bitdepth = undefined, cm = undefined;
|
||||
let sdrBrightness = undefined, sdrSaturation = undefined;
|
||||
|
||||
const transformMatch = rest.match(/,\s*transform,\s*(\d+)/);
|
||||
@@ -544,7 +588,7 @@ Singleton {
|
||||
|
||||
const vrrMatch = rest.match(/,\s*vrr,\s*(\d+)/);
|
||||
if (vrrMatch)
|
||||
vrr = vrrMatch[1] === "1";
|
||||
vrrMode = parseInt(vrrMatch[1]);
|
||||
|
||||
const bitdepthMatch = rest.match(/,\s*bitdepth,\s*(\d+)/);
|
||||
if (bitdepthMatch)
|
||||
@@ -583,13 +627,14 @@ Singleton {
|
||||
}
|
||||
],
|
||||
"current_mode": 0,
|
||||
"vrr_enabled": vrr,
|
||||
"vrr_enabled": vrrMode >= 1,
|
||||
"vrr_supported": true,
|
||||
"hyprlandSettings": {
|
||||
"bitdepth": bitdepth,
|
||||
"colorManagement": cm,
|
||||
"sdrBrightness": sdrBrightness,
|
||||
"sdrSaturation": sdrSaturation
|
||||
"sdrSaturation": sdrSaturation,
|
||||
"vrrFullscreenOnly": vrrMode === 2 ? true : undefined
|
||||
},
|
||||
"mirror": mirror
|
||||
};
|
||||
@@ -1205,6 +1250,8 @@ Singleton {
|
||||
changeDescriptions.push(outputId + ": " + I18n.tr("Force HDR") + " → " + (changes.supportsHdr ? I18n.tr("Yes") : I18n.tr("No")));
|
||||
if (changes.supportsWideColor !== undefined)
|
||||
changeDescriptions.push(outputId + ": " + I18n.tr("Force Wide Color") + " → " + (changes.supportsWideColor ? I18n.tr("Yes") : I18n.tr("No")));
|
||||
if (changes.vrrFullscreenOnly !== undefined)
|
||||
changeDescriptions.push(outputId + ": " + I18n.tr("VRR Fullscreen Only") + " → " + (changes.vrrFullscreenOnly ? I18n.tr("Enabled") : I18n.tr("Disabled")));
|
||||
}
|
||||
|
||||
if (CompositorService.isNiri) {
|
||||
@@ -1309,7 +1356,12 @@ Singleton {
|
||||
|
||||
function generateNiriOutputsKdl(outputsData, niriSettings) {
|
||||
let kdlContent = `// Auto-generated by DMS - do not edit manually\n\n`;
|
||||
for (const outputName in outputsData) {
|
||||
const sortedNames = Object.keys(outputsData).sort((a, b) => {
|
||||
const la = outputsData[a].logical || {};
|
||||
const lb = outputsData[b].logical || {};
|
||||
return (la.x ?? 0) - (lb.x ?? 0) || (la.y ?? 0) - (lb.y ?? 0);
|
||||
});
|
||||
for (const outputName of sortedNames) {
|
||||
const output = outputsData[outputName];
|
||||
const identifier = getNiriOutputIdentifier(output, outputName);
|
||||
const settings = niriSettings[identifier] || {};
|
||||
|
||||
@@ -251,7 +251,7 @@ StyledRect {
|
||||
DankToggle {
|
||||
width: parent.width
|
||||
text: I18n.tr("Variable Refresh Rate")
|
||||
visible: root.isConnected && !CompositorService.isDwl && (DisplayConfigState.outputs[root.outputName]?.vrr_supported ?? false)
|
||||
visible: root.isConnected && !CompositorService.isDwl && !CompositorService.isHyprland && !CompositorService.isNiri && (DisplayConfigState.outputs[root.outputName]?.vrr_supported ?? false)
|
||||
checked: {
|
||||
const pendingVrr = DisplayConfigState.getPendingValue(root.outputName, "vrr");
|
||||
if (pendingVrr !== undefined)
|
||||
@@ -261,13 +261,52 @@ StyledRect {
|
||||
onToggled: checked => DisplayConfigState.setPendingChange(root.outputName, "vrr", checked)
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
DankDropdown {
|
||||
width: parent.width
|
||||
text: I18n.tr("VRR On-Demand")
|
||||
description: I18n.tr("VRR activates only when applications request it")
|
||||
text: I18n.tr("Variable Refresh Rate")
|
||||
addHorizontalPadding: true
|
||||
visible: root.isConnected && CompositorService.isHyprland && (DisplayConfigState.outputs[root.outputName]?.vrr_supported ?? false)
|
||||
options: [I18n.tr("Off"), I18n.tr("On"), I18n.tr("Fullscreen Only")]
|
||||
currentValue: {
|
||||
DisplayConfigState.pendingHyprlandChanges;
|
||||
if (DisplayConfigState.getHyprlandSetting(root.outputData, root.outputName, "vrrFullscreenOnly", false))
|
||||
return I18n.tr("Fullscreen Only");
|
||||
const pendingVrr = DisplayConfigState.getPendingValue(root.outputName, "vrr");
|
||||
const vrrEnabled = pendingVrr !== undefined ? pendingVrr : (DisplayConfigState.outputs[root.outputName]?.vrr_enabled ?? false);
|
||||
if (vrrEnabled)
|
||||
return I18n.tr("On");
|
||||
return I18n.tr("Off");
|
||||
}
|
||||
onValueChanged: value => {
|
||||
const off = I18n.tr("Off");
|
||||
const fullscreen = I18n.tr("Fullscreen Only");
|
||||
DisplayConfigState.setPendingChange(root.outputName, "vrr", value !== off);
|
||||
DisplayConfigState.setHyprlandSetting(root.outputData, root.outputName, "vrrFullscreenOnly", value === fullscreen || null);
|
||||
}
|
||||
}
|
||||
|
||||
DankDropdown {
|
||||
width: parent.width
|
||||
text: I18n.tr("Variable Refresh Rate")
|
||||
addHorizontalPadding: true
|
||||
visible: root.isConnected && CompositorService.isNiri && (DisplayConfigState.outputs[root.outputName]?.vrr_supported ?? false)
|
||||
checked: DisplayConfigState.getNiriSetting(root.outputData, root.outputName, "vrrOnDemand", false)
|
||||
onToggled: checked => DisplayConfigState.setNiriSetting(root.outputData, root.outputName, "vrrOnDemand", checked)
|
||||
options: [I18n.tr("Off"), I18n.tr("On"), I18n.tr("On-Demand")]
|
||||
currentValue: {
|
||||
DisplayConfigState.pendingNiriChanges;
|
||||
if (DisplayConfigState.getNiriSetting(root.outputData, root.outputName, "vrrOnDemand", false))
|
||||
return I18n.tr("On-Demand");
|
||||
const pendingVrr = DisplayConfigState.getPendingValue(root.outputName, "vrr");
|
||||
const vrrEnabled = pendingVrr !== undefined ? pendingVrr : (DisplayConfigState.outputs[root.outputName]?.vrr_enabled ?? false);
|
||||
if (!vrrEnabled)
|
||||
return I18n.tr("Off");
|
||||
return I18n.tr("On");
|
||||
}
|
||||
onValueChanged: value => {
|
||||
const off = I18n.tr("Off");
|
||||
const onDemand = I18n.tr("On-Demand");
|
||||
DisplayConfigState.setPendingChange(root.outputName, "vrr", value !== off);
|
||||
DisplayConfigState.setNiriSetting(root.outputData, root.outputName, "vrrOnDemand", value === onDemand || null);
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
|
||||
@@ -98,8 +98,10 @@ Singleton {
|
||||
if (transform !== 0)
|
||||
monitorLine += ", transform, " + transform;
|
||||
|
||||
if (output.vrr_supported)
|
||||
monitorLine += ", vrr, " + (output.vrr_enabled ? "1" : "0");
|
||||
if (output.vrr_supported) {
|
||||
const vrrMode = outputSettings.vrrFullscreenOnly ? 2 : (output.vrr_enabled ? 1 : 0);
|
||||
monitorLine += ", vrr, " + vrrMode;
|
||||
}
|
||||
|
||||
if (output.mirror && output.mirror.length > 0)
|
||||
monitorLine += ", mirror, " + output.mirror;
|
||||
|
||||
@@ -1359,7 +1359,12 @@ Singleton {
|
||||
return;
|
||||
let kdlContent = `// Auto-generated by DMS - do not edit manually\n\n`;
|
||||
|
||||
for (const outputName in data) {
|
||||
const sortedNames = Object.keys(data).sort((a, b) => {
|
||||
const la = data[a].logical || {};
|
||||
const lb = data[b].logical || {};
|
||||
return (la.x ?? 0) - (lb.x ?? 0) || (la.y ?? 0) - (lb.y ?? 0);
|
||||
});
|
||||
for (const outputName of sortedNames) {
|
||||
const output = data[outputName];
|
||||
const identifier = getOutputIdentifier(output, outputName);
|
||||
const niriSettings = SettingsData.getNiriOutputSettings(identifier);
|
||||
@@ -1397,7 +1402,7 @@ Singleton {
|
||||
}
|
||||
}
|
||||
|
||||
if (output.vrr_enabled) {
|
||||
if (output.vrr_enabled || niriSettings.vrrOnDemand) {
|
||||
const vrrOnDemand = niriSettings.vrrOnDemand ?? false;
|
||||
kdlContent += vrrOnDemand ? ` variable-refresh-rate on-demand=true\n` : ` variable-refresh-rate\n`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user