GUACAMOLE-55: Only the guacClipboard directive should fire guacClipboard events.

This commit is contained in:
Michael Jumper
2016-06-22 00:26:46 -07:00
parent 0eed6c32ae
commit 0edc730308
4 changed files with 90 additions and 86 deletions

View File

@@ -32,7 +32,6 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
// Required services
var $location = $injector.get('$location');
var authenticationService = $injector.get('authenticationService');
var clipboardService = $injector.get('clipboardService');
var guacClientManager = $injector.get('guacClientManager');
var guacNotification = $injector.get('guacNotification');
var preferenceService = $injector.get('preferenceService');
@@ -245,15 +244,6 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
*/
var keysCurrentlyPressed = {};
/**
* Map of all currently pressed keys (by keysym) to the clipboard contents
* received from the remote desktop while those keys were pressed. All keys
* not currently pressed will not have entries within this map.
*
* @type Object.<Number, String>
*/
var clipboardDataFromKey = {};
/*
* Check to see if all currently pressed keys are in the set of menu keys.
*/
@@ -384,24 +374,11 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
$scope.$watch('menu.shown', function menuVisibilityChanged(menuShown, menuShownPreviousState) {
// Send clipboard data if menu is hidden
if (!menuShown && menuShownPreviousState)
$scope.$broadcast('guacClipboard', 'text/plain', $scope.client.clipboardData);
// Disable client keyboard if the menu is shown
$scope.client.clientProperties.keyboardEnabled = !menuShown;
});
// Watch clipboard for new data, associating it with any pressed keys
$scope.$watch('client.clipboardData', function clipboardChanged(data) {
// Associate new clipboard data with any currently-pressed key
for (var keysym in keysCurrentlyPressed)
clipboardDataFromKey[keysym] = data;
});
// Track pressed keys, opening the Guacamole menu after Ctrl+Alt+Shift
$scope.$on('guacKeydown', function keydownListener(event, keysym, keyboard) {
@@ -437,18 +414,9 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
});
// Update pressed keys as they are released, synchronizing the clipboard
// with any data that appears to have come from those key presses
// Update pressed keys as they are released
$scope.$on('guacKeyup', function keyupListener(event, keysym, keyboard) {
// Sync local clipboard with any clipboard data received while this
// key was pressed (if any)
var clipboardData = clipboardDataFromKey[keysym];
if (clipboardData) {
clipboardService.setLocalClipboard(clipboardData);
delete clipboardDataFromKey[keysym];
}
// Mark key as released
delete keysCurrentlyPressed[keysym];
@@ -561,19 +529,6 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
});
}
// Hide status and sync local clipboard once connected
else if (connectionState === ManagedClientState.ConnectionState.CONNECTED) {
// Sync with local clipboard
clipboardService.getLocalClipboard().then(function clipboardRead(data) {
$scope.$broadcast('guacClipboard', 'text/plain', data);
});
// Hide status notification
guacNotification.showStatus(false);
}
// Hide status for all other states
else
guacNotification.showStatus(false);

View File

