]> git.proxmox.com Git - mirror_novnc.git/commitdiff
Improved focus handling on touch input field
authorPierre Ossman <ossman@cendio.se>
Thu, 2 Nov 2017 14:30:36 +0000 (15:30 +0100)
committerPierre Ossman <ossman@cendio.se>
Thu, 2 Nov 2017 14:30:36 +0000 (15:30 +0100)
The previous method of retaining focus didn't work reliably when
the RFB object tried to move the focus to the canvas. Add a setting
to control "focus on click" behaviour instead of letting them try
to fight it out.

app/ui.js
core/rfb.js
docs/API.md

index dc7dbbd8344d1f328959de841a2039e78b145d33..da912f332ae03baea2ff0212cfdbcb4b2b320e8e 100644 (file)
--- a/app/ui.js
+++ b/app/ui.js
@@ -292,8 +292,6 @@ var UI = {
 
         document.documentElement
             .addEventListener('mousedown', UI.keepVirtualKeyboard, true);
-        document.documentElement
-            .addEventListener('touchstart', UI.keepVirtualKeyboard, true);
 
         document.getElementById("noVNC_control_bar")
             .addEventListener('touchstart', UI.activateControlbar);
@@ -1460,11 +1458,17 @@ var UI = {
     onfocusVirtualKeyboard: function(event) {
         document.getElementById('noVNC_keyboard_button')
             .classList.add("noVNC_selected");
+        if (UI.rfb) {
+            UI.rfb.set_focus_on_click(false);
+        }
     },
 
     onblurVirtualKeyboard: function(event) {
         document.getElementById('noVNC_keyboard_button')
             .classList.remove("noVNC_selected");
+        if (UI.rfb) {
+            UI.rfb.set_focus_on_click(true);
+        }
     },
 
     keepVirtualKeyboard: function(event) {
@@ -1492,14 +1496,7 @@ var UI = {
             }
         }
 
-        // The default action of touchstart is to generate other
-        // events, which other elements might depend on. So we can't
-        // blindly prevent that. Instead restore focus right away.
-        if (event.type === "touchstart") {
-            setTimeout(input.focus.bind(input));
-        } else {
-            event.preventDefault();
-        }
+        event.preventDefault();
     },
 
     keyboardinputReset: function() {
index 284a01bbaf82076b6cccaeba961a0df509dde3a7..a16093b6aaadbc080a12eec3117c5ef8675b4a22 100644 (file)
@@ -124,6 +124,7 @@ export default function RFB(defaults) {
         'local_cursor': false,                  // Request locally rendered cursor
         'shared': true,                         // Request shared mode
         'view_only': false,                     // Disable client mouse/keyboard
+        'focus_on_click': true,                 // Grab focus on canvas on mouse click
         'xvp_password_sep': '@',                // Separator for XVP password fields
         'disconnectTimeout': 3,                 // Time (s) to wait for disconnection
         'wsProtocols': ['binary'],              // Protocols to use in the WebSocket connection
@@ -144,6 +145,11 @@ export default function RFB(defaults) {
         'onXvpInit': function () { }            // onXvpInit(version): XVP extensions active for this connection
     });
 
+    // Bound event handlers
+    this._eventHandlers = {
+        focusCanvas: this._focusCanvas.bind(this),
+    };
+
     // main setup
     Log.Debug(">> RFB.constructor");
 
@@ -390,16 +396,16 @@ RFB.prototype = {
         }
 
         // Always grab focus on some kind of click event
-        this._target.addEventListener("mousedown", this._focusCanvas);
-        this._target.addEventListener("touchstart", this._focusCanvas);
+        this._target.addEventListener("mousedown", this._eventHandlers.focusCanvas);
+        this._target.addEventListener("touchstart", this._eventHandlers.focusCanvas);
 
         Log.Debug("<< RFB.connect");
     },
 
     _disconnect: function () {
         Log.Debug(">> RFB.disconnect");
-        this._target.removeEventListener("mousedown", this._focusCanvas);
-        this._target.removeEventListener("touchstart", this._focusCanvas);
+        this._target.removeEventListener("mousedown", this._eventHandlers.focusCanvas);
+        this._target.removeEventListener("touchstart", this._eventHandlers.focusCanvas);
         this._cleanup();
         this._sock.close();
         this._print_stats();
@@ -458,11 +464,17 @@ RFB.prototype = {
         }
     },
 
-    // Event handler for canvas so this points to the canvas element
     _focusCanvas: function(event) {
         // Respect earlier handlers' request to not do side-effects
-        if (!event.defaultPrevented)
-            this.focus();
+        if (event.defaultPrevented) {
+            return;
+        }
+
+        if (!this._focus_on_click) {
+            return;
+        }
+
+        this._target.focus();
     },
 
     /*
@@ -1478,6 +1490,7 @@ make_properties(RFB, [
     ['local_cursor', 'rw', 'bool'],         // Request locally rendered cursor
     ['shared', 'rw', 'bool'],               // Request shared mode
     ['view_only', 'rw', 'bool'],            // Disable client mouse/keyboard
+    ['focus_on_click', 'rw', 'bool'],       // Grab focus on canvas on mouse click
     ['xvp_password_sep', 'rw', 'str'],      // Separator for XVP password fields
     ['disconnectTimeout', 'rw', 'int'],     // Time (s) to wait for disconnection
     ['wsProtocols', 'rw', 'arr'],           // Protocols to use in the WebSocket connection
index a658cadebc11b65ca1b4d026c1a5e252c6740bb5..2a9e93e9236ba6b8a91e37cfee9bc26720171b2d 100644 (file)
@@ -180,6 +180,7 @@ callback event name, and the callback function.
 | local_cursor      | bool | RW   | false      | Request locally rendered cursor
 | shared            | bool | RW   | true       | Request shared VNC mode
 | view_only         | bool | RW   | false      | Disable client mouse/keyboard
+| focus_on_click    | bool | RW   | true       | Grab focus on canvas on mouse click
 | xvp_password_sep  | str  | RW   | '@'        | Separator for XVP password fields
 | disconnectTimeout | int  | RW   | 3          | Time (in seconds) to wait for disconnection
 | wsProtocols       | arr  | RW   | ['binary'] | Protocols to use in the WebSocket connection