From 4e6e73a2138e368c9d70905c8acde4f51e2fce85 Mon Sep 17 00:00:00 2001
From: matt1432 <matt@nelim.org>
Date: Tue, 19 Nov 2024 22:05:12 -0500
Subject: [PATCH] feat(ags): add freeze option for screenshot

---
 .../ags/config/widgets/screenshot/capture.sh  | 18 +++++++
 .../ags/config/widgets/screenshot/main.tsx    | 49 +++++++++++++------
 nixosModules/ags/packages.nix                 |  1 +
 3 files changed, 54 insertions(+), 14 deletions(-)
 create mode 100755 nixosModules/ags/config/widgets/screenshot/capture.sh

diff --git a/nixosModules/ags/config/widgets/screenshot/capture.sh b/nixosModules/ags/config/widgets/screenshot/capture.sh
new file mode 100755
index 00000000..d3a1e729
--- /dev/null
+++ b/nixosModules/ags/config/widgets/screenshot/capture.sh
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+
+if [[ "$1" == "region" ]]; then
+    if [[ "$2" == "true" ]]; then
+        wayfreeze & PID=$!
+        sleep .1
+    fi
+
+    selection="$(slurp)"
+
+    if [[ "$2" == "true" ]]; then
+        kill "$PID"
+    fi
+
+    exec grim -g "$selection" - | satty -f - || true
+else
+    exec grim "$@" - | satty -f - || true
+fi
diff --git a/nixosModules/ags/config/widgets/screenshot/main.tsx b/nixosModules/ags/config/widgets/screenshot/main.tsx
index 4c800512..13192b7a 100644
--- a/nixosModules/ags/config/widgets/screenshot/main.tsx
+++ b/nixosModules/ags/config/widgets/screenshot/main.tsx
@@ -14,15 +14,13 @@ import { hyprMessage } from '../../lib';
 
 
 const ICON_SEP = 6;
-const takeScreenshot = (selector: string, delay = 1000): void => {
+const takeScreenshot = (selector: string[], delay = 1000): void => {
     App.get_window('win-screenshot')?.set_visible(false);
 
     setTimeout(() => {
         execAsync([
-            'bash',
-            '-c',
-            `grim ${selector} - | satty -f - || true`,
-        ]).catch(console.error);
+            `${SRC}/widgets/screenshot/capture.sh`,
+        ].concat(selector)).catch(console.error);
     }, delay);
 };
 
@@ -42,7 +40,7 @@ export default () => {
                     cursor="pointer"
 
                     onButtonReleaseEvent={() => {
-                        takeScreenshot(`-w ${client.address}`);
+                        takeScreenshot(['-w', client.address]);
                     }}
                 >
                     <box halign={Gtk.Align.CENTER}>
@@ -78,7 +76,7 @@ export default () => {
                             cursor="pointer"
 
                             onButtonReleaseEvent={() => {
-                                takeScreenshot(`-o ${monitor.name}`);
+                                takeScreenshot(['-o', monitor.name]);
                             }}
                         >
                             <label
@@ -117,21 +115,41 @@ export default () => {
         </button>
     ) as Widget.Button;
 
+    let frozen = false;
+    const freezeIcon = <icon icon="checkbox-symbolic" /> as Widget.Icon;
+    const freezeButton = (
+        <button
+            cursor="pointer"
+            className="header-btn"
+
+            onButtonReleaseEvent={() => {
+                frozen = !frozen;
+                freezeIcon.icon = frozen ?
+                    'checkbox-checked-symbolic' :
+                    'checkbox-symbolic';
+            }}
+        >
+            <box halign={Gtk.Align.CENTER}>
+                {freezeIcon}
+
+                <Separator size={ICON_SEP} />
+
+                freeze
+            </box>
+        </button>
+    ) as Widget.Button;
+
     const regionButton = (
         <button
             cursor="pointer"
             className="header-btn"
 
             onButtonReleaseEvent={() => {
-                takeScreenshot('-g "$(slurp)"', 0);
+                takeScreenshot(['region', frozen ? 'true' : 'false'], 0);
             }}
         >
             <box halign={Gtk.Align.CENTER}>
-                <icon icon="tool-pencil-symbolic" />
-
-                <Separator size={ICON_SEP} />
-
-                region
+                <icon icon="tool-crop-symbolic" />
             </box>
         </button>
     ) as Widget.Button;
@@ -153,7 +171,10 @@ export default () => {
                 >
                     <StackButton label="monitors" iconName="display-symbolic" />
                     <StackButton label="windows" iconName="window-symbolic" />
-                    {regionButton}
+                    <box>
+                        {regionButton}
+                        {freezeButton}
+                    </box>
                 </box>
 
                 {stack}
diff --git a/nixosModules/ags/packages.nix b/nixosModules/ags/packages.nix
index ee8f7026..6ee938ae 100644
--- a/nixosModules/ags/packages.nix
+++ b/nixosModules/ags/packages.nix
@@ -77,6 +77,7 @@ in {
             (pkgs)
             playerctl
             pavucontrol # TODO: replace with ags widget
+            wayfreeze
             ;
         })
         ++ (optionals cfgDesktop.isTouchscreen (builtins.attrValues {