- hypr/apps.lua - hypr/autostart.lua - hypr/envs.lua - hypr/hyprland.lua - hypr/hyprsunset.conf - hypr/input.lua - hypr/looknfeel.lua - hypr/omasettings.lua - hypr/xdph.conf - omarchy/branding/about.txt - omarchy/branding/screensaver.txt - omarchy/extensions/omarchy-menu.jsonc - omarchy/hooks/battery-low.d/play-warning-sound.sample - omarchy/hooks/font-set.d/show-font-notification.sample - omarchy/hooks/post-boot.d/weather.sample - omarchy/hooks/post-update.d/install-voxtype.hook - omarchy/hooks/post-update.d/setup-agent.hook - omarchy/hooks/post-update.d/setup-fingerprint.hook - omarchy/hooks/post-update.d/show-update-notification.sample - omarchy/hooks/pre-refresh-pacman.d/add-custom-repo.sample - omarchy/hooks/theme-set.d/show-theme-notification.sample - omarchy/shell.json - omarchy/shell.toml - omarchy/theme.name - omarchy/themes/azure-glow/README.md - omarchy/themes/azure-glow/alacritty.toml - omarchy/themes/azure-glow/btop.theme - omarchy/themes/azure-glow/hyprland.conf - omarchy/themes/azure-glow/hyprlock.conf - omarchy/themes/azure-glow/icons.theme - … 269 more
92 lines
2.6 KiB
Python
92 lines
2.6 KiB
Python
"""Where Nexthop keeps its state.
|
|
|
|
Two directories since 0.2.22. The state dir (XDG_STATE_HOME, like the rest
|
|
of Omarchy) holds what must outlive the session: history.db, the
|
|
config.json the panel writes for the daemon, and the lock so two daemons
|
|
never fight. The runtime dir (XDG_RUNTIME_DIR, a per-user tmpfs) holds the
|
|
three snapshots the daemon rewrites continuously — live.json twice a
|
|
second, apps.json every three, recent.json every five. They are derived,
|
|
session-scoped, and worth nothing after a reboot, and on this laptop's
|
|
btrfs each 2.5 KB rewrite cost 62.5 KiB at the block layer with fsync:
|
|
14.65 GB a day for a bar widget, measured from the kernel's own counter.
|
|
On tmpfs it is nothing. Without XDG_RUNTIME_DIR they fall back to the
|
|
state dir, so reader and writer always agree in one session environment.
|
|
"""
|
|
|
|
import os
|
|
from pathlib import Path
|
|
|
|
|
|
def state_dir() -> Path:
|
|
base = os.environ.get("XDG_STATE_HOME") or os.path.join(Path.home(), ".local", "state")
|
|
return Path(base) / "nexthop"
|
|
|
|
|
|
def ensure_state_dir() -> Path:
|
|
"""Create the state dir, private to the user (0700).
|
|
|
|
The files inside carry the daemon's pid and the version string the
|
|
shell service uses to authorize a SIGTERM — nothing another account
|
|
has any business reading, let alone writing.
|
|
"""
|
|
d = state_dir()
|
|
d.mkdir(parents=True, exist_ok=True)
|
|
try:
|
|
d.chmod(0o700)
|
|
except OSError:
|
|
pass
|
|
return d
|
|
|
|
|
|
def runtime_dir() -> Path:
|
|
"""The volatile snapshots' home: the session's tmpfs, else the state dir."""
|
|
base = os.environ.get("XDG_RUNTIME_DIR")
|
|
if base and os.path.isdir(base):
|
|
return Path(base) / "nexthop"
|
|
return state_dir()
|
|
|
|
|
|
def ensure_runtime_dir() -> Path:
|
|
"""Create the runtime dir, private to the user like the state dir."""
|
|
d = runtime_dir()
|
|
d.mkdir(parents=True, exist_ok=True, mode=0o700)
|
|
try:
|
|
d.chmod(0o700)
|
|
except OSError:
|
|
pass
|
|
return d
|
|
|
|
|
|
LIVE = "live.json"
|
|
RECENT = "recent.json"
|
|
APPS = "apps.json"
|
|
DB = "history.db"
|
|
LOCK = "nexthopd.lock"
|
|
|
|
|
|
def live_path() -> Path:
|
|
return runtime_dir() / LIVE
|
|
|
|
|
|
def recent_path() -> Path:
|
|
return runtime_dir() / RECENT
|
|
|
|
|
|
def apps_path() -> Path:
|
|
return runtime_dir() / APPS
|
|
|
|
|
|
def manifest_path() -> Path:
|
|
"""The plugin's own manifest, beside this package rather than in the
|
|
state dir — the shell service reads it to spot a fast-forwarded
|
|
checkout."""
|
|
return Path(__file__).resolve().parent.parent / "manifest.json"
|
|
|
|
|
|
def db_path() -> Path:
|
|
return state_dir() / DB
|
|
|
|
|
|
def lock_path() -> Path:
|
|
return state_dir() / LOCK
|