186 lines
5.5 KiB
QML
186 lines
5.5 KiB
QML
pragma Singleton
|
|
pragma ComponentBehavior: Bound
|
|
|
|
import qs.config
|
|
import qs.custom
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import QtQuick
|
|
|
|
Singleton {
|
|
id: root
|
|
|
|
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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
onMonitorsChanged: {
|
|
ddcMonitors = [];
|
|
ddcProc.running = true;
|
|
}
|
|
|
|
Variants {
|
|
id: variants
|
|
|
|
model: Quickshell.screens
|
|
|
|
Monitor {}
|
|
}
|
|
|
|
Process {
|
|
running: true
|
|
command: ["sh", "-c", "asdbctl get"] // To avoid warnings if asdbctl is not installed
|
|
stdout: StdioCollector {
|
|
onStreamFinished: root.appleDisplayPresent = text.trim().length > 0
|
|
}
|
|
}
|
|
|
|
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 {
|
|
id: brightnessUp
|
|
name: "brightnessUp"
|
|
description: "Increase brightness"
|
|
onPressed: {
|
|
root.increaseBrightness();
|
|
brightnessUpTimer.interval = 500;
|
|
brightnessUpTimer.running = true;
|
|
}
|
|
onReleased: {
|
|
brightnessUpTimer.running = false;
|
|
}
|
|
}
|
|
Timer {
|
|
id: brightnessUpTimer
|
|
repeat: true
|
|
onTriggered: {
|
|
interval = 100;
|
|
root.increaseBrightness();
|
|
}
|
|
}
|
|
|
|
CustomShortcut {
|
|
id: brightnessDown
|
|
name: "brightnessDown"
|
|
description: "Decrease brightness"
|
|
onPressed: {
|
|
root.decreaseBrightness();
|
|
brightnessDownTimer.interval = 500;
|
|
brightnessDownTimer.running = true;
|
|
}
|
|
onReleased: {
|
|
brightnessDownTimer.running = false;
|
|
}
|
|
}
|
|
Timer {
|
|
id: brightnessDownTimer
|
|
repeat: true
|
|
onTriggered: {
|
|
interval = 100;
|
|
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()
|
|
}
|
|
}
|