Add power settings for the lighting, bump to 1.4.0
New Power page: - toggle for the firmware's 30 s keyboard backlight timeout - idle timeout for keyboard and lightbar, separately for AC and battery; predatord watches all input devices and restores the lighting on the next input - battery rules: dimmed keyboard brightness, keyboard off, lightbar off The rules only change what is sent to the hardware; the saved lighting settings stay untouched. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -26,6 +26,7 @@ PAGES = [
|
||||
("fans", "Fans"),
|
||||
("rgb", "RGB Studio"),
|
||||
("battery", "Battery"),
|
||||
("power", "Power"),
|
||||
("system", "System"),
|
||||
]
|
||||
|
||||
@@ -591,6 +592,92 @@ class RgbPage(Page):
|
||||
self.lb_speed.setValue(lb["speed"])
|
||||
|
||||
|
||||
IDLE_CHOICES = [(0, "Never"), (30, "30 seconds"), (60, "1 minute"), (120, "2 minutes"), (300, "5 minutes"),
|
||||
(600, "10 minutes"), (900, "15 minutes"), (1800, "30 minutes")]
|
||||
|
||||
|
||||
class PowerPage(Page):
|
||||
def __init__(self, win):
|
||||
super().__init__(win)
|
||||
self.lay.addWidget(_title("Power", "Energy settings for the keyboard lighting and lightbar"))
|
||||
|
||||
fw = Card("Firmware backlight timeout")
|
||||
self.fw_timeout = QCheckBox("Turn the keyboard backlight off after 30 s without input (firmware)")
|
||||
self.fw_timeout.clicked.connect(lambda v: (win.backend.run("set_firmware", name="kbd_timeout", value=bool(v)),
|
||||
QTimer.singleShot(800, lambda: win.backend.run("get_firmware"))))
|
||||
fw.body.addWidget(self.fw_timeout)
|
||||
fw.body.addWidget(_muted("This is the built-in automatic switch-off of the laptop. Turn it off to keep the "
|
||||
"lighting on permanently, or use the adjustable timeout below instead."))
|
||||
self.lay.addWidget(fw)
|
||||
|
||||
idle = Card("Turn lighting off when idle")
|
||||
g = QGridLayout()
|
||||
self.idle_ac = QComboBox()
|
||||
self.idle_bat = QComboBox()
|
||||
for combo, key, label in ((self.idle_ac, "idle_off_ac", "On AC power"),
|
||||
(self.idle_bat, "idle_off_battery", "On battery")):
|
||||
for val, text in IDLE_CHOICES:
|
||||
combo.addItem(text, val)
|
||||
combo.activated.connect(lambda _=0, c=combo, k=key: win.backend.run("set_power", **{k: c.currentData()}))
|
||||
g.addWidget(QLabel("On AC power"), 0, 0)
|
||||
g.addWidget(self.idle_ac, 0, 1)
|
||||
g.addWidget(QLabel("On battery"), 1, 0)
|
||||
g.addWidget(self.idle_bat, 1, 1)
|
||||
g.setColumnStretch(2, 1)
|
||||
idle.body.addLayout(g)
|
||||
idle.body.addWidget(_muted("Keyboard and lightbar turn off after this time without keyboard, touchpad or "
|
||||
"mouse input, and come back on with the next input."))
|
||||
self.idle_state = _muted("")
|
||||
idle.body.addWidget(self.idle_state)
|
||||
self.lay.addWidget(idle)
|
||||
|
||||
bat = Card("On battery")
|
||||
h = QHBoxLayout()
|
||||
h.addWidget(QLabel("Keyboard brightness"))
|
||||
self.bat_bright = _slider(10, 100, 100)
|
||||
self.bat_bright.setSingleStep(10)
|
||||
self.bat_bright_l = QLabel("100 %")
|
||||
self.bat_bright.valueChanged.connect(lambda v: self.bat_bright_l.setText("%d %%" % v))
|
||||
self.bat_bright.sliderReleased.connect(lambda: win.backend.run("set_power", battery_brightness=self.bat_bright.value()))
|
||||
h.addWidget(self.bat_bright, 1)
|
||||
h.addWidget(self.bat_bright_l)
|
||||
bat.body.addLayout(h)
|
||||
bat.body.addWidget(_muted("Percentage of your normal keyboard brightness while running on battery."))
|
||||
self.bat_off = QCheckBox("Turn the keyboard lighting off completely on battery")
|
||||
self.bat_off.clicked.connect(lambda v: win.backend.run("set_power", battery_lights_off=bool(v)))
|
||||
bat.body.addWidget(self.bat_off)
|
||||
self.bat_lb = QCheckBox("Turn the lightbar off on battery")
|
||||
self.bat_lb.clicked.connect(lambda v: win.backend.run("set_power", battery_lightbar_off=bool(v)))
|
||||
bat.body.addWidget(self.bat_lb)
|
||||
self.lay.addWidget(bat)
|
||||
self.lay.addStretch(1)
|
||||
|
||||
def showEvent(self, e):
|
||||
super().showEvent(e)
|
||||
self.win.backend.run("get_firmware")
|
||||
|
||||
def firmware(self, fw):
|
||||
v = fw.get("kbd_timeout", {})
|
||||
self.fw_timeout.setEnabled(v.get("value") is not None)
|
||||
self.fw_timeout.setChecked(bool(v.get("value")))
|
||||
self.fw_timeout.setToolTip(v.get("error", "") or "")
|
||||
|
||||
def update_state(self, st):
|
||||
p = st["config"].get("power", {})
|
||||
for combo, key in ((self.idle_ac, "idle_off_ac"), (self.idle_bat, "idle_off_battery")):
|
||||
if not combo.view().isVisible():
|
||||
i = combo.findData(p.get(key, 0))
|
||||
if i < 0:
|
||||
combo.addItem("%d seconds" % p[key], p[key])
|
||||
i = combo.count() - 1
|
||||
combo.setCurrentIndex(i)
|
||||
if not self.bat_bright.isSliderDown():
|
||||
self.bat_bright.setValue(p.get("battery_brightness", 100))
|
||||
self.bat_off.setChecked(bool(p.get("battery_lights_off")))
|
||||
self.bat_lb.setChecked(bool(p.get("battery_lightbar_off")))
|
||||
self.idle_state.setText("Lighting is currently off because the laptop is idle." if st.get("lights_idle") else "")
|
||||
|
||||
|
||||
class BatteryPage(Page):
|
||||
def __init__(self, win):
|
||||
super().__init__(win)
|
||||
@@ -735,7 +822,7 @@ class SystemPage(Page):
|
||||
|
||||
def firmware(self, fw):
|
||||
for name, info in fw.items():
|
||||
if "label" not in info:
|
||||
if "label" not in info or name == "kbd_timeout": # shown on the Power page
|
||||
continue
|
||||
if name == "usb_charging":
|
||||
w = self.fw_boxes.get(name)
|
||||
@@ -843,7 +930,8 @@ class MainWindow(QMainWindow):
|
||||
self.nav = QButtonGroup(self)
|
||||
self.pages = {}
|
||||
classes = {"home": HomePage, "performance": PerformancePage, "fans": FansPage,
|
||||
"rgb": RgbPage, "battery": BatteryPage, "system": SystemPage}
|
||||
"rgb": RgbPage, "battery": BatteryPage, "power": PowerPage,
|
||||
"system": SystemPage}
|
||||
for key, label in PAGES:
|
||||
b = QPushButton(label)
|
||||
b.setObjectName("nav")
|
||||
@@ -916,6 +1004,7 @@ class MainWindow(QMainWindow):
|
||||
elif cmd == "get_firmware":
|
||||
self.pages["system"][0].firmware(result)
|
||||
self.pages["battery"][0].firmware(result)
|
||||
self.pages["power"][0].firmware(result)
|
||||
return
|
||||
else:
|
||||
self.statusBar().showMessage("Applied", 2000)
|
||||
|
||||
Reference in New Issue
Block a user