refactor: group stow packages into common, mac and kde

Split the packages by platform so each app stays an opt-in Stow package
under common/, mac/ or kde/. KDE gets its own Fastfetch, Helium and
Spectacle packages, and darwin-breeze becomes kde/theme. The READMEs
document stowing a whole group as well as individual packages.
This commit is contained in:
tri committed 2026-10-30 21:57:15 +07:00
1 parent 1e99a15f6c
commit 34e978e84c
74 files changed
+532 -151

No files matched your search

+85
View File
@@ -0,0 +1,85 @@
#!/usr/bin/env python3
"""Apply screenshot preferences and reload Spectacle's KDE shortcuts."""
import ast
import configparser
import os
from pathlib import Path
import re
import subprocess
HERE = Path(__file__).resolve().parent
COMPONENT = "org.kde.spectacle.desktop"
ACCEL = "/component/org_kde_spectacle_desktop"
def run(*args, **kwargs):
return subprocess.run(args, check=True, text=True, **kwargs)
def accel(path, method, *args):
return run(
"gdbus", "call", "--session", "--dest", "org.kde.kglobalaccel",
"--object-path", path, "--method", method, *args,
capture_output=True,
).stdout
def main():
for name in ("spectaclerc", "klipperrc"):
config = configparser.ConfigParser(interpolation=None)
config.optionxform = str
config.read(HERE / "settings" / name)
for group in config.sections():
for key, value in config[group].items():
run("kwriteconfig6", "--file", name, "--group", group,
"--key", key, value)
# T3's locale and XDG_DATA_DIRS can differ from the running KDE session.
# Build the cache KDE actually reads, rather than an app-specific cache.
session = dict(
line.split("=", 1) for line in
run("systemctl", "--user", "show-environment", capture_output=True)
.stdout.splitlines() if "=" in line
)
env = os.environ.copy()
for key in ("LANG", "LANGUAGE", "XDG_DATA_DIRS", "XDG_DATA_HOME",
"XDG_CACHE_HOME", "XDG_CONFIG_HOME"):
env.pop(key, None)
if key in session:
env[key] = session[key]
for key in set(env) | set(session):
if key.startswith("LC_"):
env.pop(key, None)
if key in session:
env[key] = session[key]
run("kbuildsycoca6", "--noincremental", env=env)
# Existing shortcut components retain their old Exec commands. Recreate
# only Spectacle's component, preserving any customized key bindings.
try:
output = accel(ACCEL, "org.kde.kglobalaccel.Component.allShortcutInfos")
except subprocess.CalledProcessError:
shortcuts = [] # Component has not been registered yet.
else:
shortcuts = ast.literal_eval(re.sub(r"@a[is] ", "", output))[0]
accel(ACCEL, "org.kde.kglobalaccel.Component.cleanUp")
action = [COMPONENT, "_reload_config", "Spectacle", "Reload configuration"]
accel("/kglobalaccel", "org.kde.KGlobalAccel.doRegister", repr(action))
accel("/kglobalaccel", "org.kde.KGlobalAccel.unregister",
COMPONENT, "_reload_config")
for name, label, component, friendly, context, _, keys, defaults in shortcuts:
if keys != defaults:
identity = component if context == "default" else f"{component}|{context}"
accel("/kglobalaccel", "org.kde.KGlobalAccel.setForeignShortcut",
repr([identity, name, friendly, label]), repr(keys))
run("qdbus6", "org.kde.klipper", "/klipper",
"org.kde.klipper.klipper.reloadConfig")
print("Applied Spectacle: copy to clipboard with a notification, no preview.")
if __name__ == "__main__":
main()