fix(wayland): stop reprompting for portal permission on every restore

some backends never report clipboard as enabled even when granted, so the retry looped forever; now it only retries once per role, then keeps the session.
This commit is contained in:
ElCruncharino 2026-07-25 10:57:36 -04:00 committed by Nick Bolton
parent 0baecf3fa7
commit 0ab18b86b3
3 changed files with 45 additions and 32 deletions

View file

@ -43,6 +43,7 @@ public:
inline static const auto XScrollScale = QStringLiteral("client/xScrollScale");
inline static const auto LanguageSync = QStringLiteral("client/languageSync");
inline static const auto RemoteHost = QStringLiteral("client/remoteHost");
inline static const auto XdpClipboardRetried = QStringLiteral("client/xdpClipboardRetried");
inline static const auto XdpRestoreToken = QStringLiteral("client/xdpRestoreToken");
};
struct Core
@ -121,6 +122,7 @@ public:
inline static const auto SwitchDelay = QStringLiteral("server/switchDelay");
inline static const auto SwitchDoubleTap = QStringLiteral("server/switchDoubleTap");
inline static const auto Win32KeepForeground = QStringLiteral("server/win32KeepForeground");
inline static const auto XdpClipboardRetried = QStringLiteral("server/xdpClipboardRetried");
inline static const auto XdpRestoreToken = QStringLiteral("server/xdpRestoreToken");
};
@ -334,6 +336,7 @@ private:
, Client::DynamicConnectionRetry
, Client::InvertYScroll
, Client::InvertXScroll
, Client::XdpClipboardRetried
, Log::ToFile
, Log::GuiDebug
, Server::DefaultLockToComputerState
@ -343,6 +346,7 @@ private:
, Server::EnableSwitchDoubleTap
, Server::ExternalConfig
, Server::RelativeMouseMoves
, Server::XdpClipboardRetried
};
// When checking the default values this list contains the ones that default to true.
@ -362,7 +366,9 @@ private:
// Settings saved in our State file
inline static const QStringList m_stateKeys = {
Gui::WindowGeometry
, Client::XdpClipboardRetried
, Client::XdpRestoreToken
, Server::XdpClipboardRetried
, Server::XdpRestoreToken
};

View file

@ -11,6 +11,7 @@
#include "base/Event.h"
#include "base/Log.h"
#include "base/TMethodJob.h"
#include "common/Settings.h"
#include "deskflow/ClipboardTypes.h"
#include "platform/EiClipboard.h"
@ -18,10 +19,6 @@
#include "platform/PortalClipboard.h"
#endif
#ifdef HAVE_LIBPORTAL_INPUTCAPTURE_RESTORE
#include "common/Settings.h"
#endif
#include <algorithm>
#include <cmath>
#include <limits>
@ -298,18 +295,21 @@ void PortalInputCapture::setupSession(XdpInputCaptureSession *session)
#ifdef HAVE_LIBPORTAL_CLIPBOARD
if (!xdp_session_is_clipboard_enabled(parentSession) && m_portalVersion > 1) {
// Restored sessions can pre-date clipboard support, leaving the channel
// disabled even though we requested it. Drop the saved token and recreate
// the session from scratch so the user gets a fresh permission dialog.
if (Settings::value(Settings::Server::XdpClipboardRetried).toBool()) {
// some backends never report clipboard enabled even when granted; don't loop forever
LOG_DEBUG("clipboard still not enabled on session after one retry, continuing without it");
} else {
LOG_WARN("clipboard not enabled on session, discarding restore token to force a fresh session");
#ifdef HAVE_LIBPORTAL_INPUTCAPTURE_RESTORE
Settings::setValue(Settings::Server::XdpRestoreToken, QString());
#endif
Settings::setValue(Settings::Server::XdpClipboardRetried, true);
g_object_unref(m_session);
m_session = nullptr;
g_idle_add([](gpointer data) { return static_cast<PortalInputCapture *>(data)->initSession(); }, this);
return;
}
}
#endif
auto fd = xdp_input_capture_session_connect_to_eis(session, &error);

View file

@ -100,8 +100,13 @@ void PortalRemoteDesktop::handleSessionStarted(GObject *object, GAsyncResult *re
#ifdef HAVE_LIBPORTAL_CLIPBOARD
if (!xdp_session_is_clipboard_enabled(session)) {
if (Settings::value(Settings::Client::XdpClipboardRetried).toBool()) {
// some backends never report clipboard enabled even when granted; don't loop forever
LOG_DEBUG("clipboard still not enabled on remote desktop session after one retry, continuing without it");
} else {
LOG_WARN("clipboard not enabled on remote desktop session, discarding restore token to force a fresh session");
Settings::setValue(Settings::Client::XdpRestoreToken, QString());
Settings::setValue(Settings::Client::XdpClipboardRetried, true);
free(m_sessionRestoreToken);
m_sessionRestoreToken = nullptr;
if (m_selectionTransferSignalId) {
@ -120,8 +125,10 @@ void PortalRemoteDesktop::handleSessionStarted(GObject *object, GAsyncResult *re
reconnect(0);
return;
}
}
#endif
free(m_sessionRestoreToken);
m_sessionRestoreToken = xdp_session_get_restore_token(session);
if (m_sessionRestoreToken) {
Settings::setValue(Settings::Client::XdpRestoreToken, QString(m_sessionRestoreToken));
@ -227,7 +234,7 @@ void PortalRemoteDesktop::claimClipboard() const
return;
}
if (!xdp_session_is_clipboard_enabled(m_session)) {
LOG_WARN("portal remote desktop clipboard not enabled on session, cannot claim");
LOG_DEBUG("portal remote desktop clipboard not enabled on session, cannot claim");
return;
}
PortalClipboard::claimOwnership(m_screen->getClipboardCache(), m_session);