[kwayland] Clipboard Manager protocol
Open, Needs TriagePublic

Description

A dedicated protocol is required to forward all clipboard changes to Klipper and allow Klipper to always update the clipboard content.

WIP branches exist, currently at unit test phase

sitter added a subscriber: sitter.
sitter assigned this task to graesslin.Nov 7 2016, 2:51 PM

We should talk to GNOME and wlroots about a common protocol for this functionality.

Is this task currently still actively being worked on? Otherwise I put it back in the Backlog for now.

apol added a subscriber: apol.Feb 19 2019, 1:35 PM

KDE Connect needs something like that for the clipboard plugin too.

This is wanted for KDE Connect too

romangg added a comment.EditedJul 20 2019, 2:47 PM

Problem description

On Wayland data offers are sent directly from a client as data source to another client's data device. In particular:

  1. For security reasons it is not per se possible for clients to read or write on arbitrary data offers. KWin for example only allows the currently active client to do that.
  2. Data offers get lost when the data source client closes the Wayland connection.

(1) is desired behavior but we want out clipboard manager Klipper to be an exception. (2) is unwanted in general for small data offers.

Goals

  • Allow Klipper and only Klipper to eavesdrop on selections.
  • Give selection source to Klipper when no other client provides it. Allows to provide data after other client goes down with the data source.

Constraints

  1. Passwords must not be copied to Klipper history. Possible when data source provides x-kde-passwordManagerHint mimetype. KeepassXC does this since version 2.4.0.
  2. Clients killing off their data source after data was sent once. This is probably not possible to handle in all cases since we need to at least transfer once to Klipper besides sending to the other client and we might abort sending to Klipper if the data is too large.
  3. We need to buffer content directly in case the client connection dies down later on. We don't want to do this in KWin, so always directly transfer to Klipper.

Possible solutions

wlroots has the wlr-data-control-unstable-v1 protocol for clipboard managers. It's on the one hand a bit clunky because it's just a copy of the respective core Wayland interfaces, on the other side this solution is genius because there is no need for another specialized interface. The question is if this integrates nicely with our KWayland code which is complicated in regards to data sharing.

An alternative would be to implement a simple protocol that just activates a client as clipboard manager and then for every data source a data offer will first get routed to the clipboard manager before being sent to currently focused one. This could be part of plasma-window-management protocol. Such a clipboard manager could maybe not use the Wayland core data protocol for normal data transfers anymore in a sensible way.

Another question is if we should just directly replace any client's data source with the clipboard manager ones in case the clipboard manager buffers the data offer. In this case we would need an additional request for the clipboard manager in comparision to wlroot's protocol.

davidedmundson claimed this task.
davidedmundson added a subscriber: graesslin.
evpokp added a subscriber: evpokp.Oct 6 2019, 7:59 AM
mzramli added a subscriber: mzramli.Dec 6 2019, 1:36 PM
ktonga added a subscriber: ktonga.Jan 19 2020, 8:19 AM

The hard part is the seat handling.

DataDevice now needs to handle forwarding both DataSource's and DataControlSources and vice versa.

Action plan is:

  • Change SeatInterface to reference a DataSource instead of a DataDevice - it'll fix up the code a lot and clean up many things.
  • Introduce AbstractDataSource as a wrapper round DataSource (API break, but now fine)
  • Add wrappers for DataControl
  • Hook up the remaining bits of DataControl to Seat, which will now be easy
bam added a subscriber: bam.Apr 27 2020, 8:12 PM
davidedmundson added a comment.EditedMay 12 2020, 12:15 PM

That's now all done. Pending merge after 5.19 forks.

Porting klipper is another story.
I've implemented an abstract SystemClipboard that wraps QClipboard or a client API of the protocol. Returns a QMimeData* which generally works fine.
It's written so it can be moved to a high level KWindowSystem somewhere in future.

One challenge it blocks when reading mimedata.
Returning a QByteArray blob async is easy, but QMimeData has additional code to turn that into the right QVariant. QMimeData is very syncronous.

Options are:

  1. merge as-is, it's no worse than X. Problem for another day.
  1. copy the relevant parts of QMimeData + KUrlMimeData::urlsFromMimeData into klipper code and make them call the async version
  1. Introduce a wrapper that constructs a completed QMimeData
class DaveMimeData
{
    QStringList availableFormats();
    QFuture<QMimeData*> init(QStringList formats); //QFuture or KJob or whatever
}

Where klipper can can then just list all the mimetypes it cares about, then we do one async call that gets a fully loaded completed QMimeData.

apol added a comment.May 12 2020, 3:11 PM

I wouldn't have a big problem with merging as is, it could make sense to have QFuture<QVariant> retrieveData as is. It would make it easier to time out when a client is being shitty and would allow to parallelize different queries.

Oh, that's a good compromise given I'll want it anyway.

kleag added a subscriber: kleag.May 27 2020, 9:37 AM
T-bond added a subscriber: T-bond.May 27 2020, 3:51 PM
pejakm added a subscriber: pejakm.Jun 6 2020, 12:39 PM