diff --git a/README.md b/README.md index c94e13c2c..592cd888d 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ Please tweet [@noVNC](http://www.twitter.com/noVNC) if you do. * Supports all modern browsers including mobile (iOS, Android) * Supported VNC encodings: raw, copyrect, rre, hextile, tight, tightPNG * Supports scaling, clipping and resizing the desktop -* Local cursor rendering +* Local or remote cursor rendering * Clipboard copy/paste * Translations * Touch gestures for emulating common mouse actions diff --git a/core/rfb.js b/core/rfb.js index e6647eff4..2a6db1c35 100644 --- a/core/rfb.js +++ b/core/rfb.js @@ -285,6 +285,7 @@ export default class RFB extends EventTargetMixin { this.focusOnClick = true; this._viewOnly = false; + this._remoteCursor = false; this._clipViewport = false; this._scaleViewport = false; this._resizeSession = false; @@ -315,6 +316,16 @@ export default class RFB extends EventTargetMixin { } } + get remoteCursor() { return this._remoteCursor; } + set remoteCursor(remoteCursor) { + this._remoteCursor = remoteCursor; + + this._cursor.setVisibility(!remoteCursor); + if (this._rfbConnectionState === "connected") { + this._sendEncodings(); + } + } + get capabilities() { return this._capabilities; } get touchButton() { return 0; } @@ -2072,7 +2083,7 @@ export default class RFB extends EventTargetMixin { encs.push(encodings.pseudoEncodingDesktopName); encs.push(encodings.pseudoEncodingExtendedClipboard); - if (this._fbDepth == 24) { + if (this._fbDepth == 24 && !this._remoteCursor) { encs.push(encodings.pseudoEncodingVMwareCursor); encs.push(encodings.pseudoEncodingCursor); } diff --git a/core/util/cursor.js b/core/util/cursor.js index 12bccedad..6b3056ef5 100644 --- a/core/util/cursor.js +++ b/core/util/cursor.js @@ -10,7 +10,8 @@ const useFallback = !supportsCursorURIs || isTouchDevice; export default class Cursor { constructor() { - this._target = null; + this._target = null; + this._visible = true; this._canvas = document.createElement('canvas'); @@ -109,6 +110,15 @@ export default class Cursor { this._hotSpot.y = 0; } + setVisibility(visible) { + this._visible = visible; + if (visible) { + this._showCursor(); + } else { + this._hideCursor(); + } + } + // Mouse events might be emulated, this allows // moving the cursor in such cases move(clientX, clientY) { @@ -201,6 +211,9 @@ export default class Cursor { if (!target) { return false; } + if (!this._visible) { + return false; + } // Easy case if (target === this._target) { return true; diff --git a/docs/API.md b/docs/API.md index 77e905675..529e5fbde 100644 --- a/docs/API.md +++ b/docs/API.md @@ -21,6 +21,14 @@ protocol stream. movement) should be prevented from being sent to the server. Disabled by default. +`remoteCursor` + - Is a `boolean` indicating if the cursor should be drawn on the server. + Usually the cursor is drawn on the client because it provides a more + responsive user experience. However in certain situations, for example + in conjuction with `viewOnly` it might be desirable to render the + mouse cursor on the server. + Disabled by default. + `focusOnClick` - Is a `boolean` indicating if keyboard focus should automatically be moved to the remote session when a `mousedown` or `touchstart`