diff --git a/guacamole/src/main/webapp/client.xhtml b/guacamole/src/main/webapp/client.xhtml index d275ad882..cade3dde5 100644 --- a/guacamole/src/main/webapp/client.xhtml +++ b/guacamole/src/main/webapp/client.xhtml @@ -50,7 +50,7 @@ -
+
diff --git a/guacamole/src/main/webapp/scripts/client-ui.js b/guacamole/src/main/webapp/scripts/client-ui.js index 6cae6bb68..81212aee3 100644 --- a/guacamole/src/main/webapp/scripts/client-ui.js +++ b/guacamole/src/main/webapp/scripts/client-ui.js @@ -212,10 +212,6 @@ GuacUI.Client = { "container" : document.getElementById("text-input"), "sent" : document.getElementById("sent-history"), "target" : document.getElementById("target"), - "ctrl" : document.getElementById("text-ctrl"), - "alt" : document.getElementById("text-alt"), - "esc" : document.getElementById("text-esc"), - "tab" : document.getElementById("text-tab"), "enabled" : false }, @@ -1378,6 +1374,8 @@ GuacUI.Client.attach = function(guac) { // One-time UI initialization (function() { + var i; + /** * Keys which should be allowed through to the client when in text input * mode, providing corresponding key events are received. Keys in this @@ -1943,12 +1941,15 @@ GuacUI.Client.attach = function(guac) { if (codepoint === 10) { send_keysym(0xFF0D); + release_sticky_keys(); return; } var keysym = keysym_from_codepoint(codepoint); - if (keysym) + if (keysym) { send_keysym(keysym); + release_sticky_keys(); + } } @@ -1981,6 +1982,90 @@ GuacUI.Client.attach = function(guac) { } + /** + * Set of all active key elements, indexed by keysym. + * + * @private + * @type Object. + */ + var active_sticky_keys = {}; + + /** + * Presses/releases the keysym defined by the "data-keysym" attribute on + * the given element whenever the element is pressed. The "data-sticky" + * attribute, if present and set to "true", causes the key to remain + * pressed until text is sent. + * + * @param {Element} key The element which will control its associated key. + */ + function apply_key_behavior(key) { + + function __update_key(e) { + + var guac = GuacUI.Client.attachedClient; + if (!guac) + return; + + e.preventDefault(); + e.stopPropagation(); + + // Pull properties of key + var keysym = parseInt(key.getAttribute("data-keysym")); + var sticky = (key.getAttribute("data-sticky") === "true"); + var pressed = (key.className.indexOf("pressed") !== -1); + + // If sticky, toggle pressed state + if (sticky) { + if (pressed) { + GuacUI.removeClass(key, "pressed"); + guac.sendKeyEvent(0, keysym); + delete active_sticky_keys[keysym]; + } + else { + GuacUI.addClass(key, "pressed"); + guac.sendKeyEvent(1, keysym); + active_sticky_keys[keysym] = key; + } + } + + // For all non-sticky keys, press and release key immediately + else + send_keysym(keysym); + + } + + // Press/release key when clicked + key.addEventListener("click", __update_key, false); + key.addEventListener("touchstart", __update_key, false); + + } + + /** + * Releases all currently-held sticky keys within the text input UI. + */ + function release_sticky_keys() { + + var guac = GuacUI.Client.attachedClient; + if (!guac) + return; + + // Release all active sticky keys + for (var keysym in active_sticky_keys) { + var key = active_sticky_keys[keysym]; + GuacUI.removeClass(key, "pressed"); + guac.sendKeyEvent(0, keysym); + } + + // Reset set of active keys + active_sticky_keys = {}; + + } + + // Apply key behavior to all keys within the text input UI + var keys = GuacUI.Client.text_input.container.getElementsByClassName("key"); + for (i=0; i