diff --git a/scripts/ctl b/scripts/ctl index 383906b..164da58 100755 --- a/scripts/ctl +++ b/scripts/ctl @@ -239,6 +239,153 @@ media) ;; esac ;; +wallpaper) + require python + python - "$2" << 'PYTHON' +import os +import random +import subprocess +import sys + +try: + from PIL import Image, ImageDraw +except ImportError: + print("ctl: missing dependency: pillow", file=sys.stderr) + sys.exit(1) + +HOME = os.environ["HOME"] +DIR = os.path.join(os.environ.get("XDG_PICTURES_DIR", os.path.join(HOME, "Pictures")), "Screensavers") +os.makedirs(DIR, exist_ok=True) + + +def get_resolution(): + output = "1920x1080" + if "WAYLAND_DISPLAY" in os.environ: + desktop = os.environ.get("XDG_CURRENT_DESKTOP", "") + if desktop == "Hyprland": + output = ( + subprocess.check_output( + "hyprctl monitors -j | jq -r '.[] | select(.focused==true) | .width, .height' | paste -sd x -", + shell=True, + ) + .decode() + .strip() + ) + elif desktop == "sway": + output = ( + subprocess.check_output( + "swaymsg -t get_outputs -r | jq -r '.[] | select(.active==true) | .current_mode.width,.current_mode.height' | paste -sd x -", + shell=True, + ) + .decode() + .strip() + ) + else: + output = ( + subprocess.check_output( + "xrandr | grep '*' | awk '{print $1}'", shell=True + ) + .decode() + .strip() + ) + return map(int, output.split("x")) + + +def lock(): + W, H = get_resolution() + UNIT = 16 + grid_w = W // UNIT + grid_h = H // UNIT + + bg_color = tuple(random.randint(0, 255) for _ in range(3)) + img = Image.new("RGB", (W, H), bg_color) + draw = ImageDraw.Draw(img) + + MU = 0.8 + SIGMA = 0.7 + SCALE_FACTOR = 1.8 + + S = {(x, y) for x in range(grid_w) for y in range(grid_h)} + N = len(S) + + while S: + if random.random() < 1 / N: + break + gx, gy = S.pop() + w_units = max( + 1, + min( + grid_w - gx, + int(round(random.lognormvariate(MU, SIGMA) * SCALE_FACTOR)), + ), + ) + h_units = max( + 1, + min( + grid_h - gy, + int(round(random.lognormvariate(MU, SIGMA) * SCALE_FACTOR)), + ), + ) + color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) + + dx = random.choice([1, -1]) + dy = random.choice([1, -1]) + + gx_end = gx + dx * (w_units - 1) + gy_end = gy + dy * (h_units - 1) + + x0, x1 = sorted([gx, gx_end]) + y0, y1 = sorted([gy, gy_end]) + + draw.rectangle( + [x0 * UNIT, y0 * UNIT, (x1 + 1) * UNIT - 1, (y1 + 1) * UNIT - 1], + fill=color, + ) + + img.save(f"{DIR}/lock.jpg", quality=95) + + +def wall(): + W, H = get_resolution() + + colors = [ + "#aa0000", + "#ff3333", + "#ff7777", + "#ffbb55", + "#ffcc88", + "#ff88ff", + "#aaaaff", + "#77ddbb", + "#77ff77", + "#cccccc", + ] + + colors.reverse() + + img = Image.new("RGB", (W, H), "white") + draw = ImageDraw.Draw(img) + + num_bars = len(colors) + + for i, color in enumerate(reversed(colors)): + top = round(i * H / num_bars) + bottom = round((i + 1) * H / num_bars) + draw.rectangle([0, top, W, bottom], fill=color) + + img.save(f"{DIR}/wallpaper.jpg", quality=95) + + +cmd = sys.argv[1] if len(sys.argv) > 1 else None +if cmd == "lock": + lock() +elif cmd == "wall": + wall() +else: + print("Usage: ctl wallpaper {wall|lock}", file=sys.stderr) + sys.exit(1) +PYTHON + ;; power) require fuzzel lock="󰌾 Lock" @@ -256,7 +403,7 @@ power) esac ;; *) - echo "Usage: ctl {screenshot|ocr|keyboard|audio|wifi|brightness|volume|media|power}" >&2 + echo "Usage: ctl {screenshot|ocr|keyboard|audio|wifi|brightness|volume|media|wallpaper|power}" >&2 exit 1 ;; esac diff --git a/scripts/wp b/scripts/wp deleted file mode 100755 index 7ac4d9b..0000000 --- a/scripts/wp +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/env python3 -# Requires python3 with Pillow (provided by home-manager packages) - -import os -import random -import subprocess -import sys - -try: - from PIL import Image, ImageDraw -except ImportError: - print("wp: missing dependency: pillow (should be in home-manager python3 package)", file=sys.stderr) - sys.exit(1) - -HOME = os.environ["HOME"] -DIR = f"{HOME}/Pictures/Screensavers" -os.makedirs(DIR, exist_ok=True) - - -def get_resolution(): - output = "1920x1080" - if "WAYLAND_DISPLAY" in os.environ: - desktop = os.environ.get("XDG_CURRENT_DESKTOP", "") - if desktop == "Hyprland": - output = ( - subprocess.check_output( - "hyprctl monitors -j | jq -r '.[] | select(.focused==true) | .width, .height' | paste -sd x -", - shell=True, - ) - .decode() - .strip() - ) - elif desktop == "sway": - output = ( - subprocess.check_output( - "swaymsg -t get_outputs -r | jq -r '.[] | select(.active==true) | .current_mode.width,.current_mode.height' | paste -sd x -", - shell=True, - ) - .decode() - .strip() - ) - else: - output = ( - subprocess.check_output( - "xrandr | grep '*' | awk '{print $1}'", shell=True - ) - .decode() - .strip() - ) - return map(int, output.split("x")) - - -def lock(): - W, H = get_resolution() - UNIT = 16 - grid_w = W // UNIT - grid_h = H // UNIT - - bg_color = tuple(random.randint(0, 255) for _ in range(3)) - img = Image.new("RGB", (W, H), bg_color) - draw = ImageDraw.Draw(img) - - MU = 0.8 - SIGMA = 0.7 - SCALE_FACTOR = 1.8 - - S = {(x, y) for x in range(grid_w) for y in range(grid_h)} - N = len(S) - - while S: - if random.random() < 1 / N: - break - gx, gy = S.pop() - w_units = max( - 1, - min( - grid_w - gx, - int(round(random.lognormvariate(MU, SIGMA) * SCALE_FACTOR)), - ), - ) - h_units = max( - 1, - min( - grid_h - gy, - int(round(random.lognormvariate(MU, SIGMA) * SCALE_FACTOR)), - ), - ) - color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) - - dx = random.choice([1, -1]) - dy = random.choice([1, -1]) - - gx_end = gx + dx * (w_units - 1) - gy_end = gy + dy * (h_units - 1) - - x0, x1 = sorted([gx, gx_end]) - y0, y1 = sorted([gy, gy_end]) - - draw.rectangle( - [x0 * UNIT, y0 * UNIT, (x1 + 1) * UNIT - 1, (y1 + 1) * UNIT - 1], - fill=color, - ) - - img.save(f"{DIR}/lock.jpg", quality=95) - - -def wall(): - W, H = get_resolution() - - colors = [ - "#aa0000", - "#ff3333", - "#ff7777", - "#ffbb55", - "#ffcc88", - "#ff88ff", - "#aaaaff", - "#77ddbb", - "#77ff77", - "#cccccc", - ] - - colors.reverse() - - img = Image.new("RGB", (W, H), "white") - draw = ImageDraw.Draw(img) - - num_bars = len(colors) - - for i, color in enumerate(reversed(colors)): - top = round(i * H / num_bars) - bottom = round((i + 1) * H / num_bars) - draw.rectangle([0, top, W, bottom], fill=color) - - img.save(f"{DIR}/wallpaper.jpg", quality=95) - - -if len(sys.argv) < 2: - print("Usage: wp {lock|wall}", file=sys.stderr) - sys.exit(1) - -cmd = sys.argv[1] -if cmd == "lock": - lock() -elif cmd == "wall": - wall() -else: - print("Usage: wp {lock|wall}", file=sys.stderr) - sys.exit(1)