adds the new rebased patches, based on current novnc master
notable changes:
* (most of) our code is in an es6 module, opposed to patching the ui.js
* removed our sendkeys menu in favor of the novnc one
* you can now enter fullscreen from a popup console
* when a vm resizes its resolution, the canvas should also rescale in
  the console tab

Signed-off-by: Dominik Csapak <d.csa...@proxmox.com>
---
 debian/patches/0001-add-pve-specific-js-code.patch | 639 +++++++++++++++++++++
 ...2-change-scaling-when-toggling-fullscreen.patch |  45 ++
 debian/patches/0003-add-pve-style.patch            |  75 +++
 debian/patches/0004-remove-vnc-logos.patch         |  54 ++
 ...-change-src-directory-for-images-js-files.patch | 232 ++++++++
 debian/patches/0006-add-pve-vnc-commands.patch     |  44 ++
 ...0007-add-replaceable-snippets-in-vnc.html.patch |  41 ++
 debian/patches/0008-focus-canvas-after-load.patch  |  43 ++
 debian/patches/0009-decrease-animation-time.patch  |  73 +++
 9 files changed, 1246 insertions(+)
 create mode 100644 debian/patches/0001-add-pve-specific-js-code.patch
 create mode 100644 
debian/patches/0002-change-scaling-when-toggling-fullscreen.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-vnc-commands.patch
 create mode 100644 
debian/patches/0007-add-replaceable-snippets-in-vnc.html.patch
 create mode 100644 debian/patches/0008-focus-canvas-after-load.patch
 create mode 100644 debian/patches/0009-decrease-animation-time.patch

