1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-30 08:22:51 -05:00

displays: allow choosing logarithmic mode for backlight devices

This commit is contained in:
bbedward
2025-11-04 17:01:50 -05:00
parent cd51eb25ce
commit 1ac95f0d14
4 changed files with 259 additions and 80 deletions

View File

@@ -60,6 +60,8 @@ Singleton {
property bool showThirdPartyPlugins: false property bool showThirdPartyPlugins: false
property string launchPrefix: "" property string launchPrefix: ""
property string lastBrightnessDevice: "" property string lastBrightnessDevice: ""
property var brightnessLogarithmicDevices: ({})
property var brightnessUserSetValues: ({})
property int selectedGpuIndex: 0 property int selectedGpuIndex: 0
property bool nvidiaGpuTempEnabled: false property bool nvidiaGpuTempEnabled: false
@@ -107,6 +109,8 @@ Singleton {
wallpaperPathDark = settings.wallpaperPathDark !== undefined ? settings.wallpaperPathDark : "" wallpaperPathDark = settings.wallpaperPathDark !== undefined ? settings.wallpaperPathDark : ""
monitorWallpapersLight = settings.monitorWallpapersLight !== undefined ? settings.monitorWallpapersLight : {} monitorWallpapersLight = settings.monitorWallpapersLight !== undefined ? settings.monitorWallpapersLight : {}
monitorWallpapersDark = settings.monitorWallpapersDark !== undefined ? settings.monitorWallpapersDark : {} monitorWallpapersDark = settings.monitorWallpapersDark !== undefined ? settings.monitorWallpapersDark : {}
brightnessLogarithmicDevices = settings.brightnessLogarithmicDevices !== undefined ? settings.brightnessLogarithmicDevices : {}
brightnessUserSetValues = settings.brightnessUserSetValues !== undefined ? settings.brightnessUserSetValues : {}
doNotDisturb = settings.doNotDisturb !== undefined ? settings.doNotDisturb : false doNotDisturb = settings.doNotDisturb !== undefined ? settings.doNotDisturb : false
nightModeEnabled = settings.nightModeEnabled !== undefined ? settings.nightModeEnabled : false nightModeEnabled = settings.nightModeEnabled !== undefined ? settings.nightModeEnabled : false
nightModeTemperature = settings.nightModeTemperature !== undefined ? settings.nightModeTemperature : 4500 nightModeTemperature = settings.nightModeTemperature !== undefined ? settings.nightModeTemperature : 4500
@@ -185,6 +189,8 @@ Singleton {
"wallpaperPathDark": wallpaperPathDark, "wallpaperPathDark": wallpaperPathDark,
"monitorWallpapersLight": monitorWallpapersLight, "monitorWallpapersLight": monitorWallpapersLight,
"monitorWallpapersDark": monitorWallpapersDark, "monitorWallpapersDark": monitorWallpapersDark,
"brightnessLogarithmicDevices": brightnessLogarithmicDevices,
"brightnessUserSetValues": brightnessUserSetValues,
"doNotDisturb": doNotDisturb, "doNotDisturb": doNotDisturb,
"nightModeEnabled": nightModeEnabled, "nightModeEnabled": nightModeEnabled,
"nightModeTemperature": nightModeTemperature, "nightModeTemperature": nightModeTemperature,
@@ -268,7 +274,7 @@ Singleton {
} }
function cleanupUnusedKeys() { function cleanupUnusedKeys() {
const validKeys = ["isLightMode", "wallpaperPath", "perMonitorWallpaper", "monitorWallpapers", "perModeWallpaper", "wallpaperPathLight", "wallpaperPathDark", "monitorWallpapersLight", "monitorWallpapersDark", "doNotDisturb", "nightModeEnabled", "nightModeTemperature", "nightModeHighTemperature", "nightModeAutoEnabled", "nightModeAutoMode", "nightModeStartHour", "nightModeStartMinute", "nightModeEndHour", "nightModeEndMinute", "latitude", "longitude", "nightModeUseIPLocation", "nightModeLocationProvider", "pinnedApps", "selectedGpuIndex", "nvidiaGpuTempEnabled", "nonNvidiaGpuTempEnabled", "enabledGpuPciIds", "wallpaperCyclingEnabled", "wallpaperCyclingMode", "wallpaperCyclingInterval", "wallpaperCyclingTime", "monitorCyclingSettings", "lastBrightnessDevice", "launchPrefix", "wallpaperTransition", "includedTransitions", "recentColors", "showThirdPartyPlugins", "configVersion"] const validKeys = ["isLightMode", "wallpaperPath", "perMonitorWallpaper", "monitorWallpapers", "perModeWallpaper", "wallpaperPathLight", "wallpaperPathDark", "monitorWallpapersLight", "monitorWallpapersDark", "doNotDisturb", "nightModeEnabled", "nightModeTemperature", "nightModeHighTemperature", "nightModeAutoEnabled", "nightModeAutoMode", "nightModeStartHour", "nightModeStartMinute", "nightModeEndHour", "nightModeEndMinute", "latitude", "longitude", "nightModeUseIPLocation", "nightModeLocationProvider", "pinnedApps", "selectedGpuIndex", "nvidiaGpuTempEnabled", "nonNvidiaGpuTempEnabled", "enabledGpuPciIds", "wallpaperCyclingEnabled", "wallpaperCyclingMode", "wallpaperCyclingInterval", "wallpaperCyclingTime", "monitorCyclingSettings", "lastBrightnessDevice", "brightnessLogarithmicDevices", "brightnessUserSetValues", "launchPrefix", "wallpaperTransition", "includedTransitions", "recentColors", "showThirdPartyPlugins", "configVersion"]
try { try {
const content = settingsFile.text() const content = settingsFile.text()
@@ -656,6 +662,36 @@ Singleton {
saveSettings() saveSettings()
} }
function setBrightnessLogarithmic(deviceName, enabled) {
var newSettings = Object.assign({}, brightnessLogarithmicDevices)
if (enabled) {
newSettings[deviceName] = true
} else {
delete newSettings[deviceName]
}
brightnessLogarithmicDevices = newSettings
saveSettings()
if (typeof DisplayService !== "undefined") {
DisplayService.updateDeviceBrightnessDisplay(deviceName)
}
}
function getBrightnessLogarithmic(deviceName) {
return brightnessLogarithmicDevices[deviceName] === true
}
function setBrightnessUserSetValue(deviceName, value) {
var newValues = Object.assign({}, brightnessUserSetValues)
newValues[deviceName] = value
brightnessUserSetValues = newValues
saveSettings()
}
function getBrightnessUserSetValue(deviceName) {
return brightnessUserSetValues[deviceName]
}
function setSelectedGpuIndex(index) { function setSelectedGpuIndex(index) {
selectedGpuIndex = index selectedGpuIndex = index
saveSettings() saveSettings()

View File

@@ -210,103 +210,147 @@ Rectangle {
required property var modelData required property var modelData
required property int index required property int index
property real deviceBrightness: {
DisplayService.brightnessVersion
return DisplayService.getDeviceBrightness(modelData.name)
}
width: parent.width width: parent.width
height: 80 height: 100
radius: Theme.cornerRadius radius: Theme.cornerRadius
color: Theme.withAlpha(Theme.surfaceContainerHighest, Theme.popupTransparency) color: Theme.withAlpha(Theme.surfaceContainerHighest, Theme.popupTransparency)
border.color: modelData.name === currentDeviceName ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12) border.color: modelData.name === currentDeviceName ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
border.width: modelData.name === currentDeviceName ? 2 : 0 border.width: modelData.name === currentDeviceName ? 2 : 0
Row { Column {
anchors.left: parent.left anchors.fill: parent
anchors.verticalCenter: parent.verticalCenter anchors.margins: Theme.spacingM
anchors.leftMargin: Theme.spacingM spacing: Theme.spacingS
spacing: Theme.spacingM
Column { Row {
anchors.verticalCenter: parent.verticalCenter width: parent.width
spacing: 2 spacing: Theme.spacingM
DankIcon { Column {
name: { anchors.verticalCenter: parent.verticalCenter
const deviceClass = modelData.class || "" spacing: 2
const deviceName = modelData.name || ""
if (deviceClass === "backlight" || deviceClass === "ddc") { DankIcon {
const brightness = DisplayService.getDeviceBrightness(modelData.name) name: {
if (brightness <= 33) const deviceClass = modelData.class || ""
return "brightness_low" const deviceName = modelData.name || ""
if (brightness <= 66)
return "brightness_medium" if (deviceClass === "backlight" || deviceClass === "ddc") {
return "brightness_high" if (deviceBrightness <= 33)
} else if (deviceName.includes("kbd")) { return "brightness_low"
return "keyboard" if (deviceBrightness <= 66)
} else { return "brightness_medium"
return "lightbulb" return "brightness_high"
} else if (deviceName.includes("kbd")) {
return "keyboard"
} else {
return "lightbulb"
}
} }
size: Theme.iconSize
color: modelData.name === currentDeviceName ? Theme.primary : Theme.surfaceText
anchors.horizontalCenter: parent.horizontalCenter
}
StyledText {
text: Math.round(deviceBrightness) + "%"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
anchors.horizontalCenter: parent.horizontalCenter
} }
size: Theme.iconSize
color: modelData.name === currentDeviceName ? Theme.primary : Theme.surfaceText
anchors.horizontalCenter: parent.horizontalCenter
} }
StyledText { Column {
text: Math.round(DisplayService.getDeviceBrightness(modelData.name)) + "%" anchors.verticalCenter: parent.verticalCenter
font.pixelSize: Theme.fontSizeSmall width: parent.width - parent.spacing - 50
color: Theme.surfaceText
anchors.horizontalCenter: parent.horizontalCenter StyledText {
text: {
const name = modelData.name || ""
const deviceClass = modelData.class || ""
if (deviceClass === "backlight") {
return name.replace("_", " ").replace(/\b\w/g, c => c.toUpperCase())
}
return name
}
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: modelData.name === currentDeviceName ? Font.Medium : Font.Normal
elide: Text.ElideRight
width: parent.width
}
StyledText {
text: modelData.name
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
elide: Text.ElideRight
width: parent.width
}
StyledText {
text: {
const deviceClass = modelData.class || ""
if (deviceClass === "backlight")
return "Backlight device"
if (deviceClass === "ddc")
return "DDC/CI monitor"
if (deviceClass === "leds")
return "LED device"
return deviceClass
}
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
elide: Text.ElideRight
width: parent.width
}
} }
} }
Column { Rectangle {
anchors.verticalCenter: parent.verticalCenter width: parent.width
width: parent.parent.width - parent.parent.anchors.leftMargin - parent.spacing - 50 - Theme.spacingM height: 24
radius: height / 2
color: SessionData.getBrightnessLogarithmic(modelData.name) ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05)
StyledText { Row {
text: { anchors.centerIn: parent
const name = modelData.name || "" spacing: 4
const deviceClass = modelData.class || ""
if (deviceClass === "backlight") { DankIcon {
return name.replace("_", " ").replace(/\b\w/g, c => c.toUpperCase()) name: "show_chart"
} size: 14
return name color: SessionData.getBrightnessLogarithmic(modelData.name) ? Theme.primary : Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: SessionData.getBrightnessLogarithmic(modelData.name) ? "Logarithmic" : "Linear"
font.pixelSize: Theme.fontSizeSmall
color: SessionData.getBrightnessLogarithmic(modelData.name) ? Theme.primary : Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
} }
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: modelData.name === currentDeviceName ? Font.Medium : Font.Normal
elide: Text.ElideRight
width: parent.width
} }
StyledText { MouseArea {
text: modelData.name anchors.fill: parent
font.pixelSize: Theme.fontSizeSmall cursorShape: Qt.PointingHandCursor
color: Theme.surfaceVariantText onClicked: {
elide: Text.ElideRight const currentState = SessionData.getBrightnessLogarithmic(modelData.name)
width: parent.width SessionData.setBrightnessLogarithmic(modelData.name, !currentState)
}
StyledText {
text: {
const deviceClass = modelData.class || ""
if (deviceClass === "backlight")
return "Backlight device"
if (deviceClass === "ddc")
return "DDC/CI monitor"
if (deviceClass === "leds")
return "LED device"
return deviceClass
} }
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
elide: Text.ElideRight
width: parent.width
} }
} }
} }
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
anchors.bottomMargin: 28
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {

View File

@@ -71,6 +71,7 @@ Row {
} }
property real targetBrightness: { property real targetBrightness: {
DisplayService.brightnessVersion
if (!targetDeviceName) { if (!targetDeviceName) {
return 0 return 0
} }

View File

@@ -1,6 +1,6 @@
pragma Singleton pragma Singleton
pragma ComponentBehavior pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import Quickshell import Quickshell
@@ -13,9 +13,12 @@ Singleton {
property bool brightnessAvailable: devices.length > 0 property bool brightnessAvailable: devices.length > 0
property var devices: [] property var devices: []
property var deviceBrightness: ({}) property var deviceBrightness: ({})
property var deviceBrightnessUserSet: ({})
property int brightnessVersion: 0
property string currentDevice: "" property string currentDevice: ""
property string lastIpcDevice: "" property string lastIpcDevice: ""
property int brightnessLevel: { property int brightnessLevel: {
brightnessVersion
const deviceToUse = lastIpcDevice === "" ? getDefaultDevice() : (lastIpcDevice || currentDevice) const deviceToUse = lastIpcDevice === "" ? getDefaultDevice() : (lastIpcDevice || currentDevice)
if (!deviceToUse) { if (!deviceToUse) {
return 50 return 50
@@ -52,17 +55,30 @@ Singleton {
devices = newDevices devices = newDevices
} }
const isLogarithmic = SessionData.getBrightnessLogarithmic(device.id)
const userSetValue = deviceBrightnessUserSet[device.id]
let displayValue = device.currentPercent
if (isLogarithmic) {
if (userSetValue !== undefined) {
displayValue = userSetValue
} else {
displayValue = linearToLogarithmic(device.currentPercent)
}
}
const oldValue = deviceBrightness[device.id] const oldValue = deviceBrightness[device.id]
const newBrightness = Object.assign({}, deviceBrightness) const newBrightness = Object.assign({}, deviceBrightness)
newBrightness[device.id] = device.currentPercent newBrightness[device.id] = displayValue
deviceBrightness = newBrightness deviceBrightness = newBrightness
brightnessVersion++
const shouldSuppress = suppressSignal || suppressNextOsd const shouldSuppress = suppressSignal || suppressNextOsd
if (suppressNextOsd) { if (suppressNextOsd) {
suppressNextOsd = false suppressNextOsd = false
} }
if (!shouldSuppress && oldValue !== device.currentPercent) { if (!shouldSuppress && oldValue !== displayValue) {
brightnessChanged() brightnessChanged()
} }
} }
@@ -84,9 +100,21 @@ Singleton {
const newBrightness = {} const newBrightness = {}
for (const device of state.devices) { for (const device of state.devices) {
newBrightness[device.id] = device.currentPercent const isLogarithmic = SessionData.getBrightnessLogarithmic(device.id)
const userSetValue = deviceBrightnessUserSet[device.id]
if (isLogarithmic) {
if (userSetValue !== undefined) {
newBrightness[device.id] = userSetValue
} else {
newBrightness[device.id] = linearToLogarithmic(device.currentPercent)
}
} else {
newBrightness[device.id] = device.currentPercent
}
} }
deviceBrightness = newBrightness deviceBrightness = newBrightness
brightnessVersion++
brightnessAvailable = devices.length > 0 brightnessAvailable = devices.length > 0
@@ -129,10 +157,24 @@ Singleton {
suppressNextOsd = true suppressNextOsd = true
} }
DMSService.sendRequest("brightness.setBrightness", { const isLogarithmic = SessionData.getBrightnessLogarithmic(actualDevice)
"device": actualDevice,
"percent": clampedValue if (isLogarithmic) {
}, response => { const newUserSet = Object.assign({}, deviceBrightnessUserSet)
newUserSet[actualDevice] = clampedValue
deviceBrightnessUserSet = newUserSet
SessionData.setBrightnessUserSetValue(actualDevice, clampedValue)
}
const params = {
"device": actualDevice,
"percent": clampedValue
}
if (isLogarithmic) {
params.logarithmic = true
}
DMSService.sendRequest("brightness.setBrightness", params, response => {
if (response.error) { if (response.error) {
console.error("DisplayService: Failed to set brightness:", response.error) console.error("DisplayService: Failed to set brightness:", response.error)
ToastService.showError("Failed to set brightness: " + response.error) ToastService.showError("Failed to set brightness: " + response.error)
@@ -167,6 +209,12 @@ Singleton {
return 50 return 50
} }
function linearToLogarithmic(linearPercent) {
const normalized = linearPercent / 100.0
const logPercent = Math.pow(normalized, 2.0) * 100.0
return Math.round(logPercent)
}
function getDefaultDevice() { function getDefaultDevice() {
for (const device of devices) { for (const device of devices) {
if (device.class === "backlight") { if (device.class === "backlight") {
@@ -504,8 +552,14 @@ Singleton {
}) })
} }
function updateDeviceBrightnessDisplay(deviceName) {
brightnessVersion++
brightnessChanged()
}
Component.onCompleted: { Component.onCompleted: {
nightModeEnabled = SessionData.nightModeEnabled nightModeEnabled = SessionData.nightModeEnabled
deviceBrightnessUserSet = Object.assign({}, SessionData.brightnessUserSetValues)
if (DMSService.isConnected) { if (DMSService.isConnected) {
checkGammaControlAvailability() checkGammaControlAvailability()
} }
@@ -717,11 +771,55 @@ Singleton {
let result = "Available devices:\n" let result = "Available devices:\n"
for (const device of root.devices) { for (const device of root.devices) {
result += device.id + " (" + device.class + ")\n" const isLog = SessionData.getBrightnessLogarithmic(device.id)
result += device.id + " (" + device.class + ")" + (isLog ? " [logarithmic]" : "") + "\n"
} }
return result return result
} }
function enableLogarithmic(device: string): string {
const targetDevice = device || root.currentDevice
if (!targetDevice) {
return "No device specified"
}
if (!root.devices.some(d => d.id === targetDevice)) {
return "Device not found: " + targetDevice
}
SessionData.setBrightnessLogarithmic(targetDevice, true)
return "Logarithmic mode enabled for " + targetDevice
}
function disableLogarithmic(device: string): string {
const targetDevice = device || root.currentDevice
if (!targetDevice) {
return "No device specified"
}
if (!root.devices.some(d => d.id === targetDevice)) {
return "Device not found: " + targetDevice
}
SessionData.setBrightnessLogarithmic(targetDevice, false)
return "Logarithmic mode disabled for " + targetDevice
}
function toggleLogarithmic(device: string): string {
const targetDevice = device || root.currentDevice
if (!targetDevice) {
return "No device specified"
}
if (!root.devices.some(d => d.id === targetDevice)) {
return "Device not found: " + targetDevice
}
const currentState = SessionData.getBrightnessLogarithmic(targetDevice)
SessionData.setBrightnessLogarithmic(targetDevice, !currentState)
return "Logarithmic mode " + (!currentState ? "enabled" : "disabled") + " for " + targetDevice
}
target: "brightness" target: "brightness"
} }