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,17 +295,20 @@ 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.
LOG_WARN("clipboard not enabled on session, discarding restore token to force a fresh session");
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());
Settings::setValue(Settings::Server::XdpRestoreToken, QString());
#endif
g_object_unref(m_session);
m_session = nullptr;
g_idle_add([](gpointer data) { return static_cast<PortalInputCapture *>(data)->initSession(); }, this);
return;
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

View file

@ -100,28 +100,35 @@ void PortalRemoteDesktop::handleSessionStarted(GObject *object, GAsyncResult *re
#ifdef HAVE_LIBPORTAL_CLIPBOARD
if (!xdp_session_is_clipboard_enabled(session)) {
LOG_WARN("clipboard not enabled on remote desktop session, discarding restore token to force a fresh session");
Settings::setValue(Settings::Client::XdpRestoreToken, QString());
free(m_sessionRestoreToken);
m_sessionRestoreToken = nullptr;
if (m_selectionTransferSignalId) {
g_signal_handler_disconnect(session, m_selectionTransferSignalId);
m_selectionTransferSignalId = 0;
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) {
g_signal_handler_disconnect(session, m_selectionTransferSignalId);
m_selectionTransferSignalId = 0;
}
if (m_selectionOwnerChangedSignalId) {
g_signal_handler_disconnect(session, m_selectionOwnerChangedSignalId);
m_selectionOwnerChangedSignalId = 0;
}
if (m_sessionSignalId) {
g_signal_handler_disconnect(session, m_sessionSignalId);
m_sessionSignalId = 0;
}
g_clear_object(&m_session);
reconnect(0);
return;
}
if (m_selectionOwnerChangedSignalId) {
g_signal_handler_disconnect(session, m_selectionOwnerChangedSignalId);
m_selectionOwnerChangedSignalId = 0;
}
if (m_sessionSignalId) {
g_signal_handler_disconnect(session, m_sessionSignalId);
m_sessionSignalId = 0;
}
g_clear_object(&m_session);
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);