84 lines
3 KiB
Python
Executable file
84 lines
3 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
"""
|
|
wallpaper.py - random wallpaper/output utility for i3/Sway
|
|
|
|
usage: wallpaper.py [-h] [--select {common,unique}] directory
|
|
|
|
Selection modes:
|
|
Common: One wallpaper selected and shared for *all* displays
|
|
Unique: One wallpaper selected for *each* display
|
|
"""
|
|
import argparse
|
|
import os
|
|
import sys
|
|
import random
|
|
import asyncio
|
|
from typing import List
|
|
from i3ipc.aio import Connection
|
|
|
|
EXTS = ['.jpg', '.jpeg', '.png', '.bmp', '.gif']
|
|
|
|
def parse_args():
|
|
'''Handles argparse on startup'''
|
|
parser = argparse.ArgumentParser(description='Random Wallpaper Setter for Sway')
|
|
parser.add_argument('directory', type=str, help='Directory containing wallpapers')
|
|
parser.add_argument('--select',
|
|
type=str,
|
|
choices=['common', 'unique'],
|
|
default='common',
|
|
help='Wallpaper selection mode: all displays, or each?')
|
|
return parser.parse_args()
|
|
|
|
async def main():
|
|
'''you know what it is'''
|
|
args = parse_args()
|
|
sway = await Connection(auto_reconnect=True).connect()
|
|
def list_image_files(d: str) -> List[str]:
|
|
'''
|
|
Given the path to a *'directory'*, returns a list of image files to consider for wallpapers.
|
|
'''
|
|
return [os.path.join(d, f) for f in os.listdir(d) if os.path.splitext(f)[1].lower() in EXTS]
|
|
|
|
async def set_wallpaper(file_path: str, output=None):
|
|
'''
|
|
Given an image path, sets the wallpaper for (optional) outputs in i3/Sway.
|
|
|
|
If no output is specified then *all* will receive the wallpaper.
|
|
'''
|
|
print(f"{output if output else 'all'}: wallpaper='{file_path}'")
|
|
if output:
|
|
await sway.command(f'output "{output}" bg "{file_path}" fill')
|
|
else:
|
|
for _output in await sway.get_outputs():
|
|
await sway.command(f'output "{_output.name}" bg "{file_path}" fill')
|
|
|
|
if os.path.isdir(args.directory):
|
|
image_files = list_image_files(args.directory)
|
|
else:
|
|
sys.exit(f'ERR: not a directory: {args.directory}')
|
|
if not image_files:
|
|
print("No image files found in the specified directory.")
|
|
return
|
|
|
|
print(f'Found {len(image_files)} candidate image files')
|
|
outputs = await sway.get_outputs()
|
|
|
|
if args.select == 'common':
|
|
wallpaper = random.choice(image_files)
|
|
await set_wallpaper(wallpaper)
|
|
else: # args.select == 'unique', we need to determine a wallpaper for each display
|
|
for output in outputs:
|
|
if len(image_files) == 0:
|
|
print(f"Not enough images in '{args.directory}' for each display.")
|
|
break
|
|
wallpaper = random.choice(image_files)
|
|
image_files.remove(wallpaper)
|
|
await set_wallpaper(wallpaper, output.name)
|
|
|
|
if __name__ == "__main__":
|
|
loop = asyncio.new_event_loop()
|
|
asyncio.set_event_loop(loop)
|
|
try:
|
|
loop.run_until_complete(main())
|
|
except KeyboardInterrupt:
|
|
pass
|