mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 21:27:40 +00:00
Do not attempt to monitor up/down if key handled via keypress (fixes #208). Partial style fix.
This commit is contained in:
@@ -80,7 +80,7 @@ Guacamole.Keyboard = function(element) {
|
|||||||
* to their unshifted X11 keysym equivalents.
|
* to their unshifted X11 keysym equivalents.
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
var unshiftedKeySym = {
|
var unshiftedKeysym = {
|
||||||
8: 0xFF08, // backspace
|
8: 0xFF08, // backspace
|
||||||
9: 0xFF09, // tab
|
9: 0xFF09, // tab
|
||||||
13: 0xFF0D, // enter
|
13: 0xFF0D, // enter
|
||||||
@@ -209,10 +209,19 @@ Guacamole.Keyboard = function(element) {
|
|||||||
* equivalents.
|
* equivalents.
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
var shiftedKeySym = {
|
var shiftedKeysym = {
|
||||||
18: 0xFFE7 // alt
|
18: 0xFFE7 // alt
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All keysyms which should not repeat when held down.
|
||||||
|
*/
|
||||||
|
var no_repeat = {
|
||||||
|
0xFFE1: true,
|
||||||
|
0xFFE3: true,
|
||||||
|
0xFFE9: true
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All modifiers and their states.
|
* All modifiers and their states.
|
||||||
*/
|
*/
|
||||||
@@ -242,28 +251,23 @@ Guacamole.Keyboard = function(element) {
|
|||||||
*/
|
*/
|
||||||
this.pressed = {};
|
this.pressed = {};
|
||||||
|
|
||||||
var keydownChar = new Array();
|
/**
|
||||||
|
* The keysym associated with a given keycode when keydown fired.
|
||||||
|
*/
|
||||||
|
var keydownChar = [];
|
||||||
|
|
||||||
// ID of routine repeating keystrokes. -1 = not repeating.
|
/**
|
||||||
var repeatKeyTimeoutId = -1;
|
* Timeout before key repeat starts.
|
||||||
var repeatKeyIntervalId = -1;
|
*/
|
||||||
|
var key_repeat_timeout = null;
|
||||||
|
|
||||||
// Starts repeating keystrokes
|
/**
|
||||||
function startRepeat(keySym) {
|
* Interval which presses and releases the last key pressed while that
|
||||||
repeatKeyIntervalId = setInterval(function() {
|
* key is still being held down.
|
||||||
sendKeyReleased(keySym);
|
*/
|
||||||
sendKeyPressed(keySym);
|
var key_repeat_interval = null;
|
||||||
}, 50);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stops repeating keystrokes
|
function keysym_from_key_identifier(shifted, keyIdentifier) {
|
||||||
function stopRepeat() {
|
|
||||||
if (repeatKeyTimeoutId != -1) clearTimeout(repeatKeyTimeoutId);
|
|
||||||
if (repeatKeyIntervalId != -1) clearInterval(repeatKeyIntervalId);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function getKeySymFromKeyIdentifier(shifted, keyIdentifier) {
|
|
||||||
|
|
||||||
var unicodePrefixLocation = keyIdentifier.indexOf("U+");
|
var unicodePrefixLocation = keyIdentifier.indexOf("U+");
|
||||||
if (unicodePrefixLocation >= 0) {
|
if (unicodePrefixLocation >= 0) {
|
||||||
@@ -281,7 +285,7 @@ Guacamole.Keyboard = function(element) {
|
|||||||
// Get codepoint
|
// Get codepoint
|
||||||
codepoint = typedCharacter.charCodeAt(0);
|
codepoint = typedCharacter.charCodeAt(0);
|
||||||
|
|
||||||
return getKeySymFromCharCode(codepoint);
|
return keysym_from_charcode(codepoint);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,7 +297,7 @@ Guacamole.Keyboard = function(element) {
|
|||||||
return codepoint <= 0x1F || (codepoint >= 0x7F && codepoint <= 0x9F);
|
return codepoint <= 0x1F || (codepoint >= 0x7F && codepoint <= 0x9F);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getKeySymFromCharCode(codepoint) {
|
function keysym_from_charcode(codepoint) {
|
||||||
|
|
||||||
// Keysyms for control characters
|
// Keysyms for control characters
|
||||||
if (isControlCharacter(codepoint)) return 0xFF00 | codepoint;
|
if (isControlCharacter(codepoint)) return 0xFF00 | codepoint;
|
||||||
@@ -310,13 +314,13 @@ Guacamole.Keyboard = function(element) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getKeySymFromKeyCode(keyCode) {
|
function keysyom_from_keycode(keyCode) {
|
||||||
|
|
||||||
var keysym = null;
|
var keysym = null;
|
||||||
if (!guac_keyboard.modifiers.shift) keysym = unshiftedKeySym[keyCode];
|
if (!guac_keyboard.modifiers.shift) keysym = unshiftedKeysym[keyCode];
|
||||||
else {
|
else {
|
||||||
keysym = shiftedKeySym[keyCode];
|
keysym = shiftedKeysym[keyCode];
|
||||||
if (keysym == null) keysym = unshiftedKeySym[keyCode];
|
if (keysym == null) keysym = unshiftedKeysym[keyCode];
|
||||||
}
|
}
|
||||||
|
|
||||||
return keysym;
|
return keysym;
|
||||||
@@ -324,69 +328,62 @@ Guacamole.Keyboard = function(element) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Sends a single keystroke over the network
|
/**
|
||||||
function sendKeyPressed(keysym) {
|
* Marks a key as pressed, firing the keydown event if registered. Key
|
||||||
|
* repeat for the pressed key will start after a delay if that key is
|
||||||
|
* not a modifier.
|
||||||
|
*/
|
||||||
|
function press_key(keysym) {
|
||||||
|
|
||||||
// Mark key as pressed
|
// Only press if released
|
||||||
guac_keyboard.pressed[keysym] = true;
|
if (!guac_keyboard.pressed[keysym]) {
|
||||||
|
|
||||||
// Send key event
|
// Mark key as pressed
|
||||||
if (keysym != null && guac_keyboard.onkeydown)
|
guac_keyboard.pressed[keysym] = true;
|
||||||
guac_keyboard.onkeydown(keysym);
|
|
||||||
|
|
||||||
}
|
// Send key event
|
||||||
|
if (keysym != null && guac_keyboard.onkeydown) {
|
||||||
|
guac_keyboard.onkeydown(keysym);
|
||||||
|
|
||||||
// Sends a single keystroke over the network
|
// Stop any current repeat
|
||||||
function sendKeyReleased(keysym) {
|
window.clearTimeout(key_repeat_timeout);
|
||||||
|
window.clearInterval(key_repeat_interval);
|
||||||
|
|
||||||
// Mark key as released
|
// Repeat after a delay as long as pressed
|
||||||
delete guac_keyboard.pressed[keysym];
|
if (!no_repeat[keysym])
|
||||||
|
key_repeat_timeout = setTimeout(function() {
|
||||||
// Send key event
|
key_repeat_interval = window.setInterval(function() {
|
||||||
if (keysym != null && guac_keyboard.onkeyup)
|
guac_keyboard.onkeyup(keysym);
|
||||||
guac_keyboard.onkeyup(keysym);
|
guac_keyboard.onkeydown(keysym);
|
||||||
|
}, 50);
|
||||||
}
|
}, 500);
|
||||||
|
|
||||||
|
|
||||||
var expect_keypress = true;
|
}
|
||||||
var keydown_code = null;
|
|
||||||
|
|
||||||
var deferred_keypress = null;
|
|
||||||
var keydown_keysym = null;
|
|
||||||
var keypress_keysym = null;
|
|
||||||
|
|
||||||
function handleKeyEvents() {
|
|
||||||
|
|
||||||
// Prefer keysym from keypress
|
|
||||||
var keysym = keypress_keysym || keydown_keysym;
|
|
||||||
var keynum = keydown_code;
|
|
||||||
|
|
||||||
if (keydownChar[keynum] != keysym) {
|
|
||||||
|
|
||||||
// If this button is already pressed, release first
|
|
||||||
var lastKeyDownChar = keydownChar[keydown_code];
|
|
||||||
if (lastKeyDownChar)
|
|
||||||
sendKeyReleased(lastKeyDownChar);
|
|
||||||
|
|
||||||
// Send event
|
|
||||||
keydownChar[keynum] = keysym;
|
|
||||||
sendKeyPressed(keysym);
|
|
||||||
|
|
||||||
// Clear old key repeat, if any.
|
|
||||||
stopRepeat();
|
|
||||||
|
|
||||||
// Start repeating (if not a modifier key) after a short delay
|
|
||||||
if (keynum != 16 && keynum != 17 && keynum != 18)
|
|
||||||
repeatKeyTimeoutId = setTimeout(function() { startRepeat(keysym); }, 500);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Done with deferred key event
|
}
|
||||||
deferred_keypress = null;
|
|
||||||
keypress_keysym = null;
|
/**
|
||||||
keydown_keysym = null;
|
* Marks a key as released, firing the keyup event if registered.
|
||||||
keydown_code = null;
|
*/
|
||||||
|
function release_key(keysym) {
|
||||||
|
|
||||||
|
// Only release if pressed
|
||||||
|
if (guac_keyboard.pressed[keysym]) {
|
||||||
|
|
||||||
|
// Mark key as released
|
||||||
|
delete guac_keyboard.pressed[keysym];
|
||||||
|
|
||||||
|
// Stop repeat
|
||||||
|
window.clearTimeout(key_repeat_timeout);
|
||||||
|
window.clearInterval(key_repeat_interval);
|
||||||
|
|
||||||
|
// Send key event
|
||||||
|
if (keysym != null && guac_keyboard.onkeyup)
|
||||||
|
guac_keyboard.onkeyup(keysym);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -425,25 +422,26 @@ Guacamole.Keyboard = function(element) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
expect_keypress = true;
|
|
||||||
|
|
||||||
// Ctrl/Alt/Shift
|
// Ctrl/Alt/Shift
|
||||||
if (keynum == 16) guac_keyboard.modifiers.shift = true;
|
if (keynum == 16) guac_keyboard.modifiers.shift = true;
|
||||||
else if (keynum == 17) guac_keyboard.modifiers.ctrl = true;
|
else if (keynum == 17) guac_keyboard.modifiers.ctrl = true;
|
||||||
else if (keynum == 18) guac_keyboard.modifiers.alt = true;
|
else if (keynum == 18) guac_keyboard.modifiers.alt = true;
|
||||||
|
|
||||||
// Try to get keysym from keycode
|
// Try to get keysym from keycode
|
||||||
keydown_keysym = getKeySymFromKeyCode(keynum);
|
var keysym = keysyom_from_keycode(keynum);
|
||||||
|
|
||||||
|
// By default, we expect a corresponding keypress event
|
||||||
|
var expect_keypress = true;
|
||||||
|
|
||||||
// If key is known from keycode, prevent default
|
// If key is known from keycode, prevent default
|
||||||
if (keydown_keysym)
|
if (keysym)
|
||||||
expect_keypress = false;
|
expect_keypress = false;
|
||||||
|
|
||||||
// Also try to get get keysym from keyIdentifier
|
// Also try to get get keysym from keyIdentifier
|
||||||
if (e.keyIdentifier) {
|
if (e.keyIdentifier) {
|
||||||
|
|
||||||
keydown_keysym = keydown_keysym ||
|
keysym = keysym ||
|
||||||
getKeySymFromKeyIdentifier(guac_keyboard.modifiers.shift, e.keyIdentifier);
|
keysym_from_key_identifier(guac_keyboard.modifiers.shift, e.keyIdentifier);
|
||||||
|
|
||||||
// Prevent default if non-typable character or if modifier combination
|
// Prevent default if non-typable character or if modifier combination
|
||||||
// likely to be eaten by browser otherwise (NOTE: We must not prevent
|
// likely to be eaten by browser otherwise (NOTE: We must not prevent
|
||||||
@@ -457,20 +455,11 @@ Guacamole.Keyboard = function(element) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set keycode which will be associated with any future keypress
|
// If we do not expect to handle via keypress, handle now
|
||||||
keydown_code = keynum;
|
if (!expect_keypress) {
|
||||||
|
|
||||||
// If we expect to handle via keypress, set failsafe timeout and
|
|
||||||
// wait for keypress.
|
|
||||||
if (expect_keypress) {
|
|
||||||
if (!deferred_keypress)
|
|
||||||
deferred_keypress = window.setTimeout(handleKeyEvents, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, handle now
|
|
||||||
else {
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
handleKeyEvents();
|
keydownChar[keynum] = keysym;
|
||||||
|
press_key(keysym);
|
||||||
}
|
}
|
||||||
|
|
||||||
}, true);
|
}, true);
|
||||||
@@ -479,33 +468,26 @@ Guacamole.Keyboard = function(element) {
|
|||||||
element.addEventListener("keypress", function(e) {
|
element.addEventListener("keypress", function(e) {
|
||||||
|
|
||||||
// Only intercept if handler set
|
// Only intercept if handler set
|
||||||
if (!guac_keyboard.onkeydown) return;
|
if (!guac_keyboard.onkeydown && !guac_keyboard.onkeyup) return;
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
// Do not handle if we weren't expecting this event (will have already
|
|
||||||
// been handled by keydown)
|
|
||||||
if (!expect_keypress) return;
|
|
||||||
|
|
||||||
var keynum;
|
var keynum;
|
||||||
if (window.event) keynum = window.event.keyCode;
|
if (window.event) keynum = window.event.keyCode;
|
||||||
else if (e.which) keynum = e.which;
|
else if (e.which) keynum = e.which;
|
||||||
|
|
||||||
keypress_keysym = getKeySymFromCharCode(keynum);
|
var keysym = keysym_from_charcode(keynum);
|
||||||
|
|
||||||
// If event identified as a typable character, and we're holding Ctrl+Alt,
|
// If event identified as a typable character, and we're holding Ctrl+Alt,
|
||||||
// assume Ctrl+Alt is actually AltGr, and release both.
|
// assume Ctrl+Alt is actually AltGr, and release both.
|
||||||
if (!isControlCharacter(keynum) && guac_keyboard.modifiers.ctrl && guac_keyboard.modifiers.alt) {
|
if (!isControlCharacter(keynum) && guac_keyboard.modifiers.ctrl && guac_keyboard.modifiers.alt) {
|
||||||
sendKeyReleased(0xFFE3);
|
release_key(0xFFE3);
|
||||||
sendKeyReleased(0xFFE9);
|
release_key(0xFFE9);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear timeout, if any
|
// Send press + release
|
||||||
if (deferred_keypress)
|
press_key(keysym);
|
||||||
window.clearTimeout(deferred_keypress);
|
release_key(keysym);
|
||||||
|
|
||||||
// Handle event with all aggregated data
|
|
||||||
handleKeyEvents();
|
|
||||||
|
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
@@ -522,27 +504,22 @@ Guacamole.Keyboard = function(element) {
|
|||||||
else if (e.which) keynum = e.which;
|
else if (e.which) keynum = e.which;
|
||||||
|
|
||||||
// Ctrl/Alt/Shift
|
// Ctrl/Alt/Shift
|
||||||
if (keynum == 16) guac_keyboard.modifiers.shift = false;
|
if (keynum == 16) guac_keyboard.modifiers.shift = false;
|
||||||
else if (keynum == 17) guac_keyboard.modifiers.ctrl = false;
|
else if (keynum == 17) guac_keyboard.modifiers.ctrl = false;
|
||||||
else if (keynum == 18) guac_keyboard.modifiers.alt = false;
|
else if (keynum == 18) guac_keyboard.modifiers.alt = false;
|
||||||
else
|
|
||||||
stopRepeat();
|
|
||||||
|
|
||||||
// Get corresponding character
|
// Send release event
|
||||||
var lastKeyDownChar = keydownChar[keynum];
|
release_key(keydownChar[keynum]);
|
||||||
|
|
||||||
// Clear character record
|
// Clear character record
|
||||||
keydownChar[keynum] = null;
|
keydownChar[keynum] = null;
|
||||||
|
|
||||||
// Send release event
|
|
||||||
sendKeyReleased(lastKeyDownChar);
|
|
||||||
|
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
// When focus is lost, clear modifiers.
|
// When focus is lost, clear modifiers.
|
||||||
element.addEventListener("blur", function() {
|
element.addEventListener("blur", function() {
|
||||||
guac_keyboard.modifiers.alt = false;
|
guac_keyboard.modifiers.alt = false;
|
||||||
guac_keyboard.modifiers.ctrl = false;
|
guac_keyboard.modifiers.ctrl = false;
|
||||||
guac_keyboard.modifiers.shift = false;
|
guac_keyboard.modifiers.shift = false;
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user