Эх сурвалжийг харах

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

Conflicts:
	include/ui.js
	vnc.html
samhed 11 жил өмнө
parent
commit
f4f72e9db9
6 өөрчлөгдсөн 93 нэмэгдсэн , 71 устгасан
  1. 3 3
      include/input.js
  2. 18 47
      include/rfb.js
  3. 61 12
      include/ui.js
  4. 5 3
      include/util.js
  5. 1 1
      vnc.html
  6. 5 5
      vnc_auto.html

+ 3 - 3
include/input.js

@@ -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) &&
-        (pos.x < conf.target.offsetWidth) &&
-        (pos.y < conf.target.offsetHeight)) {
+    if ((pos.realx >= 0) && (pos.realy >= 0) &&
+        (pos.realx < conf.target.offsetWidth) &&
+        (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;

+ 18 - 47
include/rfb.js

@@ -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, [
 
 
     ['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) {
         }
         }
 
 
         if (msgTimer) {
         if (msgTimer) {
-            clearInterval(msgTimer);
+            clearTimeout(msgTimer);
             msgTimer = null;
             msgTimer = null;
         }
         }
 
 
@@ -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) {
     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) {
-        if (! flushClient()) {
-            now = new Date().getTime();
-            if (now > last_req_time + conf.fbu_req_rate) {
-                last_req_time = now;
-                ws.send(fbUpdateRequests());
-            }
-        }
+    if (rfb_state === 'normal' && !viewportDragging && mouse_arr.length > 0) {
+        ws.send(mouse_arr);
+        mouse_arr = [];
     }
     }
-    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);
-    arr = arr.concat(fbUpdateRequests());
-    ws.send(arr);
+    ws.send(keyEvent(keysym, down));
 };
 };
 
 
 mouseButton = function(x, y, down, bmask) {
 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) {
 
 
     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) {
     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() {
 
 
         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 */
-        setTimeout(checkEvents, conf.check_rate);
+        checkEvents();
 
 
         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() {
     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() {
     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() {
     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) {
         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);
 };
 };
 
 

+ 61 - 12
include/ui.js

@@ -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) {
 
 
 // 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) {
     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) {
                   '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) {
     //    };
     //    };
 
 
     // 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) {
         // 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
-        UI.toggleConnectPanel();
+        // Show the connect panel on first load unless autoconnecting
+        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() {
     $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() {
         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() {
         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) {
 
 
 // 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();
-        $D('showKeyboard').className = "noVNC_status_button";
+        kbi.blur();
+        skb.className = "noVNC_status_button";
         UI.keyboardVisible = false;
         UI.keyboardVisible = false;
     }
     }
 },
 },
@@ -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

+ 5 - 3
include/util.js

@@ -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 y = Math.max(Math.min(docY - pos.y, obj.height-1), 0);
-    return {'x': x / scale, 'y': y / scale};
+    var realx = docX - pos.x;
+    var realy = docY - pos.y;
+    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};
 };
 };
 
 
 
 

+ 1 - 1
vnc.html

@@ -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"

+ 5 - 5
vnc_auto.html

@@ -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 @@
             // 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') {            
-                    port = 80;
-                }
-                else if (window.location.protocol.substring(0,5) == 'https') {            
+                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.