init
This commit is contained in:
121 files changed
+17641
No files matched your search
@@ -0,0 +1,140 @@
|
||||
"""Starting with the session, the way the desktop expects.
|
||||
|
||||
Two mechanisms, because the two desktops disagree about which is canonical:
|
||||
|
||||
* a `.desktop` file in `~/.config/autostart` — the XDG standard, honoured by
|
||||
KDE, GNOME, XFCE and friends;
|
||||
* a **systemd user unit**, which is what you actually want on a modern box: it
|
||||
restarts the app if it dies and keeps its logs in the journal.
|
||||
|
||||
Either can be switched on alone; the app only ever touches files under the
|
||||
user's own config, never system paths.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
DESKTOP_FILE_NAME = "kadence.desktop"
|
||||
SERVICE_NAME = "kadence-desktop.service"
|
||||
|
||||
|
||||
def _autostart_dir() -> Path:
|
||||
base = os.environ.get("XDG_CONFIG_HOME") or str(Path.home() / ".config")
|
||||
path = Path(base) / "autostart"
|
||||
path.mkdir(parents=True, exist_ok=True)
|
||||
return path
|
||||
|
||||
|
||||
def _systemd_user_dir() -> Path:
|
||||
base = os.environ.get("XDG_CONFIG_HOME") or str(Path.home() / ".config")
|
||||
path = Path(base) / "systemd" / "user"
|
||||
path.mkdir(parents=True, exist_ok=True)
|
||||
return path
|
||||
|
||||
|
||||
def launch_command() -> str:
|
||||
"""How to start this app again, whether installed or run from a checkout."""
|
||||
executable = shutil.which("kadence-desktop")
|
||||
if executable:
|
||||
return executable
|
||||
return f"{sys.executable} -m kadence_desktop"
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# XDG autostart
|
||||
# --------------------------------------------------------------------------
|
||||
def autostart_enabled() -> bool:
|
||||
return (_autostart_dir() / DESKTOP_FILE_NAME).exists()
|
||||
|
||||
|
||||
def set_autostart(enabled: bool, *, minimized: bool = True) -> None:
|
||||
path = _autostart_dir() / DESKTOP_FILE_NAME
|
||||
if not enabled:
|
||||
path.unlink(missing_ok=True)
|
||||
return
|
||||
command = launch_command() + (" --minimized" if minimized else "")
|
||||
path.write_text(
|
||||
"\n".join(
|
||||
[
|
||||
"[Desktop Entry]",
|
||||
"Type=Application",
|
||||
"Name=Kadence",
|
||||
"Comment=Pomodoro timer, task list and focus guard",
|
||||
f"Exec={command}",
|
||||
"Icon=kadence",
|
||||
"Terminal=false",
|
||||
"Categories=Utility;Office;",
|
||||
"X-GNOME-Autostart-enabled=true",
|
||||
"",
|
||||
]
|
||||
),
|
||||
"utf-8",
|
||||
)
|
||||
log.info("autostart entry written to %s", path)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# systemd user service
|
||||
# --------------------------------------------------------------------------
|
||||
def service_installed() -> bool:
|
||||
return (_systemd_user_dir() / SERVICE_NAME).exists()
|
||||
|
||||
|
||||
def service_enabled() -> bool:
|
||||
if not shutil.which("systemctl"):
|
||||
return False
|
||||
result = subprocess.run(
|
||||
["systemctl", "--user", "is-enabled", SERVICE_NAME],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=False,
|
||||
)
|
||||
return result.stdout.strip() == "enabled"
|
||||
|
||||
|
||||
def install_service(*, enable: bool = True) -> str:
|
||||
"""Write (and optionally enable) the user unit. Returns a status line."""
|
||||
path = _systemd_user_dir() / SERVICE_NAME
|
||||
path.write_text(
|
||||
"\n".join(
|
||||
[
|
||||
"[Unit]",
|
||||
"Description=Kadence desktop client",
|
||||
"PartOf=graphical-session.target",
|
||||
"After=graphical-session.target",
|
||||
"",
|
||||
"[Service]",
|
||||
"Type=simple",
|
||||
f"ExecStart={launch_command()} --minimized",
|
||||
"Restart=on-failure",
|
||||
"RestartSec=5",
|
||||
"",
|
||||
"[Install]",
|
||||
"WantedBy=graphical-session.target",
|
||||
"",
|
||||
]
|
||||
),
|
||||
"utf-8",
|
||||
)
|
||||
if not shutil.which("systemctl"):
|
||||
return f"unit written to {path} (systemctl not found)"
|
||||
subprocess.run(["systemctl", "--user", "daemon-reload"], check=False)
|
||||
if enable:
|
||||
subprocess.run(["systemctl", "--user", "enable", SERVICE_NAME], check=False)
|
||||
return f"unit written to {path}" + (" and enabled" if enable else "")
|
||||
|
||||
|
||||
def remove_service() -> None:
|
||||
if shutil.which("systemctl"):
|
||||
subprocess.run(["systemctl", "--user", "disable", "--now", SERVICE_NAME], check=False)
|
||||
(_systemd_user_dir() / SERVICE_NAME).unlink(missing_ok=True)
|
||||
if shutil.which("systemctl"):
|
||||
subprocess.run(["systemctl", "--user", "daemon-reload"], check=False)
|
||||
Reference in new issue
Block a user