99 lines
3.1 KiB
Python
99 lines
3.1 KiB
Python
"""Hyprland Game Mode service."""
|
|
|
|
from fabric.core.service import Property, Service, Signal
|
|
|
|
from utils.functions import run_command
|
|
|
|
HYPRCTL = "hyprctl"
|
|
|
|
_ENABLE_LUA = (
|
|
"hl.config({"
|
|
" animations = { enabled = false },"
|
|
" decoration = { shadow = { enabled = false }, blur = { enabled = false },"
|
|
" active_opacity = 1.0, inactive_opacity = 1.0, active_rounding = 0, "
|
|
" rounding = 0 },"
|
|
" general = { gaps_in = 0, gaps_out = 0, border_size = 1 }"
|
|
"})"
|
|
)
|
|
|
|
|
|
class GameModeService(Service):
|
|
"""Owns all Hyprland interaction for game mode and notifies observers."""
|
|
|
|
_instance = None
|
|
|
|
def __new__(cls):
|
|
if cls._instance is None:
|
|
cls._instance = super().__new__(cls)
|
|
return cls._instance
|
|
|
|
@staticmethod
|
|
def get_initial():
|
|
if GameModeService._instance is None:
|
|
GameModeService._instance = GameModeService()
|
|
return GameModeService._instance
|
|
|
|
@Signal
|
|
def changed(self, enabled: bool) -> None:
|
|
"""Emitted when game mode is enabled or disabled."""
|
|
|
|
def __init__(self, **kwargs):
|
|
if getattr(self, "_initialized", False):
|
|
return
|
|
super().__init__(**kwargs)
|
|
self._initialized = True
|
|
self._enabled = False
|
|
self.sync_state()
|
|
|
|
@Property(bool, "readable", default_value=False)
|
|
def enabled(self) -> bool:
|
|
"""Whether game mode (visual effects off) is currently active."""
|
|
return self._enabled
|
|
|
|
def toggle(self) -> None:
|
|
if self._enabled:
|
|
self.disable()
|
|
else:
|
|
self.enable()
|
|
|
|
def enable(self) -> None:
|
|
if self._enabled:
|
|
return
|
|
run_command([HYPRCTL, "eval", _ENABLE_LUA], timeout=5)
|
|
self._set_enabled(True)
|
|
|
|
def disable(self) -> None:
|
|
if not self._enabled:
|
|
return
|
|
# A full reload restores the user's exact prior configuration (gaps,
|
|
# border, rounding, etc.) which per-option restores cannot reproduce,
|
|
# so it is kept instead of guessing default values.
|
|
run_command([HYPRCTL, "reload"], timeout=5)
|
|
self._set_enabled(False)
|
|
|
|
def sync_state(self) -> None:
|
|
"""Read the authoritative state from Hyprland (animations toggle)."""
|
|
result = run_command(
|
|
[HYPRCTL, "eval", "return hl.get_config('animations.enabled')"], timeout=5
|
|
)
|
|
if result.returncode != 0:
|
|
return
|
|
value = result.stdout.strip().lower()
|
|
if value in ("true", "1", "on"):
|
|
animations_on = True
|
|
elif value in ("false", "0", "off"):
|
|
animations_on = False
|
|
else:
|
|
# Unrecognized output (e.g. an error string): keep current state
|
|
# rather than falsely reporting game mode as active.
|
|
return
|
|
# Game mode is on when Hyprland animations are disabled.
|
|
self._set_enabled(not animations_on)
|
|
|
|
def _set_enabled(self, enabled: bool) -> None:
|
|
if enabled == self._enabled:
|
|
return
|
|
self._enabled = enabled
|
|
self.notify("enabled")
|
|
self.emit("changed", enabled)
|