mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
Merge pull request #1899 from yuzujr/feat/add-setting-display-backlight
feat(brightness): add per-output backlight device mapping with default fallback
This commit is contained in:
@@ -1006,6 +1006,9 @@
|
||||
"weather-show-background-description": "Zeige den Hintergrundcontainer für das Wetter-Widget an."
|
||||
},
|
||||
"display": {
|
||||
"monitors-backlight-device-auto-option": "Standard",
|
||||
"monitors-backlight-device-description": "Wählen Sie ein Backlight-Gerät für diesen Ausgang.",
|
||||
"monitors-backlight-device-label": "Backlight-Gerät",
|
||||
"monitors-brightness-step-description": "Schrittgröße für Helligkeitsänderungen anpassen (Mausrad und Tastenkürzel).",
|
||||
"monitors-brightness-step-label": "Helligkeits-Schrittgröße",
|
||||
"monitors-brightness-unavailable-ddc-disabled": "Helligkeitssteuerung nicht verfügbar. Aktivieren Sie \"Externe Helligkeitsunterstützung\", um die Helligkeit dieses Displays zu steuern.",
|
||||
|
||||
@@ -1006,6 +1006,9 @@
|
||||
"weather-show-background-description": "Show the background container for the weather widget."
|
||||
},
|
||||
"display": {
|
||||
"monitors-backlight-device-auto-option": "Default",
|
||||
"monitors-backlight-device-description": "Select a backlight device for this output.",
|
||||
"monitors-backlight-device-label": "Backlight device",
|
||||
"monitors-brightness-step-description": "Adjust the step size for brightness changes (scroll wheel and keyboard shortcuts).",
|
||||
"monitors-brightness-step-label": "Brightness step size",
|
||||
"monitors-brightness-unavailable-ddc-disabled": "Brightness control unavailable. Enable \"External brightness support\" to control this display's brightness.",
|
||||
|
||||
@@ -1006,6 +1006,9 @@
|
||||
"weather-show-background-description": "Mostrar el contenedor de fondo para el widget del clima."
|
||||
},
|
||||
"display": {
|
||||
"monitors-backlight-device-auto-option": "Predeterminado",
|
||||
"monitors-backlight-device-description": "Selecciona un dispositivo de retroiluminación para esta salida.",
|
||||
"monitors-backlight-device-label": "Dispositivo de retroiluminación",
|
||||
"monitors-brightness-step-description": "Ajusta el tamaño del paso para los cambios de brillo (rueda de desplazamiento y atajos de teclado).",
|
||||
"monitors-brightness-step-label": "Tamaño del paso de brillo",
|
||||
"monitors-brightness-unavailable-ddc-disabled": "Control de brillo no disponible. Habilita \"Soporte de brillo externo\" para controlar el brillo de esta pantalla.",
|
||||
|
||||
@@ -1006,6 +1006,9 @@
|
||||
"weather-show-background-description": "Afficher le conteneur d'arrière-plan pour le widget météo."
|
||||
},
|
||||
"display": {
|
||||
"monitors-backlight-device-auto-option": "Par défaut",
|
||||
"monitors-backlight-device-description": "Sélectionnez un périphérique de rétroéclairage pour cette sortie.",
|
||||
"monitors-backlight-device-label": "Périphérique de rétroéclairage",
|
||||
"monitors-brightness-step-description": "Ajustez l'incrément pour les changements de luminosité (molette de la souris et raccourcis clavier).",
|
||||
"monitors-brightness-step-label": "Incrément de luminosité",
|
||||
"monitors-brightness-unavailable-ddc-disabled": "Contrôle de la luminosité indisponible. Activez \"Prise en charge de la luminosité externe\" pour contrôler la luminosité de cet écran.",
|
||||
|
||||
@@ -1006,6 +1006,9 @@
|
||||
"weather-show-background-description": "Jelenítse meg az időjárás widget háttérkonténerét."
|
||||
},
|
||||
"display": {
|
||||
"monitors-backlight-device-auto-option": "Alapértelmezett",
|
||||
"monitors-backlight-device-description": "Válasszon háttérvilágítási eszközt ehhez a kimenethez.",
|
||||
"monitors-backlight-device-label": "Háttérvilágítási eszköz",
|
||||
"monitors-brightness-step-description": "Állítsa be a lépésméretet a fényerő változásokhoz (görgetőkerék és billentyűparancsok).",
|
||||
"monitors-brightness-step-label": "Fényerő lépésméret",
|
||||
"monitors-brightness-unavailable-ddc-disabled": "Fényerő vezérlés nem érhető el. Engedélyezze a \"Külső fényerő támogatás\" opciót a kijelző fényerejének szabályozásához.",
|
||||
|
||||
@@ -1006,6 +1006,9 @@
|
||||
"weather-show-background-description": "天気ウィジェットの背景コンテナを表示します。"
|
||||
},
|
||||
"display": {
|
||||
"monitors-backlight-device-auto-option": "デフォルト",
|
||||
"monitors-backlight-device-description": "この出力に使用するバックライトデバイスを選択します。",
|
||||
"monitors-backlight-device-label": "バックライトデバイス",
|
||||
"monitors-brightness-step-description": "明るさの変化量(スクロールホイールやショートカットキー)を調整します。",
|
||||
"monitors-brightness-step-label": "明るさの調整ステップ",
|
||||
"monitors-brightness-unavailable-ddc-disabled": "明るさ調整を利用できません。このディスプレイを操作するには「外部ディスプレイの明るさ制御」を有効にしてください。",
|
||||
|
||||
@@ -1006,6 +1006,9 @@
|
||||
"weather-show-background-description": "날씨 위젯의 배경 컨테이너를 표시합니다."
|
||||
},
|
||||
"display": {
|
||||
"monitors-backlight-device-auto-option": "기본값",
|
||||
"monitors-backlight-device-description": "이 출력에 사용할 백라이트 장치를 선택하세요.",
|
||||
"monitors-backlight-device-label": "백라이트 장치",
|
||||
"monitors-brightness-step-description": "밝기 변경(스크롤 휠 및 키보드 단축키)의 단계 크기를 조정합니다.",
|
||||
"monitors-brightness-step-label": "밝기 단계 크기",
|
||||
"monitors-brightness-unavailable-ddc-disabled": "밝기 제어를 사용할 수 없습니다. 이 디스플레이의 밝기를 제어하려면 \"외부 밝기 지원\"을 활성화하세요.",
|
||||
|
||||
@@ -926,6 +926,9 @@
|
||||
"weather-show-background-description": "Konteynera paşrûyê ya sepanokê rewşa bayê nîşan bide."
|
||||
},
|
||||
"display": {
|
||||
"monitors-backlight-device-auto-option": "Xwerû",
|
||||
"monitors-backlight-device-description": "Ji bo vê derketinê amûra ronahiya paşîn hilbijêre.",
|
||||
"monitors-backlight-device-label": "Amûra ronahiya paşîn",
|
||||
"monitors-brightness-step-description": "Pîvana gava guhertinên ronahiyê (tekerê mişkê û kurteriyên klavyeyê) eyar bike.",
|
||||
"monitors-brightness-step-label": "Mezinahiya gava ronahiyê",
|
||||
"monitors-brightness-unavailable-ddc-disabled": "Kontrola ronahiyê peyda nabe. Ji bo kontrolkirina ronahiya vê dîmenderê, \"Piştgiriya ronahiya derveyî\" çalak bike.",
|
||||
|
||||
@@ -1006,6 +1006,9 @@
|
||||
"weather-show-background-description": "Toon de achtergrondcontainer voor de weerwidget."
|
||||
},
|
||||
"display": {
|
||||
"monitors-backlight-device-auto-option": "Standaard",
|
||||
"monitors-backlight-device-description": "Selecteer een backlightapparaat voor deze uitgang.",
|
||||
"monitors-backlight-device-label": "Backlightapparaat",
|
||||
"monitors-brightness-step-description": "Pas de stapgrootte voor helderheidswijzigingen aan (scrollwiel en sneltoetsen).",
|
||||
"monitors-brightness-step-label": "Stapgrootte helderheid",
|
||||
"monitors-brightness-unavailable-ddc-disabled": "Helderheidsregeling niet beschikbaar. Schakel \"Ondersteuning voor externe helderheid\" in om de helderheid van dit scherm te regelen.",
|
||||
|
||||
@@ -207,6 +207,13 @@
|
||||
"width-description": "Rombreidd i molar."
|
||||
}
|
||||
},
|
||||
"panels": {
|
||||
"display": {
|
||||
"monitors-backlight-device-auto-option": "Fyrevald",
|
||||
"monitors-backlight-device-description": "Vel ei bakgrunnslyseining for denne utgangen.",
|
||||
"monitors-backlight-device-label": "Bakgrunnslyseining"
|
||||
}
|
||||
},
|
||||
"common": {
|
||||
"brightness": "Ljosstyrke",
|
||||
"select-color-description": "Lita med hamlitene for tyngd."
|
||||
|
||||
@@ -990,6 +990,9 @@
|
||||
"weather-show-background-description": "Viser bakgrunnsilåt for miniprogrammet for vêr."
|
||||
},
|
||||
"display": {
|
||||
"monitors-backlight-device-auto-option": "Standard",
|
||||
"monitors-backlight-device-description": "Vel ei bakgrunnslyseining for denne utgangen.",
|
||||
"monitors-backlight-device-label": "Bakgrunnslyseining",
|
||||
"monitors-brightness-step-description": "Endra på kor store endringane i ljosstyrke er med beinvegar og rullehjul.",
|
||||
"monitors-brightness-step-label": "Ljosstyrkesteg",
|
||||
"monitors-brightness-unavailable-ddc-disabled": "Kan ikkje endra på ljosstyrke. Slå på \"Ekstern ljosstyrkestøtte\" for å endra på ljosstyrken på denne skjermen.",
|
||||
|
||||
@@ -1006,6 +1006,9 @@
|
||||
"weather-show-background-description": "Pokaż tło dla widżetu pogody."
|
||||
},
|
||||
"display": {
|
||||
"monitors-backlight-device-auto-option": "Domyślny",
|
||||
"monitors-backlight-device-description": "Wybierz urządzenie podświetlenia dla tego wyjścia.",
|
||||
"monitors-backlight-device-label": "Urządzenie podświetlenia",
|
||||
"monitors-brightness-step-description": "Dostosuj skok zmiany jasności (kółko myszy i skróty klawiszowe).",
|
||||
"monitors-brightness-step-label": "Skok jasności",
|
||||
"monitors-brightness-unavailable-ddc-disabled": "Sterowanie jasnością niedostępne. Włącz \"Obsługa zewnętrznej jasności\", aby sterować jasnością tego ekranu.",
|
||||
|
||||
@@ -1006,6 +1006,9 @@
|
||||
"weather-show-background-description": "Mostrar o contêiner de fundo para o widget de clima."
|
||||
},
|
||||
"display": {
|
||||
"monitors-backlight-device-auto-option": "Padrão",
|
||||
"monitors-backlight-device-description": "Selecione um dispositivo de retroiluminação para esta saída.",
|
||||
"monitors-backlight-device-label": "Dispositivo de retroiluminação",
|
||||
"monitors-brightness-step-description": "Ajuste o tamanho do passo para alterações de brilho (roda do mouse e atalhos de teclado).",
|
||||
"monitors-brightness-step-label": "Tamanho do passo do brilho",
|
||||
"monitors-brightness-unavailable-ddc-disabled": "Controle de brilho indisponível. Ative \"Suporte de brilho externo\" para controlar o brilho desta tela.",
|
||||
|
||||
@@ -1006,6 +1006,9 @@
|
||||
"weather-show-background-description": "Показать фоновый контейнер для погодного виджета."
|
||||
},
|
||||
"display": {
|
||||
"monitors-backlight-device-auto-option": "По умолчанию",
|
||||
"monitors-backlight-device-description": "Выберите устройство подсветки для этого выхода.",
|
||||
"monitors-backlight-device-label": "Устройство подсветки",
|
||||
"monitors-brightness-step-description": "Настройка шага изменения яркости (колесо прокрутки и сочетания клавиш).",
|
||||
"monitors-brightness-step-label": "Шаг изменения яркости",
|
||||
"monitors-brightness-unavailable-ddc-disabled": "Управление яркостью недоступно. Включите \"Поддержка внешней яркости\", чтобы управлять яркостью этого дисплея.",
|
||||
|
||||
@@ -1006,6 +1006,9 @@
|
||||
"weather-show-background-description": "Visa bakgrundsbehållaren för väderwidgeten."
|
||||
},
|
||||
"display": {
|
||||
"monitors-backlight-device-auto-option": "Standard",
|
||||
"monitors-backlight-device-description": "Välj en bakgrundsbelysningsenhet för den här utgången.",
|
||||
"monitors-backlight-device-label": "Bakgrundsbelysningsenhet",
|
||||
"monitors-brightness-step-description": "Justera stegstorleken för ljusstyrkeändringar (rullhjul och kortkommandon).",
|
||||
"monitors-brightness-step-label": "Ljusstyrkestegstorlek",
|
||||
"monitors-brightness-unavailable-ddc-disabled": "Ljusstyrkekontroll otillgänglig. Aktivera \"Extern ljusstyrkestöd\"för att kontrollera ljusstyrkan på denna skärm.",
|
||||
|
||||
@@ -1006,6 +1006,9 @@
|
||||
"weather-show-background-description": "Hava durumu widget'ı için arka plan konteynerini göster."
|
||||
},
|
||||
"display": {
|
||||
"monitors-backlight-device-auto-option": "Varsayılan",
|
||||
"monitors-backlight-device-description": "Bu çıkış için bir arka aydınlatma aygıtı seçin.",
|
||||
"monitors-backlight-device-label": "Arka aydınlatma aygıtı",
|
||||
"monitors-brightness-step-description": "Parlaklık değişimleri için adım boyutunu ayarlayın (tekerlek ve klavye kısayolları).",
|
||||
"monitors-brightness-step-label": "Parlaklık adım boyutu",
|
||||
"monitors-brightness-unavailable-ddc-disabled": "Parlaklık kontrolü kullanılamıyor. Bu ekranın parlaklığını kontrol etmek için \"Harici parlaklık desteği\"ni etkinleştirin.",
|
||||
|
||||
@@ -1006,6 +1006,9 @@
|
||||
"weather-show-background-description": "Показати фоновий контейнер для погодного віджета."
|
||||
},
|
||||
"display": {
|
||||
"monitors-backlight-device-auto-option": "За замовчуванням",
|
||||
"monitors-backlight-device-description": "Виберіть пристрій підсвітки для цього виходу.",
|
||||
"monitors-backlight-device-label": "Пристрій підсвітки",
|
||||
"monitors-brightness-step-description": "Налаштуйте крок зміни яскравості (колесо миші та гарячі клавіші).",
|
||||
"monitors-brightness-step-label": "Крок зміни яскравості",
|
||||
"monitors-brightness-unavailable-ddc-disabled": "Регулювання яскравості недоступне. Увімкніть \"Підтримку зовнішньої яскравості\", щоб керувати яскравістю цього дисплея.",
|
||||
|
||||
@@ -1006,6 +1006,9 @@
|
||||
"weather-show-background-description": "显示天气小部件的背景容器。"
|
||||
},
|
||||
"display": {
|
||||
"monitors-backlight-device-auto-option": "默认",
|
||||
"monitors-backlight-device-description": "为此输出选择一个背光设备。",
|
||||
"monitors-backlight-device-label": "背光设备",
|
||||
"monitors-brightness-step-description": "调整亮度变化的步长(滚轮和键盘快捷键)。",
|
||||
"monitors-brightness-step-label": "亮度步长",
|
||||
"monitors-brightness-unavailable-ddc-disabled": "亮度控制不可用。启用“外部亮度支持”以控制此显示器的亮度。",
|
||||
|
||||
@@ -1006,6 +1006,9 @@
|
||||
"weather-show-background-description": "顯示天氣小工具的填充背景"
|
||||
},
|
||||
"display": {
|
||||
"monitors-backlight-device-auto-option": "預設",
|
||||
"monitors-backlight-device-description": "為此輸出選擇一個背光裝置。",
|
||||
"monitors-backlight-device-label": "背光裝置",
|
||||
"monitors-brightness-step-description": "微調亮度調整一格的大小 (滾輪及鍵盤快捷鍵)",
|
||||
"monitors-brightness-step-label": "亮度步進大小",
|
||||
"monitors-brightness-unavailable-ddc-disabled": "無法使用亮度控制, 啟用 \"外部亮度調整支援\" 來控制這個顯示器的亮度",
|
||||
|
||||
@@ -460,7 +460,8 @@
|
||||
"brightness": {
|
||||
"brightnessStep": 5,
|
||||
"enforceMinimum": true,
|
||||
"enableDdcSupport": false
|
||||
"enableDdcSupport": false,
|
||||
"backlightDeviceMappings": []
|
||||
},
|
||||
"colorSchemes": {
|
||||
"useWallpaperColors": false,
|
||||
@@ -505,4 +506,4 @@
|
||||
"gridSnap": false,
|
||||
"monitorWidgets": []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -528,6 +528,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",
|
||||
@@ -2024,4 +2033,4 @@
|
||||
"subTab": 1,
|
||||
"subTabLabel": "common.look"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -670,6 +670,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 {
|
||||
|
||||
@@ -325,13 +325,29 @@ Item {
|
||||
highlightOverlay.opacity = 0;
|
||||
}
|
||||
|
||||
// Find and highlight a widget by its label key
|
||||
function isEffectivelyVisible(item) {
|
||||
var current = item;
|
||||
while (current) {
|
||||
if (current.visible === false)
|
||||
return false;
|
||||
if (current.opacity !== undefined && current.opacity <= 0)
|
||||
return false;
|
||||
current = current.parent;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Find and highlight a widget by its label key.
|
||||
function findAndHighlightWidget(item, labelKey) {
|
||||
if (!item)
|
||||
return null;
|
||||
|
||||
// Check if this item has a matching label
|
||||
if (item.hasOwnProperty("label") && item.label === I18n.tr(labelKey)) {
|
||||
// Skip hidden branches to avoid highlighting controls that are not on screen.
|
||||
if (!isEffectivelyVisible(item))
|
||||
return null;
|
||||
|
||||
// Check if this item has a matching label.
|
||||
if (item.hasOwnProperty("label") && item.label === I18n.tr(labelKey) && item.width > 0 && item.height > 0) {
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
@@ -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