MacOSX Tip: Automatically Copy Your Screen Grabs to the Clipboard

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:

  1. Cmd + Shift + Control + 4 to capture a region to the clipboard
  2. Cmd + Ctrl + S to 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.

Leave a Reply

Your email address will not be published. Required fields are marked *