Commit bbe1f9e7a471

Vincent Demeester <vincent@sbr.pm>
2026-03-27 12:55:03
feat: integrate shotty for screenshots and recording
Replaced niri-screenshot shell wrapper and shot/shotf raffi entries with shotty, a dedicated Go tool wrapping grim, slurp, wf-recorder, satty, and niri native screenshot actions. Added waybar recording widget, screen recording keybindings, and satty annotation support via Shift+Print. Updated chick-group flake input to include the shotty package.
1 parent 025527e
Changed files (5)
dots
config
home
common
dots/config/niri/config.kdl
@@ -95,7 +95,7 @@ spawn-at-startup "jamesdsp" "-t"
 
 prefer-no-csd
 
-// screenshot-path is handled by ~/bin/niri-screenshot wrapper
+// screenshot-path is handled by shotty
 screenshot-path null
 
 animations {
@@ -380,10 +380,16 @@ binds {
     Mod+Space       { switch-layout "next"; }
     Mod+Shift+Space { switch-layout "prev"; }
 
-    XF86SelectiveScreenshot { spawn "niri-screenshot" "select"; }
-    Print { spawn "niri-screenshot" "screen"; }
-    Ctrl+Print { spawn "niri-screenshot" "select"; }
-    Alt+Print { spawn "niri-screenshot" "window"; }
+    // Screenshots (shotty)
+    XF86SelectiveScreenshot { spawn "shotty" "select-file"; }
+    Print { spawn "shotty" "screen-file"; }
+    Ctrl+Print { spawn "shotty" "select-file"; }
+    Alt+Print { spawn "shotty" "window-file"; }
+    Shift+Print { spawn "shotty" "select-edit"; }
+
+    // Screen recording (shotty)
+    Mod+Print { spawn "shotty" "record-toggle"; }
+    Mod+Shift+Print { spawn "shotty" "record-pause"; }
 
     // Applications such as rEmote-desktop clients and software KVM switches may
     // request that niri stops processing the keyboard shortcuts defined here
dots/config/raffi/raffi.yaml
@@ -268,27 +268,55 @@ launchers:
     script: |
       cliphist list | fuzzel -d | cliphist decode | wl-copy
     ifenvset: NIRI_SOCKET
-  screenshot-clipboard:
-    binary: shot
+  screenshot-select-clipboard:
+    binary: shotty
     args:
-    - '%c'
-    description: Screenshot to clipboard
+    - select-clipboard
+    description: Screenshot selection to clipboard
     icon: applets-screenshooter
     ifenvset: NIRI_SOCKET
-  screenshot-file:
-    binary: shot
+  screenshot-select-file:
+    binary: shotty
     args:
-    - '%d'
-    description: Screenshot to file
+    - select-file
+    description: Screenshot selection to file
     icon: applets-screenshooter
     ifenvset: NIRI_SOCKET
-  screenshot-fullscreen:
-    binary: shotf
+  screenshot-select-edit:
+    binary: shotty
     args:
-    - '%c'
-    description: Screenshot fullscreen to clipboard
+    - select-edit
+    description: Screenshot selection and edit (satty)
     icon: applets-screenshooter
     ifenvset: NIRI_SOCKET
+  screenshot-window:
+    binary: shotty
+    args:
+    - window-file
+    description: Screenshot focused window
+    icon: applets-screenshooter
+    ifenvset: NIRI_SOCKET
+  screenshot-screen:
+    binary: shotty
+    args:
+    - screen-file
+    description: Screenshot full screen
+    icon: applets-screenshooter
+    ifenvset: NIRI_SOCKET
+  recording-toggle:
+    binary: shotty
+    args:
+    - record-toggle
+    description: Toggle screen recording
+    icon: media-record
+    ifenvset: NIRI_SOCKET
+  recording-stop:
+    binary: shotty
+    args:
+    - record-stop
+    description: Stop screen recording
+    icon: media-playback-stop
+    ifenvset: NIRI_SOCKET
   toggle-color-scheme:
     binary: toggle-color-scheme
     description: Toggle dark/light color scheme
home/common/desktop/niri/default.nix
@@ -1,27 +1,4 @@
 { pkgs, ... }:
-let
-  niri-screenshot = pkgs.writeShellApplication {
-    name = "niri-screenshot";
-    runtimeInputs = with pkgs; [ niri ];
-    text = ''
-      # Wrapper around niri screenshot actions that expands hostname in the path.
-      # Usage: niri-screenshot [screen|window|select]
-      dir="$HOME/desktop/pictures/screenshots/$(hostname)"
-      mkdir -p "$dir"
-      path="$dir/$(date +%Y-%m-%d-%H%M%S).png"
-
-      case "''${1:-select}" in
-          screen) niri msg action screenshot-screen --path "$path" ;;
-          window) niri msg action screenshot-window --path "$path" ;;
-          select) niri msg action screenshot --path "$path" ;;
-          *)
-              echo "Usage: niri-screenshot [screen|window|select]" >&2
-              exit 1
-              ;;
-      esac
-    '';
-  };
-in
 {
   imports = [
     ../sway/mako.nix
@@ -32,16 +9,17 @@ in
 
   home.packages = with pkgs; [
     pinentry-gnome3
-    wf-recorder
     wl-clipboard
     wl-kbptr
     wtype
     wlprop
 
-    # Screenshots and screen recording
-    niri-screenshot
+    # Screenshots and screen recording (shotty wraps grim, slurp, wf-recorder, etc.)
+    shotty
     grim
     slurp
+    wf-recorder
+    satty
 
     zenity
     wofi
home/common/desktop/niri/waybar.nix
@@ -16,6 +16,8 @@
           "clock"
         ];
         "modules-right" = [
+          "custom/shotty"
+          "custom/separator"
           "custom/voxtype"
           "custom/separator"
           "niri/language"
@@ -109,6 +111,14 @@
           "on-click-right" = "niri msg action switch-layout prev";
           "on-click" = "niri msg action switch-layout next";
         };
+        "custom/shotty" = {
+          "exec" = "${lib.getExe pkgs.shotty} waybar-status --follow";
+          "return-type" = "json";
+          "format" = "{}";
+          "tooltip" = true;
+          "on-click" = "${lib.getExe pkgs.shotty} record-toggle";
+          "on-click-right" = "${lib.getExe pkgs.shotty} record-stop";
+        };
         "custom/voxtype" = {
           "exec" = "voxtype status --follow --format json";
           "return-type" = "json";
@@ -230,6 +240,23 @@
         margin: 0 1px;
       }
 
+      #custom-shotty {
+        padding: 0 10px;
+      }
+
+      #custom-shotty.recording {
+        color: #ff5555;
+        animation: pulse 1s ease-in-out infinite;
+      }
+
+      #custom-shotty.paused {
+        color: #f1fa8c;
+      }
+
+      #custom-shotty.idle {
+        color: #6272a4;
+      }
+
       #custom-voxtype {
         padding: 0 10px;
       }
flake.lock
@@ -128,11 +128,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1774403797,
-        "narHash": "sha256-Uy0JRJK1qDRi/I0SWg1prVi/6WsOjFHpXiCpS1pbDjY=",
+        "lastModified": 1774611969,
+        "narHash": "sha256-oZHuoPeSdaE9KLBx3mLjKQSPvvID0H7SBb69gjPwQk8=",
         "owner": "vdemeester",
         "repo": "chick-group",
-        "rev": "5c0a908fd46f008984f2edb0e07d071f0875791b",
+        "rev": "248c0f33c0926140650ef00b622db96fa2818949",
         "type": "github"
       },
       "original": {