dot/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/plugins/clipboard.js

179 lines
4.9 KiB
JavaScript
Raw Normal View History

2020-05-11 09:16:27 +00:00
'use strict';
const Gdk = imports.gi.Gdk;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const PluginsBase = imports.service.plugins.base;
var Metadata = {
label: _('Clipboard'),
id: 'org.gnome.Shell.Extensions.GSConnect.Plugin.Clipboard',
incomingCapabilities: [
'kdeconnect.clipboard',
'kdeconnect.clipboard.connect'
],
outgoingCapabilities: [
'kdeconnect.clipboard',
'kdeconnect.clipboard.connect'
],
actions: {
clipboardPush: {
label: _('Clipboard Push'),
icon_name: 'edit-paste-symbolic',
parameter_type: null,
incoming: [],
outgoing: ['kdeconnect.clipboard']
},
clipboardPull: {
label: _('Clipboard Pull'),
icon_name: 'edit-copy-symbolic',
parameter_type: null,
incoming: ['kdeconnect.clipboard'],
outgoing: []
}
}
};
/**
* Clipboard Plugin
* https://github.com/KDE/kdeconnect-kde/tree/master/plugins/clipboard
*/
var Plugin = GObject.registerClass({
GTypeName: 'GSConnectClipboardPlugin',
}, class Plugin extends PluginsBase.Plugin {
_init(device) {
super._init(device, 'clipboard');
try {
this._clipboard = this.service.components.get('clipboard');
// Watch local clipboard for changes
this._textChangedId = this._clipboard.connect(
'notify::text',
this._onLocalClipboardChanged.bind(this)
);
} catch (e) {
this.destroy();
throw e;
}
// Buffer content to allow selective sync
this._localBuffer = null;
this._localTimestamp = 0;
this._remoteBuffer = null;
}
connected() {
super.connected();
// TODO: if we're not auto-syncing local->remote, but we are doing the
// reverse, it's possible older remote content will end up
// overwriting newer local content.
if (!this.settings.get_boolean('send-content')) return;
if (this._localBuffer !== null && this._localTimestamp) {
this.device.sendPacket({
type: 'kdeconnect.clipboard.connect',
body: {
content: this._localBuffer,
timestamp: this._localTimestamp
}
});
}
}
handlePacket(packet) {
if (!packet.body.hasOwnProperty('content')) return;
if (packet.type === 'kdeconnect.clipboard') {
this._handleContent(packet);
} else if (packet.type === 'kdeconnect.clipboard.connect') {
this._handleConnectContent(packet);
}
}
_handleContent(packet) {
this._onRemoteClipboardChanged(packet.body.content);
}
_handleConnectContent(packet) {
if (packet.body.hasOwnProperty('timestamp') &&
packet.body.timestamp > this._localTimestamp) {
this._onRemoteClipboardChanged(packet.body.content);
}
}
/**
* Store the updated clipboard content and forward it if enabled
*/
_onLocalClipboardChanged(clipboard, pspec) {
this._localBuffer = clipboard.text;
this._localTimestamp = Date.now();
if (this.settings.get_boolean('send-content')) {
this.clipboardPush();
}
}
/**
* Store the updated clipboard content and apply it if enabled
*/
_onRemoteClipboardChanged(text) {
this._remoteBuffer = text;
if (this.settings.get_boolean('receive-content')) {
this.clipboardPull();
}
}
/**
* Copy to the remote clipboard; called by _onLocalClipboardChanged()
*/
clipboardPush() {
// Don't sync if the clipboard is empty or not text
if (!this._localTimestamp) return;
if (this._remoteBuffer !== this._localBuffer) {
this._remoteBuffer = this._localBuffer;
// If the buffer is %null, the clipboard contains non-text content,
// so we neither clear the remote clipboard nor pass the content
if (this._localBuffer !== null) {
this.device.sendPacket({
type: 'kdeconnect.clipboard',
body: {
content: this._localBuffer
}
});
}
}
}
/**
* Copy from the remote clipboard; called by _onRemoteClipboardChanged()
*/
clipboardPull() {
if (this._localBuffer !== this._remoteBuffer) {
this._localBuffer = this._remoteBuffer;
this._localTimestamp = Date.now();
this._clipboard.text = this._remoteBuffer;
}
}
destroy() {
if (this._clipboard && this._textChangedId) {
this._clipboard.disconnect(this._textChangedId);
}
super.destroy();
}
});