GUACAMOLE-2175: Merge wait clipboard synchronization before pasting.

This commit is contained in:
Virtually Nick authored and GitHub committed 2025-12-03 20:14:16 -06:00
commit 20abbea291
2 files changed
+51 -5

No files matched your search

@@ -132,6 +132,13 @@ angular.module('client').directive('guacClient', [function guacClient() {
*/
const touch = new Guacamole.Touch(displayContainer);
/**
* Whether clipboard synchronization is currently in progress.
*
* @type boolean
*/
let clipboardSyncInProgress = false;
/**
* Updates the scale of the attached Guacamole.Client based on current window
* size and "auto-fit" setting.
@@ -239,15 +246,47 @@ angular.module('client').directive('guacClient', [function guacClient() {
event.stopPropagation();
event.preventDefault();
// Send mouse state, show cursor if necessary
display.showCursor(!localCursor);
client.sendMouseState(event.state, true);
// Wait for any in-progress clipboard synchronization to complete.
// This avoids the pasting of outdated clipboard content when guacamole
// window regains focus.
waitForClipboardSync().then(() => {
// Broadcast the mouse event
$rootScope.$broadcast(getMouseEventName(event), event, client);
// Send mouse state, show cursor if necessary
display.showCursor(!localCursor);
client.sendMouseState(event.state, true);
// Broadcast the mouse event
$rootScope.$broadcast(getMouseEventName(event), event, client);
});
};
/**
* Returns a promise which resolves once any in-progress clipboard
* synchronization has completed.
*
* @returns {Promise}
* A promise which resolves once any in-progress clipboard
* synchronization has completed.
*/
function waitForClipboardSync() {
return new Promise((resolve) => {
function checkClipboardSync() {
if (!clipboardSyncInProgress) {
resolve();
return;
}
// Synchronization can take 8-10ms, so check again shortly
// to not add slight latency in fast environments.
setTimeout(checkClipboardSync, 10);
}
checkClipboardSync();
});
}
/**
* Handles a mouse event originating from one of Guacamole's mouse
* emulation objects. This differs from handleMouseState() in that
@@ -601,6 +640,11 @@ angular.module('client').directive('guacClient', [function guacClient() {
client.sendKeyEvent(0, keysym);
});
// Track clipboard synchronization status
$rootScope.$on('clipboardSyncInProgress', function clipboardSyncStatus(event, status) {
clipboardSyncInProgress = status;
});
/**
* Whether a drag/drop operation is currently in progress (the user has
* dragged a file over the Guacamole connection but has not yet
@@ -603,6 +603,7 @@ angular.module('clipboard').factory('clipboardService', ['$injector',
// updated contents
storedClipboardData(data);
$rootScope.$broadcast('guacClipboard', data);
$rootScope.$broadcast('clipboardSyncInProgress', false);
});
};
@@ -615,6 +616,7 @@ angular.module('clipboard').factory('clipboardService', ['$injector',
* components like the "guacClient" directive.
*/
service.resyncClipboard = function resyncClipboard() {
$rootScope.$broadcast('clipboardSyncInProgress', true);
getLocalClipboard().then(function clipboardRead(data) {
return service.setClipboard(data);
}, angular.noop);