Initial commit

This commit is contained in:
Alex E. Tafoya
2026-09-17 15:15:45 -05:00
commit 87fe7927c4
36 changed files with 5113 additions and 0 deletions
+117
View File
@@ -0,0 +1,117 @@
# 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.