GUAC-1379: Ensure focus is assigned back to the document, even if it would otherwise be prevented by preventDefault() within Guacamole.Mouse.

This commit is contained in:
Michael Jumper
2016-01-18 22:10:18 -08:00
parent 3c35437627
commit 7d759a5718

View File

@@ -211,6 +211,53 @@ angular.module('client').directive('guacClient', [function guacClient() {
}; };
/**
* Handles a mouse event originating from the user's actual mouse.
* This differs from handleEmulatedMouseState() in that the
* software mouse cursor must be shown only if the user's browser
* does not support explicitly setting the hardware mouse cursor.
*
* @param {Guacamole.Mouse.State} mouseState
* The current state of the user's hardware mouse.
*/
var handleMouseState = function handleMouseState(mouseState) {
// Do not attempt to handle mouse state changes if the client
// or display are not yet available
if (!client || !display)
return;
// Send mouse state, show cursor if necessary
display.showCursor(!localCursor);
sendScaledMouseState(mouseState);
};
/**
* Handles a mouse event originating from one of Guacamole's mouse
* emulation objects. This differs from handleMouseState() in that
* the software mouse cursor must always be shown (as the emulated
* mouse device will not have its own cursor).
*
* @param {Guacamole.Mouse.State} mouseState
* The current state of the user's emulated (touch) mouse.
*/
var handleEmulatedMouseState = function handleEmulatedMouseState(mouseState) {
// Do not attempt to handle mouse state changes if the client
// or display are not yet available
if (!client || !display)
return;
// Ensure software cursor is shown
display.showCursor(true);
// Send mouse state, ensure cursor is visible
scrollToMouse(mouseState);
sendScaledMouseState(mouseState);
};
// Attach any given managed client // Attach any given managed client
$scope.$watch('client', function attachManagedClient(managedClient) { $scope.$watch('client', function attachManagedClient(managedClient) {
@@ -264,20 +311,8 @@ angular.module('client').directive('guacClient', [function guacClient() {
}); });
// Swap mouse emulation modes depending on absolute mode flag // Swap mouse emulation modes depending on absolute mode flag
$scope.$watch('client.clientProperties.emulateAbsoluteMouse', function(emulateAbsoluteMouse) { $scope.$watch('client.clientProperties.emulateAbsoluteMouse',
function mouseEmulationModeChanged(emulateAbsoluteMouse) {
if (!client || !display) return;
var handleMouseState = function handleMouseState(mouseState) {
// Ensure software cursor is shown
display.showCursor(true);
// Send mouse state, ensure cursor is visible
scrollToMouse(mouseState);
sendScaledMouseState(mouseState);
};
var newMode, oldMode; var newMode, oldMode;
@@ -296,13 +331,17 @@ angular.module('client').directive('guacClient', [function guacClient() {
// Set applicable mouse emulation object, unset the old one // Set applicable mouse emulation object, unset the old one
if (newMode) { if (newMode) {
// Clear old handlers and copy state to new emulation mode
if (oldMode) { if (oldMode) {
oldMode.onmousedown = oldMode.onmouseup = oldMode.onmousemove = null; oldMode.onmousedown = oldMode.onmouseup = oldMode.onmousemove = null;
newMode.currentState.x = oldMode.currentState.x; newMode.currentState.x = oldMode.currentState.x;
newMode.currentState.y = oldMode.currentState.y; newMode.currentState.y = oldMode.currentState.y;
} }
newMode.onmousedown = newMode.onmouseup = newMode.onmousemove = handleMouseState; // Handle emulated events only from the new emulation mode
newMode.onmousedown =
newMode.onmouseup =
newMode.onmousemove = handleEmulatedMouseState;
} }
@@ -357,21 +396,16 @@ angular.module('client').directive('guacClient', [function guacClient() {
}; };
// Watch for changes to mouse emulation mode // Ensure focus is regained via mousedown before forwarding event
// Send all received mouse events to the client mouse.onmousedown = function(mouseState) {
mouse.onmousedown = document.body.focus();
mouse.onmouseup = handleMouseState(mouseState);
mouse.onmousemove = function(mouseState) {
if (!client || !display)
return;
// Send mouse state, show cursor if necessary
display.showCursor(!localCursor);
sendScaledMouseState(mouseState);
}; };
// Forward mouseup / mousemove events untouched
mouse.onmouseup =
mouse.onmousemove = handleMouseState;
// Hide software cursor when mouse leaves display // Hide software cursor when mouse leaves display
mouse.onmouseout = function() { mouse.onmouseout = function() {
if (!display) return; if (!display) return;