Como me molestaba no poder hacer ⌘C dos veces, convertí el portapapeles de macOS en 3 - DualClip
(github.com/RAKKUNN)¡Hola! Quería compartir DualClip, un mini proyecto que hice al usar macOS por primera vez.
Es la primera vez que escribo algo así, así que estoy un poco nervioso. Aunque las frases suenen algo torpes, les pido que me tengan paciencia 🙇
Qué es esto
Es simplemente una pequeña app de barra de menú que te da 3 'slots' de portapapeles.
Slot A → el portapapeles predeterminado tal cual (⌘C / ⌘V)
Slot B → ⌥⌘C / ⌥⌘V
Slot C → ⌃⌘C / ⌃⌘V
No es un sistema de 'historial' como Paste o Maccy, sino un sistema de 'slots'.
Puedes dejar fijo en B algo como un correo que usas seguido o un nombre de variable, y seguir usando ⌘C/⌘V normalmente para copiar y pegar del día a día.
Por qué lo hice
Cuando estás refactorizando o haciendo traducciones, si presionas ⌘C una vez más, lo que habías copiado antes simplemente se pierde.
Y cuando eso se acumula durante todo el día, termina siendo más estresante de lo que parece.
Probé apps de historial también, pero para mí tenían estos puntos flojos.
- Ese tiempo extra de abrir un popup y elegir se siente lento
- Si quieres encontrar "no lo de hace un momento, sino lo anterior", al final tienes que buscarlo con la vista
- Yo solo quería que al presionar ⌥⌘V se pegara eso de inmediato
Así que, en lugar de meterle funciones por todos lados, dejé solo un concepto muy simple: "lo dejas fijo en un slot y lo sacas con un atajo".
La parte más divertida de hacerlo (Atomic Paste)
Esto fue más complicado de lo que parecía, porque en macOS ⌘V siempre lee únicamente del system pasteboard.
Entonces, para pegar el Slot B, hay que sobrescribir por un momento el system clipboard, pero si haces eso, desaparece lo que habías copiado originalmente con ⌘C.
Me pasé bastante tiempo pensando cómo resolverlo.
Al final hice que funcionara en este orden.
- Primero hago backup del system clipboard actual (deep copy de todos los tipos)
- Lo sobrescribo con el contenido del Slot B
- Simulo ⌘V con
CGEvent - Después de 150 ms, restauro el original que había respaldado
Todo este ciclo termina en menos de 150 ms, así que la persona que lo usa ni siquiera alcanza a notar que "lo que había copiado con ⌘C desapareció por un momento".
Yo solo le digo 'Atomic Paste'... (me puse nombre yo solo y me sentí orgulloso 😅).
La parte de pausar el polling por un momento y ajustar el timing para ignorar changeCount fue la que más tiempo me tomó.
Me perdí bastante rato pensando: "¿por qué el Slot A cambió al contenido del Slot B...?"
Otras cositas:
- Soporta texto/imágenes/archivos/RTF, todo (deep copy de
NSPasteboardItem) - En campos de contraseña no funciona en absoluto (
IsSecureEventInputEnabledcheck) - Al salir, hace zero-fill de la memoria de los slots (
memset_s) - Todos los atajos se pueden cambiar (gracias a
sindresorhus/KeyboardShortcuts)
Sobre privacidad
Como una app de portapapeles maneja datos sensibles, aquí sí quise poner mucha atención.
- No escribe nada en disco. Todo se queda solo en RAM.
- No tiene código de red en absoluto. Tampoco hay verificación de actualizaciones ni telemetría.
- Es open source bajo MIT, así que pueden revisarlo directamente.
Si quieren probarlo
Lo más cómodo probablemente sea Homebrew.
brew install RAKKUNN/tap/dualclip
O también pueden bajar el zip desde GitHub Releases y ponerlo en /Applications.
Como es un build notarizado por Apple, no aparece una advertencia al ejecutarlo por primera vez.
GitHub: https://github.com/RAKKUNN/DualClip
Requisitos: macOS 13+ (Apple Silicon), permisos de accesibilidad
Como es la primera app de macOS que hago, seguro todavía tiene varias partes torpes.
Si me dejan feedback como "esto sería mejor hacerlo así" o "aquí ocurre un error", de verdad se los agradecería mucho y aprendería bastante.
¡Déjenme sus comentarios con confianza!
¡¡Que todos tengan un excelente día!!
4 comentarios
El programa de gestión del portapapeles para Windows, Ditto, también funciona de manera similar a lo que implementaste.
Creo que podría servirte como referencia para encontrar una dirección de mejora~
¡Gracias por la información!🙇🙇
Le echaré un vistazo y consideraré tomar algunas partes.
Creo que estaría bueno agregar también una función de guardado, como en Clipy.
¿Buscan historial o snippets?
Pero el historial no va en la dirección de DualClip.
Estoy esforzándome por hacerlo lo más ligero y cómodo posible.
Gracias por sus comentarios.