Clipboard sync on new connection
Summary: Added a timestamp to track clipboard changes, so when a new device connects it will sync the most recently updated clipboard to both devices. Reviewers: #kde_connect, albertvaka Reviewed By: #kde_connect, albertvaka Subscribers: albertvaka, sredman, kdeconnect Tags: #kde_connect Differential Revision: https://phabricator.kde.org/D22584
This commit is contained in:
parent
88e0ffa01a
commit
7799973371
5 changed files with 82 additions and 14 deletions
|
@ -38,16 +38,28 @@ void ClipboardListener::updateClipboard(QClipboard::Mode mode)
|
|||
|
||||
QString content = clipboard->text();
|
||||
|
||||
if (content == currentContent) {
|
||||
if (content == m_currentContent) {
|
||||
return;
|
||||
}
|
||||
currentContent = content;
|
||||
m_updateTimestamp = QDateTime::currentDateTime().toMSecsSinceEpoch();
|
||||
m_currentContent = content;
|
||||
|
||||
Q_EMIT clipboardChanged(content);
|
||||
}
|
||||
|
||||
QString ClipboardListener::currentContent()
|
||||
{
|
||||
return m_currentContent;
|
||||
}
|
||||
|
||||
qint64 ClipboardListener::updateTimestamp(){
|
||||
|
||||
return m_updateTimestamp;
|
||||
}
|
||||
|
||||
void ClipboardListener::setText(const QString& content)
|
||||
{
|
||||
currentContent = content;
|
||||
m_updateTimestamp = QDateTime::currentDateTime().toMSecsSinceEpoch();
|
||||
m_currentContent = content;
|
||||
clipboard->setText(content);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#ifndef CLIPBOARDLISTENER_H
|
||||
#define CLIPBOARDLISTENER_H
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QTimer>
|
||||
#include <QObject>
|
||||
#include <QClipboard>
|
||||
|
@ -35,7 +36,8 @@ class ClipboardListener : public QObject
|
|||
|
||||
private:
|
||||
ClipboardListener();
|
||||
QString currentContent;
|
||||
QString m_currentContent;
|
||||
qint64 m_updateTimestamp = 0;
|
||||
QClipboard* clipboard;
|
||||
#ifdef Q_OS_MAC
|
||||
QTimer m_clipboardMonitorTimer;
|
||||
|
@ -56,6 +58,9 @@ public:
|
|||
|
||||
void setText(const QString& content);
|
||||
|
||||
QString currentContent();
|
||||
qint64 updateTimestamp();
|
||||
|
||||
Q_SIGNALS:
|
||||
void clipboardChanged(const QString& content);
|
||||
};
|
||||
|
|
|
@ -35,17 +35,44 @@ ClipboardPlugin::ClipboardPlugin(QObject* parent, const QVariantList& args)
|
|||
this, &ClipboardPlugin::propagateClipboard);
|
||||
}
|
||||
|
||||
void ClipboardPlugin::connected()
|
||||
{
|
||||
sendConnectPacket();
|
||||
}
|
||||
|
||||
void ClipboardPlugin::propagateClipboard(const QString& content)
|
||||
{
|
||||
NetworkPacket np(PACKET_TYPE_CLIPBOARD, {{QStringLiteral("content"), content}});
|
||||
sendPacket(np);
|
||||
}
|
||||
|
||||
void ClipboardPlugin::sendConnectPacket()
|
||||
{
|
||||
NetworkPacket np(PACKET_TYPE_CLIPBOARD_CONNECT, {
|
||||
{QStringLiteral("content"), ClipboardListener::instance()->currentContent()},
|
||||
{QStringLiteral("timestamp"), ClipboardListener::instance()->updateTimestamp()}
|
||||
});
|
||||
sendPacket(np);
|
||||
}
|
||||
|
||||
|
||||
bool ClipboardPlugin::receivePacket(const NetworkPacket& np)
|
||||
{
|
||||
QString content = np.get<QString>(QStringLiteral("content"));
|
||||
if (np.type() == PACKET_TYPE_CLIPBOARD) {
|
||||
ClipboardListener::instance()->setText(content);
|
||||
return true;
|
||||
} else if (np.type() == PACKET_TYPE_CLIPBOARD_CONNECT) {
|
||||
qint64 packetTime = np.get<qint64>(QStringLiteral("timestamp"));
|
||||
// If the packetTime is 0, it means the timestamp is unknown (so do nothing).
|
||||
if (packetTime == 0 || packetTime < ClipboardListener::instance()->updateTimestamp()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ClipboardListener::instance()->setText(content);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#include "clipboardplugin.moc"
|
||||
|
|
|
@ -27,8 +27,32 @@
|
|||
#include <core/kdeconnectplugin.h>
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(KDECONNECT_PLUGIN_CLIPBOARD)
|
||||
|
||||
/**
|
||||
* Packet containing just clipboard contents, sent when a device updates its clipboard.
|
||||
* <p>
|
||||
* The body should look like so:
|
||||
* {
|
||||
* "content": "password"
|
||||
* }
|
||||
*/
|
||||
#define PACKET_TYPE_CLIPBOARD QStringLiteral("kdeconnect.clipboard")
|
||||
|
||||
/**
|
||||
* Packet containing clipboard contents and a timestamp that the contents were last updated, sent
|
||||
* on first connection
|
||||
* <p>
|
||||
* The timestamp is milliseconds since epoch. It can be 0, which indicates that the clipboard
|
||||
* update time is currently unknown.
|
||||
* <p>
|
||||
* The body should look like so:
|
||||
* {
|
||||
* "timestamp": 542904563213,
|
||||
* "content": "password"
|
||||
* }
|
||||
*/
|
||||
#define PACKET_TYPE_CLIPBOARD_CONNECT QStringLiteral("kdeconnect.clipboard.connect")
|
||||
|
||||
class ClipboardPlugin
|
||||
: public KdeConnectPlugin
|
||||
{
|
||||
|
@ -38,10 +62,10 @@ public:
|
|||
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 sendConnectPacket();
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -129,9 +129,9 @@
|
|||
"Website": "https://albertvaka.wordpress.com"
|
||||
},
|
||||
"X-KdeConnect-OutgoingPacketType": [
|
||||
"kdeconnect.clipboard"
|
||||
"kdeconnect.clipboard", "kdeconnect.clipboard.connect"
|
||||
],
|
||||
"X-KdeConnect-SupportedPacketType": [
|
||||
"kdeconnect.clipboard"
|
||||
"kdeconnect.clipboard", "kdeconnect.clipboard.connect"
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue