[pve-devel] [RFC novnc 1/3] upgrade novnc to commit a7619faf18993384dc12b66da1c39c49f57596cf

Dominik Csapak d.csapak at proxmox.com
Mon Jan 23 13:59:27 CET 2017


this upgrades the novnc to the commit
a7619faf18993384dc12b66da1c39c49f57596cf

and rebases our patches, to make it easier to maintain upgrades in the future

the major changes are:

* new novnc gui (a bar which autohides)
* getting rid of the send-keys menu
   this can all be done now with the novnc keys menu
* better integration of our patches with upstream novnc
* many novnc fixes and improvements (see upstream commits)

Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
---
 Makefile                                           |   5 +-
 debian/install                                     |  26 +-
 ...vert-Use-Unicode-keysym-range-as-fallback.patch |  91 ++++
 debian/patches/0002-add-pve-specific-js-code.patch | 542 +++++++++++++++++++++
 debian/patches/0003-add-pve-style.patch            |  76 +++
 debian/patches/0004-remove-vnc-logos.patch         |  56 +++
 ...-change-src-directory-for-images-js-files.patch | 184 +++++++
 debian/patches/0006-add-pve.js-to-vnc.html.patch   |  26 +
 debian/patches/0007-add-pve-vnc-commands.patch     |  45 ++
 ...0008-add-replaceable-snippets-in-vnc.html.patch |  42 ++
 debian/patches/0009-focus-canvas-after-load.patch  |  44 ++
 debian/patches/0010-decrease-animation-time.patch  |  83 ++++
 debian/patches/series                              |  14 +-
 13 files changed, 1204 insertions(+), 30 deletions(-)
 create mode 100644 debian/patches/0001-Revert-Use-Unicode-keysym-range-as-fallback.patch
 create mode 100644 debian/patches/0002-add-pve-specific-js-code.patch
 create mode 100644 debian/patches/0003-add-pve-style.patch
 create mode 100644 debian/patches/0004-remove-vnc-logos.patch
 create mode 100644 debian/patches/0005-change-src-directory-for-images-js-files.patch
 create mode 100644 debian/patches/0006-add-pve.js-to-vnc.html.patch
 create mode 100644 debian/patches/0007-add-pve-vnc-commands.patch
 create mode 100644 debian/patches/0008-add-replaceable-snippets-in-vnc.html.patch
 create mode 100644 debian/patches/0009-focus-canvas-after-load.patch
 create mode 100644 debian/patches/0010-decrease-animation-time.patch

diff --git a/Makefile b/Makefile
index 701c9d6..238bb4b 100644
--- a/Makefile
+++ b/Makefile
@@ -23,9 +23,6 @@ deb ${DEB}: ${TARSRC}
 	rm -rf ${NOVNCDIR}
 	tar xf ${NOVNCSRC}
 	cp -a debian ${NOVNCDIR}/debian
-	cp ${NOVNCDIR}/include/ui.js ${NOVNCDIR}/pveui.js
-	# fix file permissions
-	chmod 0644 ${NOVNCDIR}/include/jsunzip.js
 	echo "git clone git://git.proxmox.com/git/novnc-pve.git\\ngit checkout ${GITVERSION}" > ${NOVNCDIR}/debian/SOURCE
 	cd ${NOVNCDIR}; dpkg-buildpackage -b -uc -us
 	lintian ${DEB}
@@ -34,7 +31,7 @@ deb ${DEB}: ${TARSRC}
 download:
 	rm -rf ${NOVNCDIR}
 	git clone git://github.com/kanaka/noVNC ${NOVNCDIR}
-	cd ${NOVNCDIR}; git checkout -b local a0e7ab43dca0ce11a713694ee4cf530bd3b17c5a
+	cd ${NOVNCDIR}; git checkout -b local a7619faf18993384dc12b66da1c39c49f57596cf
 	tar czf ${NOVNCSRC} ${NOVNCDIR}
 
 .PHONY: upload
