Internal
Public Access
RDP session fixes: correct keyboard scancodes, clipboard sync, cursor shapes
Fix RDP keyboard input using FreeRDP's authoritative X11-keycode-to-scancode table instead of ad hoc bit math, which misread punctuation keys as unrelated letter keys (e.g. apostrophe as B) because X11 keycode numbering only coincidentally overlaps PC/AT scancodes. Add bidirectional clipboard sync (CF_UNICODETEXT) over the cliprdr channel, and RDP pointer/cursor shape sync so the local cursor reflects what the remote OS wants displayed (resize handles, text I-beam, etc.) instead of staying a static arrow. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
#include <QPlainTextEdit>
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QMimeData>
|
||||
#include <QComboBox>
|
||||
#include <QProcessEnvironment>
|
||||
#include <QPushButton>
|
||||
@@ -74,6 +75,8 @@ SessionTab::SessionTab(const Profile& profile,
|
||||
m_terminalFontPointSize(preferences.terminalFontPointSize > 0
|
||||
? preferences.terminalFontPointSize
|
||||
: 0),
|
||||
m_clipboardSyncSupported(profile.protocol.compare(QStringLiteral("RDP"), Qt::CaseInsensitive)
|
||||
== 0),
|
||||
m_sshTerminal(nullptr),
|
||||
m_rdpDisplay(nullptr),
|
||||
m_terminalOutput(nullptr),
|
||||
@@ -193,6 +196,11 @@ SessionTab::SessionTab(const Profile& profile,
|
||||
m_backend,
|
||||
&SessionBackend::sendMouseWheelEvent,
|
||||
Qt::QueuedConnection);
|
||||
connect(this,
|
||||
&SessionTab::requestSetClipboardText,
|
||||
m_backend,
|
||||
&SessionBackend::setClipboardText,
|
||||
Qt::QueuedConnection);
|
||||
|
||||
connect(m_backend,
|
||||
&SessionBackend::stateChanged,
|
||||
@@ -237,10 +245,49 @@ SessionTab::SessionTab(const Profile& profile,
|
||||
}
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
connect(m_backend,
|
||||
&SessionBackend::remoteClipboardTextChanged,
|
||||
this,
|
||||
&SessionTab::onBackendRemoteClipboardTextChanged,
|
||||
Qt::QueuedConnection);
|
||||
connect(m_backend,
|
||||
&SessionBackend::cursorImageChanged,
|
||||
this,
|
||||
[this](const QImage& image, const QPoint& hotspot) {
|
||||
if (m_rdpDisplay != nullptr) {
|
||||
m_rdpDisplay->setCursorImage(image, hotspot);
|
||||
}
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
connect(m_backend,
|
||||
&SessionBackend::cursorHidden,
|
||||
this,
|
||||
[this]() {
|
||||
if (m_rdpDisplay != nullptr) {
|
||||
m_rdpDisplay->setCursorHidden();
|
||||
}
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
connect(m_backend,
|
||||
&SessionBackend::cursorReset,
|
||||
this,
|
||||
[this]() {
|
||||
if (m_rdpDisplay != nullptr) {
|
||||
m_rdpDisplay->setCursorDefault();
|
||||
}
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
|
||||
m_backendThread->start();
|
||||
}
|
||||
|
||||
if (m_clipboardSyncSupported) {
|
||||
connect(QApplication::clipboard(),
|
||||
&QClipboard::dataChanged,
|
||||
this,
|
||||
&SessionTab::onSystemClipboardChanged);
|
||||
}
|
||||
|
||||
setState(SessionState::Disconnected, QStringLiteral("Ready to connect."));
|
||||
QTimer::singleShot(0, this, &SessionTab::connectSession);
|
||||
}
|
||||
@@ -615,6 +662,36 @@ void SessionTab::onBackendHostKeyConfirmationRequested(const QString& prompt)
|
||||
emit requestHostKeyConfirmation(reply == QMessageBox::Yes);
|
||||
}
|
||||
|
||||
void SessionTab::onBackendRemoteClipboardTextChanged(const QString& text)
|
||||
{
|
||||
if (text == m_lastSyncedClipboardText) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_lastSyncedClipboardText = text;
|
||||
QApplication::clipboard()->setText(text);
|
||||
}
|
||||
|
||||
void SessionTab::onSystemClipboardChanged()
|
||||
{
|
||||
if (!m_clipboardSyncSupported || m_state != SessionState::Connected) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QClipboard* clipboard = QApplication::clipboard();
|
||||
if (!clipboard->mimeData()->hasText()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QString text = clipboard->text();
|
||||
if (text == m_lastSyncedClipboardText) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_lastSyncedClipboardText = text;
|
||||
emit requestSetClipboardText(text);
|
||||
}
|
||||
|
||||
void SessionTab::setupUi()
|
||||
{
|
||||
auto* rootLayout = new QVBoxLayout(this);
|
||||
|
||||
Reference in New Issue
Block a user