Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/voxd/core/typer.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import sys
import select
from voxd.utils.libw import verbo
import pyperclip # New: clipboard helper for instant paste
from voxd.core.clipboard import ClipboardManager # backend-aware clipboard (wl-copy/xclip/xsel)
from pathlib import Path

def detect_backend():
Expand Down Expand Up @@ -301,7 +301,13 @@ def _paste(self, text: str):
t = t + " "
except Exception:
pass
pyperclip.copy(t)
# Use VOXD's own ClipboardManager rather than pyperclip directly.
# pyperclip may select its `gi`/GTK backend when PyGObject is installed,
# which requires a running GTK main loop to own the selection. VOXD has
# no such loop, so the copy silently evaporates and the paste shortcut
# fires against an empty clipboard. ClipboardManager picks wl-copy on
# Wayland (xclip/xsel on X11), which owns the selection correctly.
ClipboardManager().copy(t)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restore fallback when ClipboardManager cannot copy

When paste mode is used in an environment where the selected clipboard backend cannot actually copy (for example no wl-copy/xclip/xsel so ClipboardManager falls back to pyperclip and pyperclip raises, or xclip/wl-copy exits non-zero), ClipboardManager.copy() logs and returns instead of raising, so this try still proceeds to send the paste shortcut and can paste stale clipboard contents or nothing. The previous direct pyperclip.copy() path would enter the existing _type_char_by_char fallback on copy failure; this call needs equivalent failure signaling before triggering Ctrl+V/Ctrl+Shift+V.

Useful? React with 👍 / 👎.

except Exception as e:
verbo(f"[typer] Clipboard copy failed: {e} – falling back to typing mode.")
self._type_char_by_char(text)
Expand Down