If you’re like me, you probably take dozens of screenshots daily for documentation, bug reports, or quick sharing with colleagues. The default MacOSX behavior of saving screenshots as files to your desktop can create clutter and add an extra step to your workflow.
There’s a better way.
1. The Quick Solution
Instead of using Cmd + Shift + 4 for your screen grabs, simply add the Control key:
Cmd + Shift + Control + 4
This immediately copies your screenshot to the clipboard, ready to paste wherever you need it.
2. Making It Permanent
If you want Cmd + Shift + 4 to always copy to clipboard by default, you can change the system behavior with a simple Terminal command:
defaults write com.apple.screencapture target clipboard
killall SystemUIServer The first command changes the screenshot target from file to clipboard. The second command restarts the SystemUIServer to apply the change immediately.
3. Reverting Back
Changed your mind? No problem. Restore the original file saving behavior with:
defaults write com.apple.screencapture target file
killall SystemUIServer 4. Bonus: Saving a Clipboard Screenshot to File On Demand
So now your screenshots go straight to the clipboard. Great for pasting into Slack, Jira, or email. But what happens when you actually want to keep one as a file?
You could open Preview, hit Cmd + N to create an image from the clipboard, then Cmd + S to save it. That works, but it is three steps and a dialog box. We can do better.
The idea is simple: create a macOS Quick Action that grabs whatever image is on your clipboard and saves it to a dedicated folder with a timestamped filename. Bind it to a keyboard shortcut. Done.
4.1. Install pngpaste
First, you need a command line tool that can extract images from the clipboard. pngpaste does exactly this and nothing else.
brew install pngpaste 4.2 Create setup_clipboard_save Bash script
Create the setup_clipboard_save.sh and then run the script and the Cmd + Ctrl + S will save the clipboard item to the screenshots folder.
cat > setup_clipboard_save.sh << 'EOF'
#!/bin/bash
#
# setup_clipboard_save.sh
#
# Creates a clipboard screenshot saver using Hammerspoon to bind
# the keyboard shortcut Cmd+Ctrl+S. No code signing required.
#
# Reference: https://andrewbaker.ninja/2026/02/05/macosx-tip-automatically-copy-your-screen-grabs-to-the-clipboard/
set -euo pipefail
SCREENSHOT_DIR="${HOME}/Desktop/Screenshot"
SCRIPT_PATH="${HOME}/.save_clipboard_screenshot.sh"
HAMMERSPOON_CONFIG="${HOME}/.hammerspoon/init.lua"
echo "=== Clipboard Screenshot Setup ==="
echo ""
# 1. Install pngpaste if not present
echo "[1/6] Checking for pngpaste..."
if [ -x /opt/homebrew/bin/pngpaste ]; then
echo " pngpaste found at /opt/homebrew/bin/pngpaste"
elif [ -x /usr/local/bin/pngpaste ]; then
echo " pngpaste found at /usr/local/bin/pngpaste"
else
if ! command -v brew &> /dev/null; then
echo " ERROR: Homebrew not installed. Install from https://brew.sh and re-run."
exit 1
fi
echo " Installing pngpaste via Homebrew..."
brew install pngpaste
echo " Done."
fi
# 2. Install Hammerspoon if not present
echo "[2/6] Checking for Hammerspoon..."
if [ -d "/Applications/Hammerspoon.app" ]; then
echo " Hammerspoon already installed."
else
if ! command -v brew &> /dev/null; then
echo " ERROR: Homebrew not installed. Install from https://brew.sh and re-run."
exit 1
fi
echo " Installing Hammerspoon via Homebrew..."
brew install --cask hammerspoon
echo " Done."
fi
# 3. Create screenshots directory
echo "[3/6] Creating screenshots directory at ${SCREENSHOT_DIR}..."
mkdir -p "${SCREENSHOT_DIR}"
echo " Done."
# 4. Create the shell script that does the actual work
# pngpaste saves as PNG then we convert to JPEG via sips to match existing screenshots
echo "[4/6] Creating save script at ${SCRIPT_PATH}..."
cat > "${SCRIPT_PATH}" << 'SCRIPT_EOF'
#!/bin/bash
SCREENSHOT_DIR="$HOME/Desktop/Screenshot"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
TMPFILE="/tmp/clipboard_${TIMESTAMP}.png"
FILENAME="${SCREENSHOT_DIR}/Screenshot ${TIMESTAMP}.jpg"
mkdir -p "${SCREENSHOT_DIR}"
PNGPASTE=""
if [ -x /opt/homebrew/bin/pngpaste ]; then
PNGPASTE=/opt/homebrew/bin/pngpaste
elif [ -x /usr/local/bin/pngpaste ]; then
PNGPASTE=/usr/local/bin/pngpaste
fi
if [ -n "${PNGPASTE}" ]; then
"${PNGPASTE}" "${TMPFILE}" 2>/dev/null
fi
if [ -f "${TMPFILE}" ]; then
sips -s format jpeg -s formatOptions 85 "${TMPFILE}" --out "${FILENAME}" &>/dev/null
rm -f "${TMPFILE}"
fi
if [ -f "${FILENAME}" ]; then
osascript -e "display notification \"Saved: $(basename ${FILENAME})\" with title \"Screenshot Saved\" sound name \"Glass\""
else
osascript -e 'display notification "No image found on clipboard" with title "Screenshot Save Failed" sound name "Basso"'
fi
SCRIPT_EOF
chmod +x "${SCRIPT_PATH}"
echo " Done."
# 5. Write Hammerspoon config
echo "[5/6] Writing Hammerspoon config to ${HAMMERSPOON_CONFIG}..."
mkdir -p "${HOME}/.hammerspoon"
cat > "${HAMMERSPOON_CONFIG}" << 'LUA_EOF'
-- Save Clipboard Screenshot (added by setup_clipboard_save.sh)
hs.allowAppleScript(true)
hs.ipc.cliInstall()
hs.hotkey.bind({"cmd", "ctrl"}, "s", function()
hs.task.new(os.getenv("HOME") .. "/.save_clipboard_screenshot.sh", nil):start()
end)
LUA_EOF
echo " Done."
# 6. Launch Hammerspoon and reload config
echo "[6/6] Launching Hammerspoon and reloading config..."
killall Hammerspoon 2>/dev/null || true
sleep 1
open -a Hammerspoon
sleep 3
/Applications/Hammerspoon.app/Contents/Frameworks/hs/hs -c "hs.reload()" 2>/dev/null || true
sleep 1
echo " Done."
echo ""
echo "=== Setup Complete ==="
echo ""
echo "Screenshots will be saved to: ${SCREENSHOT_DIR}"
echo "Keyboard shortcut: Cmd+Ctrl+S"
echo ""
echo "NOTE: If Hammerspoon asks for Accessibility permission, grant it in"
echo " System Settings > Privacy > Accessibility then test Cmd+Ctrl+S."
echo ""
echo "Test manually:"
echo " /Applications/Hammerspoon.app/Contents/Frameworks/hs/hs -c \"hs.task.new(os.getenv('HOME') .. '/.save_clipboard_screenshot.sh', nil):start()\""
echo ""
EOF
chmod +x setup_clipboard_save.sh ./setup_clipboard_save.sh You can grab the script from the link below. The only manual step that remains is enabling the keyboard shortcut in System Settings, because macOS requires user confirmation for new service bindings. Apple being Apple.
4.3 The Workflow
Your two step workflow is now:
Cmd + Shift + Control + 4to capture a region to the clipboardCmd + Ctrl + Sto save it as a file (only when you want to keep it)
No desktop clutter. No Preview detours. No stale screenshot files accumulating in the background. You get the speed of clipboard capture with the permanence of file saves, but only when you actually need it.
5. Testing For Issues
Use the script below for diagnose issues.
cat > diagnose_clipboard_shortcut.sh << 'EOF'
#!/bin/bash
# diagnose_clipboard_shortcut.sh
echo "=== Clipboard Screenshot Diagnostic ==="
echo ""
# 1. Check pngpaste
echo "[1] pngpaste location:"
if [ -x /opt/homebrew/bin/pngpaste ]; then
echo " OK - /opt/homebrew/bin/pngpaste"
elif [ -x /usr/local/bin/pngpaste ]; then
echo " OK - /usr/local/bin/pngpaste"
else
echo " NOT FOUND - run: brew install pngpaste"
fi
echo ""
# 2. Check save script
echo "[2] Save script:"
if [ -x "$HOME/.save_clipboard_screenshot.sh" ]; then
echo " OK - $HOME/.save_clipboard_screenshot.sh"
else
echo " NOT FOUND or not executable - re-run setup script"
fi
echo ""
# 3. Check screenshot directory
echo "[3] Screenshot directory:"
if [ -d "$HOME/Desktop/Screenshot" ]; then
COUNT=$(ls "$HOME/Desktop/Screenshot" | wc -l | tr -d ' ')
echo " OK - $HOME/Desktop/Screenshot ($COUNT files)"
echo " Most recent:"
ls -lt "$HOME/Desktop/Screenshot" | head -3
else
echo " NOT FOUND - re-run setup script"
fi
echo ""
# 4. Check Hammerspoon installation
echo "[4] Hammerspoon installation:"
if [ -d "/Applications/Hammerspoon.app" ]; then
VERSION=$(defaults read /Applications/Hammerspoon.app/Contents/Info.plist CFBundleShortVersionString 2>/dev/null || echo "unknown")
echo " OK - installed (version ${VERSION})"
else
echo " NOT FOUND - run: brew install --cask hammerspoon"
fi
echo ""
# 5. Check Hammerspoon is running
echo "[5] Hammerspoon process:"
if pgrep -x Hammerspoon > /dev/null; then
echo " OK - running (PID $(pgrep -x Hammerspoon))"
else
echo " NOT RUNNING - run: open -a Hammerspoon"
fi
echo ""
# 6. Check Hammerspoon config
echo "[6] Hammerspoon config ($HOME/.hammerspoon/init.lua):"
if [ -f "$HOME/.hammerspoon/init.lua" ]; then
if grep -q "save_clipboard_screenshot" "$HOME/.hammerspoon/init.lua"; then
echo " OK - hotkey block present"
grep -A3 "save_clipboard_screenshot" "$HOME/.hammerspoon/init.lua"
else
echo " WARNING - file exists but hotkey block missing - re-run setup script"
fi
if grep -q "hs.allowAppleScript(true)" "$HOME/.hammerspoon/init.lua"; then
echo " OK - AppleScript enabled"
else
echo " WARNING - hs.allowAppleScript(true) missing"
fi
if grep -q "hs.ipc.cliInstall()" "$HOME/.hammerspoon/init.lua"; then
echo " OK - IPC installed"
else
echo " WARNING - hs.ipc.cliInstall() missing"
fi
else
echo " NOT FOUND - re-run setup script"
fi
echo ""
# 7. Check Hammerspoon Accessibility permission
echo "[7] Hammerspoon Accessibility permission:"
if osascript -e 'tell application "System Events" to get name of first process' &>/dev/null; then
echo " OK - Accessibility granted"
else
echo " DENIED - grant in System Settings > Privacy > Accessibility"
fi
echo ""
# 8. Check Hammerspoon hotkey binding
echo "[8] Hammerspoon hotkey binding (Cmd+Ctrl+S):"
if pgrep -x Hammerspoon > /dev/null; then
HOTKEYS=$(/Applications/Hammerspoon.app/Contents/Frameworks/hs/hs -c "for k,v in pairs(hs.hotkey.getHotkeys()) do print(v['idx']) end" 2>/dev/null || echo "")
if echo "$HOTKEYS" | grep -qi "ctrl.*cmd.*s\|cmd.*ctrl.*s\|⌘⌃S\|⌃⌘S"; then
echo " OK - Cmd+Ctrl+S is bound"
else
echo " Registered hotkeys:"
/Applications/Hammerspoon.app/Contents/Frameworks/hs/hs -c "for k,v in pairs(hs.hotkey.getHotkeys()) do print(' ' .. tostring(v['idx'])) end" 2>/dev/null || echo " Could not query hotkeys"
fi
else
echo " SKIP - Hammerspoon not running"
fi
echo ""
# 9. Check Hammerspoon launch at login
echo "[9] Hammerspoon launch at login:"
if osascript -e 'tell application "System Events" to get the name of every login item' 2>/dev/null | grep -qi "hammerspoon"; then
echo " OK - configured to launch at login"
else
echo " WARNING - not set to launch at login"
echo " Fix: open Hammerspoon > Preferences > tick Launch at Login"
fi
echo ""
# 10. Live clipboard test
echo "[10] Live clipboard save test (do Cmd+Ctrl+Shift+4 first):"
TESTFILE="$HOME/Desktop/Screenshot/diag_test_$(date +%Y%m%d_%H%M%S).jpg"
TMPFILE="/tmp/diag_test_$$.png"
PNGPASTE=""
if [ -x /opt/homebrew/bin/pngpaste ]; then
PNGPASTE=/opt/homebrew/bin/pngpaste
elif [ -x /usr/local/bin/pngpaste ]; then
PNGPASTE=/usr/local/bin/pngpaste
fi
if [ -n "$PNGPASTE" ]; then
"$PNGPASTE" "$TMPFILE" 2>/dev/null
if [ -f "$TMPFILE" ]; then
sips -s format jpeg -s formatOptions 85 "$TMPFILE" --out "$TESTFILE" &>/dev/null
rm -f "$TMPFILE"
if [ -f "$TESTFILE" ]; then
SIZE=$(du -h "$TESTFILE" | cut -f1)
echo " OK - saved test file (${SIZE}): $TESTFILE"
rm "$TESTFILE"
echo " (test file cleaned up)"
fi
else
echo " SKIP - no image on clipboard (do Cmd+Ctrl+Shift+4 first)"
fi
fi
echo ""
echo "=== Diagnostic Complete ==="
EOF
chmod +x diagnose_clipboard_shortcut.sh 5. Why This Matters
This small change eliminates the friction of finding your screenshot file, opening it, copying it, and then deleting it from your desktop. It’s one of those tiny optimizations that compounds over time, especially if you’re doing technical documentation or collaborating frequently.
Give it a try. Your desktop will thank you.