Merge pull request #235 from PasteBar/backup-restore-browser-fixes

Backup restore browser fixes
This commit is contained in:
Sergey 2025-06-13 15:23:56 -04:00 committed by GitHub
commit 4bb1e2eafa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 729 additions and 232 deletions

View File

@ -0,0 +1,5 @@
---
'pastebar-app-ui': patch
---
Added user preference to copy only menu items to clipboard without auto-pasting

View File

@ -145,6 +145,7 @@ function App() {
clipTextMinLength: settings.clipTextMinLength?.valueInt,
clipTextMaxLength: settings.clipTextMaxLength?.valueInt,
isImageCaptureDisabled: settings.isImageCaptureDisabled?.valueBool,
isMenuItemCopyOnlyEnabled: settings.isMenuItemCopyOnlyEnabled?.valueBool,
isAutoClearSettingsEnabled: settings.isAutoClearSettingsEnabled?.valueBool,
autoClearSettingsDuration: settings.autoClearSettingsDuration?.valueInt,
autoClearSettingsDurationType:

View File

@ -0,0 +1,27 @@
App restart required: App-Neustart erforderlich
Application Starts with Main Window Hidden: Anwendung startet mit verborgenem Hauptfenster
Change: Ändern
Copy only from menu items: Nur aus Menüelementen kopieren
Display navbar items only when the mouse hovers over the navigation bar to minimize visible UI elements: Navigationsleistenelemente nur bei Mauszeiger anzeigen, um sichtbare UI-Elemente zu minimieren
Global System OS Hotkeys: Globale System-Tastenkombinationen
Hide Collections Navbar: Sammlungs-Navigationsleiste ausblenden
Hide collections menu dropdown on the navigation bar: Sammlungs-Dropdown-Menü in der Navigationsleiste ausblenden
Hide collections menu on the navbar: Sammlungsmenü in der Navigationsleiste ausblenden
Hide the App Dock Icon: App-Dock-Symbol ausblenden
? Keep the main application window hidden when the app restarts. You can reopen it using the menu bar or taskbar menu, or using global hotkeys.
: Hauptanwendungsfenster beim Neustart verborgen halten. Sie können es über die Menüleiste oder das Taskleistenmenü oder mit globalen Tastenkombinationen wieder öffnen.
No keys set: Keine Tasten festgelegt
PasteBar Quick Paste: PasteBar Schnelleinfügen
Press keys: Tasten drücken
Quick Paste Window: Schnelleinfügen-Fenster
? Remove PasteBar app icon from the macOS Dock while keeping the app running in the background. The app remains accessible via the menu bar icon. Requires an app restart to take effect.
: PasteBar-App-Symbol aus dem macOS Dock entfernen, während die App im Hintergrund läuft. Die App bleibt über das Menüleistensymbol zugänglich. Erfordert einen App-Neustart, um wirksam zu werden.
Set: Festlegen
Set system OS hotkeys to show/hide the main app window and quick paste window: System-Tastenkombinationen zum Anzeigen/Verbergen des Hauptfensters und des Schnelleinfügen-Fensters festlegen
Show Navbar Items Hover: Navigationsleistenelemente bei Hover anzeigen
Show collections menu on the navbar: Sammlungsmenü in der Navigationsleiste anzeigen
Show navbar elements on hover only: Navigationsleistenelemente nur bei Hover anzeigen
Show/Hide Main App Window: Hauptfenster anzeigen/verbergen
Show/Hide Quick Paste Window: Schnelleinfügen-Fenster anzeigen/verbergen
? When enabled, clicking menu items will only copy content to clipboard instead of auto-pasting. This gives you more control over when and where content is pasted.
: Wenn aktiviert, wird beim Klicken auf Menüelemente der Inhalt nur in die Zwischenablage kopiert, anstatt automatisch eingefügt zu werden. Dies gibt Ihnen mehr Kontrolle darüber, wann und wo Inhalte eingefügt werden.

View File

@ -1,6 +1,7 @@
App restart required: App restart required
Application Starts with Main Window Hidden: Application Starts with Main Window Hidden
Change: Change
Copy only from menu items: Copy only from menu items
Display navbar items only when the mouse hovers over the navigation bar to minimize visible UI elements: Display navbar items only when the mouse hovers over the navigation bar to minimize visible UI elements
Global System OS Hotkeys: Global System OS Hotkeys
Hide Collections Navbar: Hide Collections Navbar
@ -22,3 +23,5 @@ Show collections menu on the navbar: Show collections menu on the navbar
Show navbar elements on hover only: Show navbar elements on hover only
Show/Hide Main App Window: Show/Hide Main App Window
Show/Hide Quick Paste Window: Show/Hide Quick Paste Window
? When enabled, clicking menu items will only copy content to clipboard instead of auto-pasting. This gives you more control over when and where content is pasted.
: When enabled, clicking menu items will only copy content to clipboard instead of auto-pasting. This gives you more control over when and where content is pasted.

View File

@ -1,24 +1,27 @@
App restart required: Se requiere reiniciar
Application Starts with Main Window Hidden: La aplicación inicia con la ventana principal oculta
App restart required: Reinicio de aplicación requerido
Application Starts with Main Window Hidden: La aplicación se inicia con la ventana principal oculta
Change: Cambiar
Display navbar items only when the mouse hovers over the navigation bar to minimize visible UI elements: Mostrar elementos de la barra de navegación solo cuando el mouse pase por encima para minimizar los elementos visibles de la interfaz
Global System OS Hotkeys: Teclas de acceso rápido globales del sistema operativo
Hide Collections Navbar: Ocultar barra de navegación de colecciones
Copy only from menu items: Copiar solo desde elementos del menú
Display navbar items only when the mouse hovers over the navigation bar to minimize visible UI elements: Mostrar elementos de la barra de navegación solo cuando el ratón se posiciona sobre ella para minimizar elementos visibles de la interfaz
Global System OS Hotkeys: Atajos de teclado globales del sistema
Hide Collections Navbar: Ocultar barra de colecciones
Hide collections menu dropdown on the navigation bar: Ocultar menú desplegable de colecciones en la barra de navegación
Hide collections menu on the navbar: Ocultar menú de colecciones en la barra de navegación
Hide the App Dock Icon: Ocultar el icono de la aplicación en el Dock
? Keep the main application window hidden when the app restarts. You can reopen it using the menu bar or taskbar menu, or using global hotkeys.
: Mantener la ventana principal de la aplicación oculta cuando la aplicación se reinicia. Puede reabrirla usando la barra de menú o el menú de la barra de tareas, o usando teclas de acceso rápido globales.
No keys set: No hay teclas configuradas
Press keys: Presione las teclas
? Remove PasteBar app icon from the macOS Dock while keeping the app running in the background. The app remains accessible via the menu bar icon. Requires an app restart to take effect.
: Eliminar el icono de la aplicación PasteBar del Dock de macOS mientras la aplicación sigue ejecutándose en segundo plano. La aplicación sigue siendo accesible a través del icono en la barra de menú. Requiere reiniciar la aplicación para que surta efecto.
Set: Establecer
Set system OS hotkeys to show/hide the main app window and quick paste window: Configurar teclas de acceso rápido del sistema operativo para mostrar/ocultar la ventana principal de la aplicación y la ventana de pegado rápido
Show Navbar Items Hover: Mostrar elementos de la barra de navegación al pasar el mouse
Show collections menu on the navbar: Mostrar menú de colecciones en la barra de navegación
Show navbar elements on hover only: Mostrar elementos de la barra de navegación solo al pasar el mouse
Show/Hide Main App Window: Mostrar/Ocultar ventana principal de la aplicación
Show/Hide Quick Paste Window: Mostrar/Ocultar ventana de pegado rápido
: Mantener la ventana principal de la aplicación oculta al reiniciar. Puedes reabrirla usando la barra de menú o el menú de la barra de tareas, o usando atajos de teclado globales.
No keys set: Sin teclas asignadas
PasteBar Quick Paste: Pegado rápido PasteBar
Press keys: Presiona las teclas
Quick Paste Window: Ventana de pegado rápido
PasteBar Quick Paste: PasteBar Pegado Rápido
? Remove PasteBar app icon from the macOS Dock while keeping the app running in the background. The app remains accessible via the menu bar icon. Requires an app restart to take effect.
: Eliminar el icono de PasteBar del Dock de macOS mientras mantiene la aplicación ejecutándose en segundo plano. La aplicación permanece accesible a través del icono de la barra de menú. Requiere reiniciar la aplicación para que tenga efecto.
Set: Establecer
Set system OS hotkeys to show/hide the main app window and quick paste window: Establecer atajos de teclado del sistema para mostrar/ocultar la ventana principal y la ventana de pegado rápido
Show Navbar Items Hover: Mostrar elementos de barra al pasar el ratón
Show collections menu on the navbar: Mostrar menú de colecciones en la barra de navegación
Show navbar elements on hover only: Mostrar elementos de la barra solo al pasar el ratón
Show/Hide Main App Window: Mostrar/Ocultar ventana principal
Show/Hide Quick Paste Window: Mostrar/Ocultar ventana de pegado rápido
? When enabled, clicking menu items will only copy content to clipboard instead of auto-pasting. This gives you more control over when and where content is pasted.
: Cuando está habilitado, hacer clic en elementos del menú solo copiará el contenido al portapapeles en lugar de pegarlo automáticamente. Esto te da más control sobre cuándo y dónde se pega el contenido.

View File

@ -1,23 +1,27 @@
App restart required: Redémarrage de l'application requis
Application Starts with Main Window Hidden: Démarrage avec la fenêtre principale cachée
App restart required: Redémarrage de l'app requis
Application Starts with Main Window Hidden: L'application démarre avec la fenêtre principale masquée
Change: Modifier
Display navbar items only when the mouse hovers over the navigation bar to minimize visible UI elements: Afficher les éléments de la barre de navigation uniquement lorsque la souris survole la barre de navigation afin de minimiser les éléments visibles de l'interface utilisateur.
Global System OS Hotkeys: Touches de raccourci du système global
Hide Collections Navbar: Masquer la barre de navigation des collections
Copy only from menu items: Copier uniquement depuis les éléments du menu
Display navbar items only when the mouse hovers over the navigation bar to minimize visible UI elements: Afficher les éléments de la barre de navigation uniquement au survol de la souris pour minimiser les éléments visibles de l'interface
Global System OS Hotkeys: Raccourcis clavier globaux du système
Hide Collections Navbar: Masquer la barre des collections
Hide collections menu dropdown on the navigation bar: Masquer le menu déroulant des collections dans la barre de navigation
Hide collections menu on the navbar: Masquer le menu des collections dans la barre de navigation
Hide the App Dock Icon: Masquer l'icône du dock de l'application
Hide the App Dock Icon: Masquer l'icône de l'app dans le Dock
? Keep the main application window hidden when the app restarts. You can reopen it using the menu bar or taskbar menu, or using global hotkeys.
: La fenêtre principale de l'application reste cachée lorsque l'application redémarre. Vous pouvez la réouvrir en utilisant la barre de menu ou le menu de la barre des tâches, ou en utilisant les touches de raccourci globales.
: Garder la fenêtre principale de l'application masquée au redémarrage. Vous pouvez la rouvrir en utilisant la barre de menu ou le menu de la barre des tâches, ou en utilisant les raccourcis clavier globaux.
No keys set: Aucune touche définie
PasteBar Quick Paste: PasteBar Collage rapide
Press keys: Appuyez touches
Quick Paste Window: Fenêtre collage rapide
Remove PasteBar app icon from the macOS Dock while keeping the app running in the background. The app remains accessible via the menu bar icon. Requires an app restart to take effect.: Retirer l'icône de l'application PasteBar du Dock de macOS tout en laissant l'application fonctionner en arrière-plan. L'application reste accessible via l'icône de la barre de menu. Nécessite un redémarrage de l'application pour prendre effet.
PasteBar Quick Paste: Collage rapide PasteBar
Press keys: Appuyez sur les touches
Quick Paste Window: Fenêtre de collage rapide
? Remove PasteBar app icon from the macOS Dock while keeping the app running in the background. The app remains accessible via the menu bar icon. Requires an app restart to take effect.
: Supprimer l'icône PasteBar du Dock macOS tout en gardant l'app en cours d'exécution en arrière-plan. L'app reste accessible via l'icône de la barre de menu. Nécessite un redémarrage de l'app pour prendre effet.
Set: Définir
Set system OS hotkeys to show/hide the main app window and quick paste window: Définir les touches de raccourci du système d'exploitation pour afficher/masquer la fenêtre de l'application principale et la fenêtre de collage rapide
Show Navbar Items Hover: Afficher les éléments de la barre de navigation au survol
Set system OS hotkeys to show/hide the main app window and quick paste window: Définir les raccourcis clavier du système pour afficher/masquer la fenêtre principale et la fenêtre de collage rapide
Show Navbar Items Hover: Afficher éléments barre au survol
Show collections menu on the navbar: Afficher le menu des collections dans la barre de navigation
Show navbar elements on hover only: Afficher les éléments de la barre de navigation uniquement au survol
Show/Hide Main App Window: Afficher/Masquer la fenêtre principale de l'application
Show/Hide Quick Paste Window: Afficher/masquer la fenêtre de collage rapide
Show navbar elements on hover only: Afficher les éléments de la barre uniquement au survol
Show/Hide Main App Window: Afficher/Masquer fenêtre principale
Show/Hide Quick Paste Window: Afficher/Masquer fenêtre de collage rapide
? When enabled, clicking menu items will only copy content to clipboard instead of auto-pasting. This gives you more control over when and where content is pasted.
: Lorsqu'activé, cliquer sur les éléments du menu copiera uniquement le contenu dans le presse-papiers au lieu de le coller automatiquement. Cela vous donne plus de contrôle sur le moment et l'endroit où le contenu est collé.

View File

@ -1,24 +1,27 @@
App restart required: Riavvio richiesto
App restart required: Riavvio app richiesto
Application Starts with Main Window Hidden: L'applicazione si avvia con la finestra principale nascosta
Change: Cambia
Display navbar items only when the mouse hovers over the navigation bar to minimize visible UI elements: Mostra gli elementi della barra di navigazione solo quando il mouse passa sopra per minimizzare gli elementi visibili dell'interfaccia
Global System OS Hotkeys: Tasti di scelta rapida globali del sistema operativo
Hide Collections Navbar: Nascondi la barra di navigazione delle collezioni
Change: Modifica
Copy only from menu items: Copia solo dagli elementi del menu
Display navbar items only when the mouse hovers over the navigation bar to minimize visible UI elements: Mostra gli elementi della barra di navigazione solo al passaggio del mouse per minimizzare gli elementi visibili dell'interfaccia
Global System OS Hotkeys: Tasti di scelta rapida globali del sistema
Hide Collections Navbar: Nascondi barra delle collezioni
Hide collections menu dropdown on the navigation bar: Nascondi il menu a discesa delle collezioni nella barra di navigazione
Hide collections menu on the navbar: Nascondi il menu delle collezioni nella barra di navigazione
Hide the App Dock Icon: Nascondi l'icona dell'applicazione nel Dock
Hide the App Dock Icon: Nascondi l'icona dell'app nel Dock
? Keep the main application window hidden when the app restarts. You can reopen it using the menu bar or taskbar menu, or using global hotkeys.
: Mantieni la finestra principale dell'applicazione nascosta quando l'app si riavvia. Puoi riaprirla usando la barra dei menu o il menu della barra delle applicazioni, o usando i tasti di scelta rapida globali.
: Mantieni nascosta la finestra principale dell'applicazione al riavvio. Puoi riaprirla usando la barra dei menu o il menu della barra delle applicazioni, o usando i tasti di scelta rapida globali.
No keys set: Nessun tasto impostato
PasteBar Quick Paste: Incolla rapido PasteBar
Press keys: Premi i tasti
Quick Paste Window: Finestra incolla rapido
? Remove PasteBar app icon from the macOS Dock while keeping the app running in the background. The app remains accessible via the menu bar icon. Requires an app restart to take effect.
: Rimuovi l'icona dell'app PasteBar dal Dock di macOS mantenendo l'app in esecuzione in background. L'app rimane accessibile tramite l'icona nella barra dei menu. Richiede un riavvio dell'app per avere effetto.
: Rimuovi l'icona di PasteBar dal Dock di macOS mantenendo l'app in esecuzione in background. L'app rimane accessibile tramite l'icona della barra dei menu. Richiede un riavvio dell'app per avere effetto.
Set: Imposta
Set system OS hotkeys to show/hide the main app window and quick paste window: Imposta i tasti di scelta rapida del sistema operativo per mostrare/nascondere la finestra principale dell'app e la finestra di incollaggio rapido
Show Navbar Items Hover: Mostra gli elementi della barra di navigazione al passaggio del mouse
Set system OS hotkeys to show/hide the main app window and quick paste window: Imposta i tasti di scelta rapida del sistema per mostrare/nascondere la finestra principale e la finestra incolla rapido
Show Navbar Items Hover: Mostra elementi barra al passaggio del mouse
Show collections menu on the navbar: Mostra il menu delle collezioni nella barra di navigazione
Show navbar elements on hover only: Mostra gli elementi della barra di navigazione solo al passaggio del mouse
Show/Hide Main App Window: Mostra/Nascondi la finestra principale dell'applicazione
Show/Hide Quick Paste Window: Mostra/Nascondi la finestra di incollaggio rapido
Quick Paste Window: Finestra di incollaggio rapido
PasteBar Quick Paste: PasteBar Incolla Rapido
Show navbar elements on hover only: Mostra elementi della barra solo al passaggio del mouse
Show/Hide Main App Window: Mostra/Nascondi finestra principale
Show/Hide Quick Paste Window: Mostra/Nascondi finestra incolla rapido
? When enabled, clicking menu items will only copy content to clipboard instead of auto-pasting. This gives you more control over when and where content is pasted.
: Quando abilitato, cliccando sugli elementi del menu si copierà solo il contenuto negli appunti invece di incollarlo automaticamente. Questo ti dà maggior controllo su quando e dove incollare il contenuto.

View File

@ -1,24 +1,27 @@
App restart required: Требуется перезапуск
App restart required: Требуется перезапуск приложения
Application Starts with Main Window Hidden: Приложение запускается со скрытым главным окном
Change: Изменить
Copy only from menu items: Копировать только из элементов меню
Display navbar items only when the mouse hovers over the navigation bar to minimize visible UI elements: Отображать элементы панели навигации только при наведении мыши для минимизации видимых элементов интерфейса
Global System OS Hotkeys: Глобальные горячие клавиши операционной системы
Global System OS Hotkeys: Глобальные системные горячие клавиши
Hide Collections Navbar: Скрыть панель коллекций
Hide collections menu dropdown on the navigation bar: Скрыть меню коллекций на панели навигации
Hide collections menu dropdown on the navigation bar: Скрыть выпадающее меню коллекций на панели навигации
Hide collections menu on the navbar: Скрыть меню коллекций на панели навигации
Hide the App Dock Icon: Скрыть значок приложения в Dock
Hide the App Dock Icon: Скрыть иконку приложения в Dock
? Keep the main application window hidden when the app restarts. You can reopen it using the menu bar or taskbar menu, or using global hotkeys.
: Держать главное окно приложения скрытым при перезапуске. Вы можете открыть его снова, используя меню бар или панель задач, или же с помощью глобальных горячих клавиш.
: Держать главное окно приложения скрытым при перезапуске. Вы можете открыть его через меню в строке меню или панели задач, или используя глобальные горячие клавиши.
No keys set: Клавиши не установлены
PasteBar Quick Paste: Быстрая вставка PasteBar
Press keys: Нажмите клавиши
? Remove PasteBar app icon from the macOS Dock while keeping the app running in the background. The app remains accessible via the menu bar icon. Requires an app restart to take effect.
: Удалить значок приложения PasteBar из Dock macOS, сохраняя работу приложения в фоновом режиме. Приложение остается доступным через значок в строке меню. Для применения изменений требуется перезапуск приложения.
Set: Установить
Set system OS hotkeys to show/hide the main app window and quick paste window: Установить горячие клавиши ОС для показа/скрытия главного окна приложения и окна быстрой вставки
Show Navbar Items Hover: Показывать элементы панели навигации при наведении
Show collections menu on the navbar: Показать меню коллекций на панели навигации
Show navbar elements on hover only: Показывать элементы панели навигации только при наведении
Show/Hide Main App Window: Показать/Скрыть главное окно приложения
Show/Hide Quick Paste Window: Показать/Скрыть окно быстрой вставки
Quick Paste Window: Окно быстрой вставки
PasteBar Quick Paste: PasteBar Быстрая Вставка
? Remove PasteBar app icon from the macOS Dock while keeping the app running in the background. The app remains accessible via the menu bar icon. Requires an app restart to take effect.
: Удалить иконку PasteBar из macOS Dock, оставляя приложение запущенным в фоне. Приложение остается доступным через иконку в строке меню. Требуется перезапуск приложения.
Set: Установить
Set system OS hotkeys to show/hide the main app window and quick paste window: Установить системные горячие клавиши для показа/скрытия главного окна и окна быстрой вставки
Show Navbar Items Hover: Показывать элементы панели при наведении
Show collections menu on the navbar: Показывать меню коллекций на панели навигации
Show navbar elements on hover only: Показывать элементы панели только при наведении
Show/Hide Main App Window: Показать/Скрыть главное окно
Show/Hide Quick Paste Window: Показать/Скрыть окно быстрой вставки
? When enabled, clicking menu items will only copy content to clipboard instead of auto-pasting. This gives you more control over when and where content is pasted.
: При включении нажатие на элементы меню будет только копировать содержимое в буфер обмена вместо автоматической вставки. Это дает вам больше контроля над тем, когда и где вставляется содержимое.

View File

@ -1,24 +1,27 @@
App restart required: Uygulamanın yeniden başlatılması gerekiyor
Application Starts with Main Window Hidden: Uygulama Ana Pencere Gizli Olarak Başlıyor
App restart required: Uygulama yeniden başlatma gerekli
Application Starts with Main Window Hidden: Uygulama ana pencere gizli olarak başlar
Change: Değiştir
Display navbar items only when the mouse hovers over the navigation bar to minimize visible UI elements: Görünür kullanıcı arayüzü öğelerini en aza indirmek için gezinme çubuğu öğelerini yalnızca fare gezinme çubuğunun üzerindeyken görüntüleyin
Global System OS Hotkeys: Genel Işletim Sistemi Kısayolları
Hide Collections Navbar: Koleksiyonlar Navigasyon Çubuğunu Gizle
Hide collections menu dropdown on the navigation bar: Gezinme çubuğundaki koleksiyonlar menüsü açılır menüsünü gizle
Copy only from menu items: Sadece menü öğelerinden kopyala
Display navbar items only when the mouse hovers over the navigation bar to minimize visible UI elements: Görünür arayüz öğelerini en aza indirmek için gezinme çubuğu öğelerini yalnızca fare üzerine geldiğinde göster
Global System OS Hotkeys: Global Sistem Kısayol Tuşları
Hide Collections Navbar: Koleksiyonlar Gezinme Çubuğunu Gizle
Hide collections menu dropdown on the navigation bar: Gezinme çubuğundaki koleksiyonlar açılır menüsünü gizle
Hide collections menu on the navbar: Gezinme çubuğundaki koleksiyonlar menüsünü gizle
Hide the App Dock Icon: Uygulama Dock Simgesini Gizle
? Keep the main application window hidden when the app restarts. You can reopen it using the menu bar or taskbar menu, or using global hotkeys.
: Uygulama yeniden başlatıldığında ana uygulama penceresini gizli tutun. Menü çubuğunu veya görev çubuğu menüsünü kullanarak veya genel kısayol tuşlarını kullanarak yeniden açabilirsiniz.
No keys set: Anahtar ayarlanmadı
PasteBar Quick Paste: PasteBar Çabuk Yapıştır
: Uygulama yeniden başladığında ana uygulama penceresini gizli tut. Menü çubuğu veya görev çubuğu menüsünü kullanarak veya global kısayol tuşlarını kullanarak yeniden açabilirsiniz.
No keys set: Tuş atanmadı
PasteBar Quick Paste: PasteBar Hızlı Yapıştır
Press keys: Tuşlara basın
Quick Paste Window: Hızlı Yapıştır Penceresi
? Remove PasteBar app icon from the macOS Dock while keeping the app running in the background. The app remains accessible via the menu bar icon. Requires an app restart to take effect.
: Uygulamayı arka planda çalıştırmaya devam ederken macOS Dock'tan PasteBar uygulama simgesini kaldırın. Uygulama menü çubuğu simgesi aracılığıyla erişilebilir olmaya devam eder. Etkili olması için uygulamanın yeniden başlatılması gerekir.
Set: Set
Set system OS hotkeys to show/hide the main app window and quick paste window: Ana uygulama penceresini ve hızlı yapıştırma penceresini gösterm/gizle için sistem işletim sistemi kısayol tuşlarını ayarlayın
Show Navbar Items Hover: Navbar Öğelerini Göster
Show collections menu on the navbar: Gezinme çubuğunda koleksiyonlar menüsünü göster.
Show navbar elements on hover only: Navigasyon çubuğu öğelerini yalnızca üzerine gelindiğinde göster.
: PasteBar uygulama simgesini macOS Dock'tan kaldırır ancak uygulama arka planda çalışmaya devam eder. Uygulamaya menü çubuğu simgesi üzerinden erişilebilir. Etkili olması için uygulama yeniden başlatma gerekir.
Set: Ayarla
Set system OS hotkeys to show/hide the main app window and quick paste window: Ana uygulama penceresini ve hızlı yapıştır penceresini göstermek/gizlemek için sistem kısayol tuşlarını ayarla
Show Navbar Items Hover: Gezinme Çubuğu Öğelerini Üzerine Gelince Göster
Show collections menu on the navbar: Gezinme çubuğunda koleksiyonlar menüsünü göster
Show navbar elements on hover only: Gezinme çubuğu öğelerini yalnızca üzerine gelince göster
Show/Hide Main App Window: Ana Uygulama Penceresini Göster/Gizle
Show/Hide Quick Paste Window: Hızlı Yapıştır Penceresini Göster/Gizle
? When enabled, clicking menu items will only copy content to clipboard instead of auto-pasting. This gives you more control over when and where content is pasted.
: Etkinleştirildiğinde, menü öğelerine tıklamak içeriği otomatik yapıştırmak yerine yalnızca panoya kopyalar. Bu, içeriğin ne zaman ve nereye yapıştırılacağı konusunda size daha fazla kontrol sağlar.

View File

@ -1,24 +1,27 @@
App restart required: Потрібен перезапуск
App restart required: Потрібен перезапуск додатку
Application Starts with Main Window Hidden: Додаток запускається з прихованим головним вікном
Change: Змінити
Display navbar items only when the mouse hovers over the navigation bar to minimize visible UI elements: Відображати елементи панелі навігації лише при наведенні миші для мінімізації видимих елементів інтерфейсу
Global System OS Hotkeys: Глобальні гарячі клавіші операційної системи
Copy only from menu items: Копіювати тільки з елементів меню
Display navbar items only when the mouse hovers over the navigation bar to minimize visible UI elements: Відображати елементи панелі навігації тільки при наведенні миші для мінімізації видимих елементів інтерфейсу
Global System OS Hotkeys: Глобальні системні гарячі клавіші
Hide Collections Navbar: Приховати панель колекцій
Hide collections menu dropdown on the navigation bar: Приховати меню колекцій на панелі навігації
Hide collections menu dropdown on the navigation bar: Приховати випадаюче меню колекцій на панелі навігації
Hide collections menu on the navbar: Приховати меню колекцій на панелі навігації
Hide the App Dock Icon: Приховати значок додатку в Dock
Hide the App Dock Icon: Приховати іконку додатку в Dock
? Keep the main application window hidden when the app restarts. You can reopen it using the menu bar or taskbar menu, or using global hotkeys.
: Тримати головне вікно додатку прихованим при перезапуску. Ви можете відкрити його знову, використовуючи меню бар або панель завдань, або за допомогою глобальних гарячих клавіш.
: Тримати головне вікно додатку прихованим при перезапуску. Ви можете відкрити його через меню в рядку меню або панелі завдань, або використовуючи глобальні гарячі клавіші.
No keys set: Клавіші не встановлені
PasteBar Quick Paste: Швидка вставка PasteBar
Press keys: Натисніть клавіші
? Remove PasteBar app icon from the macOS Dock while keeping the app running in the background. The app remains accessible via the menu bar icon. Requires an app restart to take effect.
: Видалити значок додатку PasteBar з Dock macOS, зберігаючи роботу додатку у фоновому режимі. Додаток залишається доступним через значок у рядку меню. Для застосування змін потрібен перезапуск додатку.
Set: Встановити
Set system OS hotkeys to show/hide the main app window and quick paste window: Встановити гарячі клавіші ОС для показу/приховування головного вікна додатку та вікна швидкої вставки
Show Navbar Items Hover: Показувати елементи панелі навігації при наведенні
Show collections menu on the navbar: Показати меню колекцій на панелі навігації
Show navbar elements on hover only: Показувати елементи панелі навігації лише при наведенні
Show/Hide Main App Window: Показати/Приховати головне вікно додатку
Show/Hide Quick Paste Window: Показати/Приховати вікно швидкої вставки
Quick Paste Window: Вікно швидкої вставки
PasteBar Quick Paste: PasteBar Швидка Вставка
? Remove PasteBar app icon from the macOS Dock while keeping the app running in the background. The app remains accessible via the menu bar icon. Requires an app restart to take effect.
: Видалити іконку PasteBar з macOS Dock, залишаючи додаток запущеним у фоні. Додаток залишається доступним через іконку в рядку меню. Потрібен перезапуск додатку.
Set: Встановити
Set system OS hotkeys to show/hide the main app window and quick paste window: Встановити системні гарячі клавіші для показу/приховування головного вікна та вікна швидкої вставки
Show Navbar Items Hover: Показувати елементи панелі при наведенні
Show collections menu on the navbar: Показувати меню колекцій на панелі навігації
Show navbar elements on hover only: Показувати елементи панелі тільки при наведенні
Show/Hide Main App Window: Показати/Приховати головне вікно
Show/Hide Quick Paste Window: Показати/Приховати вікно швидкої вставки
? When enabled, clicking menu items will only copy content to clipboard instead of auto-pasting. This gives you more control over when and where content is pasted.
: При увімкненні натискання на елементи меню буде тільки копіювати вміст до буфера обміну замість автоматичної вставки. Це дає вам більше контролю над тим, коли і де вставляється вміст.

View File

@ -1,6 +1,7 @@
App restart required: 需要重启应用
Application Starts with Main Window Hidden: 应用启动时隐藏主窗口
Change: 更改
Copy only from menu items: 仅从菜单项复制
Display navbar items only when the mouse hovers over the navigation bar to minimize visible UI elements: 仅在鼠标悬停在导航栏上时显示导航栏项目减少可见的UI元素
Global System OS Hotkeys: 全局系统操作系统热键
Hide Collections Navbar: 隐藏收藏导航栏
@ -22,3 +23,6 @@ Show/Hide Main App Window: 显示/隐藏主应用窗口
Show/Hide Quick Paste Window: 显示/隐藏快速粘贴窗口
Quick Paste Window: 快速粘贴窗口
PasteBar Quick Paste: PasteBar 快速粘贴
? When enabled, clicking menu items will only copy content to clipboard instead of auto-pasting. This gives you more control over when and where content is pasted.
: 启用后,点击菜单项将仅复制内容到剪贴板而不是自动粘贴。这让您对内容粘贴的时间和位置有更多控制。

View File

@ -72,9 +72,11 @@ interface ClipboardHistoryRowProps {
searchTerm?: string
isBrokenImage?: boolean
isCopied?: boolean
isKeyboardSelected?: boolean
isPasted?: boolean
isSaved?: boolean
isLargeView?: boolean
isScrolling?: boolean
isPinnedTop?: boolean
isPinnedTopFirst?: boolean
isDisabledPinnedMoveUp?: boolean
@ -138,6 +140,8 @@ export function ClipboardHistoryRowComponent({
isWrapText = false,
isDeleting = false,
isOverPinned = false,
isKeyboardSelected = false,
isScrolling = false,
hasClipboardHistoryURLErrors = false,
addToClipboardHistoryIdsURLErrors = () => {},
hasGenerateLinkMetaDataInProgress = false,
@ -177,6 +181,7 @@ export function ClipboardHistoryRowComponent({
}: ClipboardHistoryRowProps) {
const { t } = useTranslation()
const rowRef = useRef<HTMLDivElement>(null)
const rowKeyboardRef = useRef<HTMLDivElement>(null)
const contextMenuButtonRef = useRef<HTMLDivElement>(null)
const contextMenuTriggerRef = useRef<HTMLDivElement>(null)
const isCopiedOrPasted = isCopied || isPasted || isSaved
@ -224,6 +229,14 @@ export function ClipboardHistoryRowComponent({
index,
])
useEffect(() => {
if (isKeyboardSelected && rowKeyboardRef.current && !isScrolling) {
rowKeyboardRef.current.scrollIntoView({
block: 'center',
})
}
}, [isKeyboardSelected, isScrolling])
useEffect(() => {
requestAnimationFrame(() => {
requestAnimationFrame(() => {
@ -259,7 +272,7 @@ export function ClipboardHistoryRowComponent({
clipboard.isFavorite,
clipboard.isPinned,
])
const stringValue: string = clipboard?.value ?? ''
const hasLinkCard =
clipboard?.isLink &&
@ -311,23 +324,25 @@ export function ClipboardHistoryRowComponent({
const pinnedTopOffsetFirst = !isPinnedTopFirst ? 'top-[-10px]' : 'top-[5px]'
const bgToolsPanel = `${
!isPinnedTop && isOverPinned && !isNowItem
? 'bg-orange-50 dark:!bg-transparent'
: isDeleting
? 'bg-red-50 dark:bg-red-950/80'
: contextMenuOpen.value
? `bg-slate-100 dark:bg-slate-900 ${
isNowItem ? 'bg-teal-50/80 dark:bg-sky-900/80' : ''
}`
: isCopiedOrPasted
? 'dark:bg-green-950/80'
: isSaved
? 'dark:bg-sky-950/80'
: isSelected
? 'bg-yellow-50 dark:bg-amber-950/80'
: isNowItem
? 'bg-teal-50/90 dark:bg-sky-950'
: 'bg-white dark:bg-slate-950/80'
isKeyboardSelected
? 'bg-blue-50 dark:bg-blue-950/80'
: !isPinnedTop && isOverPinned && !isNowItem
? 'bg-orange-50 dark:!bg-transparent'
: isDeleting
? 'bg-red-50 dark:bg-red-950/80'
: contextMenuOpen.value
? `bg-slate-100 dark:bg-slate-900 ${
isNowItem ? 'bg-teal-50/80 dark:bg-sky-900/80' : ''
}`
: isCopiedOrPasted
? 'dark:bg-green-950/80'
: isSaved
? 'dark:bg-sky-950/80'
: isSelected
? 'bg-yellow-50 dark:bg-amber-950/80'
: isNowItem
? 'bg-teal-50/90 dark:bg-sky-950'
: 'bg-white dark:bg-slate-950/80'
}`
return (
@ -351,7 +366,7 @@ export function ClipboardHistoryRowComponent({
}
{...(isSelected || isHovering ? listeners : {})}
>
<Box ref={rowRef}>
<Box ref={rowRef} tabIndex={0} role="option" aria-selected={isKeyboardSelected}>
{showTimeAgo && (
<Box
className={`flex justify-center text-gray-400 text-xs ${
@ -371,40 +386,51 @@ export function ClipboardHistoryRowComponent({
<ContextMenuTrigger
ref={isHovering || isSelected ? contextMenuTriggerRef : null}
>
<Box className="relative select-none history-item">
<Box
className="relative select-none history-item focus:outline-none"
ref={rowKeyboardRef}
tabIndex={0}
role="option"
aria-selected={isKeyboardSelected}
>
<Box
className={`rounded-md justify-start duration-300 relative px-3 py-1 hover:shadow-sm shadow-none border-2 flex flex-col ${
className={`rounded-md justify-start duration-300 relative px-3 py-1 hover:shadow-sm my-0.5 shadow-none border-2 flex flex-col ${
index === 0 &&
clipboard.updatedAt > Date.now() - MINUTE_IN_MS &&
!isCopiedOrPasted &&
!isDeleting &&
!isKeyboardSelected &&
!isSelected
? 'bg-teal-50 hover:border-slate-300 dark:bg-sky-900/40 dark:hover:border-slate-700 hover:bg-teal-50/90 hover:dark:bg-sky-950'
: isDeleting && !isDragPreview
? 'border-red-400 bg-red-50 dark:bg-red-950/80 dark:border-red-900/80 dark:hover:border-red-800'
: contextMenuOpen.value
? 'bg-slate-100 dark:bg-slate-950/80 border-slate-300 dark:border-slate-600'
: isSaved && !isDragPreview
? 'bg-sky-50 border-sky-600 dark:bg-sky-950/80 dark:border-sky-900/80 dark:hover:border-sky-800'
: isCopiedOrPasted && !isDragPreview
? `bg-green-50 border-green-600 dark:bg-green-950/80 dark:border-green-800`
: isSelected
? `bg-amber-50 border-amber-300 dark:bg-amber-950/80 dark:border-amber-900/80 hover:border-amber-300/80 dark:hover:border-amber-800 hover:bg-amber-50/80 ${
isPinnedTop ? '!border dark:!bg-amber-950' : ''
}`
: `hover:bg-white dark:hover:bg-slate-950/80 ${
isLargeView
? 'border-slate-500 bg-white dark:bg-slate-950 hover:dark:border-slate-500'
: `${
!isPinnedTop && isOverPinned
? 'border-orange-300 dark:border-orange-400/80 dark:bg-orange-900/80 bg-orange-50'
: isPinnedTop
? 'bg-slate-50 dark:!bg-slate-900 dark:hover:!bg-slate-950 hover:!border-orange-300/90 border-orange-300/50 dark:!border-orange-800/60 dark:hover:!border-orange-900'
: 'bg-slate-50 hover:border-slate-300 dark:border-slate-800'
}`
} dark:hover:border-slate-700 dark:bg-slate-900 ${
isDragPreview ? 'dark:border-slate-700' : ''
}`
: isKeyboardSelected
? `bg-blue-50 !shadow-sm border-blue-300 dark:bg-blue-950/80 dark:border-blue-900/80 hover:border-blue-300/80 dark:hover:border-blue-800 hover:bg-blue-50/80 ${
isPinnedTop ? ' dark:!bg-amber-950' : ''
}`
: isDeleting && !isDragPreview
? 'border-red-400 bg-red-50 dark:bg-red-950/80 dark:border-red-900/80 dark:hover:border-red-800'
: contextMenuOpen.value
? 'bg-slate-100 dark:bg-slate-950/80 border-slate-300 dark:border-slate-600'
: isSaved && !isDragPreview
? 'bg-sky-50 border-sky-600 dark:bg-sky-950/80 dark:border-sky-900/80 dark:hover:border-sky-800'
: isCopiedOrPasted && !isDragPreview
? `bg-green-50 border-green-600 dark:bg-green-950/80 dark:border-green-800`
: isSelected
? `bg-amber-50 border-amber-300 dark:bg-amber-950/80 dark:border-amber-900/80 hover:border-amber-300/80 dark:hover:border-amber-800 hover:bg-amber-50/80 ${
isPinnedTop ? '!border dark:!bg-amber-950' : ''
}`
: `hover:bg-white dark:hover:bg-slate-950/80 ${
isLargeView
? 'border-slate-500 bg-white dark:bg-slate-950 hover:dark:border-slate-500'
: `${
!isPinnedTop && isOverPinned
? 'border-orange-300 dark:border-orange-400/80 dark:bg-orange-900/80 bg-orange-50'
: isPinnedTop
? 'bg-slate-50 dark:!bg-slate-900 dark:hover:!bg-slate-950 hover:!border-orange-300/90 border-orange-300/50 dark:!border-orange-800/60 dark:hover:!border-orange-900'
: 'bg-slate-50 hover:border-slate-300 dark:border-slate-800'
}`
} dark:hover:border-slate-700 dark:bg-slate-900 ${
isDragPreview ? 'dark:border-slate-700' : ''
}`
}`}
onClickCapture={e => {
if ((isWindows && e.ctrlKey) || (e.metaKey && !isWindows)) {

View File

@ -194,7 +194,10 @@ export default function ClipboardHistoryPage() {
const [selectedHistoryItems, setSelectedHistoryItems] = useState<UniqueIdentifier[]>([])
const [showSelectHistoryItems, setShowSelectHistoryItems] = useState(false)
const [isDragPinnedHistory, setIsDragPinnedHistory] = useState(false)
const keyboardSelectedItemId = useSignal<UniqueIdentifier | null>(null)
const navigatedWithCtrl = useSignal(false)
const {
isScrolling,
setIsScrolling,
isShowHistoryPinned,
setIsShowHistoryPinned,
@ -227,6 +230,7 @@ export default function ClipboardHistoryPage() {
const isPinnedPanelHovering = useSignal(false)
const isPinnedPanelKeepOpen = useSignal(false)
const isCtrlReleased = useSignal(false)
const { showConfirmation, hoveringHistoryIdDelete } = useDeleteConfirmationTimer({
hoveringHistoryRowId,
@ -382,6 +386,81 @@ export default function ClipboardHistoryPage() {
}
)
useHotkeys(
['ctrl+enter', 'meta+enter'],
e => {
e.preventDefault()
const itemToCopy = keyboardSelectedItemId.value
? keyboardSelectedItemId.value
: clipboardHistory[0]?.historyId
if (itemToCopy) {
setCopiedItem(itemToCopy)
}
},
{ enableOnFormTags: ['input'] }
)
useHotkeys(
['ctrl+arrowdown', 'meta+arrowdown'],
e => {
e.preventDefault()
const currentItemIndex = clipboardHistory.findIndex(
item => item.historyId === keyboardSelectedItemId.value
)
const nextItem = clipboardHistory[currentItemIndex + 1]
if (nextItem) {
keyboardSelectedItemId.value = nextItem.historyId
}
},
{ enableOnFormTags: ['input'] }
)
useHotkeys(
['ctrl+arrowup', 'meta+arrowup'],
e => {
e.preventDefault()
const currentItemIndex = clipboardHistory.findIndex(
item => item.historyId === keyboardSelectedItemId.value
)
const prevItem = clipboardHistory[currentItemIndex - 1]
if (prevItem) {
keyboardSelectedItemId.value = prevItem.historyId
}
},
{ enableOnFormTags: ['input'] }
)
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === 'Control' || e.key === 'Meta') {
if (isCtrlReleased.value) {
keyboardSelectedItemId.value = clipboardHistory[0]?.historyId
isCtrlReleased.value = false
}
navigatedWithCtrl.value = true
}
}
const handleKeyUp = (e: KeyboardEvent) => {
if (e.key === 'Control' || e.key === 'Meta') {
isCtrlReleased.value = true
keyboardSelectedItemId.value = null
navigatedWithCtrl.value = false
}
}
window.addEventListener('keydown', handleKeyDown)
window.addEventListener('keyup', handleKeyUp)
return () => {
window.removeEventListener('keydown', handleKeyDown)
window.removeEventListener('keyup', handleKeyUp)
}
}, [clipboardHistory])
useEffect(() => {
if (keyboardSelectedItemId.value) {
hoveringHistoryRowId.value = keyboardSelectedItemId.value
}
}, [keyboardSelectedItemId.value])
useEffect(() => {
const listenToClipboardUnlisten = listen(
'clipboard://clipboard-monitor/update',
@ -415,6 +494,18 @@ export default function ClipboardHistoryPage() {
}, [])
useEffect(() => {
if (isCtrlReleased.value) {
hoveringHistoryRowId.value = null
keyboardSelectedItemId.value = null
}
}, [isCtrlReleased.value])
useEffect(() => {
if (copiedItem || pastedItem) {
isCtrlReleased.value = true
keyboardSelectedItemId.value = null
navigatedWithCtrl.value = false
}
if (copiedItem && selectedHistoryItems.includes(copiedItem)) {
setSelectedHistoryItems(prev => prev.filter(item => item !== copiedItem))
}
@ -1615,6 +1706,7 @@ export default function ClipboardHistoryPage() {
return (
<ClipboardHistoryRow
isScrolling={isScrolling}
isLargeView={
historyId === showLargeViewHistoryId.value
}
@ -1661,6 +1753,9 @@ export default function ClipboardHistoryPage() {
: undefined
}
isPasted={historyId === pastedItemValue}
isKeyboardSelected={
historyId === keyboardSelectedItemId.value
}
isCopied={historyId === copiedItemValue}
isSaved={historyId === savingItem}
setSavingItem={setSavingItem}

View File

@ -310,18 +310,62 @@ export default function BackupRestoreSettings() {
}
}
const handleBrowseBackupFolder = async (backupPath: string) => {
const handleBrowseBackupFolder = async (backupFilePath: string) => {
try {
// Extract directory from the backup file path
const backupDir = backupPath.substring(
0,
backupPath.lastIndexOf('/') || backupPath.lastIndexOf('\\')
)
await invoke('open_path_or_app', { path: backupDir })
let dirPath = ''
const lastSlash = backupFilePath.lastIndexOf('/')
const lastBackslash = backupFilePath.lastIndexOf('\\')
const separatorIndex = Math.max(lastSlash, lastBackslash)
if (separatorIndex > -1) {
dirPath = backupFilePath.substring(0, separatorIndex)
} else {
console.error('Could not determine directory from backup path:', backupFilePath)
toast({
id: 'backup-open-error-no-dir',
title: t('Error', { ns: 'common' }),
duration: 3000,
description: (
<Box className="word-break">
{t('Could not determine backup folder location from path {{path}}', {
ns: 'backuprestore',
path: backupFilePath,
})}
</Box>
),
variant: 'destructive',
})
return
}
const osType = await getOsType()
if (osType === 'Windows_NT' && dirPath.startsWith('\\\\?\\')) {
dirPath = dirPath.substring(4)
}
if (!dirPath) {
console.error('Derived directory path is empty for backup path:', backupFilePath)
toast({
id: 'backup-open-error-empty-dir',
title: t('Error', { ns: 'common' }),
duration: 3000,
description: (
<Box className="word-break">
{t('Failed to derive a valid backup folder location.', {
ns: 'backuprestore',
})}
</Box>
),
variant: 'destructive',
})
return
}
await invoke('open_path_or_app', { path: dirPath })
} catch (error) {
console.error('Failed to open backup folder:', error)
toast({
id: 'backup-open-error',
id: 'backup-open-error', // Existing ID for this general error
title: t('Error', { ns: 'common' }),
duration: 3000,
description: (

View File

@ -11,7 +11,7 @@ import {
uiStoreAtom,
} from '~/store'
import { useAtomValue } from 'jotai'
import { ChevronDown, ChevronUp, MessageSquare, MessageSquareDashed } from 'lucide-react'
import { MessageSquare, MessageSquareDashed } from 'lucide-react'
import { useTheme } from 'next-themes'
import { useTranslation } from 'react-i18next'
import { Link } from 'react-router-dom'
@ -71,6 +71,8 @@ export default function UserPreferences() {
hotKeysShowHideQuickPasteWindow,
setHotKeysShowHideMainAppWindow,
setHotKeysShowHideQuickPasteWindow,
isMenuItemCopyOnlyEnabled,
setIsMenuItemCopyOnlyEnabled,
} = useAtomValue(settingsStoreAtom)
const { setFontSize, fontSize, setIsSwapPanels, isSwapPanels, returnRoute, isMacOSX } =
@ -529,6 +531,32 @@ export default function UserPreferences() {
</Card>
</Box>
<Box className="animate-in fade-in max-w-xl mt-4">
<Card
className={`${
!isMenuItemCopyOnlyEnabled && 'opacity-80 bg-gray-100 dark:bg-gray-900/80'
}`}
>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-1">
<CardTitle className="animate-in fade-in text-md font-medium w-full">
{t('Copy only from menu items', { ns: 'settings2' })}
</CardTitle>
<Switch
checked={isMenuItemCopyOnlyEnabled}
className="ml-auto"
onCheckedChange={() => {
setIsMenuItemCopyOnlyEnabled(!isMenuItemCopyOnlyEnabled)
}}
/>
</CardHeader>
<CardContent>
<Text className="text-sm text-muted-foreground">
{t('When enabled, clicking menu items will only copy content to clipboard instead of auto-pasting. This gives you more control over when and where content is pasted.', { ns: 'settings2' })}
</Text>
</CardContent>
</Card>
</Box>
<Box className="animate-in fade-in max-w-xl mt-4">
<Card
className={`${

View File

@ -86,6 +86,7 @@ type Settings = {
clipTextMinLength: number
clipTextMaxLength: number
isImageCaptureDisabled: boolean
isMenuItemCopyOnlyEnabled: boolean
}
type Constants = {
@ -161,6 +162,7 @@ export interface SettingsStoreState {
setIsHideCollectionsOnNavBar: (isEnabled: boolean) => void
setIsShowNavBarItemsOnHoverOnly: (isEnabled: boolean) => void
setIsImageCaptureDisabled: (isEnabled: boolean) => void
setIsMenuItemCopyOnlyEnabled: (isEnabled: boolean) => void
hashPassword: (pass: string) => Promise<string>
isNotTourCompletedOrSkipped: (tourName: string) => boolean
verifyPassword: (pass: string, hash: string) => Promise<boolean>
@ -246,6 +248,7 @@ const initialState: SettingsStoreState & Settings = {
clipTextMinLength: 0,
clipTextMaxLength: 5000,
isImageCaptureDisabled: false,
isMenuItemCopyOnlyEnabled: false,
CONST: {
APP_DETECT_LANGUAGES_SUPPORTED: [],
},
@ -303,6 +306,7 @@ const initialState: SettingsStoreState & Settings = {
setClipTextMinLength: () => {},
setClipTextMaxLength: () => {},
setIsImageCaptureDisabled: () => {},
setIsMenuItemCopyOnlyEnabled: () => {},
initConstants: () => {},
setAppDataDir: () => {}, // Keep if used for other general app data
setCustomDbPath: () => {},
@ -375,7 +379,8 @@ export const settingsStore = createStore<SettingsStoreState & Settings>()((set,
name === 'isHistoryEnabled' ||
name === 'userSelectedLanguage' ||
name === 'isAppLocked' ||
name === 'isImageCaptureDisabled'
name === 'isImageCaptureDisabled' ||
name === 'isMenuItemCopyOnlyEnabled'
) {
invoke('build_system_menu')
}
@ -611,6 +616,9 @@ export const settingsStore = createStore<SettingsStoreState & Settings>()((set,
setIsImageCaptureDisabled: async (isEnabled: boolean) => {
return get().updateSetting('isImageCaptureDisabled', isEnabled)
},
setIsMenuItemCopyOnlyEnabled: async (isEnabled: boolean) => {
return get().updateSetting('isMenuItemCopyOnlyEnabled', isEnabled)
},
isNotTourCompletedOrSkipped: (tourName: string) => {
const { appToursCompletedList, appToursSkippedList } = get()
return (

151
src-tauri/Cargo.lock generated
View File

@ -802,10 +802,25 @@ dependencies = [
"objc-foundation",
"objc_id",
"winapi",
"windows-win",
"windows-win 2.4.1",
"x11-clipboard",
]
[[package]]
name = "clipboard-rs"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afede46921767868c5c7f8f55202bdd8bec0bab6bc9605174200f45924f93c62"
dependencies = [
"clipboard-win",
"image 0.25.6",
"objc2 0.6.1",
"objc2-app-kit",
"objc2-foundation",
"windows 0.59.0",
"x11rb",
]
[[package]]
name = "clipboard-win"
version = "5.4.0"
@ -813,6 +828,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15efe7a882b08f34e38556b14f2fb3daa98769d06c7f0c1b076dfd0d983bc892"
dependencies = [
"error-code",
"windows-win 3.0.0",
]
[[package]]
@ -2538,7 +2554,7 @@ dependencies = [
"js-sys",
"log",
"wasm-bindgen",
"windows-core",
"windows-core 0.61.2",
]
[[package]]
@ -2743,6 +2759,8 @@ dependencies = [
"num-traits",
"png",
"tiff",
"zune-core",
"zune-jpeg",
]
[[package]]
@ -3828,8 +3846,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6f29f568bec459b0ddff777cec4fe3fd8666d82d5a40ebd0ff7e66134f89bcc"
dependencies = [
"bitflags 2.9.1",
"block2",
"libc",
"objc2 0.6.1",
"objc2-cloud-kit",
"objc2-core-data",
"objc2-core-foundation",
"objc2-core-graphics",
"objc2-core-image",
"objc2-foundation",
"objc2-quartz-core",
]
[[package]]
name = "objc2-cloud-kit"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17614fdcd9b411e6ff1117dfb1d0150f908ba83a7df81b1f118005fe0a8ea15d"
dependencies = [
"bitflags 2.9.1",
"objc2 0.6.1",
"objc2-foundation",
]
[[package]]
name = "objc2-core-data"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291fbbf7d29287518e8686417cf7239c74700fd4b607623140a7d4a3c834329d"
dependencies = [
"bitflags 2.9.1",
"objc2 0.6.1",
"objc2-foundation",
]
@ -3857,6 +3904,16 @@ dependencies = [
"objc2-io-surface",
]
[[package]]
name = "objc2-core-image"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79b3dc0cc4386b6ccf21c157591b34a7f44c8e75b064f85502901ab2188c007e"
dependencies = [
"objc2 0.6.1",
"objc2-foundation",
]
[[package]]
name = "objc2-encode"
version = "4.1.0"
@ -3887,6 +3944,17 @@ dependencies = [
"objc2-core-foundation",
]
[[package]]
name = "objc2-quartz-core"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90ffb6a0cd5f182dc964334388560b12a57f7b74b3e2dec5e2722aa2dfb2ccd5"
dependencies = [
"bitflags 2.9.1",
"objc2 0.6.1",
"objc2-foundation",
]
[[package]]
name = "objc_exception"
version = "0.1.2"
@ -4107,6 +4175,8 @@ dependencies = [
"bcrypt",
"chrono",
"clipboard-master",
"clipboard-rs",
"clipboard-win",
"clokwerk",
"cocoa 0.26.1",
"colored_json",
@ -6947,6 +7017,16 @@ dependencies = [
"windows-targets 0.48.5",
]
[[package]]
name = "windows"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f919aee0a93304be7f62e8e5027811bbba96bcb1de84d6618be56e43f8a32a1"
dependencies = [
"windows-core 0.59.0",
"windows-targets 0.53.0",
]
[[package]]
name = "windows"
version = "0.61.1"
@ -6954,7 +7034,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5ee8f3d025738cb02bad7868bbb5f8a6327501e870bf51f1b455b0a2454a419"
dependencies = [
"windows-collections",
"windows-core",
"windows-core 0.61.2",
"windows-future",
"windows-link",
"windows-numerics",
@ -6976,7 +7056,20 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8"
dependencies = [
"windows-core",
"windows-core 0.61.2",
]
[[package]]
name = "windows-core"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "810ce18ed2112484b0d4e15d022e5f598113e220c53e373fb31e67e21670c1ce"
dependencies = [
"windows-implement 0.59.0",
"windows-interface",
"windows-result",
"windows-strings 0.3.1",
"windows-targets 0.53.0",
]
[[package]]
@ -6989,7 +7082,7 @@ dependencies = [
"windows-interface",
"windows-link",
"windows-result",
"windows-strings",
"windows-strings 0.4.2",
]
[[package]]
@ -6998,7 +7091,7 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
dependencies = [
"windows-core",
"windows-core 0.61.2",
"windows-link",
"windows-threading",
]
@ -7013,6 +7106,17 @@ dependencies = [
"windows-tokens",
]
[[package]]
name = "windows-implement"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83577b051e2f49a058c308f17f273b570a6a758386fc291b5f6a934dd84e48c1"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.102",
]
[[package]]
name = "windows-implement"
version = "0.60.0"
@ -7053,7 +7157,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
dependencies = [
"windows-core",
"windows-core 0.61.2",
"windows-link",
]
@ -7066,6 +7170,15 @@ dependencies = [
"windows-link",
]
[[package]]
name = "windows-strings"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-strings"
version = "0.4.2"
@ -7197,6 +7310,15 @@ dependencies = [
"winapi",
]
[[package]]
name = "windows-win"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58e23e33622b3b52f948049acbec9bcc34bf6e26d74176b88941f213c75cf2dc"
dependencies = [
"error-code",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.2"
@ -7946,6 +8068,12 @@ dependencies = [
"pkg-config",
]
[[package]]
name = "zune-core"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a"
[[package]]
name = "zune-inflate"
version = "0.2.54"
@ -7955,6 +8083,15 @@ dependencies = [
"simd-adler32",
]
[[package]]
name = "zune-jpeg"
version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f6fe2e33d02a98ee64423802e16df3de99c43e5cf5ff983767e1128b394c8ac"
dependencies = [
"zune-core",
]
[[package]]
name = "zvariant"
version = "3.15.2"

View File

@ -14,6 +14,7 @@ features = []
[target.'cfg(target_os = "windows")'.dependencies]
winapi = { version = "0.3", features = ["winuser", "windef"] }
winreg = "0.52.0"
clipboard-win = "5.4.0"
[dependencies]
fs_extra = "1.3.0"
@ -71,6 +72,7 @@ image = "0.24.9"
tempfile = "3"
base64 = "0.22.0"
clipboard-master = "3.1.3"
clipboard-rs = "0.2.4"
img_hash = "3.2.0"
sha-1 = "0.10.1"
regex = "1.9.3"

View File

@ -1,7 +1,6 @@
use arboard::{Clipboard, ImageData};
use base64::{engine::general_purpose, Engine as _};
use clipboard_master::{CallbackResult, ClipboardHandler, Master};
use diesel::dsl::date;
use image::GenericImageView;
use image::{ImageBuffer, RgbaImage};
use std::borrow::Cow;
@ -17,6 +16,10 @@ use tauri::{
Manager, Runtime,
};
// Windows-specific clipboard handling
#[cfg(target_os = "windows")]
use clipboard_win::{formats, get_clipboard};
use active_win_pos_rs::get_active_window;
use crate::cron_jobs;
@ -100,6 +103,7 @@ where
Ok(active_window) => Some(active_window.app_name),
Err(()) => None,
};
if let Ok(mut text) = clipboard_text {
let trim_text_history = settings_map
.get("isHistoryAutoTrimOnCaputureEnabled")
@ -230,8 +234,8 @@ where
));
}
}
} else if let Ok(image_binary) = clipboard_manager.get_image_binary() {
// Check if image capturing is disabled
} else {
// Check if image capturing is disabled first (before accessing clipboard)
let is_image_capture_disabled = settings_map
.get("isImageCaptureDisabled")
.and_then(|s| s.value_bool)
@ -244,33 +248,36 @@ where
return CallbackResult::Next;
}
let mut is_app_excluded = false;
// Only try to get image from clipboard if capture is enabled
if let Ok(image_binary) = clipboard_manager.get_image_binary() {
let mut is_app_excluded = false;
if let Some(setting) = settings_map.get("isExclusionAppListEnabled") {
if let Some(value_bool) = setting.value_bool {
if value_bool {
if let Some(app_name) = &copied_from_app {
let exclusion_app_list: Vec<String> = settings_map
.get("historyExclusionAppList")
.and_then(|s| s.value_text.as_ref())
.map_or(Vec::new(), |exclusion_list_text| {
exclusion_list_text.lines().map(String::from).collect()
});
if let Some(setting) = settings_map.get("isExclusionAppListEnabled") {
if let Some(value_bool) = setting.value_bool {
if value_bool {
if let Some(app_name) = &copied_from_app {
let exclusion_app_list: Vec<String> = settings_map
.get("historyExclusionAppList")
.and_then(|s| s.value_text.as_ref())
.map_or(Vec::new(), |exclusion_list_text| {
exclusion_list_text.lines().map(String::from).collect()
});
is_app_excluded |= exclusion_app_list
.iter()
.any(|item| item.to_lowercase() == app_name.to_lowercase());
is_app_excluded |= exclusion_app_list
.iter()
.any(|item| item.to_lowercase() == app_name.to_lowercase());
}
}
}
}
}
if !is_app_excluded {
do_refresh_clipboard = Some(history_service::add_clipboard_history_from_image(
image_binary,
should_auto_star_on_double_copy,
copied_from_app,
));
if !is_app_excluded {
do_refresh_clipboard = Some(history_service::add_clipboard_history_from_image(
image_binary,
should_auto_star_on_double_copy,
copied_from_app,
));
}
}
}
@ -387,37 +394,9 @@ impl ClipboardManager {
Ok(base64_str)
}
pub fn get_image_binary(&self) -> Result<ImageData, String> {
let mut clipboard = Clipboard::new().unwrap();
let image_data = clipboard.get_image().map_err(|err| err.to_string())?;
// Only check for stride alignment on Windows
#[cfg(target_os = "windows")]
{
let bytes_per_pixel = 4; // RGBA
let expected_bytes_per_row = image_data.width * bytes_per_pixel;
let actual_bytes_per_row = image_data.bytes.len() / image_data.height;
if actual_bytes_per_row != expected_bytes_per_row {
// We have stride padding, need to remove it
let mut cleaned_bytes = Vec::with_capacity(expected_bytes_per_row * image_data.height);
for row in 0..image_data.height {
let row_start = row * actual_bytes_per_row;
let row_end = row_start + expected_bytes_per_row;
cleaned_bytes.extend_from_slice(&image_data.bytes[row_start..row_end]);
}
return Ok(ImageData {
width: image_data.width,
height: image_data.height,
bytes: Cow::Owned(cleaned_bytes),
});
}
}
// For macOS, Linux, and Windows without padding, return as-is
Ok(image_data)
pub fn get_image_binary(&self) -> Result<ImageData<'static>, String> {
// Use our safe image retrieval function instead of clipboard_rs
get_image_safe()
}
// Function 2: Returns Vec<u8> of PNG file data
@ -471,6 +450,64 @@ impl ClipboardManager {
}
}
// Safe image retrieval function to avoid clipboard corruption
#[cfg(target_os = "windows")]
fn get_image_safe() -> Result<ImageData<'static>, String> {
// Try PNG format first (safest) - using the correct format ID
let png_format = clipboard_win::register_format("PNG")
.map(|f| f.into())
.unwrap_or(0);
if png_format != 0 && clipboard_win::is_format_avail(png_format) {
match get_clipboard(formats::RawData(png_format)) {
Ok(png_data) => {
// Load PNG data directly using image crate
match image::load_from_memory(&png_data) {
Ok(img) => {
let rgba_img = img.to_rgba8();
let (width, height) = img.dimensions();
return Ok(ImageData {
width: width as usize,
height: height as usize,
bytes: Cow::Owned(rgba_img.into_raw()),
});
}
Err(e) => println!("PNG decode error: {}", e),
}
}
Err(e) => println!("PNG clipboard error: {}", e),
}
}
// Fallback to DIB format (safer than DIBV5)
if clipboard_win::is_format_avail(formats::CF_DIB) {
match get_clipboard(formats::Bitmap) {
Ok(bmp_data) => match image::load_from_memory(&bmp_data) {
Ok(img) => {
let rgba_img = img.to_rgba8();
let (width, height) = img.dimensions();
return Ok(ImageData {
width: width as usize,
height: height as usize,
bytes: Cow::Owned(rgba_img.into_raw()),
});
}
Err(e) => println!("BMP decode error: {}", e),
},
Err(e) => println!("BMP clipboard error: {}", e),
}
}
Err("No supported image format found in clipboard".to_string())
}
#[cfg(target_os = "macos")]
fn get_image_safe() -> Result<ImageData<'static>, String> {
// For macos platforms, use arboard
let mut clipboard = Clipboard::new().map_err(|e| e.to_string())?;
let image_data = clipboard.get_image().map_err(|e| e.to_string())?;
Ok(image_data)
}
/// Initializes the plugin.
pub fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::new("clipboard")

View File

@ -718,10 +718,24 @@ async fn main() {
debug_output(|| {
println!("system tray received a click on item id{:?} ", item_id);
});
let w = app.get_window("main").unwrap();
let state: tauri::State<DbItems> = app.state::<DbItems>();
let db_items_state = state.0.lock().unwrap();
// Get the copy-only setting
let app_settings = app.state::<Mutex<HashMap<String, Setting>>>();
let settings_map = app_settings.lock().unwrap();
let is_copy_only = settings_map
.get("isMenuItemCopyOnlyEnabled")
.and_then(|setting| setting.value_bool)
.unwrap_or(false);
debug_output(|| {
println!("Looking for item with item_id: {:?}", item_id);
println!("is_copy_only: {:?}", is_copy_only);
});
let item_opt = db_items_state.iter().find(|&item| item.item_id == item_id);
if let Some(item) = item_opt {
@ -743,26 +757,54 @@ async fn main() {
// Convert relative path to absolute path
let absolute_path = db::to_absolute_image_path(&image_path);
let img_data = std::fs::read(&absolute_path).expect("Failed to read image from path");
let img_data =
std::fs::read(&absolute_path).expect("Failed to read image from path");
let base64_image = base64::encode(&img_data);
write_image_to_clipboard(base64_image).expect("Failed to write image to clipboard");
}
if item.is_link.unwrap_or(false) {
let url = item.value.as_deref().unwrap_or("");
let _ = opener::open(ensure_url_or_email_prefix(url))
.map_err(|e| format!("Failed to open url: {}", e));
if is_copy_only {
// Copy URL to clipboard instead of opening it
debug_output(|| {
println!("Copying URL to clipboard: {}", url);
});
manager
.write_text(url)
.expect("failed to write to clipboard");
} else {
let _ = opener::open(ensure_url_or_email_prefix(url))
.map_err(|e| format!("Failed to open url: {}", e));
}
} else if item.is_path.unwrap_or(false) {
let path = item.value.as_deref().unwrap_or("");
let _ = opener::open(path).map_err(|e| format!("Failed to open path: {}", e));
if is_copy_only {
// Copy path to clipboard instead of opening it
debug_output(|| {
println!("Copying path to clipboard: {}", path);
});
manager
.write_text(path)
.expect("failed to write to clipboard");
} else {
let _ = opener::open(path).map_err(|e| format!("Failed to open path: {}", e));
}
} else {
if item.value.as_deref().unwrap_or("").is_empty() {
debug_output(|| {
println!("Copying item name to clipboard: {}", &item.name);
});
manager
.write_text(&item.name)
.expect("failed to write to clipboard");
} else if let Some(ref item_value) = item.value {
let text_to_copy = remove_special_bbcode_tags(item_value);
debug_output(|| {
println!("Copying item value to clipboard: {}", text_to_copy);
});
manager
.write_text(remove_special_bbcode_tags(item_value))
.write_text(text_to_copy)
.expect("failed to write to clipboard");
}
}
@ -782,12 +824,15 @@ async fn main() {
return true;
}
#[cfg(any(target_os = "windows", target_os = "macos"))]
if query_accessibility_permissions() {
VKey.press_paste();
} else {
w.show().unwrap();
w.emit("macosx-permissions-modal", "show").unwrap();
// Only auto-paste if not in copy-only mode
if !is_copy_only {
#[cfg(any(target_os = "windows", target_os = "macos"))]
if query_accessibility_permissions() {
VKey.press_paste();
} else {
w.show().unwrap();
w.emit("macosx-permissions-modal", "show").unwrap();
}
}
w.emit("execMenuItemById", item_id).unwrap();
@ -801,11 +846,23 @@ async fn main() {
let delay = if cfg!(target_os = "windows") { 3 } else { 0 };
rt.block_on(async {
copy_paste_clip_item_from_menu(app_clone, item_id_string, delay).await;
if is_copy_only {
// For copy-only mode, use copy function instead of copy-paste
clipboard_commands::copy_clip_item(app_clone, item_id_string, true).await;
} else {
copy_paste_clip_item_from_menu(app_clone, item_id_string, delay).await;
}
});
});
}
} else {
debug_output(|| {
println!(
"Item not found in db_items_state, checking recent history for: {:?}",
item_id
);
});
let recent_history_state: tauri::State<DbRecentHistoryItems> =
app.state::<DbRecentHistoryItems>();
let db_recent_history_items_state = recent_history_state.0.lock().unwrap();
@ -838,7 +895,8 @@ async fn main() {
// Convert relative path to absolute path
let absolute_path = db::to_absolute_image_path(&image_path);
let img_data = std::fs::read(&absolute_path).expect("Failed to read image from path");
let img_data =
std::fs::read(&absolute_path).expect("Failed to read image from path");
let base64_image = base64::encode(&img_data);
write_image_to_clipboard(base64_image).expect("Failed to write image to clipboard");
@ -867,12 +925,15 @@ async fn main() {
return true;
}
#[cfg(any(target_os = "windows", target_os = "macos"))]
if query_accessibility_permissions() {
VKey.press_paste();
} else {
w.show().unwrap();
w.emit("macosx-permissions-modal", "show").unwrap();
// Only auto-paste if not in copy-only mode
if !is_copy_only {
#[cfg(any(target_os = "windows", target_os = "macos"))]
if query_accessibility_permissions() {
VKey.press_paste();
} else {
w.show().unwrap();
w.emit("macosx-permissions-modal", "show").unwrap();
}
}
w.emit("execMenuItemById", item_id).unwrap();