home-manager/gui: More screensavers and options
Some checks failed
CI / Check, build and cache Nix flake (push) Failing after 1m5s

This commit is contained in:
Jack O'Sullivan 2024-06-07 13:44:47 +01:00
parent 73f5a690bb
commit 9b5173a587
3 changed files with 46 additions and 38 deletions

View File

@ -15,16 +15,13 @@ let
url = "https://distro.ibiblio.org/slitaz/sources/packages/d/doom1.wad"; url = "https://distro.ibiblio.org/slitaz/sources/packages/d/doom1.wad";
hash = "sha256-HX1DvlAeZ9kn5BXguPPinDvzMHXoWXIYFvZSpSbKx3E="; hash = "sha256-HX1DvlAeZ9kn5BXguPPinDvzMHXoWXIYFvZSpSbKx3E=";
}; };
# doomNcurses = pkgs.writeShellScript "doom-ncurses" ''
# SDL_AUDIODRIVER=null SDL_VIDEODRIVER=caca CACA_DRIVER=ncurses exec ${pkgs.chocolate-doom2xx}/bin/chocolate-doom -iwad ${doomWad}
# '';
# lockCmd = "swaylock-plugin --command-each '${pkgs.windowtolayer}/bin/windowtolayer -- alacritty -e ${doomNcurses}'";
doomsaver = pkgs.runCommand "doomsaver" { doomsaver = pkgs.runCommand "doomsaver" {
inherit (pkgs) windowtolayer; inherit (pkgs) windowtolayer;
chocoDoom = pkgs.chocolate-doom2xx; chocoDoom = pkgs.chocolate-doom2xx;
python = pkgs.python3.withPackages (ps: [ ps.filelock ]); python = pkgs.python3.withPackages (ps: [ ps.filelock ]);
inherit doomWad; inherit doomWad;
enojy = ./enojy.jpg;
} '' } ''
mkdir -p "$out"/bin mkdir -p "$out"/bin
substituteAll ${./screensaver.py} "$out"/bin/doomsaver substituteAll ${./screensaver.py} "$out"/bin/doomsaver
@ -59,6 +56,7 @@ in
cowsay cowsay
fortune fortune
jp2a
terminaltexteffects terminaltexteffects
screenfetch screenfetch
neofetch neofetch

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

@ -74,8 +74,8 @@ class TTESaver(Screensaver):
def wait(self): def wait(self):
while self.running: while self.running:
effect_cmd = ['tte', random.choice(self.effects)] effect_cmd = ['tte', random.choice(self.effects)]
print(f"$ {' '.join(self.cmd)} | {' '.join(effect_cmd)}") print(f"$ {self.cmd} | {' '.join(effect_cmd)}")
content = subprocess.check_output(self.cmd, env=self.env, stderr=subprocess.DEVNULL) content = subprocess.check_output(self.cmd, shell=True, env=self.env, stderr=subprocess.DEVNULL)
self.proc = subprocess.Popen(effect_cmd, stdin=subprocess.PIPE) self.proc = subprocess.Popen(effect_cmd, stdin=subprocess.PIPE)
self.proc.stdin.write(content) self.proc.stdin.write(content)
@ -94,23 +94,27 @@ class MultiSaver:
Screensaver(['cmatrix']), Screensaver(['cmatrix']),
TTESaver(['screenfetch', '-N']), TTESaver('screenfetch -N'),
TTESaver(['fortune']), TTESaver('fortune'),
TTESaver(['top', '-n1']), TTESaver('top -n1'),
TTESaver(['ss', '-nltu']), TTESaver('ss -nltu'),
TTESaver(['ss', '-ntu']), TTESaver('ss -ntu'),
TTESaver('jp2a --width=100 @enojy@'),
] ]
state_filename = 'screensaver.json' state_filename = 'screensaver.json'
def __init__(self): def __init__(self, select=None):
self.state_path = os.path.join(f'/run/user/{os.geteuid()}', self.state_filename) self.state_path = os.path.join(f'/run/user/{os.geteuid()}', self.state_filename)
self.lock = filelock.FileLock(f'{self.state_path}.lock') self.lock = filelock.FileLock(f'{self.state_path}.lock')
self.selected = None if select is not None:
assert select >= 0 and select < len(self.savers), 'Invalid screensaver index'
self.selected = self.savers[select]
else:
self.selected = None
self.cleaned_up = False self.cleaned_up = False
def select(self): def select(self):
assert self.selected is None
with self.lock: with self.lock:
if not os.path.exists(self.state_path): if not os.path.exists(self.state_path):
state = {'instances': []} state = {'instances': []}
@ -118,33 +122,34 @@ class MultiSaver:
with open(self.state_path) as f: with open(self.state_path) as f:
state = json.load(f) state = json.load(f)
available = set(range(len(self.savers))) if self.selected is None:
new_instances = [] available = set(range(len(self.savers)))
for instance in state['instances']: new_instances = []
if not os.path.exists(f"/proc/{instance['pid']}"): for instance in state['instances']:
continue if not os.path.exists(f"/proc/{instance['pid']}"):
continue
new_instances.append(instance) new_instances.append(instance)
i = instance['saver'] i = instance['saver']
assert i in available assert i in available
available.remove(i) available.remove(i)
assert available, 'No screensavers left' assert available, 'No screensavers left'
available = list(available) available = list(available)
weights = [] weights = []
for i in available: for i in available:
weights.append(self.savers[i].weight) weights.append(self.savers[i].weight)
selected_i = random.choices(available, weights=weights)[0] selected_i = random.choices(available, weights=weights)[0]
new_instances.append({'pid': os.getpid(), 'saver': selected_i}) new_instances.append({'pid': os.getpid(), 'saver': selected_i})
state['instances'] = new_instances state['instances'] = new_instances
# print(f'Selected saver {selected_i}')
self.selected = self.savers[selected_i]
with open(self.state_path, 'w') as f: with open(self.state_path, 'w') as f:
json.dump(state, f) json.dump(state, f)
# print(f'Selected saver {selected_i}')
self.selected = self.savers[selected_i]
def cleanup(self): def cleanup(self):
if self.cleaned_up: if self.cleaned_up:
return return
@ -181,17 +186,22 @@ class MultiSaver:
def main(): def main():
parser = argparse.ArgumentParser(description='Wayland terminal-based lock screen') parser = argparse.ArgumentParser(description='Wayland terminal-based lock screen')
parser.add_argument('-l', '--locker-cmd', default='swaylock-plugin', help='swaylock-plugin command to use')
parser.add_argument('-t', '--terminal', default='alacritty', help='Terminal emulator to use') parser.add_argument('-t', '--terminal', default='alacritty', help='Terminal emulator to use')
parser.add_argument('-i', '--instance', action='store_true', help='Run as instance') parser.add_argument('-i', '--instance', action='store_true', help='Run as instance')
parser.add_argument('-s', '--screensaver', type=int, help='Force use of specific screensaver')
args = parser.parse_args() args = parser.parse_args()
if not args.instance: if not args.instance:
subprocess.check_call([ cmd = [
'swaylock-plugin', '--command-each', args.locker_cmd, '--command-each',
f'@windowtolayer@/bin/windowtolayer -- {args.terminal} -e {sys.argv[0]} --instance']) f'@windowtolayer@/bin/windowtolayer -- {args.terminal} -e {sys.argv[0]} --instance']
if args.screensaver is not None:
cmd[-1] += f' --screensaver {args.screensaver}'
subprocess.check_call(cmd)
return return
ms = MultiSaver() ms = MultiSaver(select=args.screensaver)
ms.select() ms.select()
ms.run() ms.run()