aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--hyprsunset_qt/daemon.py45
-rw-r--r--tests/test_daemon.py40
2 files changed, 85 insertions, 0 deletions
diff --git a/hyprsunset_qt/daemon.py b/hyprsunset_qt/daemon.py
new file mode 100644
index 0000000..7bf0e47
--- /dev/null
+++ b/hyprsunset_qt/daemon.py
@@ -0,0 +1,45 @@
+"""Control the hyprsunset daemon: status, restart, live preview via hyprctl."""
+
+from __future__ import annotations
+
+import shlex
+import subprocess
+from typing import Optional
+
+
+def is_running() -> bool:
+ return subprocess.run(
+ ["pgrep", "-x", "hyprsunset"],
+ stdout=subprocess.DEVNULL,
+ stderr=subprocess.DEVNULL,
+ ).returncode == 0
+
+
+def live_preview(
+ temperature: Optional[int] = None,
+ gamma: Optional[float] = None,
+ identity: bool = False,
+) -> None:
+ """Push values to the running daemon over IPC. No file write, no restart."""
+ if identity:
+ subprocess.run(["hyprctl", "hyprsunset", "identity"], check=False)
+ return
+ if temperature is not None:
+ subprocess.run(
+ ["hyprctl", "hyprsunset", "temperature", str(temperature)],
+ check=False,
+ )
+ if gamma is not None:
+ # IPC gamma is integer percent; profile gamma is a 0-2 float.
+ pct = str(round(gamma * 100))
+ subprocess.run(["hyprctl", "hyprsunset", "gamma", pct], check=False)
+
+
+def restart(command: str = "hyprsunset") -> None:
+ subprocess.run(["pkill", "hyprsunset"], check=False)
+ subprocess.Popen(
+ shlex.split(command),
+ stdout=subprocess.DEVNULL,
+ stderr=subprocess.DEVNULL,
+ start_new_session=True,
+ )
diff --git a/tests/test_daemon.py b/tests/test_daemon.py
new file mode 100644
index 0000000..337dc39
--- /dev/null
+++ b/tests/test_daemon.py
@@ -0,0 +1,40 @@
+from unittest.mock import patch, MagicMock
+from hyprsunset_qt import daemon
+
+
+def test_is_running_true():
+ with patch("hyprsunset_qt.daemon.subprocess.run") as run:
+ run.return_value = MagicMock(returncode=0)
+ assert daemon.is_running() is True
+ run.assert_called_once()
+
+
+def test_is_running_false():
+ with patch("hyprsunset_qt.daemon.subprocess.run") as run:
+ run.return_value = MagicMock(returncode=1)
+ assert daemon.is_running() is False
+
+
+def test_live_preview_identity():
+ with patch("hyprsunset_qt.daemon.subprocess.run") as run:
+ daemon.live_preview(identity=True)
+ run.assert_called_with(
+ ["hyprctl", "hyprsunset", "identity"], check=False
+ )
+
+
+def test_live_preview_temp_and_gamma():
+ with patch("hyprsunset_qt.daemon.subprocess.run") as run:
+ daemon.live_preview(temperature=5500, gamma=0.8)
+ calls = [c.args[0] for c in run.call_args_list]
+ assert ["hyprctl", "hyprsunset", "temperature", "5500"] in calls
+ assert ["hyprctl", "hyprsunset", "gamma", "80"] in calls
+
+
+def test_restart_kills_then_launches():
+ with patch("hyprsunset_qt.daemon.subprocess.run") as run, \
+ patch("hyprsunset_qt.daemon.subprocess.Popen") as popen:
+ daemon.restart("hyprsunset")
+ run.assert_called_with(["pkill", "hyprsunset"], check=False)
+ popen.assert_called_once()
+ assert popen.call_args[0][0] == ["hyprsunset"]