Files
nixos-config/modules/media.nix
T
daniil-bergandClaude Opus 4.8 38556c8839 fix(home): match wrapped waybar comm when killing bar on monitor change
`pkill -x waybar` matched only comm `waybar`, but the home-manager
wrapper launches the bar with comm `.waybar-wrapped` (arg[0] still
`waybar`), so the kill missed and left a stale bar drawing on the old
geometry after an unplug. Match both comms via an anchored ERE in both
the `monitor-hotplug` handler and `swapMonitors`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-22 19:16:44 +02:00

98 lines
4.8 KiB
Nix

# Generic viewers. mpv for video/audio, imv for images, zathura for PDFs/docs —
# all minimal, keyboard-driven, Wayland-native. No personal config here.
#
# imv key binds run external actions on the current file (yank path, rotate/flip,
# delete, open in editor, info). Wallpaper uses awww (daemon + CLI): `setbg`
# symlinks the chosen file to ~/.local/share/bg and pushes it live. The
# awww-daemon and the boot-time restore from that symlink run as Hyprland
# `exec-once` (see home.nix).
{ pkgs, config, ... }:
let
# setbg: persist the choice as an XDG-data symlink, then set it live. Startup
# restore just re-runs `awww img` against the same symlink.
setbg = pkgs.writeShellScriptBin "setbg" ''
bgloc="''${XDG_DATA_HOME:-$HOME/.local/share}/bg"
[ -n "$1" ] && ln -sf "$(readlink -f "$1")" "$bgloc"
${pkgs.awww}/bin/awww img "$bgloc"
'';
# awww-daemon paints only the outputs present when `awww img` last ran and does
# not repaint a monitor hotplugged afterwards — it comes up on the fill color
# (black), and a transparent foot on it then shows that black, not the
# wallpaper. Symmetric problem on real DP/HDMI unplug: Hyprland drops the
# layer-shell surfaces on the surviving monitor and does not recreate them, so
# its waybar and wallpaper vanish. Watch Hyprland's event socket and, on either
# add or remove, re-push the wallpaper (setbg with no arg → all current
# outputs) and fully relaunch waybar. A SIGUSR2 reload is not enough — it
# rereads config but does not recreate a bar Hyprland already tore down — so
# kill and restart, which enumerates the current outputs and draws a bar on
# each. The event flaps (several add/remove lines per plug); the loop is
# sequential so each pass converges to one waybar. Hyprland emits both
# `monitoradded` and `monitoraddedv2`; match only the non-v2 forms so each side
# fires once. Runs as a Hyprland exec-once (see home.nix).
hyprctl = "${config.wayland.windowManager.hyprland.finalPackage}/bin/hyprctl";
monitorHotplug = pkgs.writeShellScriptBin "monitor-hotplug" ''
sock="''${XDG_RUNTIME_DIR}/hypr/''${HYPRLAND_INSTANCE_SIGNATURE}/.socket2.sock"
${pkgs.socat}/bin/socat -u UNIX-CONNECT:"$sock" - | while IFS= read -r line; do
case "$line" in
"monitoradded>>"* | "monitorremoved>>"*)
sleep 1 # let Hyprland settle the new geometry
setbg # re-push wallpaper to all current outputs
# Anchored ERE matching `comm` (max 15 chars): the bar launched via the
# home-manager wrapper reports comm `.waybar-wrapped` (arg[0] is still
# `waybar`), so a bare `-x waybar` never matches it and leaves a stale bar.
wb='\.waybar-wrapped|waybar'
${pkgs.procps}/bin/pkill -x "$wb" || true # relaunch waybar fresh (see comment)
i=0
while [ $i -lt 6 ] && ${pkgs.procps}/bin/pgrep -x "$wb" >/dev/null; do sleep 0.3; i=$((i+1)); done
${pkgs.procps}/bin/pkill -9 -x "$wb" || true
${hyprctl} dispatch exec waybar
;;
esac
done
'';
in
{
programs.mpv = {
enable = true;
# gallery/thumbnail grid for playlists. Ships the scripts; key bindings to
# open it can be added later via programs.mpv.bindings (input.conf).
scripts = [ pkgs.mpvScripts.mpv-gallery-view ];
};
programs.imv = {
enable = true;
settings.binds = {
"w" = ''exec setbg "$imv_current_file"'';
"y" = ''exec printf %s "$imv_current_file" | wl-copy'';
"<Shift+Y>" = ''exec readlink -f "$imv_current_file" | wl-copy'';
"<Shift+D>" = ''exec rm "$imv_current_file"''; # no confirm
"r" = ''exec magick "$imv_current_file" -rotate 90 "$imv_current_file"'';
"<Shift+R>" = ''exec magick "$imv_current_file" -rotate -90 "$imv_current_file"'';
"f" = ''exec magick "$imv_current_file" -flop "$imv_current_file"'';
"e" = ''exec gimp "$imv_current_file"''; # edit; `g` reserved by imv's gg chord
"i" = ''exec notify-send "File info" "$(mediainfo "$imv_current_file")"'';
};
};
# PDF/document viewer. pkgs.zathura bundles the mupdf backend, so enabling is
# enough. Route yanks to the wayland clipboard.
programs.zathura = {
enable = true;
options.selection-clipboard = "clipboard";
};
home.packages = with pkgs; [
setbg
monitorHotplug # re-push wallpaper + reload waybar on monitor add/remove (see comment above)
awww # wayland wallpaper daemon (setbg backend)
wl-clipboard # wl-copy, for the yank binds
imagemagick # `magick`: rotate/flip binds
mediainfo # `i` info bind
libnotify # notify-send client (daemon = mako, in home.nix)
gimp # `e` open-in-editor bind
];
}