Skip to content

This fixes the Wayland background clipboard restriction by using St.Clipboard instead of Meta.Selection. Fixes #2153#2154

Closed
D3-crypto wants to merge 3 commits into
GSConnect:mainfrom
D3-crypto:main
Closed

This fixes the Wayland background clipboard restriction by using St.Clipboard instead of Meta.Selection. Fixes #2153#2154
D3-crypto wants to merge 3 commits into
GSConnect:mainfrom
D3-crypto:main

Conversation

@D3-crypto

Copy link
Copy Markdown

This PR fixes the silent failure of Android-to-PC clipboard syncing on strict Wayland sessions (GNOME 45+).

Fixes #2153

The Bug
On modern GNOME Wayland sessions, Meta.SelectionSourceMemory.new is denied permission to set the clipboard when called from a background context without explicit window focus. This results in a silent failure/crash in clipboard.js when the Android app pushes a clipboard payload.

The Solution
Native UI API: Implemented St.Clipboard as the primary method to set clipboard text, which natively bypasses the Wayland background window restriction.
Graceful Fallback: Wrapped it in a try/catch block to gracefully fall back to the original Meta.SelectionSourceMemory implementation if St.Clipboard fails (ensuring backwards compatibility for X11 or older GNOME releases).
Added a detailed technical explanation in docs/wayland-clipboard-fix.md.
Testing
Locally patched and verified working seamlessly on GNOME 49.4 (Wayland).
Both PC-to-Android and Android-to-PC sync operate correctly without needing global shortcuts.

Copilot AI review requested due to automatic review settings March 30, 2026 10:07

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses Wayland clipboard write restrictions in GNOME Shell by switching Android→PC clipboard updates to use the Shell’s St.Clipboard API instead of Meta.SelectionSourceMemory, and documents the rationale and testing notes.

Changes:

  • Use St.Clipboard to set clipboard text in src/shell/clipboard.js, with a fallback to the prior Meta.SelectionSourceMemory approach.
  • Add documentation describing the Wayland failure mode and the adopted fix (docs/wayland-clipboard-fix.md).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/shell/clipboard.js Changes clipboard write path to prefer St.Clipboard to avoid Wayland background restrictions.
docs/wayland-clipboard-fix.md Adds a technical write-up of the issue, solution, and testing notes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/shell/clipboard.js Outdated
Comment on lines 272 to 282
try {
const clipboard = St.Clipboard.get_default();
clipboard.set_text(St.ClipboardType.CLIPBOARD, text);
} catch (e) {
// Fallback to older Meta.Selection if St fails
const source = Meta.SelectionSourceMemory.new(
'text/plain;charset=utf-8', GLib.Bytes.new(text));
this._selection.set_owner(
Meta.SelectionType.SELECTION_CLIPBOARD, source);
}

Copilot AI Mar 30, 2026

Copy link

Choose a reason for hiding this comment

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

St.Clipboard.set_text() doesn't report failures via exceptions (it returns void and has no GError), so this try/catch only catches argument/import/runtime JS errors and won't trigger the Meta.Selection fallback if the clipboard write is silently denied. Consider either (a) removing the nested try/catch and always using St here, or (b) verifying the write (eg read back via St.Clipboard.get_text callback / selection mimetypes) and only then falling back if the clipboard didn't update. Also adjust the inline comment to reflect what failures are actually caught.

Suggested change
try {
const clipboard = St.Clipboard.get_default();
clipboard.set_text(St.ClipboardType.CLIPBOARD, text);
} catch (e) {
// Fallback to older Meta.Selection if St fails
const source = Meta.SelectionSourceMemory.new(
'text/plain;charset=utf-8', GLib.Bytes.new(text));
this._selection.set_owner(
Meta.SelectionType.SELECTION_CLIPBOARD, source);
}
const clipboard = St.Clipboard.get_default();
clipboard.set_text(St.ClipboardType.CLIPBOARD, text);
// Verify clipboard content and fall back to older Meta.Selection if needed
clipboard.get_text(St.ClipboardType.CLIPBOARD,
(clip, currentText) => {
if (currentText !== text) {
const source = Meta.SelectionSourceMemory.new(
'text/plain;charset=utf-8', GLib.Bytes.new(text));
this._selection.set_owner(
Meta.SelectionType.SELECTION_CLIPBOARD, source);
}
});

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

"Great catch! I've removed the try/catch and implemented the read-back verification fallback in the latest commit."

Comment thread docs/wayland-clipboard-fix.md Outdated
Comment on lines +1 to +26
# Wayland Clipboard Sync Fix (GNOME 45+)

## Issue Description
On modern Wayland sessions (specifically tested on GNOME 49), pushing clipboard data from an Android device to the desktop via GSConnect fails silently.

When the Android device pushes the clipboard payload, `journalctl` logs the following crash in the background daemon:
`_onHandleMethodCall@file:///[...]/shell/clipboard.js:140:30`

### Root Cause
The `SetText(text)` function originally relied exclusively on `Meta.SelectionSourceMemory.new`. In modern Wayland security models, background processes lacking explicit window focus are denied permission to set the clipboard via the `Meta.Selection` API, causing a silent rejection and failure to sync.

## The Solution
To bypass the strict Wayland background window restriction while remaining native to the GNOME environment, the logic was refactored to utilize the Shell's UI toolkit clipboard API (`St.Clipboard`).

### Code Changes
1. **Imported the St library:**
`import St from 'gi://St';`
2. **Refactored `SetText(text)` logic:**
The function now attempts to grab the default `St.Clipboard` and set the text natively:
```javascript
const clipboard = St.Clipboard.get_default();
clipboard.set_text(St.ClipboardType.CLIPBOARD, text);
```
3. **Graceful Fallback:**
If the `St` method fails (ensuring backward compatibility with older GNOME releases or X11 sessions where `St` might behave differently), it catches the exception and falls back to the original `Meta.SelectionSourceMemory` implementation.

Copilot AI Mar 30, 2026

Copy link

Choose a reason for hiding this comment

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

This doc implies the try/catch fallback will handle St failing to set the clipboard. In practice St.Clipboard.set_text() doesn't expose permission/denial failures via exceptions, so the fallback only applies to exceptions (eg API/arg issues) and not silent rejections. Reword this section to describe the actual fallback behavior (and/or note that St is expected to work on supported GNOME Shell versions). Also, the heading says “GNOME 45+” but the extension metadata targets GNOME 46–50; consider aligning the stated version range.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

"Updated the markdown file to correctly explain the silent failure and adjusted the header to GNOME 46-50."

@daniellandau

Copy link
Copy Markdown
Member

These don't seem relevant at all https://github.com/GSConnect/gnome-shell-extension-gsconnect/pull/2154/changes#diff-6b47a1ca15b440d8c917a76a480c8782b223599d8a64c6cffba155b331afa830R98-R99 and the added docs folder with a markdown file + the very large amount of spurious changes give the impression of an LLM generated pull request.

Also the problem in the linked issue was already fixed in main by #2150 which will be in the next release imminently when I have the time to make the release, so I'm going to close this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Clipboard sync from Android to PC fails silently on GNOME 49 (Wayland)

3 participants