Hyprland drops the layer-shell surfaces on the remaining output when a monitor is removed and does not recreate them, so waybar and the awww wallpaper vanish on unplug. The socket2 watcher only reacted to `monitoradded`, which masked it — reconnecting re-fired the add and restored both. Handle `monitorremoved` too, and on either event re-push the wallpaper and reload waybar (SIGUSR2 rebuilds its per-output bars). Renamed `wallpaper-hotplug` to `monitor-hotplug` since it now does both. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
84 lines
3.8 KiB
Nix
84 lines
3.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, ... }:
|
|
|
|
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 unplug: removing an output makes Hyprland
|
|
# drop and not recreate the layer-shell surfaces on the surviving monitor, 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 reload waybar (SIGUSR2 rebuilds its per-output bars). 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).
|
|
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>>"*)
|
|
setbg
|
|
${pkgs.procps}/bin/pkill -USR2 -x .waybar-wrapped || true
|
|
;;
|
|
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
|
|
];
|
|
}
|