@@ -23,7 +23,9 @@
* cannot be directly accessed, the user can at least directly copy/paste data
* within the field provided by this directive. The contents of this clipboard
* directive, whether retrieved from the local or manipulated manually by the
* user, are exposed via the "data" attribute.
* user, are exposed via the "data" attribute. In addition to updating the
* "data" attribute, changes to clipboard data will be broadcast on the scope
* via "guacClipboard" events.
*/
angular.module('client').directive('guacClipboard', [function guacClipboard() {
@@ -59,7 +61,87 @@ angular.module('client').directive('guacClipboard', [function guacClipboard() {
config.controller = ['$scope', '$injector', '$element',
function guacClipboardController($scope, $injector, $element) {
// STUB
// Required services
var $rootScope = $injector.get('$rootScope');
var clipboardService = $injector.get('clipboardService');
/**
* Map of all currently pressed keys by keysym. If a particular key is
* currently pressed, the value stored under that key's keysym within
* this map will be true. All keys not currently pressed will not have entries
* within this map.
*
* @type Object.<Number, Boolean>
*/
var keysCurrentlyPressed = {};
/**
* Map of all currently pressed keys (by keysym) to the clipboard
* contents received while those keys were pressed. All keys not
* currently pressed will not have entries within this map.
*
* @type Object.<Number, String>
*/
var clipboardDataFromKey = {};
// Watch clipboard for new data, associating it with any pressed keys
$scope.$watch('data', function clipboardChanged(data) {
// Associate new clipboard data with any currently-pressed key
for (var keysym in keysCurrentlyPressed)
clipboardDataFromKey[keysym] = data;
// Notify of updated clipboard data
$rootScope.$broadcast('guacClipboard', 'text/plain', data);
});
// Track pressed keys
$scope.$on('guacKeydown', function keydownListener(event, keysym, keyboard) {
// Record key as pressed
keysCurrentlyPressed[keysym] = true;
});
// Update pressed keys as they are released, synchronizing the clipboard
// with any data that appears to have come from those key presses
$scope.$on('guacKeyup', function keyupListener(event, keysym, keyboard) {
// Sync local clipboard with any clipboard data received while this
// key was pressed (if any)
var clipboardData = clipboardDataFromKey[keysym];
if (clipboardData) {
clipboardService.setLocalClipboard(clipboardData);
delete clipboardDataFromKey[keysym];
}
// Mark key as released
delete keysCurrentlyPressed[keysym];
});
/**
* Checks whether the clipboard data has changed, firing a new
* "guacClipboard" event if it has.
*/
var checkClipboard = function checkClipboard() {
clipboardService.getLocalClipboard().then(function clipboardRead(data) {
$scope.data = data;
});
};
// Attempt to read the clipboard if it may have changed
window.addEventListener('load', checkClipboard, true);
window.addEventListener('copy', checkClipboard, true);
window.addEventListener('cut', checkClipboard, true);
window.addEventListener('focus', function focusGained(e) {
// Only recheck clipboard if it's the window itself that gained focus
if (e.target === window)
checkClipboard();
}, true);
}];

View File

@@ -24,8 +24,7 @@ angular.module('client').factory('clipboardService', ['$injector',
function clipboardService($injector) {
// Get required services
var $q = $injector.get('$q');
var $rootScope = $injector.get('$rootScope');
var $q = $injector.get('$q');
var service = {};
@@ -44,14 +43,6 @@ angular.module('client').factory('clipboardService', ['$injector',
*/
var clipboardContent = document.createElement('textarea');
/**
* The contents of the last clipboard event broadcast by this service when
* the clipboard contents changed.
*
* @type String
*/
var lastClipboardEvent = '';
// Ensure textarea is selectable but not visible
clipElement.appendChild(clipboardContent);
clipElement.style.position = 'absolute';
@@ -129,34 +120,6 @@ angular.module('client').factory('clipboardService', ['$injector',
return deferred.promise;
};
/**
* Checks whether the clipboard data has changed, firing a new
* "guacClipboard" event if it has.
*/
var checkClipboard = function checkClipboard() {
service.getLocalClipboard().then(function clipboardRead(data) {
// Fire clipboard event if the data has changed
if (data !== lastClipboardEvent) {
$rootScope.$broadcast('guacClipboard', 'text/plain', data);
lastClipboardEvent = data;
}
});
};
// Attempt to read the clipboard if it may have changed
window.addEventListener('load', checkClipboard, true);
window.addEventListener('copy', checkClipboard, true);
window.addEventListener('cut', checkClipboard, true);
window.addEventListener('focus', function focusGained(e) {
// Only recheck clipboard if it's the window itself that gained focus
if (e.target === window)
checkClipboard();
}, true);
return service;
}]);

View File

@@ -383,6 +383,10 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
ManagedClientState.setConnectionState(managedClient.clientState,
ManagedClientState.ConnectionState.CONNECTED);
// Send any clipboard data already provided
if (managedClient.clipboardData)
client.setClipboard(managedClient.clipboardData);
// Begin streaming audio input if possible
requestAudioStream(client);