/ services / Brightness.qml
Brightness.qml
  1  pragma Singleton
  2  pragma ComponentBehavior: Bound
  3  
  4  import "root:/widgets"
  5  import Quickshell
  6  import Quickshell.Io
  7  import QtQuick
  8  
  9  Singleton {
 10      id: root
 11  
 12      property var ddcMonitors: []
 13      readonly property list<Monitor> monitors: variants.instances
 14  
 15      function getMonitorForScreen(screen: ShellScreen): var {
 16          return monitors.find(m => m.modelData === screen);
 17      }
 18  
 19      function increaseBrightness(): void {
 20          const focusedName = Hyprland.focusedMonitor.name;
 21          const monitor = monitors.find(m => focusedName === m.modelData.name);
 22          if (monitor)
 23              monitor.setBrightness(monitor.brightness + 0.1);
 24      }
 25  
 26      function decreaseBrightness(): void {
 27          const focusedName = Hyprland.focusedMonitor.name;
 28          const monitor = monitors.find(m => focusedName === m.modelData.name);
 29          if (monitor)
 30              monitor.setBrightness(monitor.brightness - 0.1);
 31      }
 32  
 33      reloadableId: "brightness"
 34  
 35      onMonitorsChanged: {
 36          ddcMonitors = [];
 37          ddcProc.running = true;
 38      }
 39  
 40      Variants {
 41          id: variants
 42  
 43          model: Quickshell.screens
 44  
 45          Monitor {}
 46      }
 47  
 48      Process {
 49          id: ddcProc
 50  
 51          command: ["ddcutil", "detect", "--brief"]
 52          stdout: SplitParser {
 53              splitMarker: "\n\n"
 54              onRead: data => {
 55                  if (data.startsWith("Display ")) {
 56                      const lines = data.split("\n").map(l => l.trim());
 57                      root.ddcMonitors.push({
 58                          model: lines.find(l => l.startsWith("Monitor:")).split(":")[2],
 59                          busNum: lines.find(l => l.startsWith("I2C bus:")).split("/dev/i2c-")[1]
 60                      });
 61                  }
 62              }
 63          }
 64          onExited: root.ddcMonitorsChanged()
 65      }
 66  
 67      Process {
 68          id: setProc
 69      }
 70  
 71      CustomShortcut {
 72          name: "brightnessUp"
 73          onPressed: root.increaseBrightness()
 74      }
 75  
 76      CustomShortcut {
 77          name: "brightnessDown"
 78          onPressed: root.decreaseBrightness()
 79      }
 80  
 81      component Monitor: QtObject {
 82          id: monitor
 83  
 84          required property ShellScreen modelData
 85          readonly property bool isDdc: root.ddcMonitors.some(m => m.model === modelData.model)
 86          readonly property string busNum: root.ddcMonitors.find(m => m.model === modelData.model)?.busNum ?? ""
 87          property real brightness
 88  
 89          readonly property Process initProc: Process {
 90              stdout: SplitParser {
 91                  onRead: data => {
 92                      const [, , , current, max] = data.split(" ");
 93                      monitor.brightness = parseInt(current) / parseInt(max);
 94                  }
 95              }
 96          }
 97  
 98          function setBrightness(value: real): void {
 99              value = Math.max(0, Math.min(1, value));
100              const rounded = Math.round(value * 100);
101              if (Math.round(brightness * 100) === rounded)
102                  return;
103              brightness = value;
104              setProc.command = isDdc ? ["ddcutil", "-b", busNum, "setvcp", "10", rounded] : ["brightnessctl", "s", `${rounded}%`];
105              setProc.startDetached();
106          }
107  
108          onBusNumChanged: {
109              initProc.command = isDdc ? ["ddcutil", "-b", busNum, "getvcp", "10", "--brief"] : ["sh", "-c", `echo "a b c $(brightnessctl g) $(brightnessctl m)"`];
110              initProc.running = true;
111          }
112  
113          Component.onCompleted: {
114              initProc.command = isDdc ? ["ddcutil", "-b", busNum, "getvcp", "10", "--brief"] : ["sh", "-c", `echo "a b c $(brightnessctl g) $(brightnessctl m)"`];
115              initProc.running = true;
116          }
117      }
118  }