feature: toggle LED lighting of connected devices with screen locking
When the screen is locked, LED lighting is turned off. When the screen is unlocked, it is turned on again to its previous state. To accomplish this, the devices RGB settings are changed in a volatile manner when the screen is locked, by writing only to the device and not to the cache or configuration, causing the Solaars state and the state of the devices to become intentionally out-of-sync. When the screen is unlocked again, the local configuration values can just be applied again.
This commit is contained in:
parent
b5bff32117
commit
9ccc7231f0
|
|
@ -802,6 +802,17 @@ class RGBPowerManager:
|
|||
if logger.isEnabledFor(logging.WARNING):
|
||||
logger.warning("%s: failed to wake RGB LEDs: %s", self._device, e)
|
||||
|
||||
# --- Suspend / Restore (used e.g. to toggle LEDs on screen lock) ---
|
||||
|
||||
def suspend_leds(self):
|
||||
"""Force enter sleep state (e.g. on screen lock)."""
|
||||
if self._state != self.SLEEPING:
|
||||
self._start_sleep()
|
||||
|
||||
def restore_leds(self):
|
||||
"""Force wake from sleep state (e.g. on screen unlock)."""
|
||||
self._wake()
|
||||
|
||||
def _cancel_dim_timer(self):
|
||||
if self._dim_timer_id is not None:
|
||||
GLib.source_remove(self._dim_timer_id)
|
||||
|
|
|
|||
|
|
@ -198,6 +198,8 @@ def main():
|
|||
else:
|
||||
dbus.watch_suspend_resume(lambda: listener.ping_all(True))
|
||||
|
||||
dbus.watch_screen_lock_state(listener.suspend_leds, listener.restore_leds)
|
||||
|
||||
configuration.defer_saves = True # allow configuration saves to be deferred
|
||||
|
||||
# main UI event loop
|
||||
|
|
|
|||
|
|
@ -30,11 +30,8 @@ from typing import Callable
|
|||
import gi
|
||||
import logitech_receiver
|
||||
|
||||
from logitech_receiver import base
|
||||
from logitech_receiver import exceptions
|
||||
from logitech_receiver import hidpp10_constants
|
||||
from logitech_receiver import listener
|
||||
from logitech_receiver import notifications
|
||||
from logitech_receiver import base, exceptions, hidpp10_constants, listener, notifications, rgb_power, settings_templates as st
|
||||
from logitech_receiver.hidpp20 import LEDEffectSetting
|
||||
|
||||
from . import configuration
|
||||
from . import dbus
|
||||
|
|
@ -452,6 +449,49 @@ def ping_all(resuming=False):
|
|||
break
|
||||
|
||||
|
||||
def suspend_leds():
|
||||
"""Turn off LEDs for all connected devices."""
|
||||
logger.info("screen locked, suspending LED lighting on all devices")
|
||||
|
||||
for listener_thread in _all_listeners.values():
|
||||
devices = [listener_thread.receiver] if listener_thread.receiver.isDevice else list(listener_thread.receiver)
|
||||
for dev in devices:
|
||||
if not dev.online:
|
||||
continue
|
||||
|
||||
if mgr := rgb_power.get_manager(dev):
|
||||
mgr.suspend_leds()
|
||||
return
|
||||
|
||||
for s in dev.settings:
|
||||
if s.name in (st.Backlight.name, st.Backlight2.name, st.Backlight2Level.name):
|
||||
s.write(0, save=False, volatile=True)
|
||||
elif s.name.startswith(st.LEDZoneSetting.name) or s.name.startswith(st.RGBEffectSetting.name):
|
||||
s.write(LEDEffectSetting(ID=0), save=False, volatile=True)
|
||||
elif s.name == st.PerKeyLighting.name and s.read():
|
||||
s.write({k: 0 for k in s._value.keys()}, save=False, volatile=True)
|
||||
|
||||
|
||||
def restore_leds():
|
||||
"""Restore LED lighting for all connected devices to their saved states."""
|
||||
logger.info("screen unlocked, restoring LED lighting on all devices")
|
||||
|
||||
for listener_thread in _all_listeners.values():
|
||||
devices = [listener_thread.receiver] if listener_thread.receiver.isDevice else list(listener_thread.receiver)
|
||||
for dev in devices:
|
||||
if not dev.online:
|
||||
continue
|
||||
|
||||
if mgr := rgb_power.get_manager(dev):
|
||||
mgr.restore_leds()
|
||||
return
|
||||
|
||||
for s in dev.settings:
|
||||
if s.name in (st.Backlight.name, st.Backlight2.name, st.Backlight2Level.name, st.PerKeyLighting.name) \
|
||||
or s.name.startswith(st.LEDZoneSetting.name) or s.name.startswith(st.RGBEffectSetting.name):
|
||||
s.apply()
|
||||
|
||||
|
||||
_status_callback = None # GUI callback to change UI in response to changes to receiver or device status
|
||||
_setting_callback = None # GUI callback to change UI in response to changes to status
|
||||
_error_callback = None # GUI callback to report errors
|
||||
|
|
|
|||
Loading…
Reference in New Issue