diff --git a/guacamole/src/main/webapp/client.xhtml b/guacamole/src/main/webapp/client.xhtml
index 0f817a0e4..f083b5075 100644
--- a/guacamole/src/main/webapp/client.xhtml
+++ b/guacamole/src/main/webapp/client.xhtml
@@ -36,6 +36,9 @@
+
+
+
diff --git a/guacamole/src/main/webapp/scripts/interface.js b/guacamole/src/main/webapp/scripts/interface.js
index 36f5f6b48..7f65deb37 100644
--- a/guacamole/src/main/webapp/scripts/interface.js
+++ b/guacamole/src/main/webapp/scripts/interface.js
@@ -20,23 +20,30 @@
// UI Definition
var GuacamoleUI = {
- /* UI Elements */
+ /* Detection Constants */
+
+ "LONG_PRESS_DETECT_TIMEOUT" : 800, /* milliseconds */
+ "LONG_PRESS_MOVEMENT_THRESHOLD" : 10, /* pixels */
+ "KEYBOARD_AUTO_RESIZE_INTERVAL" : 30, /* milliseconds */
- "viewport" : document.getElementById("viewportClone"),
- "display" : document.getElementById("display"),
- "logo" : document.getElementById("status-logo"),
+ /* UI Components */
+
+ "viewport" : document.getElementById("viewportClone"),
+ "display" : document.getElementById("display"),
+ "logo" : document.getElementById("status-logo"),
"buttons": {
- "reconnect" : document.getElementById("reconnect")
+ "reconnect" : document.getElementById("reconnect")
},
"containers": {
- "state" : document.getElementById("statusDialog")
+ "state" : document.getElementById("statusDialog"),
+ "keyboard" : document.getElementById("keyboardContainer")
},
- "state" : document.getElementById("statusText"),
- "client" : null,
- "sessionState" : new GuacamoleSessionState()
+ "state" : document.getElementById("statusText"),
+ "client" : null,
+ "sessionState" : new GuacamoleSessionState()
};
@@ -52,6 +59,56 @@ GuacamoleUI.supportedAudio = [];
*/
GuacamoleUI.supportedVideo = [];
+// On-screen keyboard
+GuacamoleUI.keyboard = new Guacamole.OnScreenKeyboard("layouts/en-us-qwerty.xml");
+GuacamoleUI.containers.keyboard.appendChild(GuacamoleUI.keyboard.getElement());
+
+GuacamoleUI.lastKeyboardWidth = 0;
+
+// Function for automatically updating keyboard size
+GuacamoleUI.updateKeyboardSize = function() {
+ var currentSize = GuacamoleUI.keyboard.getElement().offsetWidth;
+ if (GuacamoleUI.lastKeyboardWidth != currentSize) {
+ GuacamoleUI.keyboard.resize(currentSize);
+ GuacamoleUI.lastKeyboardWidth = currentSize;
+ }
+};
+
+GuacamoleUI.keyboardResizeInterval = null;
+
+// Show/Hide keyboard
+GuacamoleUI.toggleKeyboard = function() {
+
+ // If Guac OSK shown, hide it.
+ var displayed = GuacamoleUI.containers.keyboard.style.display;
+ if (displayed == "block") {
+
+ // Hide keyboard
+ GuacamoleUI.containers.keyboard.style.display = "none";
+
+ // Stop automatic periodic update
+ window.clearInterval(GuacamoleUI.keyboardResizeInterval);
+
+ }
+
+ // Otherwise, show it
+ else {
+
+ // Show keyboard
+ GuacamoleUI.containers.keyboard.style.display = "block";
+
+ // Start periodic update of keyboard size
+ GuacamoleUI.keyboardResizeInterval = window.setInterval(
+ GuacamoleUI.updateKeyboardSize,
+ GuacamoleUI.KEYBOARD_AUTO_RESIZE_INTERVAL);
+
+ // Update keyboard size initially
+ GuacamoleUI.updateKeyboardSize();
+
+ }
+
+};
+
// Constant UI initialization and behavior
(function() {
@@ -302,28 +359,45 @@ GuacamoleUI.attach = function(guac) {
// Keyboard
var keyboard = new Guacamole.Keyboard(document);
+ var show_keyboard_gesture_possible = true;
+
+ keyboard.onkeydown = function (keysym) {
+ guac.sendKeyEvent(1, keysym);
+
+ // If key is NOT one of the expected keys, gesture not possible
+ if (keysym != 0xFFE3 && keysym != 0xFFE9 && keysym != 0xFFE1)
+ show_keyboard_gesture_possible = false;
+
+ };
+
+ keyboard.onkeyup = function (keysym) {
+ guac.sendKeyEvent(0, keysym);
+
+ // If lifting up on shift, toggle keyboard if rest of gesture
+ // conditions satisfied
+ if (show_keyboard_gesture_possible && keysym == 0xFFE1) {
+ if (keyboard.pressed[0xFFE3] && keyboard.pressed[0xFFE9])
+ GuacamoleUI.toggleKeyboard();
+ }
+
+ // Detect if no keys are pressed
+ var reset_gesture = true;
+ for (var pressed in keyboard.pressed) {
+ reset_gesture = false;
+ break;
+ }
+
+ // Reset gesture state if possible
+ if (reset_gesture)
+ show_keyboard_gesture_possible = true;
+
+ };
+
function isTypableCharacter(keysym) {
return (keysym & 0xFFFF00) != 0xFF00;
}
- function disableKeyboard() {
- keyboard.onkeydown = null;
- keyboard.onkeyup = null;
- }
-
- function enableKeyboard() {
-
- keyboard.onkeydown = function (keysym) {
- guac.sendKeyEvent(1, keysym);
- };
-
- keyboard.onkeyup = function (keysym) {
- guac.sendKeyEvent(0, keysym);
- };
-
- }
-
function updateThumbnail() {
// Get screenshot
@@ -354,9 +428,6 @@ GuacamoleUI.attach = function(guac) {
}
- // Enable keyboard by default
- enableKeyboard();
-
function updateDisplayScale() {
// If auto-fit is enabled, scale display
@@ -474,6 +545,7 @@ GuacamoleUI.attach = function(guac) {
guac.sendSize(window.innerWidth, window.innerHeight);
updateDisplayScale();
+ GuacamoleUI.updateKeyboardSize();
};