Commit f4f72e9d authored by samhed's avatar samhed

Merge branch 'master' of https://github.com/kanaka/noVNC into ctrlalttabesc

Conflicts:
	include/ui.js
	vnc.html
parents b4a979a0 69127447
...@@ -645,9 +645,9 @@ function onMouseDisable(e) { ...@@ -645,9 +645,9 @@ function onMouseDisable(e) {
evt = (e ? e : window.event); evt = (e ? e : window.event);
pos = Util.getEventPosition(e, conf.target, conf.scale); pos = Util.getEventPosition(e, conf.target, conf.scale);
/* Stop propagation if inside canvas area */ /* Stop propagation if inside canvas area */
if ((pos.x >= 0) && (pos.y >= 0) && if ((pos.realx >= 0) && (pos.realy >= 0) &&
(pos.x < conf.target.offsetWidth) && (pos.realx < conf.target.offsetWidth) &&
(pos.y < conf.target.offsetHeight)) { (pos.realy < conf.target.offsetHeight)) {
//Util.Debug("mouse event disabled"); //Util.Debug("mouse event disabled");
Util.stopEvent(e); Util.stopEvent(e);
return false; return false;
......
...@@ -103,7 +103,6 @@ var that = {}, // Public API methods ...@@ -103,7 +103,6 @@ var that = {}, // Public API methods
fb_height = 0, fb_height = 0,
fb_name = "", fb_name = "",
last_req_time = 0,
rre_chunk_sz = 100, rre_chunk_sz = 100,
timing = { timing = {
...@@ -148,9 +147,6 @@ Util.conf_defaults(conf, that, defaults, [ ...@@ -148,9 +147,6 @@ Util.conf_defaults(conf, that, defaults, [
['viewportDrag', 'rw', 'bool', false, 'Move the viewport on mouse drags'], ['viewportDrag', 'rw', 'bool', false, 'Move the viewport on mouse drags'],
['check_rate', 'rw', 'int', 217, 'Timing (ms) of send/receive check'],
['fbu_req_rate', 'rw', 'int', 1413, 'Timing (ms) of frameBufferUpdate requests'],
// Callback functions // Callback functions
['onUpdateState', 'rw', 'func', function() { }, ['onUpdateState', 'rw', 'func', function() { },
'onUpdateState(rfb, state, oldstate, statusMsg): RFB state update/change '], 'onUpdateState(rfb, state, oldstate, statusMsg): RFB state update/change '],
...@@ -403,7 +399,7 @@ updateState = function(state, statusMsg) { ...@@ -403,7 +399,7 @@ updateState = function(state, statusMsg) {
} }
if (msgTimer) { if (msgTimer) {
clearInterval(msgTimer); clearTimeout(msgTimer);
msgTimer = null; msgTimer = null;
} }
...@@ -444,13 +440,13 @@ updateState = function(state, statusMsg) { ...@@ -444,13 +440,13 @@ updateState = function(state, statusMsg) {
if (connTimer && (rfb_state !== 'connect')) { if (connTimer && (rfb_state !== 'connect')) {
Util.Debug("Clearing connect timer"); Util.Debug("Clearing connect timer");
clearInterval(connTimer); clearTimeout(connTimer);
connTimer = null; connTimer = null;
} }
if (disconnTimer && (rfb_state !== 'disconnect')) { if (disconnTimer && (rfb_state !== 'disconnect')) {
Util.Debug("Clearing disconnect timer"); Util.Debug("Clearing disconnect timer");
clearInterval(disconnTimer); clearTimeout(disconnTimer);
disconnTimer = null; disconnTimer = null;
} }
...@@ -569,44 +565,18 @@ function genDES(password, challenge) { ...@@ -569,44 +565,18 @@ function genDES(password, challenge) {
return (new DES(passwd)).encrypt(challenge); return (new DES(passwd)).encrypt(challenge);
} }
function flushClient() {
if (mouse_arr.length > 0) {
//send(mouse_arr.concat(fbUpdateRequests()));
ws.send(mouse_arr);
setTimeout(function() {
ws.send(fbUpdateRequests());
}, 50);
mouse_arr = [];
return true;
} else {
return false;
}
}
// overridable for testing // overridable for testing
checkEvents = function() { checkEvents = function() {
var now; if (rfb_state === 'normal' && !viewportDragging && mouse_arr.length > 0) {
if (rfb_state === 'normal' && !viewportDragging) { ws.send(mouse_arr);
if (! flushClient()) { mouse_arr = [];
now = new Date().getTime();
if (now > last_req_time + conf.fbu_req_rate) {
last_req_time = now;
ws.send(fbUpdateRequests());
}
}
} }
setTimeout(checkEvents, conf.check_rate);
}; };
keyPress = function(keysym, down) { keyPress = function(keysym, down) {
var arr;
if (conf.view_only) { return; } // View only, skip keyboard events if (conf.view_only) { return; } // View only, skip keyboard events
arr = keyEvent(keysym, down); ws.send(keyEvent(keysym, down));
arr = arr.concat(fbUpdateRequests());
ws.send(arr);
}; };
mouseButton = function(x, y, down, bmask) { mouseButton = function(x, y, down, bmask) {
...@@ -625,7 +595,6 @@ mouseButton = function(x, y, down, bmask) { ...@@ -625,7 +595,6 @@ mouseButton = function(x, y, down, bmask) {
return; return;
} else { } else {
viewportDragging = false; viewportDragging = false;
ws.send(fbUpdateRequests()); // Force immediate redraw
} }
} }
...@@ -633,7 +602,8 @@ mouseButton = function(x, y, down, bmask) { ...@@ -633,7 +602,8 @@ mouseButton = function(x, y, down, bmask) {
mouse_arr = mouse_arr.concat( mouse_arr = mouse_arr.concat(
pointerEvent(display.absX(x), display.absY(y)) ); pointerEvent(display.absX(x), display.absY(y)) );
flushClient(); ws.send(mouse_arr);
mouse_arr = [];
}; };
mouseMove = function(x, y) { mouseMove = function(x, y) {
...@@ -656,7 +626,9 @@ mouseMove = function(x, y) { ...@@ -656,7 +626,9 @@ mouseMove = function(x, y) {
if (conf.view_only) { return; } // View only, skip mouse events if (conf.view_only) { return; } // View only, skip mouse events
mouse_arr = mouse_arr.concat( mouse_arr = mouse_arr.concat(
pointerEvent(display.absX(x), display.absY(y)) ); pointerEvent(display.absX(x), display.absY(y)));
checkEvents();
}; };
...@@ -900,13 +872,12 @@ init_msg = function() { ...@@ -900,13 +872,12 @@ init_msg = function() {
response = pixelFormat(); response = pixelFormat();
response = response.concat(clientEncodings()); response = response.concat(clientEncodings());
response = response.concat(fbUpdateRequests()); response = response.concat(fbUpdateRequests()); // initial fbu-request
timing.fbu_rt_start = (new Date()).getTime(); timing.fbu_rt_start = (new Date()).getTime();
timing.pixels = 0; timing.pixels = 0;
ws.send(response); ws.send(response);
/* Start pushing/polling */ checkEvents();
setTimeout(checkEvents, conf.check_rate);
if (conf.encrypt) { if (conf.encrypt) {
updateState('normal', "Connected (encrypted) to: " + fb_name); updateState('normal', "Connected (encrypted) to: " + fb_name);
...@@ -934,6 +905,10 @@ normal_msg = function() { ...@@ -934,6 +905,10 @@ normal_msg = function() {
switch (msg_type) { switch (msg_type) {
case 0: // FramebufferUpdate case 0: // FramebufferUpdate
ret = framebufferUpdate(); // false means need more data ret = framebufferUpdate(); // false means need more data
if (ret) {
// only allow one outstanding fbu-request at a time
ws.send(fbUpdateRequests());
}
break; break;
case 1: // SetColourMapEntries case 1: // SetColourMapEntries
Util.Debug("SetColourMapEntries"); Util.Debug("SetColourMapEntries");
...@@ -1596,8 +1571,6 @@ encHandlers.DesktopSize = function set_desktopsize() { ...@@ -1596,8 +1571,6 @@ encHandlers.DesktopSize = function set_desktopsize() {
conf.onFBResize(that, fb_width, fb_height); conf.onFBResize(that, fb_width, fb_height);
display.resize(fb_width, fb_height); display.resize(fb_width, fb_height);
timing.fbu_rt_start = (new Date()).getTime(); timing.fbu_rt_start = (new Date()).getTime();
// Send a new non-incremental request
ws.send(fbUpdateRequests());
FBU.bytes = 0; FBU.bytes = 0;
FBU.rects -= 1; FBU.rects -= 1;
...@@ -1823,7 +1796,6 @@ that.sendCtrlAltDel = function() { ...@@ -1823,7 +1796,6 @@ that.sendCtrlAltDel = function() {
arr = arr.concat(keyEvent(0xFFFF, 0)); // Delete arr = arr.concat(keyEvent(0xFFFF, 0)); // Delete
arr = arr.concat(keyEvent(0xFFE9, 0)); // Alt arr = arr.concat(keyEvent(0xFFE9, 0)); // Alt
arr = arr.concat(keyEvent(0xFFE3, 0)); // Control arr = arr.concat(keyEvent(0xFFE3, 0)); // Control
arr = arr.concat(fbUpdateRequests());
ws.send(arr); ws.send(arr);
}; };
...@@ -1840,7 +1812,6 @@ that.sendKey = function(code, down) { ...@@ -1840,7 +1812,6 @@ that.sendKey = function(code, down) {
arr = arr.concat(keyEvent(code, 1)); arr = arr.concat(keyEvent(code, 1));
arr = arr.concat(keyEvent(code, 0)); arr = arr.concat(keyEvent(code, 0));
} }
arr = arr.concat(fbUpdateRequests());
ws.send(arr); ws.send(arr);
}; };
......
...@@ -29,6 +29,7 @@ hideKeyboardTimeout: null, ...@@ -29,6 +29,7 @@ hideKeyboardTimeout: null,
extraKeysVisible: false, extraKeysVisible: false,
ctrlOn: false, ctrlOn: false,
altOn: false, altOn: false,
isTouchDevice: false,
// Setup rfb object, load settings from browser storage, then call // Setup rfb object, load settings from browser storage, then call
// UI.init to setup the UI/menus // UI.init to setup the UI/menus
...@@ -38,7 +39,9 @@ load: function (callback) { ...@@ -38,7 +39,9 @@ load: function (callback) {
// Render default UI and initialize settings menu // Render default UI and initialize settings menu
start: function(callback) { start: function(callback) {
var html = '', i, sheet, sheets, llevels, port; var html = '', i, sheet, sheets, llevels, port, autoconnect;
UI.isTouchDevice = 'ontouchstart' in document.documentElement;
// Stylesheet selection dropdown // Stylesheet selection dropdown
sheet = WebUtil.selectStylesheet(); sheet = WebUtil.selectStylesheet();
...@@ -80,7 +83,7 @@ start: function(callback) { ...@@ -80,7 +83,7 @@ start: function(callback) {
UI.initSetting('password', ''); UI.initSetting('password', '');
UI.initSetting('encrypt', (window.location.protocol === "https:")); UI.initSetting('encrypt', (window.location.protocol === "https:"));
UI.initSetting('true_color', true); UI.initSetting('true_color', true);
UI.initSetting('cursor', false); UI.initSetting('cursor', !UI.isTouchDevice);
UI.initSetting('shared', true); UI.initSetting('shared', true);
UI.initSetting('view_only', false); UI.initSetting('view_only', false);
UI.initSetting('connectTimeout', 2); UI.initSetting('connectTimeout', 2);
...@@ -91,6 +94,15 @@ start: function(callback) { ...@@ -91,6 +94,15 @@ start: function(callback) {
'onUpdateState': UI.updateState, 'onUpdateState': UI.updateState,
'onClipboard': UI.clipReceive, 'onClipboard': UI.clipReceive,
'onDesktopName': UI.updateDocumentTitle}); 'onDesktopName': UI.updateDocumentTitle});
autoconnect = WebUtil.getQueryVar('autoconnect', false);
if (autoconnect === 'true' || autoconnect == '1') {
autoconnect = true;
UI.connect();
} else {
autoconnect = false;
}
UI.updateVisualState(); UI.updateVisualState();
// Unfocus clipboard when over the VNC area // Unfocus clipboard when over the VNC area
...@@ -102,7 +114,7 @@ start: function(callback) { ...@@ -102,7 +114,7 @@ start: function(callback) {
// }; // };
// Show mouse selector buttons on touch screen devices // Show mouse selector buttons on touch screen devices
if ('ontouchstart' in document.documentElement) { if (UI.isTouchDevice) {
// Show mobile buttons // Show mobile buttons
$D('noVNC_mobile_buttons').style.display = "inline"; $D('noVNC_mobile_buttons').style.display = "inline";
UI.setMouseButton(); UI.setMouseButton();
...@@ -140,8 +152,10 @@ start: function(callback) { ...@@ -140,8 +152,10 @@ start: function(callback) {
// Open the description dialog // Open the description dialog
$D('noVNC_description').style.display = "block"; $D('noVNC_description').style.display = "block";
} else { } else {
// Open the connect panel on first load // Show the connect panel on first load unless autoconnecting
UI.toggleConnectPanel(); if (autoconnect === UI.connSettingsOpen) {
UI.toggleConnectPanel();
}
} }
// Add mouse event click/focus/blur event handlers to the UI // Add mouse event click/focus/blur event handlers to the UI
...@@ -160,7 +174,8 @@ addMouseHandlers: function() { ...@@ -160,7 +174,8 @@ addMouseHandlers: function() {
$D("noVNC_mouse_button2").onclick = function () { UI.setMouseButton(4); }; $D("noVNC_mouse_button2").onclick = function () { UI.setMouseButton(4); };
$D("noVNC_mouse_button4").onclick = function () { UI.setMouseButton(0); }; $D("noVNC_mouse_button4").onclick = function () { UI.setMouseButton(0); };
$D("showKeyboard").onclick = UI.showKeyboard; $D("showKeyboard").onclick = UI.showKeyboard;
//$D("keyboardinput").onkeydown = function (event) { onKeyDown(event); };
$D("keyboardinput").oninput = UI.keyInput;
$D("keyboardinput").onblur = UI.keyInputBlur; $D("keyboardinput").onblur = UI.keyInputBlur;
$D("showExtraKeysButton").onclick = UI.showExtraKeys; $D("showExtraKeysButton").onclick = UI.showExtraKeys;
...@@ -367,7 +382,7 @@ toggleSettingsPanel: function() { ...@@ -367,7 +382,7 @@ toggleSettingsPanel: function() {
if (UI.rfb.get_display().get_cursor_uri()) { if (UI.rfb.get_display().get_cursor_uri()) {
UI.updateSetting('cursor'); UI.updateSetting('cursor');
} else { } else {
UI.updateSetting('cursor', false); UI.updateSetting('cursor', !UI.isTouchDevice);
$D('noVNC_cursor').disabled = true; $D('noVNC_cursor').disabled = true;
} }
UI.updateSetting('clip'); UI.updateSetting('clip');
...@@ -529,7 +544,7 @@ updateVisualState: function() { ...@@ -529,7 +544,7 @@ updateVisualState: function() {
UI.rfb.get_display().get_cursor_uri()) { UI.rfb.get_display().get_cursor_uri()) {
$D('noVNC_cursor').disabled = connected; $D('noVNC_cursor').disabled = connected;
} else { } else {
UI.updateSetting('cursor', false); UI.updateSetting('cursor', !UI.isTouchDevice);
$D('noVNC_cursor').disabled = true; $D('noVNC_cursor').disabled = true;
} }
$D('noVNC_shared').disabled = connected; $D('noVNC_shared').disabled = connected;
...@@ -715,13 +730,18 @@ setViewDrag: function(drag) { ...@@ -715,13 +730,18 @@ setViewDrag: function(drag) {
// On touch devices, show the OS keyboard // On touch devices, show the OS keyboard
showKeyboard: function() { showKeyboard: function() {
var kbi, skb, l;
kbi = $D('keyboardinput');
skb = $D('showKeyboard');
l = kbi.value.length;
if(UI.keyboardVisible === false) { if(UI.keyboardVisible === false) {
$D('keyboardinput').focus(); kbi.focus();
kbi.setSelectionRange(l, l); // Move the caret to the end
UI.keyboardVisible = true; UI.keyboardVisible = true;
$D('showKeyboard').className = "noVNC_status_button_selected"; skb.className = "noVNC_status_button_selected";
} else if(UI.keyboardVisible === true) { } else if(UI.keyboardVisible === true) {
$D('keyboardinput').blur(); kbi.blur();
$D('showKeyboard').className = "noVNC_status_button"; skb.className = "noVNC_status_button";
UI.keyboardVisible = false; UI.keyboardVisible = false;
} }
}, },
...@@ -737,6 +757,35 @@ keepKeyboard: function() { ...@@ -737,6 +757,35 @@ keepKeyboard: function() {
} }
}, },
// When keypress events are left uncought, catch the input events from
// the keyboardinput element instead and send the corresponding key events.
keyInput: function(event) {
var elem, input, len;
elem = $D('keyboardinput');
input = event.target.value;
len = (elem.selectionStart > input.length) ? elem.selectionStart : input.length;
if (len < 1) { // something removed?
UI.rfb.sendKey(0xff08); // send BACKSPACE
} else if (len > 1) { // new input?
for (var i = len-1; i > 0; i -= 1) {
// HTML does not consider trailing whitespaces as a part of the string
// and they are therefore undefined.
if (input[len-i] !== undefined) {
UI.rfb.sendKey(input.charCodeAt(len-i)); // send charCode
} else {
UI.rfb.sendKey(0x0020); // send SPACE
}
}
}
// In order to be able to delete text which has been written in
// another session there has to always be text in the
// keyboardinput element with which backspace can interact.
// We also need to reset the input field text to avoid overflow.
elem.value = "x";
},
keyInputBlur: function() { keyInputBlur: function() {
$D('showKeyboard').className = "noVNC_status_button"; $D('showKeyboard').className = "noVNC_status_button";
//Weird bug in iOS if you change keyboardVisible //Weird bug in iOS if you change keyboardVisible
......
...@@ -298,9 +298,11 @@ Util.getEventPosition = function (e, obj, scale) { ...@@ -298,9 +298,11 @@ Util.getEventPosition = function (e, obj, scale) {
if (typeof scale === "undefined") { if (typeof scale === "undefined") {
scale = 1; scale = 1;
} }
var x = Math.max(Math.min(docX - pos.x, obj.width-1), 0); var realx = docX - pos.x;
var y = Math.max(Math.min(docY - pos.y, obj.height-1), 0); var realy = docY - pos.y;
return {'x': x / scale, 'y': y / scale}; var x = Math.max(Math.min(realx, obj.width-1), 0);
var y = Math.max(Math.min(realy, obj.height-1), 0);
return {'x': x / scale, 'y': y / scale, 'realx': realx / scale, 'realy': realy / scale};
}; };
......
...@@ -66,7 +66,7 @@ ...@@ -66,7 +66,7 @@
<input type="image" src="images/keyboard.png" <input type="image" src="images/keyboard.png"
id="showKeyboard" class="noVNC_status_button" id="showKeyboard" class="noVNC_status_button"
value="Keyboard" title="Show Keyboard"/> value="Keyboard" title="Show Keyboard"/>
<input type="email" autocapitalize="off" autocorrect="off" <input type="text" autocapitalize="off" autocorrect="off"
id="keyboardinput" class=""/> id="keyboardinput" class=""/>
<div id="noVNC_extra_keys"> <div id="noVNC_extra_keys">
<input type="image" src="images/showextrakeys.png" <input type="image" src="images/showextrakeys.png"
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<!-- <!--
noVNC example: simple example using default UI noVNC example: simple example using default UI
Copyright (C) 2012 Joel Martin Copyright (C) 2012 Joel Martin
Copyright (C) 2013 Samuel Mannehed for Cendio AB Copyright (C) 2013 Samuel Mannehed for Cendio AB
...@@ -128,12 +128,12 @@ ...@@ -128,12 +128,12 @@
// if port == 80 (or 443) then it won't be present and should be // if port == 80 (or 443) then it won't be present and should be
// set manually // set manually
if (!port) { if (!port) {
if (window.location.protocol.substring(0,4) == 'http') { if (window.location.protocol.substring(0,5) == 'https') {
port = 80;
}
else if (window.location.protocol.substring(0,5) == 'https') {
port = 443; port = 443;
} }
else if (window.location.protocol.substring(0,4) == 'http') {
port = 80;
}
} }
// If a token variable is passed in, set the parameter in a cookie. // If a token variable is passed in, set the parameter in a cookie.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment