diff --git a/guacamole/src/main/webapp/client.xhtml b/guacamole/src/main/webapp/client.xhtml
index 8a91c1bf2..68d46580b 100644
--- a/guacamole/src/main/webapp/client.xhtml
+++ b/guacamole/src/main/webapp/client.xhtml
@@ -55,7 +55,6 @@
-
@@ -85,10 +84,10 @@
// Add client to UI
guac.getDisplay().className = "software-cursor";
- GuacamoleUI.display.appendChild(guac.getDisplay());
+ GuacUI.Client.display.appendChild(guac.getDisplay());
// Tie UI to client
- GuacamoleUI.attach(guac);
+ GuacUI.Client.attach(guac);
try {
@@ -127,7 +126,7 @@
}
catch (e) {
- GuacamoleUI.showError(e.message);
+ GuacUI.Client.showError(e.message);
}
}, 0);
diff --git a/guacamole/src/main/webapp/scripts/client-ui.js b/guacamole/src/main/webapp/scripts/client-ui.js
index 7f148566c..db2dc343e 100644
--- a/guacamole/src/main/webapp/scripts/client-ui.js
+++ b/guacamole/src/main/webapp/scripts/client-ui.js
@@ -58,7 +58,6 @@ GuacUI.Client = {
"state" : document.getElementById("statusText"),
"client" : null,
- "sessionState" : new GuacamoleSessionState(),
/* Expected Input Rectangle */
@@ -69,6 +68,380 @@ GuacUI.Client = {
};
+// Tie UI events / behavior to a specific Guacamole client
+GuacUI.Client.attach = function(guac) {
+
+ GuacUI.client = guac;
+
+ var title_prefix = null;
+ var connection_name = "Guacamole";
+
+ var guac_display = guac.getDisplay();
+
+ // Set document title appropriately, based on prefix and connection name
+ function updateTitle() {
+
+ // Use title prefix if present
+ if (title_prefix) {
+
+ document.title = title_prefix;
+
+ // Include connection name, if present
+ if (connection_name)
+ document.title += " " + connection_name;
+
+ }
+
+ // Otherwise, just set to connection name
+ else if (connection_name)
+ document.title = connection_name;
+
+ }
+
+ guac_display.onclick = function(e) {
+ e.preventDefault();
+ return false;
+ };
+
+ // Mouse
+ var mouse = new Guacamole.Mouse(guac_display);
+ var touch = new Guacamole.Mouse.Touchpad(guac_display);
+ touch.onmousedown = touch.onmouseup = touch.onmousemove =
+ mouse.onmousedown = mouse.onmouseup = mouse.onmousemove =
+ function(mouseState) {
+
+ // Determine mouse position within view
+ var mouse_view_x = mouseState.x + guac_display.offsetLeft - window.pageXOffset;
+ var mouse_view_y = mouseState.y + guac_display.offsetTop - window.pageYOffset;
+
+ // Determine viewport dimensioins
+ var view_width = GuacUI.Client.viewport.offsetWidth;
+ var view_height = GuacUI.Client.viewport.offsetHeight;
+
+ // Determine scroll amounts based on mouse position relative to document
+
+ var scroll_amount_x;
+ if (mouse_view_x > view_width)
+ scroll_amount_x = mouse_view_x - view_width;
+ else if (mouse_view_x < 0)
+ scroll_amount_x = mouse_view_x;
+ else
+ scroll_amount_x = 0;
+
+ var scroll_amount_y;
+ if (mouse_view_y > view_height)
+ scroll_amount_y = mouse_view_y - view_height;
+ else if (mouse_view_y < 0)
+ scroll_amount_y = mouse_view_y;
+ else
+ scroll_amount_y = 0;
+
+ // Scroll (if necessary) to keep mouse on screen.
+ window.scrollBy(scroll_amount_x, scroll_amount_y);
+
+ // Scale event by current scale
+ var scaledState = new Guacamole.Mouse.State(
+ mouseState.x / guac.getScale(),
+ mouseState.y / guac.getScale(),
+ mouseState.left,
+ mouseState.middle,
+ mouseState.right,
+ mouseState.up,
+ mouseState.down);
+
+ // Send mouse event
+ guac.sendMouseState(scaledState);
+
+ };
+
+ // 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]) {
+
+ // If in INTERACTIVE mode, switch to OSK
+ if (GuacUI.StateManager.getState() == GuacUI.Client.states.INTERACTIVE)
+ GuacUI.StateManager.setState(GuacUI.Client.states.OSK);
+
+ // If in OSK mode, switch to INTERACTIVE
+ else if (GuacUI.StateManager.getState() == GuacUI.Client.states.OSK)
+ GuacUI.StateManager.setState(GuacUI.Client.states.INTERACTIVE);
+
+ }
+ }
+
+ // 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 updateThumbnail() {
+
+ // Get screenshot
+ var canvas = guac.flatten();
+
+ // Calculate scale of thumbnail (max 320x240, max zoom 100%)
+ var scale = Math.min(
+ 320 / canvas.width,
+ 240 / canvas.height,
+ 1
+ );
+
+ // Create thumbnail canvas
+ var thumbnail = document.createElement("canvas");
+ thumbnail.width = canvas.width*scale;
+ thumbnail.height = canvas.height*scale;
+
+ // Scale screenshot to thumbnail
+ var context = thumbnail.getContext("2d");
+ context.drawImage(canvas,
+ 0, 0, canvas.width, canvas.height,
+ 0, 0, thumbnail.width, thumbnail.height
+ );
+
+ // Save thumbnail to history
+ var id = decodeURIComponent(window.location.search.substring(4));
+ GuacamoleHistory.update(id, thumbnail.toDataURL());
+
+ }
+
+ function updateDisplayScale() {
+
+ // If auto-fit is enabled, scale display
+ if (GuacUI.sessionState.getProperty("auto-fit")) {
+
+ // Calculate scale to fit screen
+ var fit_scale = Math.min(
+ window.innerWidth / guac.getWidth(),
+ window.innerHeight / guac.getHeight()
+ );
+
+ // Scale client
+ if (fit_scale != guac.getScale())
+ guac.scale(fit_scale);
+
+ }
+
+ // Otherwise, scale to 100%
+ else if (guac.getScale() != 1.0)
+ guac.scale(1.0);
+
+ }
+
+ // Handle resize
+ guac.onresize = function(width, height) {
+ updateDisplayScale();
+ }
+
+ var last_status_notification = null;
+ function hideStatus() {
+ if (last_status_notification)
+ last_status_notification.hide();
+ last_status_notification = null;
+ }
+
+ function showStatus(status) {
+ hideStatus();
+
+ last_status_notification = new GuacUI.Client.ModalStatus(status);
+ last_status_notification.show();
+ }
+
+ function showError(status) {
+ hideStatus();
+
+ last_status_notification = new GuacUI.Client.ModalStatus(status);
+ last_status_notification.show();
+ }
+
+ // Handle client state change
+ guac.onstatechange = function(clientState) {
+
+ switch (clientState) {
+
+ // Idle
+ case 0:
+ showStatus("Idle.");
+ title_prefix = "[Idle]";
+ break;
+
+ // Connecting
+ case 1:
+ showStatus("Connecting...");
+ title_prefix = "[Connecting...]";
+ break;
+
+ // Connected + waiting
+ case 2:
+ showStatus("Connected, waiting for first update...");
+ title_prefix = "[Waiting...]";
+ break;
+
+ // Connected
+ case 3:
+
+ hideStatus();
+ title_prefix = null;
+
+ // Update clipboard with current data
+ if (GuacUI.sessionState.getProperty("clipboard"))
+ guac.setClipboard(GuacUI.sessionState.getProperty("clipboard"));
+
+ // Regularly update screenshot
+ window.setInterval(updateThumbnail, 1000);
+
+ break;
+
+ // Disconnecting
+ case 4:
+ showStatus("Disconnecting...");
+ title_prefix = "[Disconnecting...]";
+ break;
+
+ // Disconnected
+ case 5:
+ showStatus("Disconnected.");
+ title_prefix = "[Disconnected]";
+ break;
+
+ // Unknown status code
+ default:
+ showStatus("[UNKNOWN STATUS]");
+
+ }
+
+ updateTitle();
+ };
+
+ // Name instruction handler
+ guac.onname = function(name) {
+ connection_name = name;
+ updateTitle();
+ };
+
+ // Error handler
+ guac.onerror = function(error) {
+
+ // Disconnect, if connected
+ guac.disconnect();
+
+ // Display error message
+ showError(error);
+
+ };
+
+ // Disconnect and update thumbnail on close
+ window.onunload = function() {
+
+ updateThumbnail();
+ guac.disconnect();
+
+ };
+
+ // Send size events on resize
+ window.onresize = function() {
+
+ guac.sendSize(window.innerWidth, window.innerHeight);
+ updateDisplayScale();
+
+ };
+
+ // Server copy handler
+ guac.onclipboard = function(data) {
+ GuacUI.sessionState.setProperty("clipboard", data);
+ };
+
+ GuacUI.sessionState.onchange = function(old_state, new_state, name) {
+ if (name == "clipboard")
+ guac.setClipboard(new_state[name]);
+ else if (name == "auto-fit")
+ updateDisplayScale();
+
+ };
+
+ var long_press_start_x = 0;
+ var long_press_start_y = 0;
+ var longPressTimeout = null;
+
+ GuacUI.Client.startLongPressDetect = function() {
+
+ if (!longPressTimeout) {
+
+ longPressTimeout = window.setTimeout(function() {
+ longPressTimeout = null;
+ if (GuacUI.Client.client.getScale() != 1.0)
+ GuacUI.StateManager.setState(GuacUI.Client.states.MAGNIFIER);
+ else
+ GuacUI.StateManager.setState(GuacUI.Client.states.PAN);
+ }, GuacUI.Client.LONG_PRESS_DETECT_TIMEOUT);
+
+ }
+ };
+
+ GuacUI.Client.stopLongPressDetect = function() {
+ window.clearTimeout(longPressTimeout);
+ longPressTimeout = null;
+ };
+
+ // Detect long-press at bottom of screen
+ GuacUI.Client.display.addEventListener('touchstart', function(e) {
+
+ // Record touch location
+ if (e.touches.length == 1) {
+ var touch = e.touches[0];
+ long_press_start_x = touch.screenX;
+ long_press_start_y = touch.screenY;
+ }
+
+ // Start detection
+ GuacUI.Client.startLongPressDetect();
+
+ }, true);
+
+ // Stop detection if touch moves significantly
+ GuacUI.Client.display.addEventListener('touchmove', function(e) {
+
+ // If touch distance from start exceeds threshold, cancel long press
+ var touch = e.touches[0];
+ if (Math.abs(touch.screenX - long_press_start_x) >= GuacUI.Client.LONG_PRESS_MOVEMENT_THRESHOLD
+ || Math.abs(touch.screenY - long_press_start_y) >= GuacUI.Client.LONG_PRESS_MOVEMENT_THRESHOLD)
+ GuacUI.Client.stopLongPressDetect();
+
+ }, true);
+
+ // Stop detection if press stops
+ GuacUI.Client.display.addEventListener('touchend', GuacUI.Client.stopLongPressDetect, true);
+
+};
+
/**
* Component which displays a magnified (100% zoomed) client display.
*
@@ -135,9 +508,9 @@ GuacUI.Client.Magnifier = function() {
// Update contents relative to new position
var clip_x = x
- / (window.innerWidth - width) * (GuacamoleUI.client.getWidth() - width);
+ / (window.innerWidth - width) * (GuacUI.Client.client.getWidth() - width);
var clip_y = y
- / (window.innerHeight - height) * (GuacamoleUI.client.getHeight() - height);
+ / (window.innerHeight - height) * (GuacUI.Client.client.getHeight() - height);
magnifier_display.style.WebkitTransform =
magnifier_display.style.MozTransform =
@@ -161,9 +534,9 @@ GuacUI.Client.Magnifier = function() {
this.show = function() {
// Copy displayed image
- magnifier_display.width = GuacamoleUI.client.getWidth();
- magnifier_display.height = GuacamoleUI.client.getHeight();
- magnifier_context.drawImage(GuacamoleUI.client.flatten(), 0, 0);
+ magnifier_display.width = GuacUI.Client.client.getWidth();
+ magnifier_display.height = GuacUI.Client.client.getHeight();
+ magnifier_context.drawImage(GuacUI.Client.client.flatten(), 0, 0);
// Show magnifier container
document.body.appendChild(magnifier_background);
@@ -221,12 +594,12 @@ GuacUI.Client.ZoomedDisplay = function() {
var old_scale = null;
this.show = function() {
- old_scale = GuacamoleUI.client.getScale();
- GuacamoleUI.client.scale(1.0);
+ old_scale = GuacUI.Client.client.getScale();
+ GuacUI.Client.client.scale(1.0);
};
this.hide = function() {
- GuacamoleUI.client.scale(old_scale);
+ GuacUI.Client.client.scale(old_scale);
};
};
@@ -394,11 +767,11 @@ GuacUI.Client.OnScreenKeyboard = function() {
}
keyboard.onkeydown = function(keysym) {
- GuacamoleUI.client.sendKeyEvent(1, keysym);
+ GuacUI.Client.client.sendKeyEvent(1, keysym);
};
keyboard.onkeyup = function(keysym) {
- GuacamoleUI.client.sendKeyEvent(0, keysym);
+ GuacUI.Client.client.sendKeyEvent(0, keysym);
};
diff --git a/guacamole/src/main/webapp/scripts/guac-ui.js b/guacamole/src/main/webapp/scripts/guac-ui.js
index 58c0d6741..f543a86ee 100644
--- a/guacamole/src/main/webapp/scripts/guac-ui.js
+++ b/guacamole/src/main/webapp/scripts/guac-ui.js
@@ -22,6 +22,11 @@
*/
var GuacUI = GuacUI || {};
+/**
+ * Current session state, including settings.
+ */
+GuacUI.sessionState = new GuacamoleSessionState();
+
/**
* Creates a new element having the given tagname and CSS class.
*/
@@ -111,7 +116,7 @@ GuacUI.Audio = new (function() {
this.supported = [];
// If sound disabled, we're done now.
- if (GuacamoleUI.sessionState.getProperty("disable-sound"))
+ if (GuacUI.sessionState.getProperty("disable-sound"))
return;
// Build array of supported audio formats
diff --git a/guacamole/src/main/webapp/scripts/interface.js b/guacamole/src/main/webapp/scripts/interface.js
deleted file mode 100644
index e12c743f3..000000000
--- a/guacamole/src/main/webapp/scripts/interface.js
+++ /dev/null
@@ -1,410 +0,0 @@
-
-/*
- * Guacamole - Clientless Remote Desktop
- * Copyright (C) 2010 Michael Jumper
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-// UI Definition
-var GuacamoleUI = {
-
- /* Constants */
-
- "LONG_PRESS_DETECT_TIMEOUT" : 800, /* milliseconds */
- "LONG_PRESS_MOVEMENT_THRESHOLD" : 10, /* pixels */
-
- /* UI Components */
-
- "viewport" : document.getElementById("viewportClone"),
- "display" : document.getElementById("display"),
-
- "client" : null,
- "sessionState" : new GuacamoleSessionState()
-
-};
-
-// Tie UI events / behavior to a specific Guacamole client
-GuacamoleUI.attach = function(guac) {
-
- GuacamoleUI.client = guac;
-
- var title_prefix = null;
- var connection_name = "Guacamole";
-
- var guac_display = guac.getDisplay();
-
- // Set document title appropriately, based on prefix and connection name
- function updateTitle() {
-
- // Use title prefix if present
- if (title_prefix) {
-
- document.title = title_prefix;
-
- // Include connection name, if present
- if (connection_name)
- document.title += " " + connection_name;
-
- }
-
- // Otherwise, just set to connection name
- else if (connection_name)
- document.title = connection_name;
-
- }
-
- guac_display.onclick = function(e) {
- e.preventDefault();
- return false;
- };
-
- // Mouse
- var mouse = new Guacamole.Mouse(guac_display);
- var touch = new Guacamole.Mouse.Touchpad(guac_display);
- touch.onmousedown = touch.onmouseup = touch.onmousemove =
- mouse.onmousedown = mouse.onmouseup = mouse.onmousemove =
- function(mouseState) {
-
- // Determine mouse position within view
- var mouse_view_x = mouseState.x + guac_display.offsetLeft - window.pageXOffset;
- var mouse_view_y = mouseState.y + guac_display.offsetTop - window.pageYOffset;
-
- // Determine viewport dimensioins
- var view_width = GuacamoleUI.viewport.offsetWidth;
- var view_height = GuacamoleUI.viewport.offsetHeight;
-
- // Determine scroll amounts based on mouse position relative to document
-
- var scroll_amount_x;
- if (mouse_view_x > view_width)
- scroll_amount_x = mouse_view_x - view_width;
- else if (mouse_view_x < 0)
- scroll_amount_x = mouse_view_x;
- else
- scroll_amount_x = 0;
-
- var scroll_amount_y;
- if (mouse_view_y > view_height)
- scroll_amount_y = mouse_view_y - view_height;
- else if (mouse_view_y < 0)
- scroll_amount_y = mouse_view_y;
- else
- scroll_amount_y = 0;
-
- // Scroll (if necessary) to keep mouse on screen.
- window.scrollBy(scroll_amount_x, scroll_amount_y);
-
- // Scale event by current scale
- var scaledState = new Guacamole.Mouse.State(
- mouseState.x / guac.getScale(),
- mouseState.y / guac.getScale(),
- mouseState.left,
- mouseState.middle,
- mouseState.right,
- mouseState.up,
- mouseState.down);
-
- // Send mouse event
- guac.sendMouseState(scaledState);
-
- };
-
- // 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]) {
-
- // If in INTERACTIVE mode, switch to OSK
- if (GuacUI.StateManager.getState() == GuacUI.Client.states.INTERACTIVE)
- GuacUI.StateManager.setState(GuacUI.Client.states.OSK);
-
- // If in OSK mode, switch to INTERACTIVE
- else if (GuacUI.StateManager.getState() == GuacUI.Client.states.OSK)
- GuacUI.StateManager.setState(GuacUI.Client.states.INTERACTIVE);
-
- }
- }
-
- // 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 updateThumbnail() {
-
- // Get screenshot
- var canvas = guac.flatten();
-
- // Calculate scale of thumbnail (max 320x240, max zoom 100%)
- var scale = Math.min(
- 320 / canvas.width,
- 240 / canvas.height,
- 1
- );
-
- // Create thumbnail canvas
- var thumbnail = document.createElement("canvas");
- thumbnail.width = canvas.width*scale;
- thumbnail.height = canvas.height*scale;
-
- // Scale screenshot to thumbnail
- var context = thumbnail.getContext("2d");
- context.drawImage(canvas,
- 0, 0, canvas.width, canvas.height,
- 0, 0, thumbnail.width, thumbnail.height
- );
-
- // Save thumbnail to history
- var id = decodeURIComponent(window.location.search.substring(4));
- GuacamoleHistory.update(id, thumbnail.toDataURL());
-
- }
-
- function updateDisplayScale() {
-
- // If auto-fit is enabled, scale display
- if (GuacamoleUI.sessionState.getProperty("auto-fit")) {
-
- // Calculate scale to fit screen
- var fit_scale = Math.min(
- window.innerWidth / guac.getWidth(),
- window.innerHeight / guac.getHeight()
- );
-
- // Scale client
- if (fit_scale != guac.getScale())
- guac.scale(fit_scale);
-
- }
-
- // Otherwise, scale to 100%
- else if (guac.getScale() != 1.0)
- guac.scale(1.0);
-
- }
-
- // Handle resize
- guac.onresize = function(width, height) {
- updateDisplayScale();
- }
-
- var last_status_notification = null;
- function hideStatus() {
- if (last_status_notification)
- last_status_notification.hide();
- last_status_notification = null;
- }
-
- function showStatus(status) {
- hideStatus();
-
- last_status_notification = new GuacUI.Client.ModalStatus(status);
- last_status_notification.show();
- }
-
- function showError(status) {
- hideStatus();
-
- last_status_notification = new GuacUI.Client.ModalStatus(status);
- last_status_notification.show();
- }
-
- // Handle client state change
- guac.onstatechange = function(clientState) {
-
- switch (clientState) {
-
- // Idle
- case 0:
- showStatus("Idle.");
- title_prefix = "[Idle]";
- break;
-
- // Connecting
- case 1:
- showStatus("Connecting...");
- title_prefix = "[Connecting...]";
- break;
-
- // Connected + waiting
- case 2:
- showStatus("Connected, waiting for first update...");
- title_prefix = "[Waiting...]";
- break;
-
- // Connected
- case 3:
-
- hideStatus();
- title_prefix = null;
-
- // Update clipboard with current data
- if (GuacamoleUI.sessionState.getProperty("clipboard"))
- guac.setClipboard(GuacamoleUI.sessionState.getProperty("clipboard"));
-
- // Regularly update screenshot
- window.setInterval(updateThumbnail, 1000);
-
- break;
-
- // Disconnecting
- case 4:
- showStatus("Disconnecting...");
- title_prefix = "[Disconnecting...]";
- break;
-
- // Disconnected
- case 5:
- showStatus("Disconnected.");
- title_prefix = "[Disconnected]";
- break;
-
- // Unknown status code
- default:
- showStatus("[UNKNOWN STATUS]");
-
- }
-
- updateTitle();
- };
-
- // Name instruction handler
- guac.onname = function(name) {
- connection_name = name;
- updateTitle();
- };
-
- // Error handler
- guac.onerror = function(error) {
-
- // Disconnect, if connected
- guac.disconnect();
-
- // Display error message
- showError(error);
-
- };
-
- // Disconnect and update thumbnail on close
- window.onunload = function() {
-
- updateThumbnail();
- guac.disconnect();
-
- };
-
- // Send size events on resize
- window.onresize = function() {
-
- guac.sendSize(window.innerWidth, window.innerHeight);
- updateDisplayScale();
-
- };
-
- // Server copy handler
- guac.onclipboard = function(data) {
- GuacamoleUI.sessionState.setProperty("clipboard", data);
- };
-
- GuacamoleUI.sessionState.onchange = function(old_state, new_state, name) {
- if (name == "clipboard")
- guac.setClipboard(new_state[name]);
- else if (name == "auto-fit")
- updateDisplayScale();
-
- };
-
- var long_press_start_x = 0;
- var long_press_start_y = 0;
- var longPressTimeout = null;
-
- GuacamoleUI.startLongPressDetect = function() {
-
- if (!longPressTimeout) {
-
- longPressTimeout = window.setTimeout(function() {
- longPressTimeout = null;
- if (GuacamoleUI.client.getScale() != 1.0)
- GuacUI.StateManager.setState(GuacUI.Client.states.MAGNIFIER);
- else
- GuacUI.StateManager.setState(GuacUI.Client.states.PAN);
- }, GuacamoleUI.LONG_PRESS_DETECT_TIMEOUT);
-
- }
- };
-
- GuacamoleUI.stopLongPressDetect = function() {
- window.clearTimeout(longPressTimeout);
- longPressTimeout = null;
- };
-
- // Detect long-press at bottom of screen
- GuacamoleUI.display.addEventListener('touchstart', function(e) {
-
- // Record touch location
- if (e.touches.length == 1) {
- var touch = e.touches[0];
- long_press_start_x = touch.screenX;
- long_press_start_y = touch.screenY;
- }
-
- // Start detection
- GuacamoleUI.startLongPressDetect();
-
- }, true);
-
- // Stop detection if touch moves significantly
- GuacamoleUI.display.addEventListener('touchmove', function(e) {
-
- // If touch distance from start exceeds threshold, cancel long press
- var touch = e.touches[0];
- if (Math.abs(touch.screenX - long_press_start_x) >= GuacamoleUI.LONG_PRESS_MOVEMENT_THRESHOLD
- || Math.abs(touch.screenY - long_press_start_y) >= GuacamoleUI.LONG_PRESS_MOVEMENT_THRESHOLD)
- GuacamoleUI.stopLongPressDetect();
-
- }, true);
-
- // Stop detection if press stops
- GuacamoleUI.display.addEventListener('touchend', GuacamoleUI.stopLongPressDetect, true);
-
-};