Internal
Public Access
Add VNC clipboard sync
RFB's ServerCutText/ClientCutText messages are much simpler than RDP's CLIPRDR channel (no format-list/format-request negotiation -- text is just sent directly in both directions), so ServerCutText now emits remoteClipboardTextChanged instead of being discarded, and VncSessionBackend overrides setClipboardText to send ClientCutText immediately. Extends session_tab.cpp's clipboard-sync gate to cover VNC alongside RDP; the QClipboard wiring itself was already protocol-agnostic. Latin-1 only, per RFB's wire format -- no Unicode clipboard extension is in scope. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+3
-2
@@ -77,8 +77,9 @@ SessionTab::SessionTab(const Profile& profile,
|
||||
m_terminalFontPointSize(preferences.terminalFontPointSize > 0
|
||||
? preferences.terminalFontPointSize
|
||||
: 0),
|
||||
m_clipboardSyncSupported(profile.protocol.compare(QStringLiteral("RDP"), Qt::CaseInsensitive)
|
||||
== 0),
|
||||
m_clipboardSyncSupported(
|
||||
profile.protocol.compare(QStringLiteral("RDP"), Qt::CaseInsensitive) == 0
|
||||
|| profile.protocol.compare(QStringLiteral("VNC"), Qt::CaseInsensitive) == 0),
|
||||
m_sshTerminal(nullptr),
|
||||
m_rdpDisplay(nullptr),
|
||||
m_vncDisplay(nullptr),
|
||||
|
||||
@@ -263,6 +263,16 @@ void VncSessionBackend::sendMouseWheelEvent(int x, int y, int deltaX, int deltaY
|
||||
}
|
||||
}
|
||||
|
||||
void VncSessionBackend::setClipboardText(const QString& text)
|
||||
{
|
||||
if (m_socket->state() != QAbstractSocket::ConnectedState) {
|
||||
return;
|
||||
}
|
||||
// Unlike RDP's CLIPRDR (list -> server request -> response), RFB's
|
||||
// ClientCutText has no negotiation: send it immediately.
|
||||
sendClientCutText(text);
|
||||
}
|
||||
|
||||
void VncSessionBackend::onSocketConnected()
|
||||
{
|
||||
emit eventLogged(QStringLiteral("TCP connection established; waiting for VNC handshake."));
|
||||
@@ -465,6 +475,19 @@ void VncSessionBackend::sendWheelClick(quint8 wheelBit)
|
||||
m_socket->write(release);
|
||||
}
|
||||
|
||||
void VncSessionBackend::sendClientCutText(const QString& text)
|
||||
{
|
||||
// Latin-1 only, matching ServerCutText's decode above -- RFB has no
|
||||
// Unicode clipboard extension in scope here.
|
||||
const QByteArray latin1 = text.toLatin1();
|
||||
QByteArray msg;
|
||||
msg.append(kMsgClientCutText);
|
||||
msg.append(3, char(0)); // padding
|
||||
appendU32BE(msg, static_cast<quint32>(latin1.size()));
|
||||
msg.append(latin1);
|
||||
m_socket->write(msg);
|
||||
}
|
||||
|
||||
void VncSessionBackend::finishHandshakeIntoRunningState()
|
||||
{
|
||||
emit remoteDesktopSizeChanged(m_framebuffer.width(), m_framebuffer.height());
|
||||
@@ -895,10 +918,13 @@ void VncSessionBackend::processReceiveBuffer()
|
||||
if (!haveBytes(static_cast<int>(m_pendingLength))) {
|
||||
return;
|
||||
}
|
||||
// Clipboard sync is out of scope for this pass; consume and
|
||||
// discard so the byte stream stays in sync.
|
||||
// RFB's ServerCutText is Latin-1 only (RFC 6143 SS7.5.4) -- no
|
||||
// Unicode extension is implemented, unlike RDP's CLIPRDR.
|
||||
const QString text =
|
||||
QString::fromLatin1(m_recvBuffer.left(static_cast<int>(m_pendingLength)));
|
||||
m_recvBuffer.remove(0, static_cast<int>(m_pendingLength));
|
||||
m_rfbState = RfbState::WaitingServerMessageType;
|
||||
emit remoteClipboardTextChanged(text);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,8 @@ class QTcpSocket;
|
||||
// Scope (see plan / issue #3 for the full rationale): standard VNC
|
||||
// Authentication (security type 2) and no-auth (type 1) only -- not
|
||||
// Apple's Screen Sharing scheme (type 30). Raw + CopyRect encodings only.
|
||||
// No dynamic resize, no remote cursor shape sync, no clipboard sync.
|
||||
// No dynamic resize, no remote cursor shape sync. Clipboard sync (Latin-1
|
||||
// only, per RFB's ServerCutText/ClientCutText) is supported.
|
||||
class VncSessionBackend : public SessionBackend
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -52,6 +53,7 @@ public slots:
|
||||
void sendMouseMoveEvent(int x, int y) override;
|
||||
void sendMouseButtonEvent(int x, int y, int button, bool pressed) override;
|
||||
void sendMouseWheelEvent(int x, int y, int deltaX, int deltaY) override;
|
||||
void setClipboardText(const QString& text) override;
|
||||
|
||||
private slots:
|
||||
void onSocketConnected();
|
||||
@@ -129,6 +131,7 @@ private:
|
||||
void onRectangleFinished();
|
||||
void sendPointerEvent();
|
||||
void sendWheelClick(quint8 wheelBit);
|
||||
void sendClientCutText(const QString& text);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user