diff --git a/install.sh b/install.sh
index 91f099d2ad..02349dcabb 100755
--- a/install.sh
+++ b/install.sh
@@ -2612,7 +2612,6 @@ SUNSTONE_PUBLIC_IMAGES_FILES="src/sunstone/public/images/ajax-loader.gif \
src/sunstone/public/images/opennebula-5.0.png \
src/sunstone/public/images/opennebula-sunstone-v4.0.png \
src/sunstone/public/images/opennebula-sunstone-v4.14-small.png \
- src/sunstone/public/images/one_small_logo.png \
src/sunstone/public/images/panel.png \
src/sunstone/public/images/panel_short.png \
src/sunstone/public/images/pbar.gif \
diff --git a/src/sunstone/public/app/console/guacamole.js b/src/sunstone/public/app/console/guacamole.js
index 84e21093bb..4940c820c7 100644
--- a/src/sunstone/public/app/console/guacamole.js
+++ b/src/sunstone/public/app/console/guacamole.js
@@ -15,24 +15,57 @@
/* -------------------------------------------------------------------------- */
define(function(require) {
+ require("jquery-ui");
+
var GuacController = require('utils/guacamole/controller');
-
- try {
- var endpoint = new URL(window.location.href);
- var encoded_socket = endpoint.searchParams.get("socket");
- var socket_string = atob(encoded_socket);
-
- var url = new URL(socket_string);
- var params = url.searchParams;
- var token = params.get("token");
- var info = params.get("info");
- var controller = new GuacController();
- controller.setInformation(info);
- controller.setConnection(token);
- } catch (error) {
- console.log(error);
- $('#guacamole-state').empty().text('Failed');
+ var controller = new GuacController();
+ var reconnectButton = document.getElementById('buttons__reconnect');
+
+ var endpoint = new URL(window.location.href);
+ var encoded_socket = endpoint.searchParams.get("socket");
+ var socket_string = atob(encoded_socket);
+
+ var url = new URL(socket_string);
+ var params = url.searchParams;
+ var token = params.get("token");
+ var connectionType = params.get("type");
+ var info = params.get("info");
+
+ controller.setInformation(info);
+
+ // Trigger first connect
+ document.readyState !== 'loading'
+ ? connect()
+ : document.addEventListener('DOMContentLoaded', connect);
+
+ window.onunload = disconnect;
+
+
+ reconnectButton.onclick = function reconnect() {
+ disconnect();
+
+ document.querySelector('.toolbar__state h5').innerHTML = "";
+ document.querySelector('.toolbar__state .spinner').style.display = "block";
+
+ setTimeout(connect, 500)
+ }
+
+ function connect() {
+ try {
+ controller && controller.setConnection(token, connectionType);
+ } catch (error) {
+ controller && controller.disconnect();
+ document.querySelector('.toolbar__state h5').innerHTML = "Failed";
+ }
+ }
+
+ function disconnect() {
+ try {
+ controller && controller.disconnect();
+ } catch (error) {
+ document.querySelector('.toolbar__state h5').innerHTML = "Failed";
+ }
}
});
diff --git a/src/sunstone/public/app/sunstone-config.js b/src/sunstone/public/app/sunstone-config.js
index 7cf57f3b53..4fc7935546 100644
--- a/src/sunstone/public/app/sunstone-config.js
+++ b/src/sunstone/public/app/sunstone-config.js
@@ -172,14 +172,14 @@ define(function(require) {
}
}
},
- "logo": (_config["view"]["provision_logo"] || "images/one_small_logo.png"),
+ "logo": (_config["view"]["provision_logo"] || "images/opennebula-5.0.png"),
},
"tableOrder": _config["user_config"]["table_order"],
"vncProxyPort": _config["system_config"]["vnc_client_port"] || _config["system_config"]["vnc_proxy_port"].split(":")[1] || _config["system_config"]["vnc_proxy_port"],
"vncWSS": _config["user_config"]["vnc_wss"],
"requestVNCPassword": _config["system_config"]["vnc_request_password"],
- "logo": (_config["view"]["small_logo"] || "images/one_small_logo.png"),
+ "logo": (_config["view"]["small_logo"] || "images/opennebula-5.0.png"),
"link_logo": (_config["view"]["link_logo"] || false),
"text_link_logo": (_config["view"]["text_link_logo"] || false),
"vmLogos": (_config["vm_logos"]),
diff --git a/src/sunstone/public/app/tabs/vms-tab/actions.js b/src/sunstone/public/app/tabs/vms-tab/actions.js
index 37411c1e30..d430d1f421 100644
--- a/src/sunstone/public/app/tabs/vms-tab/actions.js
+++ b/src/sunstone/public/app/tabs/vms-tab/actions.js
@@ -371,10 +371,13 @@ define(function(require) {
"VM.startguac_action" : {
type: "single",
call: OpenNebulaVM.guac,
- callback: function(_, response) {
- var link = RemoteActions.getLink(response, {
+ callback: function(request, response) {
+ var protocolConnection = request.request.data[0].extra_param;
+
+ var link = getLink(response, {
connnection_type: 'guac',
- extra_path: '/fireedge/guacamole'
+ extra_path: '/fireedge/guacamole',
+ extra_params: ['type=' + protocolConnection]
});
// Open in a new tab the noVNC connection
window.open(link);
diff --git a/src/sunstone/public/app/utils/guacamole/controller.js b/src/sunstone/public/app/utils/guacamole/controller.js
index 53b4d008c7..39e8148749 100644
--- a/src/sunstone/public/app/utils/guacamole/controller.js
+++ b/src/sunstone/public/app/utils/guacamole/controller.js
@@ -16,53 +16,45 @@
define(function(require) {
- require("guacamole-common-js")
- var ManagedClient = require("utils/guacamole/types/client");
- var ManagedClientState = require("utils/guacamole/types/client-state");
- var Utils = require("utils/guacamole/utils");
- var UtilsConnection = require("utils/info-connection/utils");
+ require('guacamole-common-js')
+ var ConnectionTypes = require('utils/guacamole/types/connection-types');
+ var ManagedClient = require('utils/guacamole/types/client');
+ var ManagedClientState = require('utils/guacamole/types/client-state');
+ var Utils = require('utils/guacamole/utils');
+ var UtilsConnection = require('utils/info-connection/utils');
- var GuacButtons = require("utils/guacamole/directives/guacButtons");
- var GuacClipboard = require("utils/guacamole/directives/guacClipboard");
- var GuacKeyboard = require("utils/guacamole/directives/guacKeyboard");
- var GuacMouse = require("utils/guacamole/directives/guacMouse");
- var GuacOsk = require("utils/guacamole/directives/guacOsk");
+ var GuacButtons = require('utils/guacamole/directives/guacButtons');
+ var GuacClipboard = require('utils/guacamole/directives/guacClipboard');
+ var GuacKeyboard = require('utils/guacamole/directives/guacKeyboard');
+ var GuacMouse = require('utils/guacamole/directives/guacMouse');
+ var GuacOsk = require('utils/guacamole/directives/guacOsk');
function GuacController() {
var $guac = {};
var $scope = {};
var $elements = {
- main: document.getElementById('guacamole-main'),
- displayContainer: document.getElementById('guacamole-display'),
+ main: document.querySelector('.wrapper__display'),
+ displayContainer: document.getElementById('display'),
osk: document.getElementById('osk'),
- closeOskButton: document.getElementById('osk-close'),
+ closeOskButton: document.querySelector('.osk__header__buttons .close'),
/* Buttons */
- sendCtrlAltDelButton: document.getElementById('sendCtrlAltDelButton'),
- mouseButton: document.getElementById('mouseButton'),
- screenshotButton: document.getElementById('takeScreenshot'),
- oskButton: document.getElementById('oskButton'),
+ sendCtrlAltDelButton: document.getElementById('buttons__sendctrlaltdel'),
+ mouseButton: document.getElementById('buttons__mouse'),
+ screenshotButton: document.getElementById('buttons__screenshot'),
+ oskButton: document.getElementById('buttons__osk'),
+ fullscreenButton: document.getElementById('buttons__fullscreen'),
};
- var throttleResizeFunction = Utils.throttle(containerResized, 250);
- window.addEventListener('resize', throttleResizeFunction);
+ this.disconnect = disconnect;
- this.disconnect = function() {
- if ($guac.client) $guac.client.disconnect();
- if ($guac.keyboard) GuacKeyboard.destroy();
- if ($guac.mouse) GuacMouse.destroy();
- if ($guac.osk) GuacOsk.destroy();
+ this.setConnection = function(token, connectionType) {
+ $scope.connectionType = String(connectionType).toUpperCase();
- GuacButtons.destroy();
- GuacClipboard.destroy();
- window.removeEventListener('resize', throttleResizeFunction);
- $('#guacamole-state').text('');
+ $scope.connectionType === ConnectionTypes.SSH
+ ? $elements.displayContainer.classList.add('ssh')
+ : $elements.displayContainer.classList.remove('ssh');
- $guac = {};
- $scope = {};
- }
-
- this.setConnection = function(token) {
var managedClient = ManagedClient.getInstance(token, undefined, $elements.displayContainer)
new GuacKeyboard($guac, $scope, $elements);
@@ -70,14 +62,16 @@ define(function(require) {
new GuacOsk($guac, $scope, $elements);
new GuacButtons($guac, $scope, $elements);
new GuacClipboard($guac, $scope, $elements);
+ window.addEventListener('resize', containerResized);
+ document.addEventListener('fullscreenchange', containerResized)
// Remove any existing display
- $elements.displayContainer.innerHTML = "";
+ $elements.displayContainer.innerHTML = '';
// Only proceed if a client is given
if (!managedClient) return;
$scope.client = managedClient;
-
+
// Get Guacamole client instance
$guac.client = managedClient.client;
@@ -108,36 +102,40 @@ define(function(require) {
}
}).bind(this));
- Utils.observe($scope, 'disableCursor', (function(disabled) {
- $elements.mouseButton.disabled = !!disabled;
- }).bind(this));
-
Utils.observe($scope.client.clientState, 'connectionState', (function(connectionState) {
var isLoading = connectionState === ManagedClientState.ConnectionState.WAITING;
-
- $('#guacamole-loading')[isLoading ? 'fadeIn' : 'fadeOut']('fast');
- $('#guacamole-state').text(connectionState).animate();
- }).bind(this));
+ var isConnected = connectionState === ManagedClientState.ConnectionState.CONNECTED;
+ var isDisconnected = connectionState === ManagedClientState.ConnectionState.DISCONNECTED;
- Utils.observe($scope.client.clientProperties, 'scale', (function(scale) {
- scale = Math.max(scale, $scope.client.clientProperties.minScale);
- scale = Math.min(scale, $scope.client.clientProperties.maxScale);
-
- // Apply scale if client attached
- if ($guac.display && scale !== 0) {
- $guac.display.scale(scale);
- $elements.displayContainer.style['min-height'] = $guac.display.getHeight() + "px";
- }
+ isConnected && setTimeout(containerResized, 100);
+ isDisconnected && disconnect();
- if (scale !== $scope.client.clientProperties.scale) {
- $scope.client.clientProperties.scale = scale;
- }
+ $('.spinner')[isLoading ? 'fadeIn' : 'fadeOut']('fast');
+ $('.toolbar__state h5').text(connectionState).animate();
}).bind(this));
};
this.setInformation = function(information) {
var info_decode = UtilsConnection.decodeInfoConnection(information);
- UtilsConnection.printInfoConnection($('.guacamole_info'), info_decode);
+ UtilsConnection.printInfoConnection($('.information'), info_decode);
+ }
+
+ function disconnect() {
+ if ($guac.client) $guac.client.disconnect();
+ if ($guac.keyboard) GuacKeyboard.destroy();
+ if ($guac.mouse) GuacMouse.destroy();
+ if ($guac.osk) GuacOsk.destroy();
+
+ GuacButtons.destroy();
+ GuacClipboard.destroy();
+ window.removeEventListener('resize', containerResized);
+ document.removeEventListener('fullscreenchange', containerResized)
+
+ while($elements.displayContainer.firstChild)
+ $elements.displayContainer.removeChild($elements.displayContainer.firstChild);
+
+ $guac = {};
+ $scope = {};
}
function containerResized() {
@@ -150,38 +148,37 @@ define(function(require) {
if ($guac.display.getWidth() !== width || $guac.display.getHeight() !== height) {
$guac.client.sendSize(width, height);
}
-
- if ($guac.osk) {
- var MAX_OSK_WIDTH = 1000;
- $guac.osk.resize(Math.min(MAX_OSK_WIDTH, width));
- }
+ // when type connection is SSH, display doesn't need scale
+ $scope.connectionType !== ConnectionTypes.SSH && updateDisplayScale();
}
- updateDisplayScale();
+ if ($guac.osk) {
+ $guac.osk.resize(1000);
+ }
};
function updateDisplayScale() {
if (!$guac.display) return;
- // Calculate scale to fit screen
- $scope.client.clientProperties.minScale = Math.min(
- $elements.main.offsetWidth / Math.max($guac.display.getWidth(), 1),
- $elements.main.offsetHeight / Math.max($guac.display.getHeight(), 1)
- );
+ // Get screen resolution.
+ var origHeight = Math.max($guac.display.getHeight(), 1);
+ var origWidth = Math.max($guac.display.getWidth(), 1);
+
+ var htmlWidth = window.innerWidth;
+ var htmlHeight = window.innerHeight;
+
+ var xScale = htmlWidth / origWidth;
+ var yScale = htmlHeight / origHeight;
+
+ // This is done to handle both X and Y axis
+ var scale = Math.min(yScale, xScale);
- // Calculate appropriate maximum zoom level
- $scope.client.clientProperties.maxScale = Math.max($scope.client.clientProperties.minScale, 3);
+ // Limit to 1
+ scale = Math.min(scale, 1);
- // Clamp zoom level, maintain auto-fit
- if (
- $guac.display.getScale() < $scope.client.clientProperties.minScale ||
- $scope.client.clientProperties.autoFit
- ) {
- $scope.client.clientProperties.scale = $scope.client.clientProperties.minScale;
- }
- else if ($guac.display.getScale() > $scope.client.clientProperties.maxScale) {
- $scope.client.clientProperties.scale = $scope.client.clientProperties.maxScale;
+ if (scale !== 0) {
+ $guac.display.scale(scale);
}
};
}
diff --git a/src/sunstone/public/app/utils/guacamole/directives/guacButtons.js b/src/sunstone/public/app/utils/guacamole/directives/guacButtons.js
index 38ce4e5016..5c7539c41f 100644
--- a/src/sunstone/public/app/utils/guacamole/directives/guacButtons.js
+++ b/src/sunstone/public/app/utils/guacamole/directives/guacButtons.js
@@ -17,6 +17,7 @@
define(function(require) {
var Files = require('utils/files');
+ var ConnectionTypes = require("utils/guacamole/types/connection-types");
function GuacButtons($guac, $scope, $elements) {
$elements.screenshotButton.onclick = function() {
@@ -45,7 +46,7 @@ define(function(require) {
$elements.closeOskButton.onclick = function() {
if (!$guac.client) return;
- $('#osk-container').fadeToggle('fast');
+ $('#osk__container').fadeToggle('fast');
};
$elements.mouseButton.onclick = function() {
@@ -55,16 +56,25 @@ define(function(require) {
$scope.localCursor = $elements.mouseButton.classList.contains('disabled');
};
+ $elements.fullscreenButton.onclick = function() {
+ // If the document is not in full screen mode make the video full screen
+ if (!document.fullscreenElement && document.fullscreenEnabled) {
+ $elements.main.requestFullscreen();
+ } else if (document.exitFullscreen) {
+ document.exitFullscreen();
+ }
+ };
+
GuacButtons.destroy = function() {
// reset default state
- $('#osk-container').hide();
+ $('#osk__container').hide();
$elements.mouseButton.classList.remove('disabled');
- $elements.sendCtrlAltDelButton =
- $elements.screenshotButton.onclick =
- $elements.mouseButton.onclick =
- $elements.oskButton.onclick =
- $elements.closeOskButton.onclick = null;
+ $elements.sendCtrlAltDelButton.onclick =
+ $elements.screenshotButton.onclick =
+ $elements.mouseButton.onclick =
+ $elements.oskButton.onclick =
+ $elements.closeOskButton.onclick = null;
};
}
diff --git a/src/sunstone/public/app/utils/guacamole/directives/guacMouse.js b/src/sunstone/public/app/utils/guacamole/directives/guacMouse.js
index ee3c24fad2..d80e483953 100644
--- a/src/sunstone/public/app/utils/guacamole/directives/guacMouse.js
+++ b/src/sunstone/public/app/utils/guacamole/directives/guacMouse.js
@@ -30,9 +30,7 @@ define(function(require) {
// Forward mousemove events untouched
mouse.onmousemove = function(mouseState) {
- mouseState.y = mouseState.y / $guac.display.getScale();
- mouseState.x = mouseState.x / $guac.display.getScale();
- handleMouseState(mouseState);
+ handleMouseState(mouseState, true);
}
// Hide software cursor when mouse leaves display
@@ -42,10 +40,15 @@ define(function(require) {
$guac.display.showCursor(false);
};
- function handleMouseState(mouseState) {
+ function handleMouseState(mouseState, scaleMouse = false) {
// Do not attempt to handle mouse state changes if the client
// or display are not yet available
- if (!$guac.client || !$guac.display) return;
+ if (!$guac.client || !$guac.display || $scope.disabledMouse) return;
+
+ if (scaleMouse) {
+ mouseState.y = mouseState.y / $guac.display.getScale();
+ mouseState.x = mouseState.x / $guac.display.getScale();
+ }
// Send mouse state, show cursor if necessary
$guac.display.showCursor(!$scope.localCursor);
diff --git a/src/sunstone/public/app/utils/guacamole/directives/guacOsk.js b/src/sunstone/public/app/utils/guacamole/directives/guacOsk.js
index ece5a457db..e3b4a61018 100644
--- a/src/sunstone/public/app/utils/guacamole/directives/guacOsk.js
+++ b/src/sunstone/public/app/utils/guacamole/directives/guacOsk.js
@@ -26,18 +26,21 @@ define(function(require) {
loadLayouts();
changeLayout(DEFAULT_LAYOUT);
- // $('#osk-container').draggable();
+ $('#osk__container').draggable({
+ start: function() { $scope.disabledMouse = true; },
+ stop: function() { $scope.disabledMouse = false; }
+ });
function loadLayouts() {
- $('#osk-qwerty').empty();
+ $('#select__qwerty').empty();
var enUsLayout = new Option(enUsQwerty.language, enUsQwerty.language);
- $('#osk-qwerty').append(enUsLayout);
+ $('#select__qwerty').append(enUsLayout);
var esEsLayout = new Option(esEsQwerty.language, esEsQwerty.language);
- $('#osk-qwerty').append(esEsLayout);
+ $('#select__qwerty').append(esEsLayout);
- $('#osk-qwerty').off().on('change', function() {
+ $('#select__qwerty').off().on('change', function() {
changeLayout(this.value);
})
};
diff --git a/src/sunstone/public/app/utils/guacamole/types/client.js b/src/sunstone/public/app/utils/guacamole/types/client.js
index c7adc7ee0c..bcf7654a3d 100644
--- a/src/sunstone/public/app/utils/guacamole/types/client.js
+++ b/src/sunstone/public/app/utils/guacamole/types/client.js
@@ -215,9 +215,15 @@ define(function(require) {
function getConnectString(token, connectionParameters, display = window) {
// Calculate optimal width/height for display
var pixel_density = window.devicePixelRatio || 1;
- var optimal_width = display.innerWidth * pixel_density;
- var optimal_height = display.innerHeight * pixel_density;
var optimal_dpi = pixel_density * 96;
+
+ var optimal_width = display instanceof Window
+ ? display.innerWidth * pixel_density
+ : display.offsetWidth * pixel_density;
+
+ var optimal_height = display instanceof Window
+ ? display.innerHeight * pixel_density
+ : display.offsetHeight * pixel_density;
// Build base connect string
var connectString = [
diff --git a/src/sunstone/public/app/utils/guacamole/types/connection-types.js b/src/sunstone/public/app/utils/guacamole/types/connection-types.js
new file mode 100644
index 0000000000..543316b8f2
--- /dev/null
+++ b/src/sunstone/public/app/utils/guacamole/types/connection-types.js
@@ -0,0 +1,31 @@
+/* -------------------------------------------------------------------------- */
+/* Copyright 2002-2021, OpenNebula Project, OpenNebula Systems */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
+/* not use this file except in compliance with the License. You may obtain */
+/* a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
+/* See the License for the specific language governing permissions and */
+/* limitations under the License. */
+/* -------------------------------------------------------------------------- */
+
+define(function() {
+
+ /**
+ * Valid connection type strings. Each type string represents a protocol.
+ */
+ var ConnectionTypes = {
+ SSH : "SSH",
+ RDP : "RDP",
+ VNC : "VNC",
+ TELNET : "TELNET"
+ }
+
+ return ConnectionTypes;
+
+});
\ No newline at end of file
diff --git a/src/sunstone/public/css/guac-custom.css b/src/sunstone/public/css/guac-custom.css
index 49ee565036..170049502e 100644
--- a/src/sunstone/public/css/guac-custom.css
+++ b/src/sunstone/public/css/guac-custom.css
@@ -1,87 +1,122 @@
-body {
- margin:0;
- padding:0;
- font-family: Helvetica;
- height:100%;
-}
+/*
+* CSS TABLE OF CONTENTS
+*
+* 1.0 - Globals
+* 2.0 - Header
+* 3.0 - Body
+* 3.1 - Guacamole display
+* 3.2 - Defaults classes by guacamole-common-js
+*/
+
+/*** 1.0 - Globals ***/
html {
- height:100%;
+ box-sizing: border-box;
}
-.remote-buttons {
- white-space: nowrap;
+*, *:before, *:after {
+ box-sizing: inherit;
}
-.main {
- width: 100%;
- display: inline-flex;
- height: 100%;
- flex-direction: column;
- background-color: rgb(40, 40, 40);
+body {
+ display: grid;
+ grid-template-rows: auto 1fr;
}
-.guacamole-main{
- flex-grow: 1;
+h5 {
+ margin: 0;
+ padding: 0;
}
-.guacamole-status {
- text-align: center;
- position: relative;
- width: 100%;
+/*** 2.0 - Header ***/
+
+header {
+ background: #f2f4f8;
+ padding: 1em 1em 0.8em;
+ box-shadow: 0px 2px 1px -1px rgb(0 0 0 / 20%),
+ 0px 1px 1px 0px rgb(0 0 0 / 14%), 0px 1px 3px 0px rgb(0 0 0 / 12%);
}
-.remote-logo{
- border-radius: 50%;
- background-color: #282828;
- padding: 0.4em;
- margin-right: 1em;
- height: 40px;
- width: 40px;
+.header__wrapper {
+ max-width: 1250px;
+ margin: 0 auto;
}
-.container{
+.toolbar {
+ padding: 1em;
display: flex;
- justify-content: center;
+ gap: 2em;
+ flex-wrap: wrap;
+}
+
+.toolbar img {
+ height: 40px;
+}
+
+.toolbar__state {
+ flex-grow: 1;
+ display: flex;
+ gap: 1em;
align-items: center;
+ justify-content: center;
}
-.guacamole-state{
- white-space: nowrap;
- max-width: 20em;
- overflow: hidden;
- text-overflow: ellipsis;
+.toolbar__state img {
+ width: 40px;
+ background-color: #282828;
+ border-radius: 50%;
+ padding: 0.4em;
}
+.toolbar__buttons {
+ display: flex;
+ justify-content: flex-end;
+}
-/* left-align the status text on lower resolutions */
-@media screen and (max-width: 800px){
- .guacamole-status {
- z-index: 1;
- position: relative;
- width: auto;
- float: left;
+@media (max-width: 768px) {
+ .toolbar__state {
+ justify-content: end;
+ flex-direction: row-reverse;
+ }
+ .toolbar__buttons {
+ flex-grow: 1;
}
}
-.guacamole-main {
- width: 100%;
- height: fit-content;
- display: flex;
- align-items: center;
- place-content: center;
- background-color: #282828;
+/*** 3.0 - Body ***/
+
+main {
+ background-color: #222431;
}
-.guacamole-main > div {
+main > div {
z-index: 1;
}
-.guacamole-main .guacamole-display {
+/*** 3.1 - Guacamole display ***/
+
+.wrapper__display {
+ width: 100%;
+ height: 100%;
+
+ display: flex;
+ align-items: center;
+ place-content: center;
+}
+
+#display {
+ overflow: hidden;
cursor: none;
}
-.osk-container {
+#display.ssh {
+ width: 100vw;
+ height: 100%;
+}
+
+/*** 3.2 - Guacamole OSK ***/
+
+.osk__container {
z-index: 2;
background: rgba(0, 0, 0, 0.59);
position: absolute;
@@ -93,30 +128,24 @@ html {
box-shadow: 0 0 20px #acacac;
}
-.osk-container-header {
+.osk__header {
background: linear-gradient(to top, #ebebeb, #d5d5d5);
color: #4d494d;
- font-size: 11pt;
- line-height: 20px;
- text-align: center;
- width: 100%;
- height: 28px;
+
user-select: none;
cursor: default;
+
border-top: 1px solid #f3f1f3;
- border-bottom: 1px solid #b1aeb1;
border-top-left-radius: 6px;
border-top-right-radius: 6px;
+
+ padding: 0.5em;
+ display: flex;
+ justify-content: space-between;
+ align-items: start;
}
-.osk-container-header .buttons {
- padding-left: 8px;
- padding-top: 3px;
- float: left;
- line-height: 0;
-}
-
-.osk-container-header .buttons .close {
+.osk__header__buttons .close {
background: #ff5c5c;
font-size: 13px;
font-weight: bold;
@@ -126,18 +155,17 @@ html {
display: inline-block;
}
-.osk-container-header .layouts {
- padding-right: 8px;
- padding-top: 3px;
- float: right;
- line-height: 0;
+.osk__header select {
+ width: auto;
+ margin: 0;
}
+/*** 3.2 Defaults classes by guacamole-common-js ***/
.guac-keyboard {
display: inline-block;
width: 100%;
-
+
margin: 0;
padding: 0;
cursor: default;
@@ -159,20 +187,19 @@ html {
}
.guac-keyboard .guac-keyboard-key {
-
position: absolute;
- left: 0;
- right: 0;
- top: 0;
+ left: 0;
+ right: 0;
+ top: 0;
bottom: 0;
background: #444;
border: 0.125em solid #666;
- -moz-border-radius: 0.25em;
+ -moz-border-radius: 0.25em;
-webkit-border-radius: 0.25em;
- -khtml-border-radius: 0.25em;
- border-radius: 0.25em;
+ -khtml-border-radius: 0.25em;
+ border-radius: 0.25em;
color: white;
font-size: 40%;
@@ -180,11 +207,8 @@ html {
text-align: center;
white-space: pre;
- text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.25),
- 1px -1px 0 rgba(0, 0, 0, 0.25),
- -1px 1px 0 rgba(0, 0, 0, 0.25),
- -1px -1px 0 rgba(0, 0, 0, 0.25);
-
+ text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.25), 1px -1px 0 rgba(0, 0, 0, 0.25),
+ -1px 1px 0 rgba(0, 0, 0, 0.25), -1px -1px 0 rgba(0, 0, 0, 0.25);
}
.guac-keyboard .guac-keyboard-key:hover {
@@ -232,12 +256,12 @@ html {
/* Active super */
.guac-keyboard.guac-keyboard-modifier-super .guac-keyboard-key-super {
background: #882;
- border-color: #DD4;
+ border-color: #dd4;
}
.guac-keyboard .guac-keyboard-key.guac-keyboard-pressed {
background: #822;
- border-color: #D44;
+ border-color: #d44;
}
.guac-keyboard .guac-keyboard-group {
@@ -252,7 +276,6 @@ html {
}
.guac-keyboard .guac-keyboard-group.guac-keyboard-main {
-
/* IE10 */
display: -ms-flexbox;
-ms-flex-align: stretch;
@@ -262,7 +285,7 @@ html {
display: -moz-box;
-moz-box-align: stretch;
-moz-box-orient: horizontal;
-
+
/* Ancient WebKit */
display: -webkit-box;
-webkit-box-align: stretch;
@@ -277,7 +300,6 @@ html {
display: flex;
align-items: stretch;
flex-direction: row;
-
}
.guac-keyboard .guac-keyboard-group.guac-keyboard-movement {
@@ -315,13 +337,11 @@ html {
.guac-keyboard.guac-keyboard-modifier-alt-gr
.guac-keyboard-key.guac-keyboard-uses-alt-gr
.guac-keyboard-cap:not(.guac-keyboard-requires-alt-gr) {
-
display: none;
-
}
/* Fade out keys which do not use AltGr if AltGr is active */
.guac-keyboard.guac-keyboard-modifier-alt-gr
-.guac-keyboard-key:not(.guac-keyboard-uses-alt-gr):not(.guac-keyboard-key-alt-gr) {
+ .guac-keyboard-key:not(.guac-keyboard-uses-alt-gr):not(.guac-keyboard-key-alt-gr) {
opacity: 0.5;
-}
\ No newline at end of file
+}
diff --git a/src/sunstone/public/scss/_settings.scss b/src/sunstone/public/scss/_settings.scss
index 5920359272..9e360fdbf1 100644
--- a/src/sunstone/public/scss/_settings.scss
+++ b/src/sunstone/public/scss/_settings.scss
@@ -49,7 +49,6 @@ $global-font-size: 13px;
$global-width: rem-calc(1200);
$global-lineheight: 1.5;
$foundation-palette: (
- //primary: #2199e8,
primary: #4DBBD3,
secondary: #8a8a8a,
success: #3adb76,
diff --git a/src/sunstone/views/guac.erb b/src/sunstone/views/guac.erb
index 75d369a8ef..5a57262eb0 100644
--- a/src/sunstone/views/guac.erb
+++ b/src/sunstone/views/guac.erb
@@ -4,66 +4,64 @@
-
-
-
-
+
-
-
-
-
-

-
-
-
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
+
+
+ <%### Guacamole display screen ###%>
+
-
-
-