feat!: support exponential brightness curve
I don't need most of the fluff for handling other types of displays, and getting rid of it lets me do something a lot nicer: add an exponential-gamma brightness display.
This commit is contained in:
parent
bc5d256073
commit
e45f412930
9 changed files with 28 additions and 133 deletions
|
|
@ -171,6 +171,8 @@ Singleton {
|
|||
readonly property string sunsetFrom: "21:00"
|
||||
readonly property string sunsetTo: "9:00"
|
||||
readonly property int sunsetTemperature: 4500
|
||||
|
||||
readonly property real brightnessExp: 4.0
|
||||
}
|
||||
|
||||
readonly property QtObject session: QtObject {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ Item {
|
|||
id: root
|
||||
|
||||
required property PersistentProperties uiState
|
||||
required property ShellScreen screen
|
||||
|
||||
readonly property real nonAnimWidth: content.implicitWidth
|
||||
readonly property real nonAnimHeight: y > 0 || hasCurrent ? content.implicitHeight : 0
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ Item {
|
|||
id: root
|
||||
|
||||
required property var uiState
|
||||
required property Brightness.Monitor monitor
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
|
|
@ -95,13 +94,10 @@ Item {
|
|||
implicitHeight: Config.osd.sliderLength
|
||||
|
||||
function onWheel(event: WheelEvent) {
|
||||
const monitor = root.monitor;
|
||||
if (!monitor)
|
||||
return;
|
||||
if (event.angleDelta.y > 0)
|
||||
monitor.setBrightness(monitor.brightness + 0.1);
|
||||
Brightness.setBrightness(Brightness.brightness + 0.1);
|
||||
else if (event.angleDelta.y < 0)
|
||||
monitor.setBrightness(monitor.brightness - 0.1);
|
||||
Brightness.setBrightness(Brightness.brightness - 0.1);
|
||||
}
|
||||
|
||||
CustomFilledSlider {
|
||||
|
|
@ -109,8 +105,8 @@ Item {
|
|||
|
||||
color: Config.colors.brightness
|
||||
icon: Icons.getBrightnessIcon(value)
|
||||
value: root.monitor?.brightness ?? 0
|
||||
onMoved: root.monitor?.setBrightness(value)
|
||||
value: Brightness.brightness
|
||||
onMoved: Brightness.setBrightness(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,8 @@ Scope {
|
|||
id: root
|
||||
|
||||
required property PersistentProperties uiState
|
||||
required property ShellScreen screen
|
||||
required property bool hovered
|
||||
required property bool suppressed
|
||||
readonly property Brightness.Monitor monitor: Brightness.getMonitorForScreen(screen)
|
||||
|
||||
function show(): void {
|
||||
if (!root.suppressed) {
|
||||
|
|
@ -34,7 +32,7 @@ Scope {
|
|||
}
|
||||
|
||||
Connections {
|
||||
target: root.monitor
|
||||
target: Brightness
|
||||
|
||||
function onBrightnessChanged(): void {
|
||||
if (root.uiState.osdBrightnessReact)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ Item {
|
|||
id: root
|
||||
|
||||
required property var uiState
|
||||
required property ShellScreen screen
|
||||
|
||||
visible: width > 0
|
||||
implicitWidth: 0
|
||||
|
|
@ -61,6 +60,5 @@ Item {
|
|||
id: content
|
||||
|
||||
uiState: root.uiState
|
||||
monitor: Brightness.getMonitorForScreen(root.screen)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,7 +120,6 @@ CustomMouseArea {
|
|||
|
||||
Osd.Interactions {
|
||||
uiState: root.uiState
|
||||
screen: root.screen
|
||||
hovered: root.osdHovered
|
||||
suppressed: root.osdSuppressed
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ Item {
|
|||
id: root
|
||||
|
||||
required property PersistentProperties uiState
|
||||
required property ShellScreen screen
|
||||
required property Item bar
|
||||
|
||||
readonly property alias popouts: popouts
|
||||
|
|
@ -31,14 +30,12 @@ Item {
|
|||
id: popouts
|
||||
|
||||
uiState: root.uiState
|
||||
screen: root.screen
|
||||
}
|
||||
|
||||
Osd.Wrapper {
|
||||
id: osd
|
||||
|
||||
uiState: root.uiState
|
||||
screen: root.screen
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
|
|
|
|||
|
|
@ -110,7 +110,6 @@ Variants {
|
|||
|
||||
visible: !uiState.uiState.hidden
|
||||
uiState: uiState.uiState
|
||||
screen: scope.modelData
|
||||
bar: bar
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,59 +12,39 @@ Singleton {
|
|||
|
||||
reloadableId: "brightness"
|
||||
|
||||
property list<var> ddcMonitors: []
|
||||
readonly property list<Monitor> monitors: variants.instances
|
||||
property bool appleDisplayPresent: false
|
||||
|
||||
function getMonitorForScreen(screen: ShellScreen): var {
|
||||
return monitors.find(m => m.modelData === screen);
|
||||
}
|
||||
property real brightness: 1.0
|
||||
property real maxBrightness: 0.0
|
||||
|
||||
function increaseBrightness(): void {
|
||||
const focusedName = Hypr.focusedMonitor.name;
|
||||
const monitor = monitors.find(m => focusedName === m.modelData.name);
|
||||
if (monitor)
|
||||
monitor.setBrightness(monitor.brightness + Config.osd.brightnessIncrement);
|
||||
setBrightness(brightness + Config.osd.brightnessIncrement);
|
||||
}
|
||||
|
||||
function decreaseBrightness(): void {
|
||||
const focusedName = Hypr.focusedMonitor.name;
|
||||
const monitor = monitors.find(m => focusedName === m.modelData.name);
|
||||
if (monitor)
|
||||
monitor.setBrightness(monitor.brightness - Config.osd.brightnessIncrement);
|
||||
setBrightness(brightness - Config.osd.brightnessIncrement);
|
||||
}
|
||||
|
||||
onMonitorsChanged: {
|
||||
ddcMonitors = [];
|
||||
ddcProc.running = true;
|
||||
}
|
||||
|
||||
Variants {
|
||||
id: variants
|
||||
|
||||
model: Quickshell.screens
|
||||
|
||||
Monitor {}
|
||||
function setBrightness(value: real): void {
|
||||
value = Math.max(0, Math.min(1, value));
|
||||
if (Math.abs(brightness - value) < 0.01) return;
|
||||
brightness = value;
|
||||
|
||||
const exp = Config.services.brightnessExp;
|
||||
const raw = Math.round((value ** exp) * maxBrightness);
|
||||
Quickshell.execDetached(["brightnessctl", "s", `${raw}`]);
|
||||
}
|
||||
|
||||
Component.onCompleted: initProc.running = true
|
||||
Process {
|
||||
running: true
|
||||
command: ["sh", "-c", "asdbctl get"] // To avoid warnings if asdbctl is not installed
|
||||
id: initProc
|
||||
command: ["sh", "-c", "echo $(brightnessctl g) $(brightnessctl m)"]
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: root.appleDisplayPresent = text.trim().length > 0
|
||||
onStreamFinished: {
|
||||
const exp = Config.services.brightnessExp;
|
||||
const [cur, max] = text.split(" ");
|
||||
root.maxBrightness = parseInt(max);
|
||||
root.brightness = (parseInt(cur) / root.maxBrightness) ** (1 / exp);
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: ddcProc
|
||||
|
||||
command: ["ddcutil", "detect", "--brief"]
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: root.ddcMonitors = text.trim().split("\n\n").filter(d => d.startsWith("Display ")).map(d => ({
|
||||
model: d.match(/Monitor:.*:(.*):.*/)[1],
|
||||
busNum: d.match(/I2C bus:[ ]*\/dev\/i2c-([0-9]+)/)[1]
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
CustomShortcut {
|
||||
|
|
@ -110,77 +90,4 @@ Singleton {
|
|||
root.decreaseBrightness();
|
||||
}
|
||||
}
|
||||
|
||||
component Monitor: QtObject {
|
||||
id: monitor
|
||||
|
||||
required property ShellScreen modelData
|
||||
readonly property bool isDdc: root.ddcMonitors.some(m => m.model === modelData.model)
|
||||
readonly property string busNum: root.ddcMonitors.find(m => m.model === modelData.model)?.busNum ?? ""
|
||||
readonly property bool isAppleDisplay: root.appleDisplayPresent && modelData.model.startsWith("StudioDisplay")
|
||||
property real brightness
|
||||
property real queuedBrightness: NaN
|
||||
|
||||
readonly property Process initProc: Process {
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
if (monitor.isAppleDisplay) {
|
||||
const val = parseInt(text.trim());
|
||||
monitor.brightness = val / 101;
|
||||
} else {
|
||||
const [, , , cur, max] = text.split(" ");
|
||||
monitor.brightness = parseInt(cur) / parseInt(max);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
readonly property Timer timer: Timer {
|
||||
interval: 500
|
||||
onTriggered: {
|
||||
if (!isNaN(monitor.queuedBrightness)) {
|
||||
monitor.setBrightness(monitor.queuedBrightness);
|
||||
monitor.queuedBrightness = NaN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setBrightness(value: real): void {
|
||||
value = Math.max(0, Math.min(1, value));
|
||||
const rounded = Math.round(value * 100);
|
||||
if (Math.round(brightness * 100) === rounded)
|
||||
return;
|
||||
|
||||
if (isDdc && timer.running) {
|
||||
queuedBrightness = value;
|
||||
return;
|
||||
}
|
||||
|
||||
brightness = value;
|
||||
|
||||
if (isAppleDisplay)
|
||||
Quickshell.execDetached(["asdbctl", "set", rounded]);
|
||||
else if (isDdc)
|
||||
Quickshell.execDetached(["ddcutil", "-b", busNum, "setvcp", "10", rounded]);
|
||||
else
|
||||
Quickshell.execDetached(["brightnessctl", "s", `${rounded}%`]);
|
||||
|
||||
if (isDdc)
|
||||
timer.restart();
|
||||
}
|
||||
|
||||
function initBrightness(): void {
|
||||
if (isAppleDisplay)
|
||||
initProc.command = ["asdbctl", "get"];
|
||||
else if (isDdc)
|
||||
initProc.command = ["ddcutil", "-b", busNum, "getvcp", "10", "--brief"];
|
||||
else
|
||||
initProc.command = ["sh", "-c", "echo a b c $(brightnessctl g) $(brightnessctl m)"];
|
||||
|
||||
initProc.running = true;
|
||||
}
|
||||
|
||||
onBusNumChanged: initBrightness()
|
||||
Component.onCompleted: initBrightness()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue