diff --git a/src/sunstone/public/app/console/guacamole.js b/src/sunstone/public/app/console/guacamole.js
index 4940c820c7..a05cec36e9 100644
--- a/src/sunstone/public/app/console/guacamole.js
+++ b/src/sunstone/public/app/console/guacamole.js
@@ -15,22 +15,23 @@
/* -------------------------------------------------------------------------- */
define(function(require) {
- require("jquery-ui");
+ require('jquery-ui');
var GuacController = require('utils/guacamole/controller');
var controller = new GuacController();
var reconnectButton = document.getElementById('buttons__reconnect');
+ var selectResolution = document.getElementById('select__resolution');
var endpoint = new URL(window.location.href);
- var encoded_socket = endpoint.searchParams.get("socket");
+ 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");
+ var token = params.get('token');
+ var connectionType = params.get('type');
+ var info = params.get('info');
controller.setInformation(info);
@@ -45,18 +46,22 @@ define(function(require) {
reconnectButton.onclick = function reconnect() {
disconnect();
- document.querySelector('.toolbar__state h5').innerHTML = "";
- document.querySelector('.toolbar__state .spinner').style.display = "block";
+ document.querySelector('.toolbar__state h5').innerHTML = '';
+ document.querySelector('.toolbar__state .spinner').style.display = 'block';
- setTimeout(connect, 500)
+ setTimeout(connect, 500);
}
+
+ selectResolution.onchange = function() {
+ reconnectButton.click();
+ };
function connect() {
try {
controller && controller.setConnection(token, connectionType);
} catch (error) {
controller && controller.disconnect();
- document.querySelector('.toolbar__state h5').innerHTML = "Failed";
+ document.querySelector('.toolbar__state h5').innerHTML = 'Failed';
}
}
@@ -64,7 +69,7 @@ define(function(require) {
try {
controller && controller.disconnect();
} catch (error) {
- document.querySelector('.toolbar__state h5').innerHTML = "Failed";
+ document.querySelector('.toolbar__state h5').innerHTML = 'Failed';
}
}
diff --git a/src/sunstone/public/app/opennebula/vm.js b/src/sunstone/public/app/opennebula/vm.js
index 997e83904f..f43d8b5450 100644
--- a/src/sunstone/public/app/opennebula/vm.js
+++ b/src/sunstone/public/app/opennebula/vm.js
@@ -1054,9 +1054,9 @@ define(function(require) {
});
if (ips.length === 0)
- return "
--
";
+ return "--
";
else if (ips.length === 1)
- return ""+ips[0]+"
";
+ return ""+ips[0]+"
";
var sshWithPortForwarding = getSshWithPortForwarding(element) || '';
var firstIP = ipsHtml.split("")[0];
diff --git a/src/sunstone/public/app/utils/guacamole/controller.js b/src/sunstone/public/app/utils/guacamole/controller.js
index cc3673f2ba..77217e8ae9 100644
--- a/src/sunstone/public/app/utils/guacamole/controller.js
+++ b/src/sunstone/public/app/utils/guacamole/controller.js
@@ -35,6 +35,7 @@ define(function(require) {
var $elements = {
main: document.querySelector('.wrapper__display'),
displayContainer: document.getElementById('display'),
+ selectResolution: document.getElementById('select__resolution'),
osk: document.getElementById('osk'),
closeOskButton: document.querySelector('.osk__header__buttons .close'),
@@ -55,7 +56,19 @@ define(function(require) {
? $elements.displayContainer.classList.add('ssh')
: $elements.displayContainer.classList.remove('ssh');
- var managedClient = ManagedClient.getInstance(token, undefined, $elements.displayContainer)
+ var isRDP = $scope.connectionType === ConnectionTypes.RDP
+ var resolution = $elements.selectResolution.value;
+
+ isRDP && $elements.selectResolution.classList.remove('hidden');
+
+ var displayOptions = isRDP && resolution && resolution !== ''
+ ? {
+ width: resolution.split('x')[0],
+ height: resolution.split('x')[1]
+ }
+ : { display: $elements.displayContainer }; // get width & height from container
+
+ var managedClient = ManagedClient.getInstance(token, displayOptions)
new GuacKeyboard($guac, $scope, $elements);
new GuacMouse($guac, $scope, $elements);
@@ -144,7 +157,7 @@ define(function(require) {
var pixelDensity = window.devicePixelRatio || 1;
var width = $elements.main.offsetWidth * pixelDensity;
var height = $elements.main.offsetHeight * pixelDensity;
-
+
if ($guac.display.getWidth() !== width || $guac.display.getHeight() !== height) {
$guac.client.sendSize(width, height);
}
diff --git a/src/sunstone/public/app/utils/guacamole/directives/guacButtons.js b/src/sunstone/public/app/utils/guacamole/directives/guacButtons.js
index 5c7539c41f..2e73f9255c 100644
--- a/src/sunstone/public/app/utils/guacamole/directives/guacButtons.js
+++ b/src/sunstone/public/app/utils/guacamole/directives/guacButtons.js
@@ -17,7 +17,6 @@
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() {
diff --git a/src/sunstone/public/app/utils/guacamole/types/client.js b/src/sunstone/public/app/utils/guacamole/types/client.js
index bcf7654a3d..29654a189d 100644
--- a/src/sunstone/public/app/utils/guacamole/types/client.js
+++ b/src/sunstone/public/app/utils/guacamole/types/client.js
@@ -207,34 +207,37 @@ define(function(require) {
* guaranteed to resolve successfully.
*
* @param {String} token The identifier representing the connection or group to connect to.
- * @param {String[]} [connectionParameters] Any additional HTTP parameters to pass while connecting.
- * @param {Element} [display] Element where the connection will be displayed.
+ * @param {Element} options.display Element where the connection will be displayed.
+ * @param {String} options.width Forced width connection
+ * @param {String} options.height Forced height connection
*
* @returns {String} A string of connection parameters to be passed to the Guacamole client.
*/
- function getConnectString(token, connectionParameters, display = window) {
+ function getConnectString(token, options = {}) {
+ options = Object.assign({ display: window }, options)
+
// Calculate optimal width/height for display
var pixel_density = window.devicePixelRatio || 1;
- var optimal_dpi = pixel_density * 96;
+ var optimal_dpi = options.dpi || pixel_density * 96;
- var optimal_width = display instanceof Window
- ? display.innerWidth * pixel_density
- : display.offsetWidth * pixel_density;
+ var display = options.display
- var optimal_height = display instanceof Window
- ? display.innerHeight * pixel_density
- : display.offsetHeight * pixel_density;
+ var width = options.width || (
+ display instanceof Window ? display.innerWidth : display.offsetWidth
+ )
+
+ var height = options.height || (
+ display instanceof Window ? display.innerHeight : display.offsetHeight
+ )
// Build base connect string
var connectString = [
"token=" + encodeURIComponent(token),
- "width=" + Math.floor(optimal_width),
- "height=" + Math.floor(optimal_height),
+ "width=" + Math.floor(width * pixel_density),
+ "height=" + Math.floor(height * pixel_density),
"dpi=" + Math.floor(optimal_dpi)
];
- connectionParameters && connectString.concat(connectionParameters);
-
return connectString.join('&');
}
@@ -272,14 +275,13 @@ define(function(require) {
* or group.
*
* @param {String} token The token of the connection.
- * @param {String[]} [connectionParameters] Any additional HTTP parameters to pass while connecting.
- * @param {Element} [display] Element where the connection will be displayed.
+ * @param {Object} displayOptions The options to client display
*
* @returns {ManagedClient}
* A new ManagedClient instance which is connected to the connection or
* connection group having the given ID.
*/
- ManagedClient.getInstance = function getInstance(token, connectionParameters, display = window) {
+ ManagedClient.getInstance = function getInstance(token, displayOptions) {
var endpoint = new URL(Config.publicFireedgeEndpoint);
var websocketProtocol = endpoint.protocol === 'https:' ? 'wss:' : 'ws:';
@@ -454,7 +456,7 @@ define(function(require) {
managedClient.managedDisplay = ManagedDisplay.getInstance(client.getDisplay());
// Connect the Guacamole client
- var connectString = getConnectString(token, connectionParameters, display);
+ var connectString = getConnectString(token, displayOptions);
client.connect(connectString);
return managedClient;
diff --git a/src/sunstone/public/css/guac-custom.css b/src/sunstone/public/css/guac-custom.css
index 170049502e..7cb58e7ff9 100644
--- a/src/sunstone/public/css/guac-custom.css
+++ b/src/sunstone/public/css/guac-custom.css
@@ -73,6 +73,13 @@ header {
justify-content: flex-end;
}
+.toolbar__buttons > button,
+.toolbar__buttons > select {
+ max-height: 32px;
+ margin-bottom: 0;
+ width: auto;
+}
+
@media (max-width: 768px) {
.toolbar__state {
justify-content: end;
diff --git a/src/sunstone/views/guac.erb b/src/sunstone/views/guac.erb
index 5a57262eb0..cb6e02160f 100644
--- a/src/sunstone/views/guac.erb
+++ b/src/sunstone/views/guac.erb
@@ -40,6 +40,16 @@
+