From: Michael Jumper Date: Mon, 14 May 2012 16:17:15 +0000 (-0700) Subject: Defer handling of keypress via JS event queue. X-Git-Url: http://git.alex.org.uk Defer handling of keypress via JS event queue. --- diff --git a/src/main/resources/keyboard.js b/src/main/resources/keyboard.js index fd81341..08597ff 100644 --- a/src/main/resources/keyboard.js +++ b/src/main/resources/keyboard.js @@ -265,79 +265,74 @@ Guacamole.Keyboard = function(element) { } - var KEYDOWN = 1; - var KEYPRESS = 2; + var keydown_code = null; - var keySymSource = null; + var deferred_keypress = null; + var keydown_keysym = null; + var keypress_keysym = null; - // When key pressed - var keydownCode = null; - element.onkeydown = function(e) { - - // Only intercept if handler set - if (!guac_keyboard.onkeydown) return true; + function fireKeyPress() { - var keynum; - if (window.event) keynum = window.event.keyCode; - else if (e.which) keynum = e.which; + // Prefer keysym from keypress + var keysym = keypress_keysym || keydown_keysym; + var keynum = keydown_code; - // Ctrl/Alt/Shift - if (keynum == 16) guac_keyboard.modifiers.shift = true; - else if (keynum == 17) guac_keyboard.modifiers.ctrl = true; - else if (keynum == 18) guac_keyboard.modifiers.alt = true; + if (keydownChar[keynum] != keysym) { - // If keysym is defined for given key code, key events can come from - // KEYDOWN. - var keysym = getKeySymFromKeyCode(keynum); - if (keysym) - keySymSource = KEYDOWN; + // If this button is already pressed, release first + var lastKeyDownChar = keydownChar[keydown_code]; + if (lastKeyDownChar) + sendKeyReleased(lastKeyDownChar); - // Otherwise, if modifier keys are held down, try to get from keyIdentifier - else if ((guac_keyboard.modifiers.ctrl || guac_keyboard.modifiers.alt) && e.keyIdentifier) { + // Send event + keydownChar[keynum] = keysym; + sendKeyPressed(keysym); - // Get keysym from keyIdentifier - keysym = getKeySymFromKeyIdentifier(guac_keyboard.modifiers.shift, e.keyIdentifier); + // Clear old key repeat, if any. + stopRepeat(); - // Get keysyms and events from KEYDOWN - keySymSource = KEYDOWN; + // Start repeating (if not a modifier key) after a short delay + if (keynum != 16 && keynum != 17 && keynum != 18) + repeatKeyTimeoutId = setTimeout(function() { startRepeat(keysym); }, 500); } - // Otherwise, resort to KEYPRESS - else - keySymSource = KEYPRESS; + // Done with deferred key event + deferred_keypress = null; - keydownCode = keynum; - - // Ignore key if we don't need to use KEYPRESS. - // Send key event here - if (keySymSource == KEYDOWN) { + } - if (keydownChar[keynum] != keysym) { + // When key pressed + element.onkeydown = function(e) { - // Send event - keydownChar[keynum] = keysym; - var returnValue = sendKeyPressed(keysym); + // Only intercept if handler set + if (!guac_keyboard.onkeydown) return true; - // Clear old key repeat, if any. - stopRepeat(); + var keynum; + if (window.event) keynum = window.event.keyCode; + else if (e.which) keynum = e.which; - // Start repeating (if not a modifier key) after a short delay - if (keynum != 16 && keynum != 17 && keynum != 18) - repeatKeyTimeoutId = setTimeout(function() { startRepeat(keysym); }, 500); + // Ctrl/Alt/Shift + if (keynum == 16) guac_keyboard.modifiers.shift = true; + else if (keynum == 17) guac_keyboard.modifiers.ctrl = true; + else if (keynum == 18) guac_keyboard.modifiers.alt = true; - // Use return code provided by handler - return returnValue; + // Try to get keysym from keycode + keydown_keysym = getKeySymFromKeyCode(keynum); - } + // Also try to get get keysym from keyIdentifier + if (e.keyIdentifier) + keydown_keysym = getKeySymFromKeyIdentifier(guac_keyboard.modifiers.shift, e.keyIdentifier); - // Default to canceling event if no keypress is being sent, but - // source of events is keydown. - return false; + // Set keycode which will be associated with any future keypress + keydown_code = keynum; - } + // Defer handling of event until after any other pending + // key events. + if (!deferred_keypress) + deferred_keypress = window.setTimeout(fireKeyPress, 0); - return true; + return false; }; @@ -353,30 +348,13 @@ Guacamole.Keyboard = function(element) { if (window.event) keynum = window.event.keyCode; else if (e.which) keynum = e.which; - var keysym = getKeySymFromCharCode(keynum); - if (keysym && keydownChar[keynum] != keysym) { + keypress_keysym = getKeySymFromCharCode(keynum); - // If this button already pressed, release first - var lastKeyDownChar = keydownChar[keydownCode]; - if (lastKeyDownChar) - sendKeyReleased(lastKeyDownChar); - - keydownChar[keydownCode] = keysym; - - // Clear old key repeat, if any. - stopRepeat(); - - // Send key event - var returnValue = sendKeyPressed(keysym); - - // Start repeating (if not a modifier key) after a short delay - repeatKeyTimeoutId = setTimeout(function() { startRepeat(keysym); }, 500); - - return returnValue; - } + // Defer handling of event until after any other pending + // key events. + if (!deferred_keypress) + deferred_keypress = window.setTimeout(fireKeyPress, 0); - // Default to canceling event if no keypress is being sent, but - // source of events is keypress. return false; };