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,9 +152,11 @@ start: function(callback) { ...@@ -140,9 +152,11 @@ 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
if (autoconnect === UI.connSettingsOpen) {
UI.toggleConnectPanel(); UI.toggleConnectPanel();
} }
}
// Add mouse event click/focus/blur event handlers to the UI // Add mouse event click/focus/blur event handlers to the UI
UI.addMouseHandlers(); UI.addMouseHandlers();
...@@ -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"
......
...@@ -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