diff --git a/debian/patches/0001-add-pve-specific-js-code.patch 
b/debian/patches/0001-add-pve-specific-js-code.patch
new file mode 100644
index 0000000..401e53b
--- /dev/null
+++ b/debian/patches/0001-add-pve-specific-js-code.patch
@@ -0,0 +1,639 @@
+From ad6975daaeee0798955f1d8b36d567975f4cbae5 Mon Sep 17 00:00:00 2001
+From: Dominik Csapak <d.csa...@proxmox.com>
+Date: Tue, 13 Dec 2016 16:11:35 +0100
+Subject: [PATCH 1/9] add pve specific js code
+
+this adds a es6 module 'PVEUI' which we use for defining the pve related
+methods (API2Request, etc.)
+
+we also modify ui.js so that it uses this module and sets up our
+autoresizing, commandstoggle, etc.
+
+Signed-off-by: Dominik Csapak <d.csa...@proxmox.com>
+---
+ app/pve.js | 417 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ app/ui.js  |  95 ++++++++++----
+ 2 files changed, 488 insertions(+), 24 deletions(-)
+ create mode 100644 app/pve.js
+
+diff --git a/app/pve.js b/app/pve.js
+new file mode 100644
+index 0000000..668835a
+--- /dev/null
++++ b/app/pve.js
+@@ -0,0 +1,417 @@
++/*
++ * PVE Utility functions for noVNC
++ * Copyright (C) 2017 Proxmox GmbH
++ */
++
++import * as WebUtil from "./webutil.js";
++
++export default function PVEUI(UI){
++    this.consoletype = WebUtil.getQueryVar('console');
++    this.vmid = WebUtil.getQueryVar('vmid');
++    this.vmname = WebUtil.getQueryVar('vmname');
++    this.nodename = WebUtil.getQueryVar('node');
++    this.resize = WebUtil.getQueryVar('resize');
++    this.lastFBWidth = undefined;
++    this.lastFBHeight = undefined;
++    this.sizeUpdateTimer = undefined;
++    this.UI = UI;
++
++    var baseUrl = '/nodes/' + this.nodename;
++    var url;
++    var params = { websocket: 1 };
++    var title;
++
++    switch (this.consoletype) {
++      case 'kvm':
++          baseUrl += '/qemu/' + this.vmid;
++          url =  baseUrl + '/vncproxy';
++          title = "VM " + this.vmid;
++          if (this.vmname) {
++              title += " ('" + this.vmname + "')";
++          }
++          break;
++      case 'lxc':
++          baseUrl += '/lxc/' + this.vmid;
++          url =  baseUrl + '/vncproxy';
++          title = "CT " + this.vmid;
++          if (this.vmname) {
++              title += " ('" + this.vmname + "')";
++          }
++          break;
++      case 'shell':
++          url =  baseUrl + '/vncshell';
++          title = "node '" + this.nodename + "'";
++          break;
++      case 'upgrade':
++          url =  baseUrl + '/vncshell';
++          params.upgrade = 1;
++          title = 'System upgrade on node ' + this.nodename;
++          break;
++      default:
++          throw 'implement me';
++          break;
++    }
++
++    this.baseUrl = baseUrl;
++    this.url = url;
++    this.params = params;
++    document.title = title;
++};
++
++PVEUI.prototype = {
++    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) {
++      var me = this;
++
++      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 = me.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() {
++      var me = this;
++      if (me.consoletype === 'kvm') {
++          // try to detect migrated VM
++          me.API2Request({
++              url: '/cluster/resources',
++              method: 'GET',
++              success: function(result) {
++                  var list = result.data;
++                  list.every(function(item) {
++                      if (item.type === 'qemu' && item.vmid == me.vmid) {
++                          var url = "?" + me.urlEncode({
++                              console: me.consoletype,
++                              novnc: 1,
++                              vmid: me.vmid,
++                              vmname: me.vmname,
++                              node: item.node,
++                              resize: me.resize
++                          });
++                          location.href = url;
++                          return false; // break
++                      }
++                      return true;
++                  });
++              }
++          });
++      } else if(me.consoletype === 'lxc') {
++          // lxc restart migration can take a while,
++          // so we need to find out if we are really migrating
++          var migrating;
++          var check = setInterval(function() {
++              if (migrating === undefined ||
++                  migrating === true) {
++                  // check (again) if migrating
++                  me.UI.showStatus('Checking for Migration', 'warning', 5000);
++                  me.API2Request({
++                      url: me.baseUrl + '/config',
++                      method: 'GET',
++                      success: function(result) {
++                          var lock = result.data.lock;
++                          if (lock == 'migrate') {
++                              migrating = true;
++                              me.UI.showStatus('Migration detected, 
waiting...', 'warning', 5000);
++                          } else {
++                              migrating = false;
++                          }
++                      },
++                      failure: function() {
++                          migrating = false;
++                      }
++                  });
++              } else {
++                  // not migrating any more
++                  me.UI.showStatus('Migration finished', 'warning');
++                  clearInterval(check);
++                  me.API2Request({
++                      url: '/cluster/resources',
++                      method: 'GET',
++                      success: function(result) {
++                          var list = result.data;
++                          list.every(function(item) {
++                              if (item.type === 'lxc' && item.vmid == 
me.vmid) {
++                                  var url = "?" + me.urlEncode({
++                                      console: me.consoletype,
++                                      novnc: 1,
++                                      vmid: me.vmid,
++                                      vmname: me.vmname,
++                                      node: item.node,
++                                      resize: me.resize
++                                  });
++                                  location.href = url;
++                                  return false; // break
++                              }
++                              return true;
++                          });
++                      }
++                  });
++              }
++          }, 5000);
++      }
++
++    },
++
++    pve_vm_command: function(cmd, params, reload) {
++      var me = this;
++      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}', me.vmid);
++
++      if (confirmMsg !== "" && confirm(confirmMsg) !== true) {
++          return;
++      }
++
++      me.UI.closePVECommandPanel();
++
++      if (me.consoletype === 'kvm') {
++          baseUrl = '/nodes/' + me.nodename + '/qemu/' + me.vmid;
++      } else if (me.consoletype === 'lxc') {
++          baseUrl = '/nodes/' + me.nodename + '/lxc/' + me.vmid;
++      } else {
++          throw "unknown VM type";
++      }
++
++      me.API2Request({
++          params: params,
++          url: baseUrl + "/status/" + cmd,
++          method: 'POST',
++          failure: function(msg) {
++              me.UI.showStatus(msg, 'warning');
++          },
++          success: function() {
++              me.UI.showStatus("VM command '" + cmd +"' successful", 
'normal');
++              if (reload) {
++                  setTimeout(function() {
++                      location.reload();
++                  }, 1000);
++              };
++          }
++      });
++    },
++
++    addPVEHandlers: function() {
++      var me = this;
++      document.getElementById('pve_commands_button')
++          .addEventListener('click', me.UI.togglePVECommandPanel);
++
++      // show/hide the buttons
++      document.getElementById('noVNC_settings_button')
++          .classList.add('noVNC_hidden');
++      document.getElementById('noVNC_disconnect_button')
++          .classList.add('noVNC_hidden');
++      if (me.consoletype === 'kvm') {
++          document.getElementById('noVNC_clipboard_button')
++              .classList.add('noVNC_hidden');
++      }
++
++      if (me.consoletype === 'shell' || me.consoletype === 'upgrade') {
++          document.getElementById('pve_commands_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[me.consoletype] === 1) {
++              el.onclick = function() {
++                  me.pve_vm_command(item.cmd);
++              };
++          } else {
++              el.classList.add('noVNC_hidden');
++          }
++      });
++
++      //edge/ie11 quirk
++      var canvas = document.getElementById('noVNC_canvas');
++      canvas.onclick = canvas.focus;
++    },
++
++    getFBSize: 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";
++      }
++
++      return { width: ow, height: oh };
++    },
++
++    pveStart: function(callback) {
++      var me = this;
++      me.API2Request({
++          url: me.url,
++          method: 'POST',
++          params: me.params,
++          success: function(result) {
++              var wsparams = me.urlEncode({
++                  port: result.data.port,
++                  vncticket: result.data.ticket
++              });
++
++              document.getElementById('noVNC_password_input').value = 
result.data.ticket;
++              me.UI.updateSetting('path', 'api2/json' + me.baseUrl + 
'/vncwebsocket' + "?" + wsparams);
++
++              callback();
++          },
++          failure: function(msg) {
++              me.UI.showStatus(msg, 'error');
++          }
++      });
++    },
++
++    updateFBSize: function(rfb, width, height, clip) {
++      var me = this;
++      console.log(arguments);
++      try {
++          // Note: window size must be even number for firefox
++          me.lastFBWidth = Math.floor((width + 1)/2)*2;
++          me.lastFBHeight = Math.floor((height + 1)/2)*2;
++
++          if (me.sizeUpdateTimer !== undefined) {
++              clearInterval(me.sizeUpdateTimer);
++          }
++          if (clip) return;
++
++          var update_size = function() {
++              // we do not want to resize if we are in fullscreen
++              if (document.fullscreenElement || // alternative standard method
++                  document.mozFullScreenElement || // currently working 
methods
++                  document.webkitFullscreenElement ||
++                  document.msFullscreenElement) {
++                  return;
++              }
++
++              var oldsize = me.getFBSize();
++              var offsetw = me.lastFBWidth - oldsize.width;
++              var offseth = me.lastFBHeight - oldsize.height;
++              if (offsetw !== 0 || offseth !== 0) {
++                  //console.log("try resize by " + offsetw + " " + offseth);
++                  try {
++                      window.resizeBy(offsetw, offseth);
++                      // wait a little an then fix the scrollbars
++                      // on chrome
++                      setTimeout(function() {
++                          me.UI.fixScrollbars();
++                      }, 100);
++                  } catch (e) {
++                      console.log('resizing did not work', e);
++                  }
++              }
++          };
++
++          update_size();
++          me.sizeUpdateTimer = setInterval(update_size, 1000);
++
++      } catch(e) {
++          console.log(e);
++      }
++    },
++};
+diff --git a/app/ui.js b/app/ui.js
+index 73ad2b4..def0eda 100644
+--- a/app/ui.js
++++ b/app/ui.js
+@@ -20,6 +20,7 @@ import keysyms from "../core/input/keysymdef.js";
+ import RFB from "../core/rfb.js";
+ import Display from "../core/display.js";
+ import * as WebUtil from "./webutil.js";
++import PVEUI from "./pve.js";
+ 
+ const UI = {
+ 
+@@ -63,6 +64,7 @@ const UI = {
+     // Render default UI and initialize settings menu
+     start: function(callback) {
+ 
++      UI.PVE = new PVEUI(UI);
+         // Setup global variables first
+         UI.isSafari = (navigator.userAgent.indexOf('Safari') !== -1 &&
+                        navigator.userAgent.indexOf('Chrome') === -1);
+@@ -95,6 +97,9 @@ const UI = {
+         UI.addConnectionControlHandlers();
+         UI.addClipboardHandlers();
+         UI.addSettingsHandlers();
++
++      // add pve specific event handlers
++      UI.PVE.addPVEHandlers();
+         document.getElementById("noVNC_status")
+             .addEventListener('click', UI.hideStatus);
+ 
+@@ -103,11 +108,6 @@ const UI = {
+ 
+         UI.openControlbar();
+ 
+-        // Show the connect panel on first load unless autoconnecting
+-        if (!autoconnect) {
+-            UI.openConnectPanel();
+-        }
+-
+         UI.updateViewClip();
+ 
+         UI.updateVisualState();
+@@ -115,17 +115,13 @@ const UI = {
+         document.getElementById('noVNC_setting_host').focus();
+         document.documentElement.classList.remove("noVNC_loading");
+ 
+-        var autoconnect = WebUtil.getConfigVar('autoconnect', false);
+-        if (autoconnect === 'true' || autoconnect == '1') {
+-            autoconnect = true;
+-            UI.connect();
+-        } else {
+-            autoconnect = false;
+-        }
++      UI.PVE.pveStart(function() {
++          UI.connect();
+ 
+-        if (typeof callback === "function") {
+-            callback(UI.rfb);
+-        }
++          if (typeof callback === "function") {
++              callback(UI.rfb);
++          }
++      });
+     },
+ 
+     initFullscreen: function() {
+@@ -170,10 +166,14 @@ const UI = {
+         /* Populate the controls if defaults are provided in the URL */
+         UI.initSetting('host', window.location.hostname);
+         UI.initSetting('port', port);
+-        UI.initSetting('encrypt', (window.location.protocol === "https:"));
++        UI.initSetting('encrypt', true);
+         UI.initSetting('cursor', !isTouchDevice);
+         UI.initSetting('clip', false);
+-        UI.initSetting('resize', 'off');
++      // we need updateSetting because
++      // otherwise we load from browser storage
++      // we want to overwrite the resize mode from url
++      var resize = WebUtil.getQueryVar('resize');
++      UI.updateSetting('resize', resize);
+         UI.initSetting('shared', true);
+         UI.initSetting('view_only', false);
+         UI.initSetting('path', 'websockify');
+@@ -434,6 +434,7 @@ const UI = {
+             case 'connected':
+                 UI.connected = true;
+                 UI.inhibit_reconnect = false;
++              UI.pveAllowMigratedTest = true;
+                 document.documentElement.classList.add("noVNC_connected");
+                 if (rfb && rfb.get_encrypt()) {
+                     msg = _("Connected (encrypted) to ") + UI.desktopName;
+@@ -449,6 +450,10 @@ const UI = {
+                 break;
+             case 'disconnected':
+                 UI.showStatus(_("Disconnected"));
++              if (UI.pveAllowMigratedTest === true) {
++                  UI.pveAllowMigratedTest = false;
++                  UI.PVE.pve_detect_migrated_vm();
++              }
+                 break;
+             default:
+                 msg = "Invalid UI state";
+@@ -861,6 +866,7 @@ const UI = {
+         UI.closeXvpPanel();
+         UI.closeClipboardPanel();
+         UI.closeExtraKeys();
++      UI.closePVECommandPanel();
+     },
+ 
+ /* ------^-------
+@@ -1033,9 +1039,15 @@ const UI = {
+             password = WebUtil.getConfigVar('password');
+         }
+ 
+-        if (password === null) {
+-            password = undefined;
+-        }
++      var password = document.getElementById('noVNC_password_input').value;
++
++      if (!password) {
++          password = WebUtil.getConfigVar('password');
++      }
++
++      if (password === null) {
++          password = undefined;
++      }
+ 
+         if ((!host) || (!port)) {
+             var msg = _("Must set host and port");
+@@ -1608,9 +1620,36 @@ const UI = {
+ /* ------^-------
+  *   /EXTRA KEYS
+  * ==============
+- *     MISC
++ *     PVE
+  * ------v------*/
+ 
++    togglePVECommandPanel: function() {
++      if 
(document.getElementById('pve_commands').classList.contains("noVNC_open")) {
++          UI.closePVECommandPanel();
++      } else {
++          UI.openPVECommandPanel();
++      }
++    },
++
++    openPVECommandPanel: function() {
++      var me = this;
++      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");
++    },
++
++/* ------^-------
++ *   /PVE
++ * ==============
++ *     MISC
++ * ------v------*/
+     setMouseButton: function(num) {
+         var view_only = UI.rfb.get_view_only();
+         if (UI.rfb && !view_only) {
+@@ -1658,8 +1697,16 @@ const UI = {
+     },
+ 
+     updateSessionSize: function(rfb, width, height) {
+-        UI.updateViewClip();
+-        UI.fixScrollbars();
++      var resize = UI.getSetting('resize');
++
++      if (resize == 'null') {
++          var clip = UI.getSetting('clip');
++          UI.PVE.updateFBSize(rfb, width, height, clip);
++      }
++
++      UI.applyResizeMode();
++      UI.updateViewClip();
++      UI.updateViewDrag();
+     },
+ 
+     fixScrollbars: function() {
+@@ -1704,7 +1751,7 @@ const UI = {
+     },
+ 
+ /* ------^-------
+- *    /MISC
++ *   /MISC
+  * ==============
+  */
+ };
+-- 
+2.11.0
+
diff --git a/debian/patches/0002-change-scaling-when-toggling-fullscreen.patch 
b/debian/patches/0002-change-scaling-when-toggling-fullscreen.patch
new file mode 100644
index 0000000..5bf888b
--- /dev/null
+++ b/debian/patches/0002-change-scaling-when-toggling-fullscreen.patch
@@ -0,0 +1,45 @@
+From c1073cb0f19ebd64f6ee4b221b5aa06a2f8e5c99 Mon Sep 17 00:00:00 2001
+From: Dominik Csapak <d.csa...@proxmox.com>
+Date: Thu, 11 May 2017 10:34:10 +0200
+Subject: [PATCH 2/9] change scaling when toggling fullscreen
+
+when activating fullscreen, we change the scaling to 'scale',
+and changing it back when leaving fullscreen
+
+Signed-off-by: Dominik Csapak <d.csa...@proxmox.com>
+---
+ app/ui.js | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/app/ui.js b/app/ui.js
+index def0eda..d4b0291 100644
+--- a/app/ui.js
++++ b/app/ui.js
+@@ -1174,6 +1174,15 @@ const UI = {
+             } else if (document.msExitFullscreen) {
+                 document.msExitFullscreen();
+             }
++
++          // when changing from fullscreen to window,
++          // re enable auto resize
++          if (WebUtil.getQueryVar('resize') === null) {
++              UI.updateSetting('resize', null);
++              setTimeout(function() {
++                  UI.fixScrollbars();
++              }, 100);
++          }
+         } else {
+             if (document.documentElement.requestFullscreen) {
+                 document.documentElement.requestFullscreen();
+@@ -1184,6 +1193,8 @@ const UI = {
+             } else if (document.body.msRequestFullscreen) {
+                 document.body.msRequestFullscreen();
+             }
++          // we want scaling in fullscreen mode
++          UI.updateSetting('resize', 'scale');
+         }
+         UI.enableDisableViewClip();
+         UI.updateFullscreenButton();
+-- 
+2.11.0
+
diff --git a/debian/patches/0003-add-pve-style.patch 
b/debian/patches/0003-add-pve-style.patch
new file mode 100644
index 0000000..394f8dd
--- /dev/null
+++ b/debian/patches/0003-add-pve-style.patch
@@ -0,0 +1,75 @@
+From 1cdfeafd561bfe4d9acb7ef8a838d82c64f9c1e5 Mon Sep 17 00:00:00 2001
+From: Dominik Csapak <d.csa...@proxmox.com>
+Date: Tue, 13 Dec 2016 16:03:41 +0100
+Subject: [PATCH 3/9] add pve style
+
+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.csa...@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 6cb4be4..98a9952 100644
+--- a/vnc.html
++++ b/vnc.html
+@@ -53,6 +53,7 @@
+ 
+     <!-- Stylesheets -->
+     <link rel="stylesheet" href="app/styles/base.css" />
++    <link rel="stylesheet" href="/novnc/app/styles/pve.css" />
+ 
+     <!--
+     <script type='text/javascript'
+-- 
+2.11.0
+
diff --git a/debian/patches/0004-remove-vnc-logos.patch 
b/debian/patches/0004-remove-vnc-logos.patch
new file mode 100644
index 0000000..2577119
--- /dev/null
+++ b/debian/patches/0004-remove-vnc-logos.patch
@@ -0,0 +1,54 @@
+From a28b283a224990e1b46f304d9a2067afa7633d63 Mon Sep 17 00:00:00 2001
+From: Dominik Csapak <d.csa...@proxmox.com>
+Date: Fri, 20 Jan 2017 10:35:05 +0100
+Subject: [PATCH 4/9] remove vnc logos
+
+to show the pve icon instead
+
+Signed-off-by: Dominik Csapak <d.csa...@proxmox.com>
+---
+ vnc.html | 24 ------------------------
+ 1 file changed, 24 deletions(-)
+
+diff --git a/vnc.html b/vnc.html
+index 98a9952..cd8e594 100644
+--- a/vnc.html
++++ b/vnc.html
+@@ -23,34 +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="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.11.0
+
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..43847c8
--- /dev/null
+++ b/debian/patches/0005-change-src-directory-for-images-js-files.patch
@@ -0,0 +1,232 @@
+From 0b7322fc05361366fc4e24e6d5b9d8e2254ace40 Mon Sep 17 00:00:00 2001
+From: Dominik Csapak <d.csa...@proxmox.com>
+Date: Tue, 17 Jan 2017 17:24:03 +0100
+Subject: [PATCH 5/9] change src directory for images/js files
+
+since they will be in /novnc/
+also change the directory in the build script
+
+Signed-off-by: Dominik Csapak <d.csa...@proxmox.com>
+---
+ app/ui.js                    |  2 +-
+ utils/use_require_helpers.js |  2 +-
+ vnc.html                     | 56 ++++++++++++++++++++++----------------------
+ 3 files changed, 30 insertions(+), 30 deletions(-)
+
+diff --git a/app/ui.js b/app/ui.js
+index d4b0291..d32c789 100644
+--- a/app/ui.js
++++ b/app/ui.js
+@@ -1771,7 +1771,7 @@ const UI = {
+ var LINGUAS = ["de", "el", "nl", "sv"];
+ l10n.setup(LINGUAS);
+ if (l10n.language !== "en" && l10n.dictionary === undefined) {
+-    WebUtil.fetchJSON('app/locale/' + l10n.language + '.json', function 
(translations) {
++    WebUtil.fetchJSON('/novnc/app/locale/' + l10n.language + '.json', 
function (translations) {
+         l10n.dictionary = translations;
+ 
+         // wait for translations to load before loading the UI
+diff --git a/utils/use_require_helpers.js b/utils/use_require_helpers.js
+index 990fb4d..0f44e1c 100644
+--- a/utils/use_require_helpers.js
++++ b/utils/use_require_helpers.js
+@@ -22,7 +22,7 @@ module.exports = {
+             var browserify = require('browserify');
+             var b = browserify(path.join(base_out_path, 'app/ui.js'), {});
+             b.bundle().pipe(fs.createWriteStream(out_path));
+-            return `<script src="${path.relative(base_out_path, 
out_path)}"></script>`;
++            return `<script src="/novnc/${path.relative(base_out_path, 
out_path)}"></script>`;
+         },
+         noCopyOverride: () => {},
+     },
+diff --git a/vnc.html b/vnc.html
+index cd8e594..23fc0e4 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" />
+ 
+     <!--
+@@ -37,11 +37,11 @@
+     -->
+ 
+     <!-- this is included as a normal file in order to catch script-loading 
errors as well -->
+-    <script type="text/javascript" src="app/error-handler.js"></script>
++    <script type="text/javascript" src="/novnc/app/error-handler.js"></script>
+ 
+     <!-- begin scripts -->
+     <!-- promise polyfills promises for IE11 -->
+-    <script src="vendor/promise.js"></script>
++    <script src="/novnc/vendor/promise.js"></script>
+     <!-- ES2015/ES6 modules polyfill -->
+     <script type="module">
+         window._noVNC_has_module_support = true;
+@@ -50,12 +50,12 @@
+         window.addEventListener("load", function() {
+             if (window._noVNC_has_module_support) return;
+             var loader = document.createElement("script");
+-            loader.src = 
"vendor/browser-es-module-loader/dist/browser-es-module-loader.js";
++            loader.src = 
"/novnc/vendor/browser-es-module-loader/dist/browser-es-module-loader.js";
+             document.head.appendChild(loader);
+         });
+     </script>
+     <!-- actual script modules -->
+-    <script type="module" src="app/ui.js"></script>
++    <script type="module" src="/novnc/app/ui.js"></script>
+     <!-- end scripts -->
+ </head>
+ 
+@@ -80,49 +80,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>
+@@ -130,13 +130,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" />
+@@ -145,13 +145,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 />
+@@ -161,19 +161,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>
+@@ -249,7 +249,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" />
+ 
+@@ -266,7 +266,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>
+@@ -314,8 +314,8 @@
+     </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>
+  </body>
+ </html>
+-- 
+2.11.0
+
diff --git a/debian/patches/0006-add-pve-vnc-commands.patch 
b/debian/patches/0006-add-pve-vnc-commands.patch
new file mode 100644
index 0000000..3b83959
--- /dev/null
+++ b/debian/patches/0006-add-pve-vnc-commands.patch
@@ -0,0 +1,44 @@
+From 1a042fcad1f9242cafbb589a1da5b8b270e8b8bb Mon Sep 17 00:00:00 2001
+From: Dominik Csapak <d.csa...@proxmox.com>
+Date: Fri, 20 Jan 2017 10:35:43 +0100
+Subject: [PATCH 6/9] add pve vnc commands
+
+Signed-off-by: Dominik Csapak <d.csa...@proxmox.com>
+---
+ vnc.html | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/vnc.html b/vnc.html
+index 23fc0e4..e789d04 100644
+--- a/vnc.html
++++ b/vnc.html
+@@ -165,6 +165,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.11.0
+
diff --git a/debian/patches/0007-add-replaceable-snippets-in-vnc.html.patch 
b/debian/patches/0007-add-replaceable-snippets-in-vnc.html.patch
new file mode 100644
index 0000000..6ea98a1
--- /dev/null
+++ b/debian/patches/0007-add-replaceable-snippets-in-vnc.html.patch
@@ -0,0 +1,41 @@
+From c3d885b78fd816201ed485eb7a681ce1fcf3a122 Mon Sep 17 00:00:00 2001
+From: Dominik Csapak <d.csa...@proxmox.com>
+Date: Fri, 20 Jan 2017 10:16:09 +0100
+Subject: [PATCH 7/9] add replaceable snippets in vnc.html
+
+so that we can insert the username/csrftoken via search/replace
+
+Signed-off-by: Dominik Csapak <d.csa...@proxmox.com>
+---
+ vnc.html | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/vnc.html b/vnc.html
+index e789d04..1423f78 100644
+--- a/vnc.html
++++ b/vnc.html
+@@ -15,7 +15,7 @@
+     or the fragment:
+         http://example.com/#host=HOST&port=PORT&encrypt=1
+     -->
+-    <title>noVNC</title>
++    <title>[% nodename %] - Proxmox Console</title>
+ 
+     <meta charset="utf-8" />
+ 
+@@ -38,6 +38,12 @@
+ 
+     <!-- this is included as a normal file in order to catch script-loading 
errors as well -->
+     <script type="text/javascript" src="/novnc/app/error-handler.js"></script>
++    <script type="text/javascript">
++      if (typeof(PVE) === 'undefined') PVE = {};
++      PVE.UserName = '[% username %]';
++      PVE.CSRFPreventionToken = '[% token %]';
++      INCLUDE_URI='/novnc/include';
++    </script>
+ 
+     <!-- begin scripts -->
+     <!-- promise polyfills promises for IE11 -->
+-- 
+2.11.0
+
diff --git a/debian/patches/0008-focus-canvas-after-load.patch 
b/debian/patches/0008-focus-canvas-after-load.patch
new file mode 100644
index 0000000..4c38bbb
--- /dev/null
+++ b/debian/patches/0008-focus-canvas-after-load.patch
@@ -0,0 +1,43 @@
+From b97c51d6a2ca70a5e60209cd7ab16563455b8d13 Mon Sep 17 00:00:00 2001
+From: Dominik Csapak <d.csa...@proxmox.com>
+Date: Wed, 14 Dec 2016 08:40:02 +0100
+Subject: [PATCH 8/9] focus canvas after load
+
+or else in some browsers, the canvas does not get the focus after
+loading in an iframe
+
+Signed-off-by: Dominik Csapak <d.csa...@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 d32c789..ed2897b 100644
+--- a/app/ui.js
++++ b/app/ui.js
+@@ -442,6 +442,8 @@ const 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 1423f78..ff70e0c 100644
+--- a/vnc.html
++++ b/vnc.html
+@@ -332,7 +332,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.11.0
+
diff --git a/debian/patches/0009-decrease-animation-time.patch 
b/debian/patches/0009-decrease-animation-time.patch
new file mode 100644
index 0000000..ff9ba1a
--- /dev/null
+++ b/debian/patches/0009-decrease-animation-time.patch
@@ -0,0 +1,73 @@
+From 3f13289a9f895b1ba86ad61ed085390bffda3e3a Mon Sep 17 00:00:00 2001
+From: Dominik Csapak <d.csa...@proxmox.com>
+Date: Fri, 20 Jan 2017 10:55:49 +0100
+Subject: [PATCH 9/9] decrease animation time
+
+because 0.5s is too long
+
+Signed-off-by: Dominik Csapak <d.csa...@proxmox.com>
+---
+ app/styles/base.css | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/app/styles/base.css b/app/styles/base.css
+index ce31cf7..6db4467 100644
+--- a/app/styles/base.css
++++ b/app/styles/base.css
+@@ -283,7 +283,7 @@ 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);
+@@ -300,7 +300,7 @@ 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;
+@@ -318,7 +318,7 @@ 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);
+@@ -352,7 +352,7 @@ 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 */
+@@ -440,7 +440,7 @@ 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;
+@@ -617,7 +617,7 @@ select:active {
+ 
+   cursor: pointer;
+ 
+-  transition: 0.5s ease-in-out;
++  transition: 0.1s ease-in-out;
+ 
+   visibility: hidden;
+   opacity: 0;
+-- 
+2.11.0
+
-- 
2.11.0


_______________________________________________
pve-devel mailing list
pve-devel@pve.proxmox.com
https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to