#!/usr/bin/python3

import os, random, time, subprocess, sys, fcntl, copy, signal

wallpaper_dir = os.environ['HOME'] + "/pictures/wallpapers/"
displays = ["DP-1", "DP-2"]
change_time = 60 * 60
grace_period = 5

# don't change values below this
swaybg_pids = []

# courtesy of https://stackoverflow.com/a/384493
def instance_already_running(label="default"):
    """
    Detect if an an instance with the label is already running, globally
    at the operating system level.

    Using `os.open` ensures that the file pointer won't be closed
    by Python's garbage collector after the function's scope is exited.

    The lock will be released when the program exits, or could be
    released if the file pointer were closed.
    """

    lock_file_pointer = os.open(f"/tmp/instance_{label}.lock", os.O_WRONLY | os.O_CREAT)

    try:
        fcntl.lockf(lock_file_pointer, fcntl.LOCK_EX | fcntl.LOCK_NB)
        already_running = False
    except IOError:
        already_running = True

    return already_running


already_running = instance_already_running()
while not already_running:
    print("Changing wallpapers")
    wallpapers = os.listdir(wallpaper_dir)
    random.shuffle(wallpapers)
    new_pids = []
    for idx, display in enumerate(displays):
        proc = subprocess.Popen(["swaybg", "-o", display, "-i", wallpaper_dir + wallpapers[idx], "-m", "fill"])
        new_pids.append(proc.pid)
        print(f"Appending pid {proc.pid}")
        #subprocess.run(["sway", "output", display, "bg", wallpaper_dir + wallpapers[idx], "fill"])
    # kill the old PIDs
    time.sleep(grace_period)
    for pid in swaybg_pids:
        os.kill(pid, signal.SIGTERM)
    swaybg_pids = copy.deepcopy(new_pids)
    time.sleep(change_time - grace_period)
wallpaper-changer.py