Skip to content

fix(web): dispatch the ready event after clipboard initialization - #2018

Merged
Benoît Cortier (CBenoit) merged 1 commit into
Devolutions:masterfrom
meanaverage:fix/web-ready-after-clipboard-init
Oct 1, 2026
Merged

Benoît Cortier (CBenoit) merged 1 commit into
Devolutions:masterfrom
meanaverage:fix/web-ready-after-clipboard-init

Conversation

@meanaverage

Copy link
Copy Markdown
Contributor

Problem

<iron-remote-desktop> dispatches ready at the end of initcanvas(), but onMount only then runs await clipboardService.initClipboard(). That awaits navigator.permissions.query({ name: 'clipboard-read' }) before installing the clipboard callbacks, and RemoteDesktopService.connect() only registers remoteClipboardChangedCallback / forceClipboardUpdateCallback on the session builder when those callbacks are installed.

So a host that connects as soon as ready fires gets a session with no CLIPRDR channel, and the clipboard silently doesn't work. iron-svelte-client connects after the user clicks, which hides the race.

Change

  • ready is dispatched from onMount after initClipboard() settles. If clipboard initialization throws, the error is logged and ready still fires.
  • Test setup: mounting a Svelte component under vitest needs Svelte's browser build, so vite.config.ts sets resolve.conditions: ['browser'] when VITEST is set. It also skips vite-plugin-svelte's style preprocessing in that case: the plugin (5.x, for Vite 6) crashes in preprocessCSS under vitest 2's bundled Vite 5. The component's styles are plain CSS. Builds are unchanged.
  • No public API change.

Testing

  • New src/readyEvent.test.ts (2 tests):
    • ready isn't dispatched while the permission query is pending, fires once it resolves, and connecting from it registers remoteClipboardChangedCallback. This one fails without the fix.
    • ready still fires when the clipboard is unavailable (not a secure context).
  • npm test (20 passing, 3 files), npm run check (0 errors), npm run lint, npm run build.
  • In use: an Electron app that connects on ready had no clipboard at all. With this change, text copies both ways against GNOME Remote Desktop 46 and Windows 11.

Prepared with AI assistance; I reviewed the change and ran the tests above.

`ready` was dispatched at the end of canvas initialization, before
`ClipboardService.initClipboard()` had run: that awaits a permissions
query, and only then installs the clipboard callbacks. `connect()`
registers those callbacks on the session builder only if they are
installed, so a host that connects as soon as `ready` fires got a
session without a clipboard channel. Connecting after a user action
(as iron-svelte-client does) hides the race.

Dispatch `ready` once the clipboard is initialized (or its
initialization failed), so connecting on it always sets up the
clipboard.

Adds a component test for it. Mounting the component under vitest needs
Svelte's browser build (`resolve.conditions`) and skipping
vite-plugin-svelte's style preprocessing, which fails under vitest 2's
bundled Vite 5; the component's styles are plain CSS.
@github-actions github-actions Bot added kind/protocol Affects RDP or related protocol behavior risk/medium Behavioral change that does not substantially alter a core public API scope/web Affects the web/WASM ecosystem size/S Size: up to 199 counted lines and 5 files; exceeds XS in either measure needs-review A human reviewer is the current next actor labels Sep 26, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Automated review will not run because this contributor is not yet eligible under the automation policy.

Contributors become eligible after one qualifying IronRDP pull request is merged into master. Maintainer review is required.

@CBenoit Benoît Cortier (CBenoit) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Clean fix, LGTM, thank you!

@CBenoit
Benoît Cortier (CBenoit) enabled auto-merge (squash) October 1, 2026 08:11
@CBenoit
Benoît Cortier (CBenoit) merged commit e258f6a into Devolutions:master Oct 1, 2026
41 checks passed

This branch was successfully deployed

1 active deployment
llm-providers — 1c010cd3 Deployed Sep 26, 2026 by meanaverage via Classify pull request #716
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/protocol Affects RDP or related protocol behavior needs-review A human reviewer is the current next actor risk/medium Behavioral change that does not substantially alter a core public API scope/web Affects the web/WASM ecosystem size/S Size: up to 199 counted lines and 5 files; exceeds XS in either measure

Development

Successfully merging this pull request may close these issues.

2 participants