summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Mannehed <samuel@cendio.se>2016-08-29 14:59:28 +0200
committerSamuel Mannehed <samuel@cendio.se>2016-10-01 01:29:44 +0200
commita7127fee73a5fb8941f3076eef9eab4eaaabc998 (patch)
tree7b9072ccbbb297ef0ecdbbea22cc7407c44fa815
parent4cfd49c8c395e6ff9a8cf3c458ed7fc40e3420b3 (diff)
downloadnovnc-a7127fee73a5fb8941f3076eef9eab4eaaabc998.tar.gz
Don't abuse state change function for messages
This doesn't even work anymore since we fixed it to ignore changes to the current state. Add a separate callback for notifications instead.
-rw-r--r--app/ui.js5
-rw-r--r--core/rfb.js35
-rw-r--r--tests/test.rfb.js31
-rw-r--r--vnc_auto.html4
4 files changed, 69 insertions, 6 deletions
diff --git a/app/ui.js b/app/ui.js
index 601abc2..f65e198 100644
--- a/app/ui.js
+++ b/app/ui.js
@@ -338,6 +338,7 @@ var UI;
initRFB: function() {
try {
UI.rfb = new RFB({'target': document.getElementById('noVNC_canvas'),
+ 'onNotification': UI.notification,
'onUpdateState': UI.updateState,
'onPasswordRequired': UI.passwordRequired,
'onXvpInit': UI.updateXvpButton,
@@ -486,6 +487,10 @@ var UI;
document.getElementById('noVNC_status').classList.remove("noVNC_open");
},
+ notification: function (rfb, msg, level, options) {
+ UI.showStatus(msg, level);
+ },
+
activateControlbar: function(event) {
clearTimeout(UI.idleControlbarTimeout);
// We manipulate the anchor instead of the actual control
diff --git a/core/rfb.js b/core/rfb.js
index f441dab..8a5d817 100644
--- a/core/rfb.js
+++ b/core/rfb.js
@@ -158,6 +158,7 @@
// Callback functions
'onUpdateState': function () { }, // onUpdateState(rfb, state, oldstate, statusMsg): state update/change
+ 'onNotification': function () { }, // onNotification(rfb, msg, level, options): notification for UI
'onPasswordRequired': function () { }, // onPasswordRequired(rfb, msg): VNC password is required
'onClipboard': function () { }, // onClipboard(rfb, text): RFB clipboard contents received
'onBell': function () { }, // onBell(rfb): RFB Bell message received
@@ -535,6 +536,33 @@
return false;
},
+ /*
+ * Send a notification to the UI. Valid levels are:
+ * 'normal'|'warn'|'error'
+ *
+ * NOTE: Options could be added in the future.
+ * NOTE: If this function is called multiple times, remember that the
+ * interface could be only showing the latest notification.
+ */
+ _notification: function(msg, level, options) {
+ switch (level) {
+ case 'normal':
+ case 'warn':
+ case 'error':
+ Util.Debug("Notification[" + level + "]:" + msg);
+ break;
+ default:
+ Util.Error("Invalid notification level: " + level);
+ return;
+ }
+
+ if (options) {
+ this._onNotification(this, msg, level, options);
+ } else {
+ this._onNotification(this, msg, level);
+ }
+ },
+
_handle_message: function () {
if (this._sock.rQlen() === 0) {
Util.Warn("handle_message called on an empty receive queue");
@@ -1130,7 +1158,8 @@
switch (xvp_msg) {
case 0: // XVP_FAIL
- this._updateState(this._rfb_state, "Operation Failed");
+ Util.Error("Operation Failed");
+ this._notification("XVP Operation Failed", 'error');
break;
case 1: // XVP_INIT
this._rfb_xvp_ver = xvp_ver;
@@ -1322,6 +1351,7 @@
// Callback functions
['onUpdateState', 'rw', 'func'], // onUpdateState(rfb, state, oldstate, statusMsg): RFB state update/change
+ ['onNotification', 'rw', 'func'], // onNotification(rfb, msg, level, options): notification for the UI
['onPasswordRequired', 'rw', 'func'], // onPasswordRequired(rfb, msg): VNC password is required
['onClipboard', 'rw', 'func'], // onClipboard(rfb, text): RFB clipboard contents received
['onBell', 'rw', 'func'], // onBell(rfb): RFB Bell message received
@@ -2275,7 +2305,8 @@
msg = "Unknown reason";
break;
}
- Util.Info("Server did not accept the resize request: " + msg);
+ this._notification("Server did not accept the resize request: "
+ + msg, 'normal');
return true;
}
diff --git a/tests/test.rfb.js b/tests/test.rfb.js
index e1a11f0..d6f1a1f 100644
--- a/tests/test.rfb.js
+++ b/tests/test.rfb.js
@@ -338,6 +338,28 @@ describe('Remote Frame Buffer Protocol Client', function() {
expect(client._disconnTimer).to.be.null;
});
});
+
+ describe('#_notification', function () {
+ var client;
+ beforeEach(function () { client = make_rfb(); });
+
+ it('should call the notification callback', function () {
+ client.set_onNotification(sinon.spy());
+ client._notification('notify!', 'warn');
+ var spy = client.get_onNotification();
+ expect(spy).to.have.been.calledOnce;
+ expect(spy.args[0][1]).to.equal('notify!');
+ expect(spy.args[0][2]).to.equal('warn');
+ });
+
+ it('should not call the notification callback when level is invalid', function () {
+ client.set_onNotification(sinon.spy());
+ client._notification('notify!', 'invalid');
+ var spy = client.get_onNotification();
+ expect(spy).to.not.have.been.called;
+ });
+ });
+
});
describe('Page States', function () {
@@ -1730,11 +1752,12 @@ describe('Remote Frame Buffer Protocol Client', function() {
client._fb_height = 32;
});
- it('should call updateState with a message on XVP_FAIL, but keep the same state', function () {
- client._updateState = sinon.spy();
+ it('should send a notification on XVP_FAIL', function () {
+ client.set_onNotification(sinon.spy());
client._sock._websocket._receive_data(new Uint8Array([250, 0, 10, 0]));
- expect(client._updateState).to.have.been.calledOnce;
- expect(client._updateState).to.have.been.calledWith('normal', 'Operation Failed');
+ var spy = client.get_onNotification();
+ expect(spy).to.have.been.calledOnce;
+ expect(spy.args[0][1]).to.equal('XVP Operation Failed');
});
it('should set the XVP version and fire the callback with the version on XVP_INIT', function () {
diff --git a/vnc_auto.html b/vnc_auto.html
index 1d9cd9e..4362080 100644
--- a/vnc_auto.html
+++ b/vnc_auto.html
@@ -161,6 +161,9 @@
s.innerHTML = msg;
}
}
+ function notification(rfb, msg, level, options) {
+ $D('noVNC_status').innerHTML = msg;
+ }
window.onresize = function () {
// When the window has been resized, wait until the size remains
@@ -236,6 +239,7 @@
'local_cursor': WebUtil.getConfigVar('cursor', true),
'shared': WebUtil.getConfigVar('shared', true),
'view_only': WebUtil.getConfigVar('view_only', false),
+ 'onNotification: notification,
'onUpdateState': updateState,
'onXvpInit': xvpInit,
'onPasswordRequired': passwordRequired,