https://bugs.kde.org/show_bug.cgi?id=525896
Dmitry <[email protected]> changed: What |Removed |Added ---------------------------------------------------------------------------- Resolution|--- |DUPLICATE Status|REPORTED |RESOLVED --- Comment #1 from Dmitry <[email protected]> --- Duplicate of [bug 506325](https://bugs.kde.org/show_bug.cgi?id=506325) -- "Text selection and primary clipboard malfunction on non-Qt applications" (plasmashell / Clipboard widget & pop-up), already RESOLVED FIXED. Closing this one; posting the trace since it confirms the same root cause from a different angle. ## Same root cause Klipper publishes `PRIMARY` through `wlr-data-control` with the marker MIME type `application/x-kde-onlyReplaceEmpty`, meaning "restore this only if nobody owns the selection". KWin decides whether to honour it. In 6.7.5 that decision is too weak -- `src/wayland/seat.cpp`: ```cpp const bool isKlipperEmptyReplacement = dataDevice->primarySelection() && dataDevice->primarySelection()->mimeTypes().contains(QLatin1StringView("application/x-kde-onlyReplaceEmpty")); if (isKlipperEmptyReplacement && currentPrimarySelection) { dataDevice->primarySelection()->cancel(); return; } ``` Only `currentPrimarySelection` is checked, so "the owner disconnected" and "a live owner deliberately cleared it" are indistinguishable. GTK3 clears `PRIMARY` in the middle of every mouse selection gesture (`gtk/gtktextbuffer.c`, `update_selection_clipboards()` calls `gtk_clipboard_clear()` as soon as the buffer has no selection). So on a press that starts a new selection: 1. `GtkTextView` collapses the old selection to place the cursor. 2. GTK releases `PRIMARY`. 3. `currentPrimarySelection` is null, the guard does not fire, KWin accepts Klipper's stale replacement. 4. The rest of the drag keeps extending the selection, but the application no longer owns `PRIMARY`, so `clipboard_clear_selection_cb()` (`gtktextbuffer.c:3187`) moves `selection_bound` back onto `insert` on every update. The drag produces nothing. Dragging when nothing is selected works, because the application does not own `PRIMARY` at press time, nothing is released mid-gesture, and the drag acquires ownership cleanly. ## Evidence The reproducer prints who holds `PRIMARY` right after a failed drag: ``` press#1 btn=1 at (207,32) event_window=text window (ok) had_selection=yes selection_bound moved: NO SELECTION [PRIMARY owner-change] we own it: NO (taken away), NO SELECTION [PRIMARY now offered by someone else] types: application/x-kde-onlyReplaceEmpty, text/plain;charset=utf-8, text/plain [PRIMARY content] "gtk-primary-selection-bug.c" selection_bound moved: NO SELECTION selection_bound moved: NO SELECTION after release: NO SELECTION ``` The marker MIME type is there and the content is stale -- a string selected long before the test. The same GTK build behaves correctly under X11, sway and Mutter. This also explains why the Klipper options exposed in System Settings (`IgnoreSelection`, `SyncClipboards`) change nothing: the decision is taken on the KWin side, and the relevant Klipper knob (`NoEmptyClipboard`) is not in the KCM. ## Fix and version boundary Commit `d9de57d2bda68e6964a904ca7454946515de5435`, "wayland: Only allow replacing a destroyed primary or clipboard selection" (Tomáš Hnyk, pushed by Vlad Zahorodnii 2026-09-09), `BUG: 506325`: ```diff - if (isKlipperEmptyReplacement && currentPrimarySelection) { + if (isKlipperEmptyReplacement && (currentPrimarySelection || lastPrimarySelectionOwner)) { ``` with `lastPrimarySelectionOwner` recorded in `SeatInterface::setPrimarySelection()` as a `QPointer<ClientConnection>`, so it goes null only when the owning client actually disconnects -- exactly the "owner is gone" condition the workaround needed. Verified against the KWin git tags: - `git merge-base --is-ancestor d9de57d2 v6.7.5` -> not an ancestor, the fix is **not** in 6.7.5 - `git tag --contains d9de57d2` -> `v6.7.90`, so it first ships in 6.8 Per the commit message the fix is Wayland-only: under Xwayland `selection->client()` is null, so the gating does not apply and the old, weaker check remains. ## Workaround until 6.8 `~/.config/klipperrc`: ```ini [General] NoEmptyClipboard=false ``` then restart Klipper -- currently a logout, until [plasma-workspace!6983](https://invent.kde.org/plasma/plasma-workspace/-/merge_requests/6983) lands. Trade-off: clipboard content is no longer preserved when the application that put it there closes (it stays in the Klipper history, just not directly pastable). ## Upstream GTK side The GTK behaviour that this interacts with is tracked at https://gitlab.gnome.org/GNOME/gtk/-/work_items/317 *** This bug has been marked as a duplicate of bug 506325 *** -- You are receiving this mail because: You are watching all bug changes.
