mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
add missing files
This commit is contained in:
@@ -452,7 +452,8 @@
|
||||
"brightness": {
|
||||
"brightnessStep": 5,
|
||||
"enforceMinimum": true,
|
||||
"enableDdcSupport": false
|
||||
"enableDdcSupport": false,
|
||||
"backlightDeviceMappings": []
|
||||
},
|
||||
"colorSchemes": {
|
||||
"useWallpaperColors": false,
|
||||
@@ -496,4 +497,4 @@
|
||||
"gridSnap": false,
|
||||
"monitorWidgets": []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -493,6 +493,15 @@
|
||||
"subTab": 0,
|
||||
"subTabLabel": "common.brightness"
|
||||
},
|
||||
{
|
||||
"labelKey": "panels.display.monitors-backlight-device-label",
|
||||
"descriptionKey": "panels.display.monitors-backlight-device-description",
|
||||
"widget": "NComboBox",
|
||||
"tab": 14,
|
||||
"tabLabel": "panels.display.title",
|
||||
"subTab": 0,
|
||||
"subTabLabel": "common.brightness"
|
||||
},
|
||||
{
|
||||
"labelKey": "panels.display.monitors-enforce-minimum-label",
|
||||
"descriptionKey": "panels.display.monitors-enforce-minimum-description",
|
||||
@@ -1953,4 +1962,4 @@
|
||||
"subTab": 1,
|
||||
"subTabLabel": "common.look"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -663,6 +663,8 @@ Singleton {
|
||||
property int brightnessStep: 5
|
||||
property bool enforceMinimum: true
|
||||
property bool enableDdcSupport: false
|
||||
property list<var> backlightDeviceMappings: []
|
||||
// Format: [{ "output": "eDP-1", "device": "/sys/class/backlight/intel_backlight" }]
|
||||
}
|
||||
|
||||
property JsonObject colorSchemes: JsonObject {
|
||||
|
||||
@@ -25,6 +25,32 @@ ColumnLayout {
|
||||
property var brightnessMonitor: BrightnessService.getMonitorForScreen(modelData)
|
||||
property real localBrightness: 0.5
|
||||
property bool localBrightnessChanging: false
|
||||
readonly property string automaticOptionLabel: {
|
||||
var baseLabel = I18n.tr("panels.display.monitors-backlight-device-auto-option");
|
||||
var autoDevicePath = (BrightnessService.availableBacklightDevices && BrightnessService.availableBacklightDevices.length > 0) ? BrightnessService.availableBacklightDevices[0] : "";
|
||||
if (autoDevicePath === "")
|
||||
return baseLabel;
|
||||
|
||||
var autoDeviceName = BrightnessService.getBacklightDeviceName(autoDevicePath) || autoDevicePath;
|
||||
return baseLabel + "(" + autoDeviceName + ")";
|
||||
}
|
||||
readonly property var backlightDeviceOptions: {
|
||||
var options = [{
|
||||
"key": "",
|
||||
"name": automaticOptionLabel
|
||||
}];
|
||||
|
||||
var devices = BrightnessService.availableBacklightDevices || [];
|
||||
for (var i = 0; i < devices.length; i++) {
|
||||
var devicePath = devices[i];
|
||||
var deviceName = BrightnessService.getBacklightDeviceName(devicePath) || devicePath;
|
||||
options.push({
|
||||
"key": devicePath,
|
||||
"name": deviceName
|
||||
});
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
onBrightnessMonitorChanged: {
|
||||
if (brightnessMonitor && !localBrightnessChanging)
|
||||
@@ -160,13 +186,23 @@ ColumnLayout {
|
||||
}
|
||||
|
||||
NText {
|
||||
visible: brightnessMonitor && !brightnessMonitor.brightnessControlAvailable
|
||||
visible: brightnessMonitor && !brightnessMonitor.brightnessControlAvailable && !(brightnessMonitor.method === "internal" && brightnessMonitor.initInProgress)
|
||||
text: !Settings.data.brightness.enableDdcSupport ? I18n.tr("panels.display.monitors-brightness-unavailable-ddc-disabled") : I18n.tr("panels.display.monitors-brightness-unavailable-generic")
|
||||
pointSize: Style.fontSizeXS
|
||||
color: Color.mOnSurfaceVariant
|
||||
Layout.fillWidth: true
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
NComboBox {
|
||||
Layout.fillWidth: true
|
||||
visible: brightnessMonitor && brightnessMonitor.method === "internal"
|
||||
label: I18n.tr("panels.display.monitors-backlight-device-label")
|
||||
description: I18n.tr("panels.display.monitors-backlight-device-description")
|
||||
model: backlightDeviceOptions
|
||||
currentKey: BrightnessService.getMappedBacklightDevice(modelData.name) || ""
|
||||
onSelected: key => BrightnessService.setMappedBacklightDevice(modelData.name, key)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ Singleton {
|
||||
property list<var> ddcMonitors: []
|
||||
readonly property list<Monitor> monitors: variants.instances
|
||||
property bool appleDisplayPresent: false
|
||||
property list<var> availableBacklightDevices: []
|
||||
|
||||
function getMonitorForScreen(screen: ShellScreen): var {
|
||||
return monitors.find(m => m.modelData === screen);
|
||||
@@ -47,10 +48,109 @@ Singleton {
|
||||
return detectedDisplays;
|
||||
}
|
||||
|
||||
function normalizeBacklightDevicePath(devicePath): string {
|
||||
if (devicePath === undefined || devicePath === null)
|
||||
return "";
|
||||
|
||||
var normalized = String(devicePath).trim();
|
||||
if (normalized === "")
|
||||
return "";
|
||||
|
||||
if (normalized.startsWith("/sys/class/backlight/"))
|
||||
return normalized;
|
||||
|
||||
if (normalized.indexOf("/") === -1)
|
||||
return "/sys/class/backlight/" + normalized;
|
||||
|
||||
return normalized;
|
||||
}
|
||||
|
||||
function getBacklightDeviceName(devicePath): string {
|
||||
var normalized = normalizeBacklightDevicePath(devicePath);
|
||||
if (normalized === "")
|
||||
return "";
|
||||
|
||||
var parts = normalized.split("/");
|
||||
while (parts.length > 0 && parts[parts.length - 1] === "") {
|
||||
parts.pop();
|
||||
}
|
||||
return parts.length > 0 ? parts[parts.length - 1] : "";
|
||||
}
|
||||
|
||||
function getMappedBacklightDevice(outputName): string {
|
||||
var normalizedOutput = String(outputName || "").trim();
|
||||
if (normalizedOutput === "")
|
||||
return "";
|
||||
|
||||
var mappings = Settings.data.brightness.backlightDeviceMappings || [];
|
||||
for (var i = 0; i < mappings.length; i++) {
|
||||
var mapping = mappings[i];
|
||||
if (!mapping || typeof mapping !== "object")
|
||||
continue;
|
||||
|
||||
if (String(mapping.output || "").trim() === normalizedOutput)
|
||||
return normalizeBacklightDevicePath(mapping.device || "");
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
function setMappedBacklightDevice(outputName, devicePath): void {
|
||||
var normalizedOutput = String(outputName || "").trim();
|
||||
if (normalizedOutput === "")
|
||||
return;
|
||||
|
||||
var normalizedDevicePath = normalizeBacklightDevicePath(devicePath);
|
||||
var mappings = Settings.data.brightness.backlightDeviceMappings || [];
|
||||
var nextMappings = [];
|
||||
var replaced = false;
|
||||
|
||||
for (var i = 0; i < mappings.length; i++) {
|
||||
var mapping = mappings[i];
|
||||
if (!mapping || typeof mapping !== "object")
|
||||
continue;
|
||||
|
||||
var mappingOutput = String(mapping.output || "").trim();
|
||||
var mappingDevice = normalizeBacklightDevicePath(mapping.device || "");
|
||||
if (mappingOutput === "" || mappingDevice === "")
|
||||
continue;
|
||||
|
||||
if (mappingOutput === normalizedOutput) {
|
||||
if (!replaced && normalizedDevicePath !== "") {
|
||||
nextMappings.push({
|
||||
"output": normalizedOutput,
|
||||
"device": normalizedDevicePath
|
||||
});
|
||||
}
|
||||
replaced = true;
|
||||
} else {
|
||||
nextMappings.push({
|
||||
"output": mappingOutput,
|
||||
"device": mappingDevice
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (!replaced && normalizedDevicePath !== "") {
|
||||
nextMappings.push({
|
||||
"output": normalizedOutput,
|
||||
"device": normalizedDevicePath
|
||||
});
|
||||
}
|
||||
|
||||
Settings.data.brightness.backlightDeviceMappings = nextMappings;
|
||||
}
|
||||
|
||||
function scanBacklightDevices(): void {
|
||||
if (!scanBacklightProc.running)
|
||||
scanBacklightProc.running = true;
|
||||
}
|
||||
|
||||
reloadableId: "brightness"
|
||||
|
||||
Component.onCompleted: {
|
||||
Logger.i("Brightness", "Service started");
|
||||
scanBacklightDevices();
|
||||
if (Settings.data.brightness.enableDdcSupport) {
|
||||
ddcProc.running = true;
|
||||
}
|
||||
@@ -58,6 +158,7 @@ Singleton {
|
||||
|
||||
onMonitorsChanged: {
|
||||
ddcMonitors = [];
|
||||
scanBacklightDevices();
|
||||
if (Settings.data.brightness.enableDdcSupport) {
|
||||
ddcProc.running = true;
|
||||
}
|
||||
@@ -75,6 +176,14 @@ Singleton {
|
||||
ddcMonitors = [];
|
||||
}
|
||||
}
|
||||
function onBacklightDeviceMappingsChanged() {
|
||||
scanBacklightDevices();
|
||||
for (var i = 0; i < monitors.length; i++) {
|
||||
var m = monitors[i];
|
||||
if (m && !m.isDdc && !m.isAppleDisplay)
|
||||
m.initBrightness();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Variants {
|
||||
@@ -92,6 +201,34 @@ Singleton {
|
||||
}
|
||||
}
|
||||
|
||||
// Detect available internal backlight devices
|
||||
Process {
|
||||
id: scanBacklightProc
|
||||
command: ["sh", "-c", "for dev in /sys/class/backlight/*; do if [ -f \"$dev/brightness\" ] && [ -f \"$dev/max_brightness\" ]; then echo \"$dev\"; fi; done"]
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
var data = text.trim();
|
||||
if (data === "") {
|
||||
root.availableBacklightDevices = [];
|
||||
return;
|
||||
}
|
||||
|
||||
var lines = data.split("\n");
|
||||
var found = [];
|
||||
var seen = ({});
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
var path = root.normalizeBacklightDevicePath(lines[i]);
|
||||
if (path === "" || seen[path])
|
||||
continue;
|
||||
seen[path] = true;
|
||||
found.push(path);
|
||||
}
|
||||
|
||||
root.availableBacklightDevices = found;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Detect DDC monitors
|
||||
Process {
|
||||
id: ddcProc
|
||||
@@ -152,6 +289,7 @@ Singleton {
|
||||
property string maxBrightnessPath: ""
|
||||
property int maxBrightness: 100
|
||||
property bool ignoreNextChange: false
|
||||
property bool initInProgress: false
|
||||
|
||||
// Signal for brightness changes
|
||||
signal brightnessUpdated(real newBrightness)
|
||||
@@ -296,14 +434,22 @@ Singleton {
|
||||
Logger.d("Brightness", "Internal brightness:", current + "/" + max + " =", monitor.brightness);
|
||||
Logger.d("Brightness", "Using backlight device:", monitor.backlightDevice);
|
||||
}
|
||||
} else {
|
||||
monitor.backlightDevice = "";
|
||||
monitor.brightnessPath = "";
|
||||
monitor.maxBrightnessPath = "";
|
||||
}
|
||||
}
|
||||
|
||||
// Always update
|
||||
monitor.brightnessUpdated(monitor.brightness);
|
||||
root.monitorBrightnessChanged(monitor, monitor.brightness);
|
||||
monitor.initInProgress = false;
|
||||
}
|
||||
}
|
||||
onExited: (exitCode, exitStatus) => {
|
||||
monitor.initInProgress = false;
|
||||
}
|
||||
}
|
||||
|
||||
readonly property real stepSize: Settings.data.brightness.brightnessStep / 100.0
|
||||
@@ -379,12 +525,18 @@ Singleton {
|
||||
} else if (!isDdc) {
|
||||
monitor.commandRunning = true;
|
||||
monitor.ignoreNextChange = true;
|
||||
setBrightnessProc.command = ["brightnessctl", "s", rounded + "%"];
|
||||
var backlightDeviceName = root.getBacklightDeviceName(monitor.backlightDevice);
|
||||
if (backlightDeviceName !== "") {
|
||||
setBrightnessProc.command = ["brightnessctl", "-d", backlightDeviceName, "s", rounded + "%"];
|
||||
} else {
|
||||
setBrightnessProc.command = ["brightnessctl", "s", rounded + "%"];
|
||||
}
|
||||
setBrightnessProc.running = true;
|
||||
}
|
||||
}
|
||||
|
||||
function initBrightness(): void {
|
||||
monitor.initInProgress = true;
|
||||
if (isAppleDisplay) {
|
||||
initProc.command = ["asdbctl", "get"];
|
||||
initProc.running = true;
|
||||
@@ -392,16 +544,24 @@ Singleton {
|
||||
initProc.command = ["ddcutil", "-b", busNum, "--sleep-multiplier=0.05", "getvcp", "10", "--brief"];
|
||||
initProc.running = true;
|
||||
} else if (!isDdc) {
|
||||
// Internal backlight - find the first available backlight device and get its info
|
||||
// This now returns: device_path, current_brightness, max_brightness (on separate lines)
|
||||
initProc.command = ["sh", "-c", "for dev in /sys/class/backlight/*; do " + " if [ -f \"$dev/brightness\" ] && [ -f \"$dev/max_brightness\" ]; then " + " echo \"$dev\"; " + " cat \"$dev/brightness\"; " + " cat \"$dev/max_brightness\"; " + " break; " + " fi; " + "done"];
|
||||
// Internal backlight: first try explicit output mapping, then fall back to first available.
|
||||
var preferredDevicePath = root.getMappedBacklightDevice(modelData.name);
|
||||
var probeScript = [
|
||||
"preferred=\"$1\"",
|
||||
"if [ -n \"$preferred\" ] && [ ! -d \"$preferred\" ]; then preferred=\"/sys/class/backlight/$preferred\"; fi",
|
||||
"selected=\"\"",
|
||||
"if [ -n \"$preferred\" ] && [ -f \"$preferred/brightness\" ] && [ -f \"$preferred/max_brightness\" ]; then selected=\"$preferred\"; else for dev in /sys/class/backlight/*; do if [ -f \"$dev/brightness\" ] && [ -f \"$dev/max_brightness\" ]; then selected=\"$dev\"; break; fi; done; fi",
|
||||
"if [ -n \"$selected\" ]; then echo \"$selected\"; cat \"$selected/brightness\"; cat \"$selected/max_brightness\"; fi"
|
||||
].join("; ");
|
||||
initProc.command = ["sh", "-c", probeScript, "sh", preferredDevicePath];
|
||||
initProc.running = true;
|
||||
} else {
|
||||
monitor.initInProgress = false;
|
||||
}
|
||||
}
|
||||
|
||||
onBusNumChanged: initBrightness()
|
||||
onIsDdcChanged: if (isDdc)
|
||||
initBrightness()
|
||||
onIsDdcChanged: initBrightness()
|
||||
Component.onCompleted: initBrightness()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user