feat: brightness osd

This commit is contained in:
2 * r + 2 * t 2025-05-04 22:11:03 +10:00
parent fb471f1023
commit a575245d7b
4 changed files with 151 additions and 28 deletions

View file

@ -4,7 +4,7 @@ import Quickshell
import QtQuick
Singleton {
readonly property int hideDelay: 1500
readonly property int hideDelay: 2000
readonly property Sizes sizes: Sizes {}
component Sizes: QtObject {

View file

@ -7,7 +7,7 @@ import QtQuick
Column {
id: root
required property ShellScreen screen
required property Brightness.Monitor monitor
padding: Appearance.padding.large
@ -35,6 +35,8 @@ Column {
VerticalSlider {
icon: "brightness_6"
value: root.monitor?.brightness ?? 0
onMoved: root.monitor?.setBrightness(value)
implicitWidth: OsdConfig.sizes.sliderWidth
implicitHeight: OsdConfig.sizes.sliderHeight

View file

@ -4,47 +4,55 @@ import "root:/config"
import Quickshell
import QtQuick
Scope {
id: root
Variants {
model: Quickshell.screens
property bool osdVisible
Scope {
id: root
function show(): void {
root.osdVisible = true;
timer.restart();
}
required property ShellScreen modelData
readonly property Brightness.Monitor monitor: Brightness.getMonitorForScreen(modelData)
property bool osdVisible
Connections {
target: Audio
function onMutedChanged(): void {
root.show();
function show(): void {
root.osdVisible = true;
timer.restart();
}
function onVolumeChanged(): void {
root.show();
Connections {
target: Audio
function onMutedChanged(): void {
root.show();
}
function onVolumeChanged(): void {
root.show();
}
}
}
Timer {
id: timer
Connections {
target: root.monitor
interval: OsdConfig.hideDelay
onTriggered: root.osdVisible = false
}
function onBrightnessChanged(): void {
root.show();
}
}
Variants {
model: Quickshell.screens
Timer {
id: timer
interval: OsdConfig.hideDelay
onTriggered: root.osdVisible = false
}
LazyLoader {
loading: true
required property ShellScreen modelData
StyledWindow {
id: win
screen: parent.modelData
screen: root.modelData
name: "osd"
visible: wrapper.shouldBeVisible
@ -80,7 +88,7 @@ Scope {
Content {
id: content
screen: parent.modelData
monitor: root.monitor
}
}
}

113
services/Brightness.qml Normal file
View file

@ -0,0 +1,113 @@
pragma Singleton
pragma ComponentBehavior: Bound
import "root:/widgets"
import Quickshell
import Quickshell.Io
import QtQuick
Singleton {
id: root
property var ddcMonitors: []
readonly property list<Monitor> monitors: Quickshell.screens.map(screen => monitorComp.createObject(root, {
screen
}))
function getMonitorForScreen(screen: ShellScreen): var {
return monitors.find(m => m.screen === screen);
}
function increaseBrightness(): void {
const focusedName = Hyprland.focusedMonitor.name;
const monitor = monitors.find(m => focusedName === m.screen.name);
if (monitor)
monitor.setBrightness(monitor.brightness + 0.1);
}
function decreaseBrightness(): void {
const focusedName = Hyprland.focusedMonitor.name;
const monitor = monitors.find(m => focusedName === m.screen.name);
if (monitor)
monitor.setBrightness(monitor.brightness - 0.1);
}
reloadableId: "brightness"
onMonitorsChanged: {
ddcMonitors = [];
ddcProc.running = true;
}
Process {
id: ddcProc
command: ["ddcutil", "detect", "--brief"]
stdout: SplitParser {
splitMarker: "\n\n"
onRead: data => {
if (data.startsWith("Display ")) {
const lines = data.split("\n").map(l => l.trim());
root.ddcMonitors.push({
model: lines.find(l => l.startsWith("Monitor:")).split(":")[2],
busNum: lines.find(l => l.startsWith("I2C bus:")).split("/dev/i2c-")[1]
});
}
}
}
onExited: root.ddcMonitorsChanged()
}
Process {
id: setProc
}
CustomShortcut {
name: "brightnessUp"
onPressed: root.increaseBrightness()
}
CustomShortcut {
name: "brightnessDown"
onPressed: root.decreaseBrightness()
}
component Monitor: QtObject {
id: monitor
required property ShellScreen screen
readonly property bool isDdc: root.ddcMonitors.some(m => m.model === screen.model)
readonly property string busNum: root.ddcMonitors.find(m => m.model === screen.model)?.busNum ?? ""
property real brightness
readonly property Process initProc: Process {
stdout: SplitParser {
onRead: data => {
const [, , , current, max] = data.split(" ");
monitor.brightness = parseInt(current) / parseInt(max);
}
}
}
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;
brightness = value;
setProc.command = isDdc ? ["ddcutil", "-b", busNum, "setvcp", "10", rounded] : ["brightnessctl", "s", rounded];
setProc.startDetached();
}
onBusNumChanged: {
initProc.command = isDdc ? ["ddcutil", "-b", busNum, "getvcp", "10", "--brief"] : ["sh", "-c", `echo "a b c $(brightnessctl g) $(brightnessctl m)"`];
initProc.running = true;
}
}
Component {
id: monitorComp
Monitor {}
}
}