diff --git a/plugins/clipboard/clipboardlistener.h b/plugins/clipboard/clipboardlistener.h --- a/plugins/clipboard/clipboardlistener.h +++ b/plugins/clipboard/clipboardlistener.h @@ -21,29 +21,31 @@ #ifndef CLIPBOARDLISTENER_H #define CLIPBOARDLISTENER_H +#include #include #include #include #include /** * Wrapper around QClipboard, which emits clipboardChanged only when it really changed */ -class ClipboardListener : public QObject +class ClipboardListener : public QObject { Q_OBJECT private: ClipboardListener(); QString currentContent; + qint64 updateTimestamp = 0; QClipboard* clipboard; #ifdef Q_OS_MAC QTimer m_clipboardMonitorTimer; #endif public: - static ClipboardListener* instance() + static ClipboardListener* instance() { static ClipboardListener* me = nullptr; if (!me) { @@ -56,6 +58,9 @@ void setText(const QString& content); + QString getCurrentContent(); + qint64 getUpdateTimestamp(); + Q_SIGNALS: void clipboardChanged(const QString& content); }; diff --git a/plugins/clipboard/clipboardlistener.cpp b/plugins/clipboard/clipboardlistener.cpp --- a/plugins/clipboard/clipboardlistener.cpp +++ b/plugins/clipboard/clipboardlistener.cpp @@ -20,7 +20,7 @@ #include "clipboardlistener.h" -ClipboardListener::ClipboardListener() +ClipboardListener::ClipboardListener() : clipboard(QGuiApplication::clipboard()) { #ifdef Q_OS_MAC @@ -30,7 +30,7 @@ connect(clipboard, &QClipboard::changed, this, &ClipboardListener::updateClipboard); } -void ClipboardListener::updateClipboard(QClipboard::Mode mode) +void ClipboardListener::updateClipboard(QClipboard::Mode mode) { if (mode != QClipboard::Clipboard) { return; @@ -41,13 +41,25 @@ if (content == currentContent) { return; } + updateTimestamp = QDateTime::currentDateTime().toMSecsSinceEpoch(); currentContent = content; Q_EMIT clipboardChanged(content); } +QString ClipboardListener::getCurrentContent() +{ + return currentContent; +} + +qint64 ClipboardListener::getUpdateTimestamp() +{ + return updateTimestamp; +} + void ClipboardListener::setText(const QString& content) { + updateTimestamp = QDateTime::currentDateTime().toMSecsSinceEpoch(); currentContent = content; clipboard->setText(content); } diff --git a/plugins/clipboard/clipboardplugin.h b/plugins/clipboard/clipboardplugin.h --- a/plugins/clipboard/clipboardplugin.h +++ b/plugins/clipboard/clipboardplugin.h @@ -38,10 +38,10 @@ explicit ClipboardPlugin(QObject* parent, const QVariantList& args); bool receivePacket(const NetworkPacket& np) override; - void connected() override { } - + void connected() override; private Q_SLOTS: void propagateClipboard(const QString& content); + void updateClipboard(const QString& content); }; diff --git a/plugins/clipboard/clipboardplugin.cpp b/plugins/clipboard/clipboardplugin.cpp --- a/plugins/clipboard/clipboardplugin.cpp +++ b/plugins/clipboard/clipboardplugin.cpp @@ -32,19 +32,47 @@ : KdeConnectPlugin(parent, args) { connect(ClipboardListener::instance(), &ClipboardListener::clipboardChanged, - this, &ClipboardPlugin::propagateClipboard); + this, &ClipboardPlugin::updateClipboard); +} + +void ClipboardPlugin::connected() +{ + propagateClipboard(ClipboardListener::instance()->getCurrentContent()); +} + +void ClipboardPlugin::updateClipboard(const QString& content) +{ + propagateClipboard(content); } void ClipboardPlugin::propagateClipboard(const QString& content) { NetworkPacket np(PACKET_TYPE_CLIPBOARD, {{QStringLiteral("content"), content}}); + np.set(QStringLiteral("timestamp"), ClipboardListener::instance()->getUpdateTimestamp()); sendPacket(np); } bool ClipboardPlugin::receivePacket(const NetworkPacket& np) { + if (np.has(QStringLiteral("timestamp"))){ + qint64 packetTime = np.get(QStringLiteral("timestamp")); + + // If the packetTime is 0, it means the timestamp is unknown (so do nothing). + if (packetTime == 0) { + return false; + } else if (packetTime < ClipboardListener::instance()->getUpdateTimestamp()) { + return false; + } + } + QString content = np.get(QStringLiteral("content")); - ClipboardListener::instance()->setText(content); + if (content != ClipboardListener::instance()->getCurrentContent()) { + ClipboardListener::instance()->setText(content); + return true; + }else{ + return false; + } + return true; }