/* global window, document.getElementById, Util, WebUtil, RFB, Display */
import * as Log from '../core/util/logging.js';
-import _, { l10n } from '../core/util/localization.js';
+import _, { l10n } from './localization.js';
import { isTouchDevice } from '../core/util/browsers.js';
import { setCapture, getPointerEvent } from '../core/util/events.js';
import KeyTable from "../core/input/keysym.js";
connected: false,
desktopName: "",
- resizeTimeout: null,
statusTimeout: null,
hideKeyboardTimeout: null,
idleControlbarTimeout: null,
UI.initFullscreen();
// Setup event handlers
- UI.addResizeHandlers();
UI.addControlbarHandlers();
UI.addTouchSpecificHandlers();
UI.addExtraKeysHandlers();
UI.openControlbar();
- UI.updateViewClip();
-
UI.updateVisualState('init');
document.documentElement.classList.remove("noVNC_loading");
* EVENT HANDLERS
* ------v------*/
- addResizeHandlers: function() {
- window.addEventListener('resize', UI.applyResizeMode);
- window.addEventListener('resize', UI.updateViewClip);
- },
-
addControlbarHandlers: function() {
document.getElementById("noVNC_control_bar")
.addEventListener('mousemove', UI.activateControlbar);
UI.disableSetting('port');
UI.disableSetting('path');
UI.disableSetting('repeaterID');
- UI.updateViewClip();
UI.setMouseButton(1);
// Hide the controlbar after 2 seconds
status_type = 'normal';
}
- statusElem.classList.remove("noVNC_status_normal");
- statusElem.classList.remove("noVNC_status_warn");
- statusElem.classList.remove("noVNC_status_error");
+ // Don't overwrite more severe visible statuses and never
+ // errors. Only shows the first error.
+ let visible_status_type = 'none';
+ if (statusElem.classList.contains("noVNC_open")) {
+ if (statusElem.classList.contains("noVNC_status_error")) {
+ visible_status_type = 'error';
+ } else if (statusElem.classList.contains("noVNC_status_warn")) {
+ visible_status_type = 'warn';
+ } else {
+ visible_status_type = 'normal';
+ }
+ }
+ if (visible_status_type === 'error' ||
+ (visible_status_type === 'warn' && status_type === 'normal')) {
+ return;
+ }
switch (status_type) {
+ case 'error':
+ statusElem.classList.remove("noVNC_status_warn");
+ statusElem.classList.remove("noVNC_status_normal");
+ statusElem.classList.add("noVNC_status_error");
+ break;
case 'warning':
case 'warn':
+ statusElem.classList.remove("noVNC_status_error");
+ statusElem.classList.remove("noVNC_status_normal");
statusElem.classList.add("noVNC_status_warn");
break;
- case 'error':
- statusElem.classList.add("noVNC_status_error");
- break;
case 'normal':
case 'info':
default:
+ statusElem.classList.remove("noVNC_status_error");
+ statusElem.classList.remove("noVNC_status_warn");
statusElem.classList.add("noVNC_status_normal");
break;
}
password = undefined;
}
+ UI.hideStatus();
+
if (!host) {
Log.Error("Can't connect when host is: " + host);
UI.showStatus(_("Must set host"), 'error');
}
url += '/' + path;
- UI.rfb = new RFB(document.getElementById('noVNC_canvas'), url,
+ UI.rfb = new RFB(document.getElementById('noVNC_container'), url,
{ shared: UI.getSetting('shared'),
repeaterID: UI.getSetting('repeaterID'),
credentials: { password: password } });
UI.rfb.addEventListener("disconnect", UI.disconnectFinished);
UI.rfb.addEventListener("credentialsrequired", UI.credentials);
UI.rfb.addEventListener("securityfailure", UI.securityFailed);
- UI.rfb.addEventListener("capabilities", function () { UI.updatePowerButton(); UI.initialResize(); });
+ UI.rfb.addEventListener("capabilities", function () { UI.updatePowerButton(); });
UI.rfb.addEventListener("clipboard", UI.clipboardReceive);
UI.rfb.addEventListener("bell", UI.bell);
- UI.rfb.addEventListener("fbresize", UI.updateSessionSize);
UI.rfb.addEventListener("desktopname", UI.updateDesktopName);
+ UI.rfb.clipViewport = UI.getSetting('view_clip');
+ UI.rfb.scaleViewport = UI.getSetting('resize') === 'scale';
+ UI.rfb.resizeSession = UI.getSetting('resize') === 'remote';
},
disconnect: function() {
UI.connect(null, UI.reconnect_password);
},
+ cancelReconnect: function() {
+ if (UI.reconnect_callback !== null) {
+ clearTimeout(UI.reconnect_callback);
+ UI.reconnect_callback = null;
+ }
+
+ UI.updateVisualState('disconnected');
+
+ UI.openControlbar();
+ UI.openConnectPanel();
+ },
+
connectFinished: function (e) {
UI.connected = true;
UI.inhibit_reconnect = false;
- UI.doneInitialResize = false;
let msg;
if (UI.getSetting('encrypt')) {
UI.updateVisualState('connected');
// Do this last because it can only be used on rendered elements
- document.getElementById('noVNC_canvas').focus();
+ UI.rfb.focus();
},
disconnectFinished: function (e) {
UI.showStatus(msg, 'error');
},
- cancelReconnect: function() {
- if (UI.reconnect_callback !== null) {
- clearTimeout(UI.reconnect_callback);
- UI.reconnect_callback = null;
- }
-
- UI.updateVisualState('disconnected');
-
- UI.openControlbar();
- UI.openConnectPanel();
- },
-
/* ------^-------
* /CONNECTION
* ==============
applyResizeMode: function() {
if (!UI.rfb) return;
- var screen = UI.screenSize();
-
- if (screen && UI.connected) {
-
- var resizeMode = UI.getSetting('resize');
- UI.rfb.viewportScale = 1.0;
-
- // Make sure the viewport is adjusted first
- UI.updateViewClip();
-
- if (resizeMode === 'remote') {
-
- // Request changing the resolution of the remote display to
- // the size of the local browser viewport.
-
- // In order to not send multiple requests before the browser-resize
- // is finished we wait 0.5 seconds before sending the request.
- clearTimeout(UI.resizeTimeout);
- UI.resizeTimeout = setTimeout(function(){
- // Request a remote size covering the viewport
- if (UI.rfb.requestDesktopSize(screen.w, screen.h)) {
- Log.Debug('Requested new desktop size: ' +
- screen.w + 'x' + screen.h);
- }
- }, 500);
-
- } else {
- UI.updateScaling();
- }
- }
- },
-
- // Re-calculate local scaling
- updateScaling: function() {
- if (!UI.rfb) return;
-
- var resizeMode = UI.getSetting('resize');
- if (resizeMode !== 'scale') {
- return;
- }
-
- var screen = UI.screenSize();
-
- if (!screen || !UI.connected) {
- return;
- }
-
- UI.rfb.autoscale(screen.w, screen.h);
- UI.fixScrollbars();
- },
-
- // Gets the the size of the available viewport in the browser window
- screenSize: function() {
- var screen = document.getElementById('noVNC_screen');
- return {w: screen.offsetWidth, h: screen.offsetHeight};
- },
-
- // Normally we only apply the current resize mode after a window resize
- // event. This means that when a new connection is opened, there is no
- // resize mode active.
- // We have to wait until we know the capabilities of the server as
- // some calls later in the chain is dependant on knowing the
- // server-capabilities.
- initialResize: function() {
- if (UI.doneInitialResize) return;
-
- UI.applyResizeMode();
- UI.doneInitialResize = true;
+ UI.rfb.scaleViewport = UI.getSetting('resize') === 'scale';
+ UI.rfb.resizeSession = UI.getSetting('resize') === 'remote';
},
/* ------^-------
* VIEW CLIPPING
* ------v------*/
- // Set and configure viewport clipping
- setViewClip: function(clip) {
- UI.updateSetting('view_clip', clip);
- UI.updateViewClip();
- },
-
// Update parameters that depend on the viewport clip setting
updateViewClip: function() {
if (!UI.rfb) return;
var cur_clip = UI.rfb.clipViewport;
var new_clip = UI.getSetting('view_clip');
- var resizeSetting = UI.getSetting('resize');
- if (resizeSetting === 'scale') {
- // Disable viewport clipping if we are scaling
- new_clip = false;
- } else if (isTouchDevice) {
+ if (isTouchDevice) {
// Touch devices usually have shit scrollbars
new_clip = true;
}
UI.rfb.clipViewport = new_clip;
}
- var size = UI.screenSize();
-
- if (new_clip && size) {
- // When clipping is enabled, the screen is limited to
- // the size of the browser window.
- UI.rfb.viewportChangeSize(size.w, size.h);
- UI.fixScrollbars();
- }
-
// Changing the viewport may change the state of
// the dragging button
UI.updateViewDrag();
},
updateViewDrag: function() {
- var clipping = false;
-
if (!UI.connected) return;
- // Check if viewport drag is possible. It is only possible
- // if the remote display is clipping the client display.
- if (UI.rfb.clipViewport && UI.rfb.isClipped) {
- clipping = true;
- }
-
var viewDragButton = document.getElementById('noVNC_view_drag_button');
- if (!clipping &&
- UI.rfb.dragViewport) {
- // The size of the remote display is the same or smaller
- // than the client display. Make sure viewport drag isn't
- // active when it can't be used.
+ if (!UI.rfb.clipViewport && UI.rfb.dragViewport) {
+ // We are no longer clipping the viewport. Make sure
+ // viewport drag isn't active when it can't be used.
UI.rfb.dragViewport = false;
}
if (isTouchDevice) {
viewDragButton.classList.remove("noVNC_hidden");
- if (clipping) {
+ if (UI.rfb.clipViewport) {
viewDragButton.disabled = false;
} else {
viewDragButton.disabled = true;
} else {
viewDragButton.disabled = false;
- if (clipping) {
+ if (UI.rfb.clipViewport) {
viewDragButton.classList.remove("noVNC_hidden");
} else {
viewDragButton.classList.add("noVNC_hidden");
document.getElementById('noVNC_keyboard_button')
.classList.add("noVNC_selected");
if (UI.rfb) {
- UI.rfb.set_focus_on_click(false);
+ UI.rfb.focusOnClick = false;
}
},
document.getElementById('noVNC_keyboard_button')
.classList.remove("noVNC_selected");
if (UI.rfb) {
- UI.rfb.set_focus_on_click(true);
+ UI.rfb.focusOnClick = true;
}
},
WebUtil.init_logging(UI.getSetting('logging'));
},
- updateSessionSize: function(e) {
- UI.updateViewClip();
- UI.updateScaling();
- UI.fixScrollbars();
- },
-
- fixScrollbars: function() {
- // This is a hack because Chrome screws up the calculation
- // for when scrollbars are needed. So to fix it we temporarily
- // toggle them off and on.
- var screen = document.getElementById('noVNC_screen');
- screen.style.overflow = 'hidden';
- // Force Chrome to recalculate the layout by asking for
- // an element's dimensions
- screen.getBoundingClientRect();
- screen.style.overflow = "";
- },
-
updateDesktopName: function(e) {
UI.desktopName = e.detail.name;
// Display the desktop name in the document title