Enhanced copy/paste to work with more events and to popup a message when it acts
This commit is contained in:
parent
709193db9f
commit
f77cf27a38
179
app/ui.js
179
app/ui.js
|
|
@ -34,8 +34,7 @@ const UI = {
|
||||||
isSafari: false,
|
isSafari: false,
|
||||||
lastKeyboardinput: null,
|
lastKeyboardinput: null,
|
||||||
defaultKeyboardinputLen: 100,
|
defaultKeyboardinputLen: 100,
|
||||||
|
needToCheckClipboardChange: false,
|
||||||
justEnteredVNC: false,
|
|
||||||
|
|
||||||
inhibit_reconnect: true,
|
inhibit_reconnect: true,
|
||||||
reconnect_callback: null,
|
reconnect_callback: null,
|
||||||
|
|
@ -943,43 +942,87 @@ const UI = {
|
||||||
readfuture
|
readfuture
|
||||||
.then(text => callback(text))
|
.then(text => callback(text))
|
||||||
.catch(() =>
|
.catch(() =>
|
||||||
console.error("Failed to read contents of clipboard (trying to copy to VNC clipboard)")
|
Log.Debug("Failed to read system clipboard")
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Copy text from NoVNC desktop to local computer
|
||||||
clipboardReceive(e) {
|
clipboardReceive(e) {
|
||||||
|
var curvalue = document.getElementById('noVNC_clipboard_text').value;
|
||||||
|
if (curvalue != e.detail.text) {
|
||||||
Log.Debug(">> UI.clipboardReceive: " + e.detail.text.substr(0, 40) + "...");
|
Log.Debug(">> UI.clipboardReceive: " + e.detail.text.substr(0, 40) + "...");
|
||||||
document.getElementById('noVNC_clipboard_text').value = e.detail.text;
|
document.getElementById('noVNC_clipboard_text').value = e.detail.text;
|
||||||
Log.Debug("<< UI.clipboardReceive");
|
Log.Debug("<< UI.clipboardReceive");
|
||||||
},
|
|
||||||
|
|
||||||
enterVNC(e) {
|
var writefuture = navigator.clipboard.writeText(e.detail.text);
|
||||||
UI.justEnteredVNC = true;
|
|
||||||
},
|
|
||||||
|
|
||||||
enterVncClick(e) {
|
|
||||||
UI.readClipboard(text => {
|
|
||||||
document.getElementById('noVNC_clipboard_text').value = text;
|
|
||||||
UI.rfb.clipboardPasteFrom(text);
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
leaveVNC(e) {
|
|
||||||
const text = document.getElementById('noVNC_clipboard_text').value;
|
|
||||||
var writefuture = navigator.clipboard.writeText(text);
|
|
||||||
writefuture
|
writefuture
|
||||||
.then(function() {
|
.then(function() {
|
||||||
/* clipboard successfully set */
|
/* clipboard successfully set */
|
||||||
|
UI.popupMessage("Selection Copied");
|
||||||
}, function() {
|
}, function() {
|
||||||
console.error("Failed to write clipboard (trying to copy from VNC clipboard)")
|
console.error("Failed to write system clipboard (trying to copy from NoVNC clipboard)")
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
popupMessage(msg) {
|
||||||
|
// Quick popup to give feedback that selection was copied
|
||||||
|
setTimeout(UI.showOverlay.bind(this, msg, 500), 200);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Enter and focus events come when we return to NoVNC.
|
||||||
|
// In both cases, check the local clipboard to see if it changed.
|
||||||
|
focusVNC() {
|
||||||
|
UI.copyFromLocalClipboard();
|
||||||
|
},
|
||||||
|
enterVNC() {
|
||||||
|
UI.copyFromLocalClipboard();
|
||||||
|
},
|
||||||
|
copyFromLocalClipboard() {
|
||||||
|
UI.readClipboard(text => {
|
||||||
|
var clipVal = document.getElementById('noVNC_clipboard_text').value;
|
||||||
|
if ( clipVal != text ) {
|
||||||
|
document.getElementById('noVNC_clipboard_text').value = text;
|
||||||
|
UI.popupMessage("Copied from Local Clipboard");
|
||||||
|
UI.rfb.clipboardPasteFrom(text);
|
||||||
|
}
|
||||||
|
// Reset flag to prevent checking too often
|
||||||
|
UI.needToCheckClipboardChange = false;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// These 3 events indicate the focus has gone outside the NoVNC.
|
||||||
|
// When outside the NoVNC, the system clipboard could change.
|
||||||
|
leaveVNC() {
|
||||||
|
UI.needToCheckClipboardChange = true;
|
||||||
|
},
|
||||||
|
blurVNC() {
|
||||||
|
UI.needToCheckClipboardChange = true;
|
||||||
|
},
|
||||||
|
focusoutVNC() {
|
||||||
|
UI.needToCheckClipboardChange = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
// On these 2 events, check if we need to look at clipboard.
|
||||||
|
mouseMoveVNC() {
|
||||||
|
if ( UI.needToCheckClipboardChange ) {
|
||||||
|
UI.copyFromLocalClipboard();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mouseDownVNC() {
|
||||||
|
if ( UI.needToCheckClipboardChange ) {
|
||||||
|
UI.copyFromLocalClipboard();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
clipboardClear() {
|
clipboardClear() {
|
||||||
document.getElementById('noVNC_clipboard_text').value = "";
|
document.getElementById('noVNC_clipboard_text').value = "";
|
||||||
|
UI.popupMessage("Clipboard Cleared");
|
||||||
|
// TODO: Should this also clear the local clipboard?
|
||||||
UI.rfb.clipboardPasteFrom("");
|
UI.rfb.clipboardPasteFrom("");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Send clipboard from HTML clipboard element to NoVNC desktop
|
||||||
clipboardSend() {
|
clipboardSend() {
|
||||||
const text = document.getElementById('noVNC_clipboard_text').value;
|
const text = document.getElementById('noVNC_clipboard_text').value;
|
||||||
Log.Debug(">> UI.clipboardSend: " + text.substr(0, 40) + "...");
|
Log.Debug(">> UI.clipboardSend: " + text.substr(0, 40) + "...");
|
||||||
|
|
@ -987,6 +1030,87 @@ const UI = {
|
||||||
Log.Debug("<< UI.clipboardSend");
|
Log.Debug("<< UI.clipboardSend");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the terminal overlay for a given amount of time.
|
||||||
|
*
|
||||||
|
* The terminal overlay appears in inverse video in a large font, centered
|
||||||
|
* over the terminal. You should probably keep the overlay message brief,
|
||||||
|
* since it's in a large font and you probably aren't going to check the size
|
||||||
|
* of the terminal first.
|
||||||
|
*
|
||||||
|
* @param {string} msg The text (not HTML) message to display in the overlay.
|
||||||
|
* @param {number} opt_timeout The amount of time to wait before fading out
|
||||||
|
* the overlay. Defaults to 1.5 seconds. Pass null to have the overlay
|
||||||
|
* stay up forever (or until the next overlay).
|
||||||
|
*/
|
||||||
|
showOverlay(msg, opt_timeout) {
|
||||||
|
if (!UI.overlayNode) {
|
||||||
|
UI.overlayNode = document.createElement('div');
|
||||||
|
UI.overlayNode.style.cssText = (
|
||||||
|
'border-radius: 15px;' +
|
||||||
|
'font-size: xx-large;' +
|
||||||
|
'opacity: 0.90;' +
|
||||||
|
'padding: 0.2em 0.5em 0.2em 0.5em;' +
|
||||||
|
'position: absolute;' +
|
||||||
|
'-webkit-user-select: none;' +
|
||||||
|
'-webkit-transition: opacity 180ms ease-in;' +
|
||||||
|
'-moz-user-select: none;' +
|
||||||
|
'-moz-transition: opacity 180ms ease-in;');
|
||||||
|
UI.overlayNode.style.color = 'rgb(16,16,16)';
|
||||||
|
UI.overlayNode.style.backgroundColor = 'rgb(240,240,240)';
|
||||||
|
UI.overlayNode.style.fontFamily = '"DejaVu Sans Mono", "Noto Sans Mono", "Everson Mono", FreeMono, Menlo, Terminal, monospace"';
|
||||||
|
UI.overlayNode.style.opacity = '0.90';
|
||||||
|
|
||||||
|
//UI.overlayNode.addEventListener('mousedown', function(e) {
|
||||||
|
// e.preventDefault();
|
||||||
|
// e.stopPropagation();
|
||||||
|
// }, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
UI.overlayNode.textContent = msg;
|
||||||
|
|
||||||
|
if (!UI.overlayNode.parentNode_) {
|
||||||
|
UI.overlayNode.parentNode_ = document.getElementById('noVNC_container');
|
||||||
|
}
|
||||||
|
UI.overlayNode.parentNode_.appendChild(UI.overlayNode);
|
||||||
|
|
||||||
|
var divWidth = UI.overlayNode.parentNode_.offsetWidth;
|
||||||
|
var divHeight = UI.overlayNode.parentNode_.offsetHeight;
|
||||||
|
var overlayWidth = UI.overlayNode.offsetWidth;
|
||||||
|
var overlayHeight = UI.overlayNode.offsetHeight;
|
||||||
|
|
||||||
|
UI.overlayNode.style.top =
|
||||||
|
(divHeight - overlayHeight) / 2 + 'px';
|
||||||
|
UI.overlayNode.style.left =
|
||||||
|
(divWidth - overlayWidth) / 2 + 'px';
|
||||||
|
|
||||||
|
if (UI.overlayTimeout)
|
||||||
|
clearTimeout(UI.overlayTimeout);
|
||||||
|
|
||||||
|
if (opt_timeout === null)
|
||||||
|
opt_timeout = 500;
|
||||||
|
|
||||||
|
UI.overlayTimeout = setTimeout(() => {
|
||||||
|
UI.overlayNode.style.opacity = '0';
|
||||||
|
UI.overlayTimeout = setTimeout(() => UI.hideOverlay(), 200);
|
||||||
|
}, opt_timeout || 1500);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide the terminal overlay immediately.
|
||||||
|
*
|
||||||
|
* Useful when we show an overlay for an event with an unknown end time.
|
||||||
|
*/
|
||||||
|
hideOverlay() {
|
||||||
|
if (UI.overlayTimeout)
|
||||||
|
clearTimeout(UI.overlayTimeout);
|
||||||
|
UI.overlayTimeout = null;
|
||||||
|
|
||||||
|
if (UI.overlayNode.parentNode_)
|
||||||
|
UI.overlayNode.parentNode_.removeChild(UI.overlayNode);
|
||||||
|
UI.overlayNode.style.opacity = '0.90';
|
||||||
|
},
|
||||||
|
|
||||||
/* ------^-------
|
/* ------^-------
|
||||||
* /CLIPBOARD
|
* /CLIPBOARD
|
||||||
* ==============
|
* ==============
|
||||||
|
|
@ -1057,10 +1181,14 @@ const UI = {
|
||||||
UI.rfb.addEventListener("securityfailure", UI.securityFailed);
|
UI.rfb.addEventListener("securityfailure", UI.securityFailed);
|
||||||
UI.rfb.addEventListener("capabilities", UI.updatePowerButton);
|
UI.rfb.addEventListener("capabilities", UI.updatePowerButton);
|
||||||
UI.rfb.addEventListener("clipboard", UI.clipboardReceive);
|
UI.rfb.addEventListener("clipboard", UI.clipboardReceive);
|
||||||
document//.getElementById("noVNC_container")
|
|
||||||
.addEventListener('mouseenter', UI.enterVNC);
|
document.addEventListener('mouseenter', UI.enterVNC);
|
||||||
document//.getElementById("noVNC_container")
|
document.addEventListener('mouseleave', UI.leaveVNC);
|
||||||
.addEventListener('mouseleave', UI.leaveVNC);
|
document.addEventListener('blur', UI.blurVNC);
|
||||||
|
document.addEventListener('focus', UI.focusVNC);
|
||||||
|
document.addEventListener('focusout', UI.focusoutVNC);
|
||||||
|
document.addEventListener('mousemove', UI.mouseMoveVNC);
|
||||||
|
document.addEventListener('mousedown', UI.mouseDownVNC);
|
||||||
|
|
||||||
UI.rfb.addEventListener("bell", UI.bell);
|
UI.rfb.addEventListener("bell", UI.bell);
|
||||||
UI.rfb.addEventListener("desktopname", UI.updateDesktopName);
|
UI.rfb.addEventListener("desktopname", UI.updateDesktopName);
|
||||||
|
|
@ -1411,9 +1539,8 @@ const UI = {
|
||||||
keepVirtualKeyboard(event) {
|
keepVirtualKeyboard(event) {
|
||||||
const input = document.getElementById('noVNC_keyboardinput');
|
const input = document.getElementById('noVNC_keyboardinput');
|
||||||
|
|
||||||
if ( UI.justEnteredVNC ) {
|
if ( UI.needToCheckClipboardChange ) {
|
||||||
UI.justEnteredVNC = false;
|
UI.copyFromLocalClipboard();
|
||||||
UI.enterVncClick(event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only prevent focus change if the virtual keyboard is active
|
// Only prevent focus change if the virtual keyboard is active
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue