6 Commits

Author SHA1 Message Date
Renovate Bot
27c122696c Add renovate.json 2025-09-20 07:35:59 +00:00
fa37ff76a2 update gitignore 2025-05-05 09:41:01 -07:00
dfe7cd590c update 2025-05-05 02:31:58 -07:00
db0587c942 add icon to notification in notify function 2025-05-04 14:47:59 -07:00
a7df2c1bac remove debug 2025-05-04 14:24:46 -07:00
6838145883 enhance screenshot functionality with notifications and window geometry retrieval 2025-05-04 14:22:24 -07:00
3 changed files with 82 additions and 10 deletions

1
.gitignore vendored
View File

@@ -1,2 +1,3 @@
.git
screenshot
*.png

6
renovate.json Normal file
View File

@@ -0,0 +1,6 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended"
]
}

View File

@@ -2,7 +2,9 @@ package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"log"
"os"
"os/exec"
@@ -29,12 +31,63 @@ func notify(body, title string) {
if title == "" {
title = scriptName
}
cmd := exec.Command("notify-send", title, body)
cmd := exec.Command("notify-send", "-a", "Screenshot", "-i", "camera", title, body)
if err := cmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "notify error: %v\n", err)
}
}
func notifyWithIcon(iconPath, body, title string) {
if title == "" {
title = scriptName
}
resizedPath := iconPath + ".icon.png"
resizeCmd := exec.Command("convert", iconPath, "-resize", "128x128^", "-gravity", "center", "-extent", "128x128", resizedPath)
if err := resizeCmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "resize error: %v\n", err)
resizedPath = iconPath // fallback to original if resize fails
}
cmd := exec.Command("notify-send", "-a", "Screenshot", "--hint", "string:image-path:"+resizedPath, title, body)
if err := cmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "notify error: %v\n", err)
}
os.Remove(resizedPath)
}
func moveFile(src, dst string) error {
in, err := os.Open(src)
if err != nil {
return err
}
defer in.Close()
out, err := os.Create(dst)
if err != nil {
return err
}
defer out.Close()
if _, err := io.Copy(out, in); err != nil {
return err
}
return os.Remove(src)
}
func getActiveWindowGeom() (string, error) {
type activeWindow struct {
At [2]int `json:"at"`
Size [2]int `json:"size"`
}
cmd := exec.Command("hyprctl", "-j", "activewindow")
out, err := cmd.Output()
if err != nil {
return "", err
}
var win activeWindow
if err := json.Unmarshal(out, &win); err != nil {
return "", err
}
return fmt.Sprintf("%d,%d %dx%d", win.At[0], win.At[1], win.Size[0], win.Size[1]), nil
}
func checkDeps() {
for _, cmd := range requirements {
if _, err := exec.LookPath(cmd); err != nil {
@@ -47,11 +100,11 @@ func main() {
checkDeps()
options := []Option{
{"1. Select a region and save", []string{"sh", "-c", fmt.Sprintf("slurp | grim -g - '%s'", tmpScreenshot)}},
{"2. Select a region and copy to clipboard", []string{"sh", "-c", "slurp | grim -g - - | wl-copy"}},
{"2. Select a region and copy to clipboard", []string{"sh", "-c", fmt.Sprintf("slurp | grim -g - '%s' && wl-copy < '%s'", tmpScreenshot, tmpScreenshot)}},
{"3. Whole screen", []string{"grim", tmpScreenshot}},
{"4. Current window", []string{"sh", "-c", fmt.Sprintf("hyprctl -j activewindow | jq -r '\\.at[0],(\\.at[1]) \\.size[0]x(\\.size[1])' | grim -g - '%s'", tmpScreenshot)}},
{"5. Edit", []string{"sh", "-c", "slurp | grim -g - - | swappy -f -"}},
{"6. Quit", []string{"true"}},
{"4. Current monitor", []string{"sh", "-c", fmt.Sprintf("grim -o \"$(hyprctl monitors -j | jq -r '.[] | select(.focused) | .name')\" '%s'", tmpScreenshot)}},
{"5. Current window", []string{"current-window"}},
{"6. Edit", []string{"sh", "-c", "slurp | grim -g - - | swappy -f -"}},
}
var menu bytes.Buffer
@@ -60,7 +113,7 @@ func main() {
menu.WriteByte('\n')
}
rofi := exec.Command("rofi", "-dmenu", "-i", "-p", "Enter option or select from the list", "-mesg", "Select a Screenshot Option", "-format", "i", "-theme-str", "listview {columns: 2; lines: 3;} window {width: 55%;}", "-yoffset", "30", "-xoffset", "30", "-a", "0", "-no-custom", "-location", "0")
rofi := exec.Command("rofi", "-dmenu", "-i", "-p", "Select option", "-mesg", "Select a Screenshot Option", "-format", "i", "-theme-str", "listview {columns: 1; lines: 6;} window {width: 25%;}", "-yoffset", "30", "-xoffset", "30", "-no-custom", "-location", "0", "-theme", "~/.config/rofi/launchers/type-2/style-2.rasi")
rofi.Stdin = &menu
out, err := rofi.Output()
if err != nil {
@@ -82,11 +135,21 @@ func main() {
notify("An error occurred while taking the screenshot.", "")
os.Exit(1)
}
notify("Screenshot copied to clipboard", "")
notifyWithIcon(tmpScreenshot, "Screenshot copied to clipboard", "")
os.Exit(0)
}
if err := exec.Command(selected.Cmd[0], selected.Cmd[1:]...).Run(); err != nil {
if selected.Cmd[0] == "current-window" {
geom, err := getActiveWindowGeom()
if err != nil {
notify(fmt.Sprintf("Failed to get current window geometry: %v", err), "")
os.Exit(1)
}
if err := exec.Command("grim", "-g", geom, tmpScreenshot).Run(); err != nil {
notify(fmt.Sprintf("An error occurred while taking the screenshot (grim -g '%s'): %v", geom, err), "")
os.Exit(1)
}
} else if err := exec.Command(selected.Cmd[0], selected.Cmd[1:]...).Run(); err != nil {
notify("An error occurred while taking the screenshot.", "")
os.Exit(1)
}
@@ -105,9 +168,11 @@ func main() {
}
dest := strings.TrimSpace(string(fileOut))
if err := os.Rename(tmpScreenshot, dest); err != nil {
if _, err := os.Stat(tmpScreenshot); os.IsNotExist(err) {
notify(fmt.Sprintf("Screenshot file %s does not exist. Save failed.", tmpScreenshot), "")
} else if err := moveFile(tmpScreenshot, dest); err != nil {
notify(fmt.Sprintf("Failed to save screenshot to %s", dest), "")
} else {
notify(fmt.Sprintf("Screenshot saved to %s", dest), "")
notifyWithIcon(dest, fmt.Sprintf("Screenshot saved to %s", dest), "")
}
}