Files
Snaggle/README.md
T
2026-09-17 15:15:45 -05:00

118 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# GreenshotMac
A native, Apple-silicon macOS screenshot tool modelled on [Greenshot](https://github.com/greenshot/greenshot)
for Windows. Written in Swift with AppKit, SwiftUI and ScreenCaptureKit — no Mono, no Wine,
no .NET runtime.
The original C# sources are kept in `reference-greenshot/` purely as the behavioural reference
for the port. GreenshotMac is a rewrite, not a transpile: Greenshot's Win32 foundations
(GDI+, WinForms, `RegisterHotKey`, the shell tray API) have no direct macOS counterparts.
## Requirements
* macOS 14 (Sonoma) or later
* Xcode 16 or later
* Apple silicon (the target builds `arm64` only)
## Building
```bash
open GreenshotMac.xcodeproj # then ⌘R
# or
xcodebuild -project GreenshotMac.xcodeproj -scheme GreenshotMac -configuration Release build
```
The target is configured for ad-hoc signing (`CODE_SIGN_IDENTITY = "-"`) so it builds without a
developer account. Set your own team in *Signing & Capabilities* if you want a stable signature —
macOS ties Screen Recording permission to the signature, so an ad-hoc build may ask for permission
again after some rebuilds.
On first launch macOS asks for **Screen Recording** permission
(System Settings › Privacy & Security › Screen Recording). Nothing can be captured until it is granted.
## Using it
GreenshotMac is a menu bar app (`LSUIElement`), so it has no Dock icon. The camera icon in the
menu bar holds every command.
Default global hotkeys — Greenshot's PrintScreen-based defaults don't exist on a Mac keyboard,
so these use combinations macOS leaves free:
| Action | Shortcut |
| --- | --- |
| Capture region | ⌥⇧⌘4 |
| Capture full screen | ⌥⇧⌘3 |
| Capture window | ⌥⇧⌘5 |
| Capture last region | ⌥⇧⌘6 |
All four are re-recordable in Preferences › Hotkeys.
During a capture the desktop freezes under a dimmed overlay: drag to select a region, press
**Space** to switch to window mode and click a window, **Esc** to cancel. A magnifier and a live
pixel-size readout follow the cursor.
### Editor
| Tool | Key |
| --- | --- |
| Select | V |
| Rectangle / Ellipse | R / E |
| Line / Arrow | L / A |
| Freehand | F |
| Text | T |
| Highlight | H |
| Obfuscate (pixelate or blur) | O |
| Step counter | C |
| Crop | K |
Shift constrains shapes to squares/circles and lines to 45° steps. Arrow keys nudge the selection
(⇧ for 10 px steps). ⌘Z / ⇧⌘Z undo and redo, including crops.
### Destinations
After a capture the destination picker appears: a preview of what you grabbed, one button per
destination, ⌘1…⌘9 to pick from the keyboard, Esc to discard, and "Always use this destination"
to skip the dialog next time. The buttons default to Edit / Save to Disk / Copy to Clipboard /
Send as Mail, matching Greenshot.
The full destination set is clipboard, save with a filename pattern, Save As…, print, email,
the macOS share sheet, and "open with". Set a destination as the default (skipping the picker)
in Preferences › General, from the menu bar, or via the picker's checkbox.
Filename patterns use Greenshot's syntax, ported verbatim:
```
${capturetime:d"yyyy-MM-dd HH_mm_ss"}-${title}
```
Supported variables: `${capturetime}`, `${now}`, `${title}`, `${appname}`, `${user}`,
`${hostname}`, `${mode}`, `${NUM}` (with `:d4` for zero padding), plus the `:t`, `:u`, `:l`,
`:s`, `:r` parameters.
## How the port maps onto Greenshot
| Greenshot (Windows) | GreenshotMac |
| --- | --- |
| `MainForm` + tray icon | `StatusMenuController` (`NSStatusItem`) |
| `CaptureForm` | `CaptureOverlay` (one borderless window per display) |
| `WindowCapture` / GDI+ | `CaptureEngine` (ScreenCaptureKit) |
| `HotkeyControl` / `RegisterHotKey` | `HotkeyManager` (Carbon `RegisterEventHotKey`) |
| `Surface` + `DrawableContainer` | `Surface` + `Element` hierarchy |
| `ImageEditorForm` | `EditorWindowController` + `EditorCanvasView` |
| `FilenameHelper` | `FilenamePattern` |
| `ImageIO` | `ImageExporter` |
| `IDestination` implementations | `Destinations` |
| `SettingsForm` | `PreferencesView` (SwiftUI) |
| `IniConfig` / `greenshot.ini` | `Configuration` (`UserDefaults`) |
## Not ported
The plugin destinations (Imgur, Box, Dropbox, Confluence, Jira, Office, OCR, external command),
the speech-bubble and SVG/emoji containers, `.gst` templates, and Greenshot's language packs.
The destination layer is a single `switch` in `Destinations.swift`, so adding an upload target is
a small, self-contained change.
## Licence
Greenshot is GPL-3.0; this port keeps the same licence.