diff --git a/common/rfb/SDesktop.h b/common/rfb/SDesktop.h index 5696cfd..7afc14c 100644 --- a/common/rfb/SDesktop.h +++ b/common/rfb/SDesktop.h @@ -86,6 +86,8 @@ namespace rfb { virtual void handleClipboardAnnounceBinary(const unsigned __unused_attr num, const char __unused_attr mimes[][32]) {} + virtual void clearLocalClipboards() {} + protected: virtual ~SDesktop() {} }; diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx index 9b4dc2b..7abd972 100644 --- a/common/rfb/VNCServerST.cxx +++ b/common/rfb/VNCServerST.cxx @@ -871,6 +871,8 @@ void VNCServerST::checkAPIMessages(network::GetAPIMessager *apimessager, desktop->handleClipboardAnnounceBinary(0, NULL); sendBinaryClipboardData("text/plain", NULL, 0); + + desktop->clearLocalClipboards(); break; } } diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc index a3aa73a..605e228 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.cc +++ b/unix/xserver/hw/vnc/XserverDesktop.cc @@ -182,6 +182,11 @@ XserverDesktop::queryConnection(network::Socket* sock, return rfb::VNCServerST::PENDING; } +void XserverDesktop::clearLocalClipboards() +{ + vncClearLocalClipboards(); +} + void XserverDesktop::announceClipboard(bool available) { try { diff --git a/unix/xserver/hw/vnc/XserverDesktop.h b/unix/xserver/hw/vnc/XserverDesktop.h index 32a204b..de9baa7 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.h +++ b/unix/xserver/hw/vnc/XserverDesktop.h @@ -61,6 +61,7 @@ public: void setFramebuffer(int w, int h, void* fbptr, int stride); void refreshScreenLayout(); void requestClipboard(); + void clearLocalClipboards(); void announceClipboard(bool available); void clearBinaryClipboardData(); void sendBinaryClipboardData(const char* mime, const unsigned char *data, diff --git a/unix/xserver/hw/vnc/vncSelection.c b/unix/xserver/hw/vnc/vncSelection.c index c4a90bf..103535f 100644 --- a/unix/xserver/hw/vnc/vncSelection.c +++ b/unix/xserver/hw/vnc/vncSelection.c @@ -763,3 +763,42 @@ static void vncClientStateCallback(CallbackListPtr * l, } } } + +static void vncClearLocalClipboard(Atom selection) +{ + SelectionInfoRec info; + Selection *pSel; + int rc; + + rc = dixLookupSelection(&pSel, selection, serverClient, DixSetAttrAccess); + if (rc != Success) + return; + + if (pSel->client && (pSel->client != serverClient)) { + xEvent event = { + .u.selectionClear.time = currentTime.milliseconds, + .u.selectionClear.window = pSel->window, + .u.selectionClear.atom = pSel->selection + }; + event.u.u.type = SelectionClear; + WriteEventsToClient(pSel->client, 1, &event); + } + + pSel->lastTimeChanged = currentTime; + pSel->window = None; + pSel->pWin = NULL; + pSel->client = NullClient; + + LOG_DEBUG("Cleared %s selection", NameForAtom(selection)); + + info.selection = pSel; + info.client = serverClient; + info.kind = SelectionSetOwner; + CallCallbacks(&SelectionCallback, &info); +} + +void vncClearLocalClipboards() +{ + vncClearLocalClipboard(xaPRIMARY); + vncClearLocalClipboard(xaCLIPBOARD); +} diff --git a/unix/xserver/hw/vnc/vncSelection.h b/unix/xserver/hw/vnc/vncSelection.h index 68266bf..f929c18 100644 --- a/unix/xserver/hw/vnc/vncSelection.h +++ b/unix/xserver/hw/vnc/vncSelection.h @@ -26,6 +26,7 @@ void vncSelectionInit(void); void vncHandleClipboardAnnounce(int available); void vncHandleClipboardAnnounceBinary(const unsigned num, const char mimes[][32]); +void vncClearLocalClipboards(); #ifdef __cplusplus }