Add resize as a capability

Makes the API more transparent than piggybacking on completion
of the first framebuffer update.
This commit is contained in:
Pierre Ossman 2017-10-13 14:40:25 +02:00
parent cd523e8f28
commit 832be2625b
5 changed files with 46 additions and 23 deletions

View File

@ -207,10 +207,9 @@ var UI = {
'onUpdateState': UI.updateState,
'onDisconnected': UI.disconnectFinished,
'onCredentialsRequired': UI.credentials,
'onCapabilities': UI.updatePowerButton,
'onCapabilities': function () { UI.updatePowerButton(); UI.initialResize(); },
'onClipboard': UI.clipboardReceive,
'onBell': UI.bell,
'onFBUComplete': UI.initialResize,
'onFBResize': UI.updateSessionSize,
'onDesktopName': UI.updateDesktopName});
return true;
@ -431,6 +430,7 @@ var UI = {
case 'connected':
UI.connected = true;
UI.inhibit_reconnect = false;
UI.doneInitialResize = false;
document.documentElement.classList.add("noVNC_connected");
if (rfb && rfb.get_encrypt()) {
msg = _("Connected (encrypted) to ") + UI.desktopName;
@ -1079,9 +1079,6 @@ var UI = {
// Disable automatic reconnecting
UI.inhibit_reconnect = true;
// Restore the callback used for initial resize
UI.rfb.set_onFBUComplete(UI.initialResize);
// Don't display the connection settings until we're actually disconnected
},
@ -1275,13 +1272,14 @@ var UI = {
// Normally we only apply the current resize mode after a window resize
// event. This means that when a new connection is opened, there is no
// resize mode active.
// We have to wait until the first FBU because this is where the client
// will find the supported encodings of the server. Some calls later in
// the chain is dependant on knowing the server-capabilities.
initialResize: function(rfb, fbu) {
// We have to wait until we know the capabilities of the server as
// some calls later in the chain is dependant on knowing the
// server-capabilities.
initialResize: function() {
if (UI.doneInitialResize) return;
UI.applyResizeMode();
// After doing this once, we remove the callback.
UI.rfb.set_onFBUComplete(function() { });
UI.doneInitialResize = true;
},
/* ------^-------

View File

@ -49,7 +49,7 @@ export default function RFB(defaults) {
this._rfb_tightvnc = false;
this._rfb_xvp_ver = 0;
this._capabilities = { power: false };
this._capabilities = { power: false, resize: false };
this._encHandlers = {};
this._encStats = {};
@ -638,6 +638,11 @@ RFB.prototype = {
}
},
_setCapability: function (cap, val) {
this._capabilities[cap] = val;
this._onCapabilities(this, this._capabilities);
},
_handle_message: function () {
if (this._sock.rQlen() === 0) {
Log.Warn("handle_message called on an empty receive queue");
@ -1277,8 +1282,7 @@ RFB.prototype = {
case 1: // XVP_INIT
this._rfb_xvp_ver = xvp_ver;
Log.Info("XVP extensions enabled (version " + this._rfb_xvp_ver + ")");
this._capabilities.power = true;
this._onCapabilities(this, this._capabilities)
this._setCapability("power", true);
break;
default:
this._fail("Unexpected server message",
@ -2398,6 +2402,8 @@ RFB.encodingHandlers = {
if (this._sock.rQwait("ExtendedDesktopSize", this._FBU.bytes)) { return false; }
this._supportsSetDesktopSize = true;
this._setCapability("resize", true);
var number_of_screens = this._sock.rQpeek8();
this._FBU.bytes = 4 + (number_of_screens * 16);

View File

@ -41,7 +41,7 @@ attribute mode is one of the following:
| wsProtocols | arr | RW | ['binary'] | Protocols to use in the WebSocket connection
| repeaterID | str | RW | '' | UltraVNC RepeaterID to connect to
| viewportDrag | bool | RW | false | Move the viewport on mouse drags
| capabilities | arr | RO | [] | Supported capabilities (can include: 'power')
| capabilities | arr | RO | [] | Supported capabilities (can include: 'power', 'resize')
## 2 Methods

View File

@ -1684,6 +1684,25 @@ describe('Remote Frame Buffer Protocol Client', function() {
return data;
}
it('should call callback when resize is supported', function () {
client.set_onCapabilities(sinon.spy());
expect(client._supportsSetDesktopSize).to.be.false;
expect(client.get_capabilities().resize).to.be.false;
var reason_for_change = 0; // server initiated
var status_code = 0; // No error
send_fbu_msg([{ x: reason_for_change, y: status_code,
width: 4, height: 4, encoding: -308 }],
make_screen_data(1), client);
expect(client._supportsSetDesktopSize).to.be.true;
expect(client.get_onCapabilities()).to.have.been.calledOnce;
expect(client.get_onCapabilities().args[0][1].resize).to.be.true;
expect(client.get_capabilities().resize).to.be.true;
}),
it('should handle a resize requested by this client', function () {
var reason_for_change = 1; // requested by this client
var status_code = 0; // No error
@ -1692,7 +1711,6 @@ describe('Remote Frame Buffer Protocol Client', function() {
width: 20, height: 50, encoding: -308 }],
make_screen_data(1), client);
expect(client._supportsSetDesktopSize).to.be.true;
expect(client._fb_width).to.equal(20);
expect(client._fb_height).to.equal(50);
@ -1712,7 +1730,6 @@ describe('Remote Frame Buffer Protocol Client', function() {
width: 20, height: 50, encoding: -308 }],
make_screen_data(1), client);
expect(client._supportsSetDesktopSize).to.be.true;
expect(client._fb_width).to.equal(20);
expect(client._fb_height).to.equal(50);
@ -1732,7 +1749,6 @@ describe('Remote Frame Buffer Protocol Client', function() {
width: 60, height: 50, encoding: -308 }],
make_screen_data(3), client);
expect(client._supportsSetDesktopSize).to.be.true;
expect(client._fb_width).to.equal(60);
expect(client._fb_height).to.equal(50);
@ -1799,7 +1815,8 @@ describe('Remote Frame Buffer Protocol Client', function() {
client._sock._websocket._receive_data(new Uint8Array([250, 0, 10, 1]));
expect(client._rfb_xvp_ver).to.equal(10);
expect(client.get_onCapabilities()).to.have.been.calledOnce;
expect(client.get_onCapabilities()).to.have.been.calledWith(client, { power: true });
expect(client.get_onCapabilities().args[0][1].power).to.be.true;
expect(client.get_capabilities().power).to.be.true;
});
it('should fail on unknown XVP message types', function () {

View File

@ -80,6 +80,7 @@
import RFB from './core/rfb.js';
var rfb;
var doneInitialResize;
var resizeTimeout;
var desktopName;
@ -92,9 +93,10 @@
rfb.requestDesktopSize(innerW, innerH - controlbarH);
}
}
function FBUComplete(rfb, fbu) {
function initialResize() {
if (doneInitialResize) return;
UIresize();
rfb.set_onFBUComplete(function() { });
doneInitialResize = true;
}
function updateDesktopName(rfb, name) {
desktopName = name;
@ -153,6 +155,7 @@
status("Connecting", "normal");
break;
case 'connected':
doneInitialResize = false;
if (rfb && rfb.get_encrypt()) {
status("Connected (encrypted) to " +
desktopName, "normal");
@ -262,9 +265,8 @@
'onNotification': notification,
'onUpdateState': updateState,
'onDisconnected': disconnected,
'onCapabilities': updatePowerButtons,
'onCapabilities': function () { updatePowerButtons(); initialResize(); },
'onCredentialsRequired': credentials,
'onFBUComplete': FBUComplete,
'onDesktopName': updateDesktopName});
} catch (exc) {
status('Unable to create RFB client -- ' + exc, 'error');