diff --git a/debian/install b/debian/install
index 2594cec..4ce365a 100644
--- a/debian/install
+++ b/debian/install
@@ -1,22 +1,4 @@
-pveui.js		/usr/share/novnc-pve/include
-images  		/usr/share/novnc-pve
-include/base64.js   	/usr/share/novnc-pve/include
-include/des.js  	/usr/share/novnc-pve/include
-include/display.js  	/usr/share/novnc-pve/include
-include/keysymdef.js   	/usr/share/novnc-pve/include
-include/keyboard.js   	/usr/share/novnc-pve/include
-include/input.js   	/usr/share/novnc-pve/include
-include/logo.js   	/usr/share/novnc-pve/include
-include/base.css   	/usr/share/novnc-pve/include
-include/blue.css   	/usr/share/novnc-pve/include
-include/black.css   	/usr/share/novnc-pve/include
-include/playback.js   	/usr/share/novnc-pve/include
-include/rfb.js   	/usr/share/novnc-pve/include
-include/util.js   	/usr/share/novnc-pve/include
-include/websock.js   	/usr/share/novnc-pve/include
-include/webutil.js   	/usr/share/novnc-pve/include
-include/jsunzip.js   	/usr/share/novnc-pve/include
-include/Orbitron700.ttf	/usr/share/novnc-pve/include
-include/Orbitron700.woff /usr/share/novnc-pve/include
-include/keysym.js	/usr/share/novnc-pve/include
-include/inflator.js    /usr/share/novnc-pve/include
+app			/usr/share/novnc-pve
+core	  		/usr/share/novnc-pve
+tests			/usr/share/novnc-pve
+vnc.html		/usr/share/novnc-pve
diff --git a/debian/patches/0001-Revert-Use-Unicode-keysym-range-as-fallback.patch b/debian/patches/0001-Revert-Use-Unicode-keysym-range-as-fallback.patch
new file mode 100644
index 0000000..93cf3b5
--- /dev/null
+++ b/debian/patches/0001-Revert-Use-Unicode-keysym-range-as-fallback.patch
@@ -0,0 +1,91 @@
+From a241b64300cd408102c290ba47d78f10a6710423 Mon Sep 17 00:00:00 2001
+From: Dominik Csapak <d.csapak at proxmox.com>
+Date: Tue, 17 Jan 2017 15:00:33 +0100
+Subject: [PATCH 01/10] Revert "Use Unicode keysym range as fallback"
+To: pve-devel at pve.proxmox.com
+
+This reverts commit 115eedf69c465548a44eab1b2a6492546b2ed6e1.
+
+Conflicts:
+	tests/test.helper.js
+---
+ core/input/keysymdef.js | 8 +-------
+ core/input/util.js      | 5 ++++-
+ tests/test.helper.js    | 6 +++---
+ utils/parse.js          | 8 +-------
+ 4 files changed, 9 insertions(+), 18 deletions(-)
+
+diff --git a/core/input/keysymdef.js b/core/input/keysymdef.js
+index c4d0ace..f45d9d9 100644
+--- a/core/input/keysymdef.js
++++ b/core/input/keysymdef.js
+@@ -10,13 +10,7 @@ var keysyms = (function(){
+ 
+     function lookup(k) { return k ? {keysym: k, keyname: keynames ? keynames[k] : k} : undefined; }
+     return {
+-        fromUnicode : function(u) {
+-            var keysym = codepoints[u];
+-            if (keysym === undefined) {
+-                keysym = 0x01000000 | u;
+-            }
+-            return lookup(keysym);
+-        },
++        fromUnicode : function(u) { return lookup(codepoints[u]); },
+         lookup : lookup
+     };
+ })();
+diff --git a/core/input/util.js b/core/input/util.js
+index 52b3128..efdcced 100644
+--- a/core/input/util.js
++++ b/core/input/util.js
+@@ -184,7 +184,10 @@ var KeyboardUtil = {};
+             codepoint = evt.keyCode;
+         }
+         if (codepoint) {
+-            return keysyms.fromUnicode(substituteCodepoint(codepoint));
++            var res = keysyms.fromUnicode(substituteCodepoint(codepoint));
++            if (res) {
++                return res;
++            }
+         }
+         // we could check evt.key here.
+         // Legal values are defined in http://www.w3.org/TR/DOM-Level-3-Events/#key-values-list,
+diff --git a/tests/test.helper.js b/tests/test.helper.js
+index 4a1c65f..b7edaa8 100644
+--- a/tests/test.helper.js
++++ b/tests/test.helper.js
+@@ -38,9 +38,9 @@ describe('Helpers', function() {
+         it('should map characters which aren\'t in Latin1 *or* Windows-1252 to keysyms', function() {
+             expect(keysyms.fromUnicode('ŵ'.charCodeAt())).to.have.property('keysym', 0x1000175);
+         });
+-        it('should map unknown codepoints to the Unicode range', function() {
+-            expect(keysyms.fromUnicode('\n'.charCodeAt())).to.have.property('keysym', 0x100000a);
+-            expect(keysyms.fromUnicode('\u262D'.charCodeAt())).to.have.property('keysym', 0x100262d);
++        it('should return undefined for unknown codepoints', function() {
++            expect(keysyms.fromUnicode('\n'.charCodeAt())).to.be.undefined;
++            expect(keysyms.fromUnicode('\u1F686'.charCodeAt())).to.be.undefined;
+         });
+         // This requires very recent versions of most browsers... skipping for now
+         it.skip('should map UCS-4 codepoints to the Unicode range', function() {
+diff --git a/utils/parse.js b/utils/parse.js
+index fd79b12..02ac66c 100644
+--- a/utils/parse.js
++++ b/utils/parse.js
+@@ -87,13 +87,7 @@ var out = "// This file describes mappings from Unicode codepoints to the keysym
+ "\n" +
+ "    function lookup(k) { return k ? {keysym: k, keyname: keynames ? keynames[k] : k} : undefined; }\n" +
+ "    return {\n" +
+-"        fromUnicode : function(u) {\n" +
+-"            var keysym = codepoints[u];\n" +
+-"            if (keysym === undefined) {\n" +
+-"                keysym = 0x01000000 | u;\n" +
+-"            }\n" +
+-"            return lookup(keysym);\n" +
+-"        },\n" +
++"        fromUnicode : function(u) { return lookup(codepoints[u]); },\n" +
+ "        lookup : lookup\n" +
+ "    };\n" +
+ "})();\n";
+-- 
+2.1.4
+
diff --git a/debian/patches/0002-add-pve-specific-js-code.patch b/debian/patches/0002-add-pve-specific-js-code.patch
new file mode 100644
index 0000000..9e343d4
--- /dev/null
+++ b/debian/patches/0002-add-pve-specific-js-code.patch
@@ -0,0 +1,542 @@
+From 9631898f401f04df6d511f1b0da6bcee94a1592e Mon Sep 17 00:00:00 2001
+From: Dominik Csapak <d.csapak at proxmox.com>
+Date: Tue, 13 Dec 2016 16:11:35 +0100
+Subject: [PATCH 02/10] add pve specific js code
+To: pve-devel at pve.proxmox.com
+
+this adds the pve specific javascript code for novnc,
+we define the api2 request method,
+our own initialization, and the resize and detect migrate code
+
+we also patch the ui.js sligthly, to integrate our methods,
+and to disable the qemu extended keyevent
+
+Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
+---
+ app/pve.js  | 382 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ app/ui.js   |  43 ++++++-
+ core/rfb.js |   5 +-
+ 3 files changed, 422 insertions(+), 8 deletions(-)
+ create mode 100644 app/pve.js
+
+diff --git a/app/pve.js b/app/pve.js
+new file mode 100644
+index 0000000..b8553bd
+--- /dev/null
++++ b/app/pve.js
+@@ -0,0 +1,382 @@
++/*
++ * PVE Specific noVNC code
++ *
++ * We do all specific code to pve here, e.g.
++ *
++ * sendkeys via api, start/stop/shutdown/etc via api
++ */
++
++var PVEUI;
++
++PVEUI = {
++    urlEncode: function(object) {
++	var i,value, params = [];
++
++	for (i in object) {
++	    if (object.hasOwnProperty(i)) {
++		value = object[i];
++		if (value === undefined) value = '';
++		params.push(encodeURIComponent(i) + '=' + encodeURIComponent(String(value)));
++	    }
++	}
++
++	return params.join('&');
++    },
++
++    API2Request: function(reqOpts) {
++
++	reqOpts.method = reqOpts.method || 'GET';
++
++	var xhr = new XMLHttpRequest();
++
++	xhr.onload = function() {
++	    var scope = reqOpts.scope || this;
++	    var result;
++	    var errmsg;
++
++	    if (xhr.readyState === 4) {
++		var ctype = xhr.getResponseHeader('Content-Type');
++		if (xhr.status === 200) {
++		    if (ctype.match(/application\/json;/)) {
++			result = JSON.parse(xhr.responseText);
++		    } else {
++			errmsg = 'got unexpected content type ' + ctype;
++		    }
++		} else {
++		    errmsg = 'Error ' + xhr.status + ': ' + xhr.statusText;
++		}
++	    } else {
++		errmsg = 'Connection error - server offline?';
++	    }
++
++	    if (errmsg !== undefined) {
++		if (reqOpts.failure) {
++		    reqOpts.failure.call(scope, errmsg);
++		}
++	    } else {
++		if (reqOpts.success) {
++		    reqOpts.success.call(scope, result);
++		}
++	    }
++	    if (reqOpts.callback) {
++		reqOpts.callback.call(scope, errmsg === undefined);
++	    }
++	}
++
++	var data = PVEUI.urlEncode(reqOpts.params || {});
++
++	if (reqOpts.method === 'GET') {
++	    xhr.open(reqOpts.method, "/api2/json" + reqOpts.url + '?' + data);
++	} else {
++	    xhr.open(reqOpts.method, "/api2/json" + reqOpts.url);
++	}
++	xhr.setRequestHeader('Cache-Control', 'no-cache');
++	if (reqOpts.method === 'POST' || reqOpts.method === 'PUT') {
++	    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
++	    xhr.setRequestHeader('CSRFPreventionToken', PVE.CSRFPreventionToken);
++	    xhr.send(data);
++	} else if (reqOpts.method === 'GET') {
++	    xhr.send();
++	} else {
++	    throw "unknown method";
++	}
++    },
++
++    pve_detect_migrated_vm: function() {
++	if (!(UI.consoletype === 'kvm' || UI.consoletype === 'lxc')) {
++	    return;
++	}
++
++	// try to detect migrated VM
++	PVEUI.API2Request({
++	    url: '/cluster/resources',
++	    method: 'GET',
++	    success: function(result) {
++		var list = result.data;
++		list.every(function(item) {
++		    if ((item.type === 'qemu' || item.type === 'lxc') &&
++			(item.vmid == UI.vmid)) {
++			var url = "?" + PVEUI.urlEncode({
++			    console: UI.consoletype,
++			    novnc: 1,
++			    vmid: UI.vmid,
++			    vmname: UI.vmname,
++			    node: item.node,
++			    resize: UI.resize
++			});
++			location.href = url;
++			return false; // break
++		    }
++		    return true;
++		});
++	    }
++	});
++    },
++
++    pve_vm_command: function(cmd, params, reload) {
++	var baseUrl;
++	var confirmMsg = "";
++
++	switch(cmd) {
++	    case "start":
++		reload = 1;
++	    case "shutdown":
++	    case "stop":
++	    case "reset":
++	    case "suspend":
++	    case "resume":
++		confirmMsg = "Do you really want to " + cmd + " VM/CT {0}?";
++		break;
++	    case "reload":
++		location.reload();
++		break;
++	    default:
++		throw "implement me " + cmd;
++	}
++
++	confirmMsg = confirmMsg.replace('{0}', UI.vmid);
++
++	if (confirmMsg !== "" && confirm(confirmMsg) !== true) {
++	    return;
++	}
++
++	PVEUI.closePVECommandPanel();
++
++	if (UI.consoletype === 'kvm') {
++	    baseUrl = '/nodes/' + UI.nodename + '/qemu/' + UI.vmid;
++	} else if (UI.consoletype === 'lxc') {
++	    baseUrl = '/nodes/' + UI.nodename + '/lxc/' + UI.vmid;
++	} else {
++	    throw "unknown VM type";
++	}
++
++	PVEUI.API2Request({
++	    params: params,
++	    url: baseUrl + "/status/" + cmd,
++	    method: 'POST',
++	    failure: function(msg) {
++		UI.showStatus(msg, 'warning');
++	    },
++	    success: function() {
++		UI.showStatus("VM command '" + cmd +"' successful", 'normal');
++		if (reload) {
++		    setTimeout(function() {
++			location.reload();
++		    }, 1000);
++		};
++	    }
++	});
++    },
++
++    togglePVECommandPanel: function() {
++	if (document.getElementById('pve_commands').classList.contains("noVNC_open")) {
++	    PVEUI.closePVECommandPanel();
++	} else {
++	    PVEUI.openPVECommandPanel();
++	}
++    },
++
++    openPVECommandPanel: function() {
++	UI.closeAllPanels();
++	UI.openControlbar();
++
++	document.getElementById('pve_commands').classList.add("noVNC_open");
++	document.getElementById('pve_commands_button').classList.add("noVNC_selected");
++    },
++
++    closePVECommandPanel: function() {
++	document.getElementById('pve_commands').classList.remove("noVNC_open");
++	document.getElementById('pve_commands_button').classList.remove("noVNC_selected");
++    },
++
++    addPVEHandlers: function() {
++	document.getElementById('pve_commands_button')
++	    .addEventListener('click', PVEUI.togglePVECommandPanel);
++
++	// show/hide the buttons
++	document.getElementById('noVNC_settings_button')
++	    .classList.add('noVNC_hidden');
++	document.getElementById('noVNC_disconnect_button')
++	    .classList.add('noVNC_hidden');
++	if (UI.consoletype === 'kvm') {
++	    document.getElementById('noVNC_clipboard_button')
++		.classList.add('noVNC_hidden');
++	}
++
++	if (UI.consoletype === 'shell' || UI.consoletype === 'upgrade') {
++	    document.getElementById('pve_commands_button')
++		.classList.add('noVNC_hidden');
++	}
++
++	var scaleType = UI.getSetting('resize');
++	if (scaleType !== 'scale') {
++	    document.getElementById('noVNC_fullscreen_button')
++		.classList.add('noVNC_hidden');
++	}
++
++	// add command logic
++	var commandArray = [
++	    { cmd: 'start', kvm: 1, lxc: 1},
++	    { cmd: 'stop', kvm: 1, lxc: 1},
++	    { cmd: 'shutdown', kvm: 1, lxc: 1},
++	    { cmd: 'suspend', kvm: 1},
++	    { cmd: 'resume', kvm: 1},
++	    { cmd: 'reset', kvm: 1},
++	    { cmd: 'reload', kvm: 1, lxc: 1, shell: 1},
++	];
++
++	commandArray.forEach(function(item) {
++	    var el = document.getElementById('pve_command_'+item.cmd);
++	    if (!el) {
++		return;
++	    }
++
++	    if (item[UI.consoletype] === 1) {
++		el.onclick = function() {
++		    PVEUI.pve_vm_command(item.cmd);
++		};
++	    } else {
++		el.classList.add('noVNC_hidden');
++	    }
++	});
++
++	//edge/ie11 quirk
++	var canvas = document.getElementById('noVNC_canvas');
++	canvas.onclick = canvas.focus;
++    },
++
++    start: function(callback) {
++	UI.consoletype = WebUtil.getQueryVar('console');
++	UI.vmid = WebUtil.getQueryVar('vmid');
++	UI.vmname = WebUtil.getQueryVar('vmname');
++	UI.nodename = WebUtil.getQueryVar('node');
++	UI.resize = WebUtil.getQueryVar('resize');
++
++	var url;
++	var wsurl;
++	var params = { websocket: 1 };
++	var btn;
++	var title;
++
++	if (UI.consoletype === 'kvm') {
++	    var baseUrl = '/nodes/' + UI.nodename + '/qemu/' + UI.vmid;
++	    url =  baseUrl + '/vncproxy';
++	    wsurl = baseUrl + '/vncwebsocket';
++	    title = "VM " + UI.vmid;
++	    if (UI.vmname) {
++		title += " ('" + UI.vmname + "')";
++	    }
++	} else if (UI.consoletype === 'lxc') {
++	    var baseUrl = '/nodes/' + UI.nodename + '/lxc/' + UI.vmid;
++	    url =  baseUrl + '/vncproxy';
++	    wsurl = baseUrl + '/vncwebsocket';
++	    title = "CT " + UI.vmid;
++	    if (UI.vmname) {
++		title += " ('" + UI.vmname + "')";
++	    }
++	} else if (UI.consoletype === 'shell') {
++	    var baseUrl = '/nodes/' + UI.nodename;
++	    url =  baseUrl + '/vncshell';
++	    wsurl = baseUrl + '/vncwebsocket';
++	    title = "node '" + UI.nodename + "'";
++	} else if (UI.consoletype === 'upgrade') {
++	    var baseUrl = '/nodes/' + UI.nodename;
++	    url =  baseUrl + '/vncshell';
++	    wsurl = baseUrl + '/vncwebsocket';
++	    params.upgrade = 1;
++	    title = gettext('System upgrade on node {0}');
++	    title = title.replace(/\{0\}/, UI.nodename);
++	} else {
++	    throw "implement me";
++	}
++
++	document.title = title;
++
++	var start_vnc_viewer = function(param) {
++	    var wsparams = PVEUI.urlEncode({
++		port: param.port,
++		vncticket: param.ticket
++	    });
++
++	    UI.updateSetting('host', window.location.hostname);
++	    UI.updateSetting('port', window.location.port || 443);
++//	    window.location.hash = 'password=' + param.ticket;
++	    document.getElementById('noVNC_password_input').value = param.ticket;
++	    UI.updateSetting('encrypt', true);
++	    UI.updateSetting('true_color', true);
++	    UI.updateSetting('cursor', !UI.isTouchDevice);
++	    UI.updateSetting('shared', true);
++	    UI.updateSetting('view_only', false);
++	    UI.updateSetting('resize', UI.resize);
++
++	    UI.updateSetting('path', 'api2/json' + wsurl + "?" + wsparams);
++
++	    UI.start(callback);
++	};
++
++	PVEUI.API2Request({
++	    url: url,
++	    method: 'POST',
++	    params: params,
++	    success: function(result) {
++		start_vnc_viewer(result.data);
++	    },
++	    failure: function(msg) {
++		console.log(msg);
++	    }
++	});
++    },
++
++    lastFBWidth: undefined,
++    lastFBHeight: undefined,
++    sizeUpdateTimer: undefined,
++
++    updateFBSize: function(rfb, width, height) {
++	try {
++	    // Note: window size must be even number for firefox
++	    PVEUI.lastFBWidth = Math.floor((width + 1)/2)*2;
++	    PVEUI.lastFBHeight = Math.floor((height + 1)/2)*2;
++
++	    if (PVEUI.sizeUpdateTimer !== undefined) {
++		clearInterval(PVEUI.sizeUpdateTimer);
++	    }
++	    if (UI.getSetting('clip')) return;
++
++	    var update_size = function() {
++		var oh;
++		var ow;
++
++		if (window.innerHeight) {
++		    oh = window.innerHeight;
++		    ow = window.innerWidth;
++		} else if (document.documentElement &&
++		    document.documentElement.clientHeight) {
++		    oh = document.documentElement.clientHeight;
++		    ow = document.documentElement.clientWidth;
++		} else if (document.body) {
++		    oh = document.body.clientHeight;
++		    ow = document.body.clientWidth;
++		}  else {
++		    throw "can't get window size";
++		}
++
++		var offsetw = PVEUI.lastFBWidth - ow;
++		var offseth = PVEUI.lastFBHeight - oh;
++		if (offsetw !== 0 || offseth !== 0) {
++		    //console.log("try resize by " + offsetw + " " + offseth);
++		    try {
++			window.resizeBy(offsetw, offseth);
++		    } catch (e) {
++			console.log('resizing did not work', e);
++		    }
++		}
++	    };
++
++	    update_size();
++	    PVEUI.sizeUpdateTimer = setInterval(update_size, 1000);
++
++	} catch(e) {
++	    console.log(e);
++	}
++    },
++};
+diff --git a/app/ui.js b/app/ui.js
+index 40b0c33..3fdb4fe 100644
+--- a/app/ui.js
++++ b/app/ui.js
+@@ -106,10 +106,16 @@ var UI;
+         lastKeyboardinput: null,
+         defaultKeyboardinputLen: 100,
+ 
++	pveAllowMigratedTest: false, // enable after first succesful connection
++	consoletype: undefined,
++	vmid: undefined,
++	nodename: undefined,
++	resize: undefined,
++
+         // Setup rfb object, load settings from browser storage, then call
+         // UI.init to setup the UI/menus
+         load: function(callback) {
+-            WebUtil.initSettings(UI.start, callback);
++            WebUtil.initSettings(PVEUI.start, callback);
+         },
+ 
+         // Render default UI and initialize settings menu
+@@ -149,6 +155,7 @@ var UI;
+             UI.addConnectionControlHandlers();
+             UI.addClipboardHandlers();
+             UI.addSettingsHandlers();
++	    PVEUI.addPVEHandlers();
+ 
+             UI.openControlbar();
+ 
+@@ -163,8 +170,8 @@ var UI;
+ 
+             document.getElementById('noVNC_setting_host').focus();
+ 
+-            var autoconnect = WebUtil.getConfigVar('autoconnect', false);
+-            if (autoconnect === 'true' || autoconnect == '1') {
++            var autoconnect = true;
++	    if (autoconnect === 'true' || autoconnect == '1') {
+                 autoconnect = true;
+                 UI.connect();
+             } else {
+@@ -429,6 +436,7 @@ var UI;
+                     break;
+                 case 'connected':
+                     UI.connected = true;
++		    UI.pveAllowMigratedTest = true;
+                     document.documentElement.classList.add("noVNC_connected");
+                     if (rfb && rfb.get_encrypt()) {
+                         msg = _("Connected (encrypted) to ") + UI.desktopName;
+@@ -444,6 +452,15 @@ var UI;
+                     break;
+                 case 'disconnected':
+                     UI.showStatus(_("Disconnected"));
++		    if (UI.pveAllowMigratedTest === true) {
++			UI.pveAllowMigratedTest = false;
++			if (UI.consoletype === 'lxc') {
++			    // restart migration needs some time
++			    setTimeout(PVEUI.pve_detect_migrated_vm, 5000);
++			} else {
++			    PVEUI.pve_detect_migrated_vm();
++			}
++		    }
+                     break;
+                 default:
+                     msg = "Invalid UI state";
+@@ -871,6 +888,7 @@ var UI;
+             UI.closeXvpPanel();
+             UI.closeClipboardPanel();
+             UI.closeExtraKeys();
++	    PVEUI.closePVECommandPanel();
+         },
+ 
+ /* ------^-------
+@@ -1050,7 +1068,12 @@ var UI;
+             var port = document.getElementById('noVNC_setting_port').value;
+             var path = document.getElementById('noVNC_setting_path').value;
+ 
+-            var password = WebUtil.getConfigVar('password');
++	    var password = document.getElementById('noVNC_password_input').value;
++
++	    if (!password) {
++		password = WebUtil.getConfigVar('password');
++	    }
++
+             if (password === null) {
+                 password = undefined;
+             }
+@@ -1075,6 +1098,7 @@ var UI;
+             UI.rfb.set_repeaterID(UI.getSetting('repeaterID'));
+ 
+             UI.rfb.connect(host, port, password, path);
++	    document.getElementById('noVNC_password_input').value = "";
+         },
+ 
+         disconnect: function() {
+@@ -1648,8 +1672,15 @@ var UI;
+         },
+ 
+         updateSessionSize: function(rfb, width, height) {
+-            UI.updateViewClip();
+-            UI.updateViewDrag();
++	    var scaleType = UI.getSetting('resize');
++
++	    if (typeof scaleType !== 'undefined') {
++		PVEUI.updateFBSize(rfb, width, height);
++		return;
++	    }
++
++	    UI.updateViewClip();
++	    UI.updateViewDrag();
+         },
+ 
+         updateDesktopName: function(rfb, name) {
+diff --git a/core/rfb.js b/core/rfb.js
+index c6e1973..e75b47e 100644
+--- a/core/rfb.js
++++ b/core/rfb.js
+@@ -2428,9 +2428,10 @@
+             this._FBU.rects--;
+ 
+             var keyboardEvent = document.createEvent("keyboardEvent");
++
+             if (keyboardEvent.code !== undefined) {
+-                this._qemuExtKeyEventSupported = true;
+-                this._keyboard.setQEMUVNCKeyboardHandler();
++//                this._qemuExtKeyEventSupported = true;
++//                this._keyboard.setQEMUVNCKeyboardHandler();
+             }
+         },
+ 
+-- 
+2.1.4
+
diff --git a/debian/patches/0003-add-pve-style.patch b/debian/patches/0003-add-pve-style.patch
new file mode 100644
index 0000000..75d76b6
--- /dev/null
+++ b/debian/patches/0003-add-pve-style.patch
@@ -0,0 +1,76 @@
+From ad60d48fbce1150d42227d59b3500410cc596e14 Mon Sep 17 00:00:00 2001
+From: Dominik Csapak <d.csapak at proxmox.com>
+Date: Tue, 13 Dec 2016 16:03:41 +0100
+Subject: [PATCH 03/10] add pve style
+To: pve-devel at pve.proxmox.com
+
+this adds the custom pve style (based on black.css)
+
+we hide the connect button, and add custom colors,
+and fix the z-index of the connect overlay
+
+Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
+---
+ app/styles/pve.css | 37 +++++++++++++++++++++++++++++++++++++
+ vnc.html           |  1 +
+ 2 files changed, 38 insertions(+)
+ create mode 100644 app/styles/pve.css
+
+diff --git a/app/styles/pve.css b/app/styles/pve.css
+new file mode 100644
+index 0000000..35002fe
+--- /dev/null
++++ b/app/styles/pve.css
+@@ -0,0 +1,37 @@
++/*
++ * noVNC black CSS
++ * Copyright (C) 2012 Joel Martin
++ * Copyright (C) 2013 Samuel Mannehed for Cendio AB
++ * noVNC is licensed under the MPL 2.0 (see LICENSE.txt)
++ * This file is licensed under the 2-Clause BSD license (see LICENSE.txt).
++ */
++
++.noVNC_panel {
++    border: 0px;
++    background:#4c4c4c;;
++    color:#fff;
++}
++
++#noVNC_control_bar, #noVNC_control_bar_handle, .noVNC_panel .noVNC_heading {
++    background: #4c4c4c;
++}
++
++.noVNC_button.noVNC_selected {
++    background: #3892d4;
++}
++
++#pve_commands > input[type=button] {
++    width: 100%;
++}
++
++#noVNC_canvas:focus {
++    outline: none;
++}
++
++#noVNC_transition {
++    z-index: 0;
++}
++
++#noVNC_connect_button {
++    display: none;
++}
+diff --git a/vnc.html b/vnc.html
+index 5e241a2..06dc650 100644
+--- a/vnc.html
++++ b/vnc.html
+@@ -54,6 +54,7 @@
+ 
+     <!-- Stylesheets -->
+     <link rel="stylesheet" href="app/styles/base.css" />
++    <link rel="stylesheet" href="/novnc/app/styles/pve.css" />
+ 
+     <!--
+     <script type='text/javascript'
+-- 
+2.1.4
+
diff --git a/debian/patches/0004-remove-vnc-logos.patch b/debian/patches/0004-remove-vnc-logos.patch
new file mode 100644
index 0000000..24ce388
--- /dev/null
+++ b/debian/patches/0004-remove-vnc-logos.patch
@@ -0,0 +1,56 @@
+From da147c3b8d8330779bd49e61f99c91ec0a34a88f Mon Sep 17 00:00:00 2001
+From: Dominik Csapak <d.csapak at proxmox.com>
+Date: Fri, 20 Jan 2017 10:35:05 +0100
+Subject: [PATCH 04/10] remove vnc logos
+To: pve-devel at pve.proxmox.com
+
+to show the pve icon instead
+
+Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
+---
+ vnc.html | 25 -------------------------
+ 1 file changed, 25 deletions(-)
+
+diff --git a/vnc.html b/vnc.html
+index 06dc650..b378a18 100644
+--- a/vnc.html
++++ b/vnc.html
+@@ -23,35 +23,10 @@
+                 Remove this if you use the .htaccess -->
+     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
+ 
+-    <!-- Icons (see Makefile for what the sizes are for) -->
+-    <link rel="icon" sizes="16x16" type="image/png" href="app/images/icons/novnc-16x16.png">
+-    <link rel="icon" sizes="24x24" type="image/png" href="app/images/icons/novnc-24x24.png">
+-    <link rel="icon" sizes="32x32" type="image/png" href="app/images/icons/novnc-32x32.png">
+-    <link rel="icon" sizes="48x48" type="image/png" href="app/images/icons/novnc-48x48.png">
+-    <link rel="icon" sizes="60x60" type="image/png" href="app/images/icons/novnc-60x60.png">
+-    <link rel="icon" sizes="64x64" type="image/png" href="app/images/icons/novnc-64x64.png">
+-    <link rel="icon" sizes="72x72" type="image/png" href="app/images/icons/novnc-72x72.png">
+-    <link rel="icon" sizes="76x76" type="image/png" href="app/images/icons/novnc-76x76.png">
+-    <link rel="icon" sizes="96x96" type="image/png" href="app/images/icons/novnc-96x96.png">
+-    <link rel="icon" sizes="120x120" type="image/png" href="app/images/icons/novnc-120x120.png">
+-    <link rel="icon" sizes="144x144" type="image/png" href="app/images/icons/novnc-144x144.png">
+-    <link rel="icon" sizes="152x152" type="image/png" href="app/images/icons/novnc-152x152.png">
+-    <link rel="icon" sizes="192x192" type="image/png" href="app/images/icons/novnc-192x192.png">
+-    <link rel="icon" sizes="512x512" type="image/png" href="app/images/icons/novnc-512x512.png">
+-    <link rel="icon" sizes="any" type="image/svg+xml" href="app/images/icons/novnc-icon.svg">
+-    <!-- Repeated last so that legacy handling will pick this -->
+-    <link rel="icon" sizes="16x16" type="image/png" href="app/images/icons/novnc-16x16.png">
+-
+     <!-- Apple iOS Safari settings -->
+     <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
+     <meta name="apple-mobile-web-app-capable" content="yes" />
+     <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
+-    <!-- Home Screen Icons (favourites and bookmarks use the normal icons) -->
+-    <link rel="apple-touch-icon" sizes="60x60" type="image/png" href="app/images/icons/novnc-60x60.png">
+-    <link rel="apple-touch-icon" sizes="76x76" type="image/png" href="app/images/icons/novnc-76x76.png">
+-    <link rel="apple-touch-icon" sizes="120x120" type="image/png" href="app/images/icons/novnc-120x120.png">
+-    <link rel="apple-touch-icon" sizes="152x152" type="image/png" href="app/images/icons/novnc-152x152.png">
+-
+     <!-- Stylesheets -->
+     <link rel="stylesheet" href="app/styles/base.css" />
+     <link rel="stylesheet" href="/novnc/app/styles/pve.css" />
+-- 
+2.1.4
+
diff --git a/debian/patches/0005-change-src-directory-for-images-js-files.patch b/debian/patches/0005-change-src-directory-for-images-js-files.patch
new file mode 100644
index 0000000..6e3326d
--- /dev/null
+++ b/debian/patches/0005-change-src-directory-for-images-js-files.patch
@@ -0,0 +1,184 @@
+From 1979b19655e10fc79d95fe67b222b3ccf37d532f Mon Sep 17 00:00:00 2001
+From: Dominik Csapak <d.csapak at proxmox.com>
+Date: Tue, 17 Jan 2017 17:24:03 +0100
+Subject: [PATCH 05/10] change src directory for images/js files
+To: pve-devel at pve.proxmox.com
+
+since they will be in /novnc/
+
+Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
+---
+ vnc.html | 54 +++++++++++++++++++++++++++---------------------------
+ 1 file changed, 27 insertions(+), 27 deletions(-)
+
+diff --git a/vnc.html b/vnc.html
+index b378a18..eb17ff1 100644
+--- a/vnc.html
++++ b/vnc.html
+@@ -28,7 +28,7 @@
+     <meta name="apple-mobile-web-app-capable" content="yes" />
+     <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
+     <!-- Stylesheets -->
+-    <link rel="stylesheet" href="app/styles/base.css" />
++    <link rel="stylesheet" href="/novnc/app/styles/base.css" />
+     <link rel="stylesheet" href="/novnc/app/styles/pve.css" />
+ 
+     <!--
+@@ -57,49 +57,49 @@
+             <h1 class="noVNC_logo" translate="no"><span>no</span><br />VNC</h1>
+ 
+             <!-- Drag/Pan the viewport -->
+-            <input type="image" alt="viewport drag" src="app/images/drag.svg"
++            <input type="image" alt="viewport drag" src="/novnc/app/images/drag.svg"
+                 id="noVNC_view_drag_button" class="noVNC_button noVNC_hidden"
+                 title="Move/Drag Viewport" />
+ 
+             <!--noVNC Touch Device only buttons-->
+             <div id="noVNC_mobile_buttons">
+-                <input type="image" alt="No mousebutton" src="app/images/mouse_none.svg"
++                <input type="image" alt="No mousebutton" src="/novnc/app/images/mouse_none.svg"
+                     id="noVNC_mouse_button0" class="noVNC_button"
+                     title="Active Mouse Button"/>
+-                <input type="image" alt="Left mousebutton" src="app/images/mouse_left.svg"
++                <input type="image" alt="Left mousebutton" src="/novnc/app/images/mouse_left.svg"
+                     id="noVNC_mouse_button1" class="noVNC_button"
+                     title="Active Mouse Button"/>
+-                <input type="image" alt="Middle mousebutton" src="app/images/mouse_middle.svg"
++                <input type="image" alt="Middle mousebutton" src="/novnc/app/images/mouse_middle.svg"
+                     id="noVNC_mouse_button2" class="noVNC_button"
+                     title="Active Mouse Button"/>
+-                <input type="image" alt="Right mousebutton" src="app/images/mouse_right.svg"
++                <input type="image" alt="Right mousebutton" src="/novnc/app/images/mouse_right.svg"
+                     id="noVNC_mouse_button4" class="noVNC_button"
+                     title="Active Mouse Button"/>
+-                <input type="image" alt="Keyboard" src="app/images/keyboard.svg"
++                <input type="image" alt="Keyboard" src="/novnc/app/images/keyboard.svg"
+                     id="noVNC_keyboard_button" class="noVNC_button"
+                     value="Keyboard" title="Show Keyboard" />
+             </div>
+ 
+             <!-- Extra manual keys -->
+             <div id="noVNC_extra_keys">
+-                <input type="image" alt="Extra keys" src="app/images/toggleextrakeys.svg"
++                <input type="image" alt="Extra keys" src="/novnc/app/images/toggleextrakeys.svg"
+                     id="noVNC_toggle_extra_keys_button" class="noVNC_button"
+                     title="Show Extra Keys"/>
+                 <div class="noVNC_vcenter">
+                 <div id="noVNC_modifiers" class="noVNC_panel">
+-                    <input type="image" alt="Ctrl" src="app/images/ctrl.svg"
++                    <input type="image" alt="Ctrl" src="/novnc/app/images/ctrl.svg"
+                         id="noVNC_toggle_ctrl_button" class="noVNC_button"
+                         title="Toggle Ctrl"/>
+-                    <input type="image" alt="Alt" src="app/images/alt.svg"
++                    <input type="image" alt="Alt" src="/novnc/app/images/alt.svg"
+                         id="noVNC_toggle_alt_button" class="noVNC_button"
+                         title="Toggle Alt"/>
+-                    <input type="image" alt="Tab" src="app/images/tab.svg"
++                    <input type="image" alt="Tab" src="/novnc/app/images/tab.svg"
+                         id="noVNC_send_tab_button" class="noVNC_button"
+                         title="Send Tab"/>
+-                    <input type="image" alt="Esc" src="app/images/esc.svg"
++                    <input type="image" alt="Esc" src="/novnc/app/images/esc.svg"
+                         id="noVNC_send_esc_button" class="noVNC_button"
+                         title="Send Escape"/>
+-                    <input type="image" alt="Ctrl+Alt+Del" src="app/images/ctrlaltdel.svg"
++                    <input type="image" alt="Ctrl+Alt+Del" src="/novnc/app/images/ctrlaltdel.svg"
+                         id="noVNC_send_ctrl_alt_del_button" class="noVNC_button"
+                         title="Send Ctrl-Alt-Del" />
+                 </div>
+@@ -107,13 +107,13 @@
+             </div>
+ 
+             <!-- XVP Shutdown/Reboot -->
+-            <input type="image" alt="Shutdown/Reboot" src="app/images/power.svg"
++            <input type="image" alt="Shutdown/Reboot" src="/novnc/app/images/power.svg"
+                 id="noVNC_xvp_button" class="noVNC_button"
+                 title="Shutdown/Reboot..." />
+             <div class="noVNC_vcenter">
+             <div id="noVNC_xvp" class="noVNC_panel">
+                 <div class="noVNC_heading">
+-                    <img src="app/images/power.svg"> Power
++                    <img src="/novnc/app/images/power.svg"> Power
+                 </div>
+                 <input type="button" id="noVNC_xvp_shutdown_button" value="Shutdown" />
+                 <input type="button" id="noVNC_xvp_reboot_button" value="Reboot" />
+@@ -122,13 +122,13 @@
+             </div>
+ 
+             <!-- Clipboard -->
+-            <input type="image" alt="Clipboard" src="app/images/clipboard.svg"
++            <input type="image" alt="Clipboard" src="/novnc/app/images/clipboard.svg"
+                 id="noVNC_clipboard_button" class="noVNC_button"
+                 title="Clipboard" />
+             <div class="noVNC_vcenter">
+             <div id="noVNC_clipboard" class="noVNC_panel">
+                 <div class="noVNC_heading">
+-                    <img src="app/images/clipboard.svg"> Clipboard
++                    <img src="/novnc/app/images/clipboard.svg"> Clipboard
+                 </div>
+                 <textarea id="noVNC_clipboard_text" rows=5></textarea>
+                 <br />
+@@ -138,19 +138,19 @@
+             </div>
+ 
+             <!-- Toggle fullscreen -->
+-            <input type="image" alt="Fullscreen" src="app/images/fullscreen.svg"
++            <input type="image" alt="Fullscreen" src="/novnc/app/images/fullscreen.svg"
+                 id="noVNC_fullscreen_button" class="noVNC_button noVNC_hidden"
+                 title="Fullscreen" />
+ 
+             <!-- Settings -->
+-            <input type="image" alt="Settings" src="app/images/settings.svg"
++            <input type="image" alt="Settings" src="/novnc/app/images/settings.svg"
+                 id="noVNC_settings_button" class="noVNC_button"
+                 title="Settings" />
+             <div class="noVNC_vcenter">
+             <div id="noVNC_settings" class="noVNC_panel">
+                 <ul>
+                     <li class="noVNC_heading">
+-                        <img src="app/images/settings.svg"> Settings
++                        <img src="/novnc/app/images/settings.svg"> Settings
+                     </li>
+                     <li>
+                         <label><input id="noVNC_setting_shared" type="checkbox" /> Shared Mode</label>
+@@ -225,7 +225,7 @@
+             </div>
+ 
+             <!-- Connection Controls -->
+-            <input type="image" alt="Disconnect" src="app/images/disconnect.svg"
++            <input type="image" alt="Disconnect" src="/novnc/app/images/disconnect.svg"
+                 id="noVNC_disconnect_button" class="noVNC_button"
+                 title="Disconnect" />
+ 
+@@ -242,7 +242,7 @@
+         <div id="noVNC_connect_dlg">
+             <div class="noVNC_logo" translate="no"><span>no</span>VNC</div>
+             <div id="noVNC_connect_button"><div>
+-                <img src="app/images/connect.svg"> Connect
++                <img src="/novnc/app/images/connect.svg"> Connect
+             </div></div>
+         </div>
+     </div>
+@@ -287,14 +287,14 @@
+     </div>
+ 
+     <audio id="noVNC_bell">
+-        <source src="app/sounds/bell.oga" type="audio/ogg">
+-        <source src="app/sounds/bell.mp3" type="audio/mpeg">
++        <source src="/novnc/app/sounds/bell.oga" type="audio/ogg">
++        <source src="/novnc/app/sounds/bell.mp3" type="audio/mpeg">
+     </audio>
+ 
+     <!-- begin scripts -->
+-    <script src="core/util.js"></script>
+-    <script src="app/webutil.js"></script>
+-    <script src="app/ui.js"></script>
++    <script src="/novnc/core/util.js"></script>
++    <script src="/novnc/app/webutil.js"></script>
++    <script src="/novnc/app/ui.js"></script>
+     <!-- end scripts -->
+ 
+  </body>
+-- 
+2.1.4
+
diff --git a/debian/patches/0006-add-pve.js-to-vnc.html.patch b/debian/patches/0006-add-pve.js-to-vnc.html.patch
new file mode 100644
index 0000000..e46e702
--- /dev/null
+++ b/debian/patches/0006-add-pve.js-to-vnc.html.patch
@@ -0,0 +1,26 @@
+From d1defde3f030fdf88c773ddb1b2bd51c4940ed8f Mon Sep 17 00:00:00 2001
+From: Dominik Csapak <d.csapak at proxmox.com>
+Date: Fri, 20 Jan 2017 10:35:30 +0100
+Subject: [PATCH 06/10] add pve.js to vnc.html
+To: pve-devel at pve.proxmox.com
+
+Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
+---
+ vnc.html | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/vnc.html b/vnc.html
+index eb17ff1..65f0d9b 100644
+--- a/vnc.html
++++ b/vnc.html
+@@ -294,6 +294,7 @@
+     <!-- begin scripts -->
+     <script src="/novnc/core/util.js"></script>
+     <script src="/novnc/app/webutil.js"></script>
++    <script src="/novnc/app/pve.js"></script>
+     <script src="/novnc/app/ui.js"></script>
+     <!-- end scripts -->
+ 
+-- 
+2.1.4
+
diff --git a/debian/patches/0007-add-pve-vnc-commands.patch b/debian/patches/0007-add-pve-vnc-commands.patch
new file mode 100644
index 0000000..6cb6a84
--- /dev/null
+++ b/debian/patches/0007-add-pve-vnc-commands.patch
@@ -0,0 +1,45 @@
+From b749a1c606d0755d326dfea5cb7460dd4e6fed12 Mon Sep 17 00:00:00 2001
+From: Dominik Csapak <d.csapak at proxmox.com>
+Date: Fri, 20 Jan 2017 10:35:43 +0100
+Subject: [PATCH 07/10] add pve vnc commands
+To: pve-devel at pve.proxmox.com
+
+Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
+---
+ vnc.html | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/vnc.html b/vnc.html
+index 65f0d9b..bffdd68 100644
+--- a/vnc.html
++++ b/vnc.html
+@@ -142,6 +142,26 @@
+                 id="noVNC_fullscreen_button" class="noVNC_button noVNC_hidden"
+                 title="Fullscreen" />
+ 
++	    <!-- PVE Commands -->
++            <input type="image" alt="Commands" src="/novnc/app/images/power.svg"
++                id="pve_commands_button" class="noVNC_button"
++                title="Commands" />
++
++            <div class="noVNC_vcenter">
++            <div id="pve_commands" class="noVNC_panel">
++                <div class="noVNC_heading">
++                    <img src="/novnc/app/images/power.svg"> Commands
++                </div>
++		<input id="pve_command_start" type="button" value="Start" />
++		<input id="pve_command_shutdown" type="button" value="Shutdown" />
++		<input id="pve_command_stop" type="button" value="Stop" />
++		<input id="pve_command_reset" type="button" value="Reset" />
++		<input id="pve_command_suspend" type="button" value="Suspend" />
++		<input id="pve_command_resume" type="button" value="Resume" />
++		<input id="pve_command_reload" type="button" value="Reload" />
++	    </div>
++	    </div>
++
+             <!-- Settings -->
+             <input type="image" alt="Settings" src="/novnc/app/images/settings.svg"
+                 id="noVNC_settings_button" class="noVNC_button"
+-- 
+2.1.4
+
diff --git a/debian/patches/0008-add-replaceable-snippets-in-vnc.html.patch b/debian/patches/0008-add-replaceable-snippets-in-vnc.html.patch
new file mode 100644
index 0000000..7dd23c3
--- /dev/null
+++ b/debian/patches/0008-add-replaceable-snippets-in-vnc.html.patch
@@ -0,0 +1,42 @@
+From c03aac94392a70ab8906d51c6a0ec41fc814805c Mon Sep 17 00:00:00 2001
+From: Dominik Csapak <d.csapak at proxmox.com>
+Date: Fri, 20 Jan 2017 10:16:09 +0100
+Subject: [PATCH 08/10] add replaceable snippets in vnc.html
+To: pve-devel at pve.proxmox.com
+
+so that we can insert the username/csrftoken via search/replace
+
+Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
+---
+ vnc.html | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/vnc.html b/vnc.html
+index bffdd68..2a0ae0d 100644
+--- a/vnc.html
++++ b/vnc.html
+@@ -15,7 +15,7 @@
+     or the fragment:
+         http://example.com/#host=HOST&port=PORT&encrypt=1&true_color=1
+     -->
+-    <title>noVNC</title>
++    <title>{PVETITLE}</title>
+ 
+     <meta charset="utf-8" />
+ 
+@@ -36,6 +36,12 @@
+         src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
+     -->
+ 
++    <script type="text/javascript">
++	if (typeof(PVE) === 'undefined') PVE = {};
++	PVE.UserName = '{PVEUSERNAME}';
++	PVE.CSRFPreventionToken = '{PVECSRFTOKEN}';
++	INCLUDE_URI='/novnc/';
++    </script>
+ </head>
+ 
+ <body>
+-- 
+2.1.4
+
diff --git a/debian/patches/0009-focus-canvas-after-load.patch b/debian/patches/0009-focus-canvas-after-load.patch
new file mode 100644
index 0000000..82366eb
--- /dev/null
+++ b/debian/patches/0009-focus-canvas-after-load.patch
@@ -0,0 +1,44 @@
+From add411bae4a359258ae35fd34fe3a711403a56bf Mon Sep 17 00:00:00 2001
+From: Dominik Csapak <d.csapak at proxmox.com>
+Date: Wed, 14 Dec 2016 08:40:02 +0100
+Subject: [PATCH 09/10] focus canvas after load
+To: pve-devel at pve.proxmox.com
+
+or else in some browsers, the canvas does not get the focus after
+loading in an iframe
+
+Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
+---
+ app/ui.js | 2 ++
+ vnc.html  | 2 +-
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/app/ui.js b/app/ui.js
+index 3fdb4fe..23f6d0d 100644
+--- a/app/ui.js
++++ b/app/ui.js
+@@ -444,6 +444,8 @@ var UI;
+                         msg = _("Connected (unencrypted) to ") + UI.desktopName;
+                     }
+                     UI.showStatus(msg);
++		    rfb.get_keyboard().set_focused(true);
++		    document.getElementById("noVNC_canvas").focus();
+                     break;
+                 case 'disconnecting':
+                     UI.connected = false;
+diff --git a/vnc.html b/vnc.html
+index 2a0ae0d..b47ac7b 100644
+--- a/vnc.html
++++ b/vnc.html
+@@ -305,7 +305,7 @@
+                 autocorrect="off" autocomplete="off" spellcheck="false"
+                 mozactionhint="Enter"></textarea>
+ 
+-            <canvas id="noVNC_canvas" width="0" height="0">
++            <canvas id="noVNC_canvas" width="0" height="0" tabindex="0">
+                         Canvas not supported.
+             </canvas>
+         </div>
+-- 
+2.1.4
+
diff --git a/debian/patches/0010-decrease-animation-time.patch b/debian/patches/0010-decrease-animation-time.patch
new file mode 100644
index 0000000..c2467da
--- /dev/null
+++ b/debian/patches/0010-decrease-animation-time.patch
@@ -0,0 +1,83 @@
+From faa5189910423a3eb7cbaba4e97a40861b60b250 Mon Sep 17 00:00:00 2001
+From: Dominik Csapak <d.csapak at proxmox.com>
+Date: Fri, 20 Jan 2017 10:55:49 +0100
+Subject: [PATCH 10/10] decrease animation time
+To: pve-devel at pve.proxmox.com
+
+because 0.5s is too long
+
+Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
+---
+ app/styles/base.css | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/app/styles/base.css b/app/styles/base.css
+index ebf0916..938c5b7 100644
+--- a/app/styles/base.css
++++ b/app/styles/base.css
+@@ -205,7 +205,7 @@ input[type=button]:active, select:active {
+   z-index: 1000;
+   left: 50%;
+   transform: translate(-50%, -50px);
+-  transition: 0.5s ease-in-out;
++  transition: 0.1s ease-in-out;
+ 
+   visibility: hidden;
+   opacity: 0;
+@@ -259,7 +259,7 @@ input[type=button]:active, select:active {
+   position: fixed;
+   z-index: 10;
+ 
+-  transition: 0.5s ease-in-out;
++  transition: 0.1s ease-in-out;
+ 
+   /* Edge misrenders animations wihthout this */
+   transform: translateX(0);
+@@ -276,7 +276,7 @@ input[type=button]:active, select:active {
+   position: relative;
+   left: -100%;
+ 
+-  transition: 0.5s ease-in-out;
++  transition: 0.1s ease-in-out;
+ 
+   background-color: rgb(110, 132, 163);
+   border-radius: 0 10px 10px 0;
+@@ -294,7 +294,7 @@ input[type=button]:active, select:active {
+   height: 100%;
+   width: 30px;
+   left: -30px;
+-  transition: box-shadow 0.5s ease-in-out;
++  transition: box-shadow 0.1s ease-in-out;
+ }
+ #noVNC_control_bar.noVNC_open::before {
+   box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5);
+@@ -328,7 +328,7 @@ input[type=button]:active, select:active {
+ }
+ #noVNC_control_bar_handle:after {
+   content: "";
+-  transition: transform 0.5s ease-in-out;
++  transition: transform 0.1s ease-in-out;
+   background: url("../images/handle.svg");
+   position: absolute;
+   top: 22px; /* (50px-6px)/2 */
+@@ -416,7 +416,7 @@ input[type=button]:active, select:active {
+ .noVNC_panel {
+   transform: translateX(25px);
+ 
+-  transition: 0.5s ease-in-out;
++  transition: 0.25s ease-in-out;
+ 
+   max-height: 100vh; /* Chrome is buggy with 100% */
+   overflow-x: hidden;
+@@ -605,7 +605,7 @@ input[type=button]:active, select:active {
+ 
+   cursor: pointer;
+ 
+-  transition: 0.5s ease-in-out;
++  transition: 0.1s ease-in-out;
+ 
+   visibility: hidden;
+   opacity: 0;
+-- 
+2.1.4
+
diff --git a/debian/patches/series b/debian/patches/series
index c12bbac..8b04b14 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,4 +1,10 @@
-pveui.patch
-fix-base-css.patch
-fix-ie11-resize.patch
-fix-CtrlAltDel-button-mobile.patch
+0001-Revert-Use-Unicode-keysym-range-as-fallback.patch
+0002-add-pve-specific-js-code.patch
+0003-add-pve-style.patch
+0004-remove-vnc-logos.patch
+0005-change-src-directory-for-images-js-files.patch
+0006-add-pve.js-to-vnc.html.patch
+0007-add-pve-vnc-commands.patch
+0008-add-replaceable-snippets-in-vnc.html.patch
+0009-focus-canvas-after-load.patch
+0010-decrease-animation-time.patch
-- 
2.1.4





More information about the pve-devel mailing list