DEV Community

Cover image for DualClip - Update_2026.04.04.
Im Woojin
Im Woojin

Posted on

DualClip - Update_2026.04.04.

DualClip Update — Beyond Text, and a 150ms Correction

A few hours ago, I shared DualClip, a slot-based clipboard manager for macOS. Thank you to everyone who checked it out!

Since then, I've shipped a few meaningful updates that I didn't cover in the original post. I also owe you a small correction. Let me walk through both.


🔧 First, a correction: 50ms → 150ms

In my first post, I wrote that the Atomic Paste operation completes "in less than 50ms." That was wrong. The actual restore delay is 150ms.

/// 150ms is an empirically safe value to prevent race conditions.
private let restoreDelayMs: Int = 150
Enter fullscreen mode Exit fullscreen mode

150ms was chosen empirically to avoid a race condition — if the clipboard is restored before the target application finishes reading it, the paste silently fails. 50ms sounded cooler, but 150ms is what actually works reliably. Sorry about that.


⚡ How Atomic Paste actually works

Since this is the core mechanic of DualClip, I figured it deserves a proper breakdown. When you press the hotkey to paste from Slot B, here's what happens under the hood:

1. Backup — The entire system clipboard (Slot A) is deep-copied into a temporary buffer. Not just text — all NSPasteboardItem types and their raw data.

2. Swap — Slot B's content is written to the system clipboard, replacing whatever was there.

3. Simulate — A CGEvent-based ⌘V keystroke is posted to the HID system. This is why DualClip requires Accessibility permission — it's literally pressing keys on your behalf.

4. Restore — After 150ms, the backup is written back to the system clipboard. Your original ⌘C content is untouched.

The entire flow is invisible to the user. You press a hotkey, text appears, and your clipboard stays exactly as it was.


🖼 Multi-content type support

The first post only showed text workflows, which gave the impression that DualClip is text-only. It's not — it now supports four content types:

Type Example
Plain text Code snippets, URLs, API keys
Rich text (RTF) Formatted text with bold, colors, etc.
Images Screenshots, design assets from Figma
File URLs File paths copied from Finder

Each slot stores the raw NSPasteboardItem data faithfully, so what you copy is exactly what you get back — formatting, metadata, and all.

This means you can now keep a screenshot in Slot B and a HEX code in Slot C, then paste them alternately into your editor without touching the mouse.


🔐 RAM Zeroing on termination

In the first post, I mentioned that all data lives in RAM only. That's still true, but I've taken it a step further.

When DualClip quits, it doesn't just release memory — it overwrites every byte with zeros before deallocation:

func secureWipe() {
    if let items = pasteboardItems {
        for item in items {
            for type in item.types {
                if let data = item.data(forType: type) {
                    data.withUnsafeBytes { rawBuffer in
                        guard let baseAddress = rawBuffer.baseAddress else { return }
                        let mutable = UnsafeMutableRawPointer(mutating: baseAddress)
                        memset(mutable, 0, rawBuffer.count)
                    }
                }
            }
        }
    }
    clear()
}
Enter fullscreen mode Exit fullscreen mode

This is called on applicationWillTerminate for all three slots. If you temporarily stored an API key or password in a slot, it won't linger in physical memory after the app closes.

To summarize the privacy model:

  • No disk writes. Nothing is persisted.
  • No network. Zero external communication.
  • RAM zeroing. Memory is scrubbed on exit.
  • Open source. You can verify all of the above yourself.

🏗 CI pipeline

I've added a GitHub Actions workflow that runs on every push and PR to main. It builds the project in both Debug and Release configurations on macOS 14 with Swift 5.9.

It's a simple setup — no notarization or automatic releases yet — but it catches build regressions before they land.


🛠 Building from source

There's no prebuilt binary yet, but building is straightforward if you have Xcode:

git clone https://github.com/RAKKUNN/DualClip.git
cd DualClip
open Package.swift
Enter fullscreen mode Exit fullscreen mode

Hit ▶ Run in Xcode. On first launch, macOS will ask for Accessibility permission — this is required for the CGEvent keystroke simulation that powers Atomic Paste.


What's next

  • Secure input field detection (auto-disable in password fields)
  • Homebrew Cask distribution
  • Sparkle auto-update

This is still a small, single-purpose tool, but I'm trying to get the details right. If you have feedback or want to contribute, the repo is open.

🔗 GitHub: https://github.com/RAKKUNN/DualClip

Thanks for reading!

Top comments (0)