Repository navigation
feat(cliprdr): add a Wayland data-control clipboard client - #2055
Benoît Cortier (CBenoit) merged 1 commit into
Conversation
04b9863 to
d57e221
Compare
|
This pull request may overlap with #2016. Both touch Linux clipboard support in ironrdp-cliprdr-native via a Wayland data-control client: this PR adds the data_control module (client, dispatch, state, worker for ext-data-control-v1 and wlr-data-control-unstable-v1) with delayed rendering, while This notice is advisory only. Automated review continues as usual, and how these pull requests relate is for maintainers and authors to decide. Note LLM-assisted content (no human feedback). |
There was a problem hiding this comment.
The PR adds a self-contained Wayland data-control clipboard client (ext-data-control-v1 / wlr-data-control-unstable-v1) to ironrdp-cliprdr-native, with a worker-thread architecture, a public DataControl/Content/TransferRequest API, delayed rendering, MIME charset-tolerant matching, and state-machine tests behind a __test feature. Independent inspection confirms the specialists' code-level observations: Shared::own_source_live is written in four places and read nowhere; read() can return Ok(Some(empty)) when the offer races or disappears because the worker dispatches Wayland events before commands and EOF maps to success; source-side cached_data uses a one-directional MIME fallback weaker than find_mime_match; dispatch.rs mechanically duplicates four handlers per protocol; test-only accessors restate field access; and lock-poisoning is handled inconsistently (recovering in client.rs, silently skipped in state.rs). The unwired-public-API scope question is real but depends on #2016 timin…
d57e221 to
5efe512
Compare
|
I pushed an update, rebased on current master. It answers the seven review threads and changes a few things the threads didn't cover, which I found while checking them against the code. The guard that keeps the client from reporting its own selection back now counts the echoes of the selections it sets instead of comparing MIME types, so another client's copy with the same types isn't swallowed. It has tests now. Pastes are bounded. Before, every paste got its own writer thread with a blocking write and no limit, and a paste waiting for its data had no deadline. Now at most 16 are served at once, a paste whose data isn't supplied within 5 seconds is closed with no data, a late answer is kept for the next paste, and a reader that takes nothing for 5 seconds is dropped. Dropping a TransferRequest without answering it closes its paste at once, where before the transfer stayed pending and later pastes waited behind it. The tests moved from ironrdp-testsuite-core to ironrdp-testsuite-extra, because ironrdp-cliprdr-native is in the extra tier and ARCHITECTURE.md allows no extra tier dependency in the core suite. I also removed an expect(unreachable_pub) that made clippy fail for this crate without the __test feature, and brought the inline comments in line with STYLE.md. |
5efe512 to
85be787
Compare
|
I pushed another update, still one commit on current master. The guard that keeps the client from reporting its own selection back no longer counts echoes. The client now advertises one private MIME type next to the types of its own selections, and a selection that carries it belongs to the client, in whichever order the compositor delivers things and whatever types another client's copy offers. Other clients can see that type in the list of types they are offered. The module docs link to the two protocol XML files and to MS-RDPECLIP 2.2.5.2. The docs of connect and read say that they block, and that the read timeout measures silence and not the total time. The fallback from one protocol to the other is logged at debug level. The compositor checks I had run by hand are now in ironrdp-testsuite-extra as ignored tests. They need an isolated compositor and IRONRDP_DATA_CONTROL_LIVE=1, and the docs of the live test module say how to run them. |
|
Update: no rebase needed anymore. picky-krb 0.12.5 was yanked from crates.io (re-released as 0.13.0), so the API check builds again without changes to this branch. PR automation has been re-run here and passes. |
There was a problem hiding this comment.
The new data_control module is well-built and its review-era correctness issues (echo guard, read race, charset lookup, poisoned locks, paste bounds) are fixed in the head with tests. I verified each specialist claim against the head. Published: the speculative Options/Preference/protocol/update_data public surface (no consumer per the author's own comment, merged from two findings); read() returning an empty success when the worker dies mid-transfer; the last-resort same-base charset fallback that can silently serve mismatched encodings; and three behavior-preserving compressions in state.rs. Rejected the in-crate-tests alternative: the workspace deliberately sets test=false ('keep tests in testsuite crates' FIXMEs across crates), so the testsuite-extra placement is conventional and the visibility dep is optional behind __test. Refined UpdateSourceData from a question to a conclusion: the author's comment lists #2016's API usage and update_data is absent, so the path is unconsumed.
Add the data_control module to ironrdp-cliprdr-native so a Linux CLIPRDR backend can read and set the clipboard without a window. It speaks ext-data-control-v1 and wlr-data-control-unstable-v1 and uses whichever the compositor offers. One thread owns the Wayland connection and DataControl is the handle to call from anywhere. A type advertised without data raises a TransferRequest when something pastes it, which maps onto the CLIPRDR Format Data Response. Dropping the request without answering it closes the paste with no data. A selection the client set itself isn't reported back as a local copy. It is told from another client's copy by a private MIME type that the client advertises next to the real ones. Reads are capped at 100 MiB and time out when the source stalls for 5 seconds. Pastes are bounded as well. At most 16 are served at once, a paste whose data isn't supplied within 5 seconds is closed with no data, and a reader that takes nothing for 5 seconds is dropped. The state tests live in ironrdp-testsuite-extra behind the __test feature, because inline tests aren't built for this crate. The checks that need a compositor are there too, as ignored tests.
85be787 to
37658f7
Compare
|
I pushed an update that answers the seven open review threads. Each has its own reply, and it's still one commit. The one behaviour change is in I kept I didn't rebase. Master has moved by three commits that touch none of these files. |
Benoît Cortier (CBenoit)
left a comment
There was a problem hiding this comment.
LGTM, thank you
This adds the data-control clipboard client I committed to on #2016. It lives in ironrdp-cliprdr-native as the data_control module, so a Linux CLIPRDR backend can be built on it.
The client speaks ext-data-control-v1 and wlr-data-control-unstable-v1 and uses whichever the compositor offers. One thread owns the Wayland connection and DataControl is the handle to call from anywhere. It has no async runtime.
It supports delayed rendering. A type advertised without data raises a TransferRequest when something pastes it, which maps onto the CLIPRDR Format Data Response. Dropping the request without answering it closes the paste with no data. A selection this client set itself isn't reported back as a local copy, so a backend doesn't echo its own clipboard to the server. The client tells its own selection from another client's copy by one private MIME type that it advertises next to the real ones, so other clients see that type in the list they are offered.
Reads are capped at 100 MiB and fail with a timeout if the source stalls for 5 seconds. Pastes are bounded too. At most 16 are served at once, a paste whose data isn't supplied within 5 seconds is closed with no data (an answer that comes later is kept for the next paste), and a reader that takes nothing for 5 seconds is dropped. MIME matching tolerates charset parameters. GNOME's Mutter offers no data-control protocol, so connecting returns an Unsupported error there.
This isn't wired into ironrdp-client. #2016 adds a Linux backend, and it can use this module instead of arboard.
Dependencies are wayland-client, wayland-protocols, wayland-protocols-wlr and nix, plus visibility behind the __test feature, all of which are already in the lockfile, so Cargo.lock only gains the new dependency edges. The state tests are in ironrdp-testsuite-extra behind the __test feature, because inline tests aren't built for this crate.
The client is a port of the standalone lamco-data-control crate. The checks that need a compositor are in ironrdp-testsuite-extra as ignored tests, because they change the clipboard of the compositor they run against. They do nothing unless IRONRDP_DATA_CONTROL_LIVE=1 is set, and the docs at the top of the live test module say how to run them against an isolated compositor. I ran them against a KWin instance, which offers wlr-data-control only, so the ext-data-control-v1 path has no live run.