diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml
new file mode 100644
index 0000000..8b0099f
--- /dev/null
+++ b/.github/workflows/linter.yml
@@ -0,0 +1,41 @@
+# This is a basic workflow to help you get started with Actions
+
+name: linter
+
+# Controls when the action will run. Triggers the workflow on push or pull request
+# events but only for the master branch
+on:
+  push:
+    branches: [ master ]
+  pull_request:
+    branches: [ master ]
+
+# A workflow run is made up of one or more jobs that can run sequentially or in parallel
+jobs:
+  # This workflow contains a single job called "build"
+  build:
+    # The type of runner that the job will run on
+    runs-on: ubuntu-latest
+
+  
+    # Steps represent a sequence of tasks that will be executed as part of the job
+    steps:
+    # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
+    - uses: actions/checkout@master
+    - name: Set up Python
+      uses: actions/setup-python@v2
+      with:
+        python-version: '3.x'  
+      
+    - name: install libvirt-dev
+      run: |
+        sudo apt-get install -y libvirt-dev
+    - name: Install dependencies
+      run: |
+        python3 -m pip install --upgrade pip
+        if [ -f dev/requirements.txt ]; then pip3 install -r dev/requirements.txt; fi
+    - name: Super-Linter
+      uses: github/super-linter@v2.1.0
+      env:
+        VALIDATE_RUBY: false
+        VALIDATE_ANSIBLE: false
diff --git a/console/templates/console-base.html b/console/templates/console-base.html
index be027ec..7875f7e 100644
--- a/console/templates/console-base.html
+++ b/console/templates/console-base.html
@@ -1,6 +1,7 @@
 {% load staticfiles %}
 {% load i18n %}
 <html>
+
 <head>
     <meta charset="utf-8">
     <link rel="shortcut icon" href="{% static "favicon.ico" %}">
@@ -9,19 +10,13 @@
     <link href="{% static "css/webvirtcloud.css" %}" rel="stylesheet">
 
     <style>
-        body {
-            margin: 0;
-            padding: 0;
-            background-color: #313131;
-        }
-
         #main_container {
             padding: 0;
             width: 100%;
             max-width: none;
             height: 100%;
-            background-color:#494949;
-            border-bottom-right-radius: 800px 600px;
+            background-color: #494949;
+            border-bottom-right-radius: 850px 600px;
 
         }
 
@@ -32,102 +27,90 @@
             margin-right: auto;
             display: block;
         }
-       
-        #status {
-            z-index: 10000;
-            width: 80%;
-            position: absolute;
-            top: 5px;
-            left: 10%;
-            text-align: center;
-        }
     </style>
 
-{% block head %}{% endblock %}
+    {% block head %}{% endblock %}
 
 </head>
 
 <body>
-<div id='main_container' class="container">
-<nav class="navbar navbar-expand-md navbar-dark bg-primary" arial-label="console navbar">
-  <div class="container">
-    <a class="navbar-brand">{{ instance.name }}</a>
-    <button type="button" class="navbar-toggler" data-toggle="collapse" data-target=".navbar-collapse" aria-expanded="false" aria-label="Toggle navigation">
-        <span class="navbar-toggler-icon"></span>
-    </button>
+    <div id='main_container' class="container">
+        <nav class="navbar navbar-expand-md navbar-dark bg-primary" arial-label="console navbar">
+            <div class="container">
+                <a class="navbar-brand">{{ instance.name }}</a>
+                <button type="button" class="navbar-toggler" data-toggle="collapse" data-target=".navbar-collapse"
+                    aria-expanded="false" aria-label="Toggle navigation">
+                    <span class="navbar-toggler-icon"></span>
+                </button>
 
-    <div class="collapse navbar-collapse">
-        <ul class="navbar-nav mr-auto mt-2 mt-md-0">
-            <li class="nav-item dropdown">
-                <a href="#" class="nav-link dropdown-toggle" 
-                    data-toggle="dropdown" 
-                    role="button" 
-                    id="dropdownMenuLink" 
-                    data-toggle="dropdown" 
-                    aria-haspopup="true" 
-                    aria-expanded="false">
-                    {% trans "Send key(s)" %}
-                </a>
-                <div class="dropdown-menu" aria-labelledby="dropdownMenuLink">
-                    <a class="dropdown-item" id="ctrlaltdel" href='#'>Ctrl+Alt+Del</a>
-                    <div class="dropdown-divider"></div>
-                    <a class="dropdown-item" id="ctrlaltf1" href='#'>Ctrl+Alt+F1</a>
-                    <a class="dropdown-item" id="ctrlaltf2" href='#'>Ctrl+Alt+F2</a>
-                    <a class="dropdown-item" id="ctrlaltf3" href='#'>Ctrl+Alt+F3</a>
-                    <a class="dropdown-item" id="ctrlaltf4" href='#'>Ctrl+Alt+F4</a>
-                    <a class="dropdown-item" id="ctrlaltf5" href='#'>Ctrl+Alt+F5</a>
-                    <a class="dropdown-item" id="ctrlaltf6" href='#'>Ctrl+Alt+F6</a>
-                    <a class="dropdown-item" id="ctrlaltf7" href='#'>Ctrl+Alt+F7</a>
-                    <a class="dropdown-item" id="ctrlaltf8" href='#'>Ctrl+Alt+F8</a>
-                    <a class="dropdown-item" id="ctrlaltf9" href='#'>Ctrl+Alt+F9</a>
-                    <a class="dropdown-item" id="ctrlaltf10" href='#'>Ctrl+Alt+F10</a>
-                    <a class="dropdown-item" id="ctrlaltf11" href='#'>Ctrl+Alt+F11</a>
-                    <a class="dropdown-item" id="ctrlaltf12" href='#'>Ctrl+Alt+F12</a>
+                <div class="collapse navbar-collapse">
+                    <ul class="navbar-nav mr-auto mt-2 mt-md-0">
+                        <li class="nav-item dropdown">
+                            <a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown" role="button"
+                                id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+                                {% trans "Send key(s)" %}
+                            </a>
+                            <div class="dropdown-menu" aria-labelledby="dropdownMenuLink">
+                                <a class="dropdown-item" id="ctrlaltdel" href='#'>Ctrl+Alt+Del</a>
+                                <div class="dropdown-divider"></div>
+                                <a class="dropdown-item" id="ctrlaltf1" href='#'>Ctrl+Alt+F1</a>
+                                <a class="dropdown-item" id="ctrlaltf2" href='#'>Ctrl+Alt+F2</a>
+                                <a class="dropdown-item" id="ctrlaltf3" href='#'>Ctrl+Alt+F3</a>
+                                <a class="dropdown-item" id="ctrlaltf4" href='#'>Ctrl+Alt+F4</a>
+                                <a class="dropdown-item" id="ctrlaltf5" href='#'>Ctrl+Alt+F5</a>
+                                <a class="dropdown-item" id="ctrlaltf6" href='#'>Ctrl+Alt+F6</a>
+                                <a class="dropdown-item" id="ctrlaltf7" href='#'>Ctrl+Alt+F7</a>
+                                <a class="dropdown-item" id="ctrlaltf8" href='#'>Ctrl+Alt+F8</a>
+                                <a class="dropdown-item" id="ctrlaltf9" href='#'>Ctrl+Alt+F9</a>
+                                <a class="dropdown-item" id="ctrlaltf10" href='#'>Ctrl+Alt+F10</a>
+                                <a class="dropdown-item" id="ctrlaltf11" href='#'>Ctrl+Alt+F11</a>
+                                <a class="dropdown-item" id="ctrlaltf12" href='#'>Ctrl+Alt+F12</a>
+                            </div>
+                        </li>
+                        <li class="nav-item" id="fullscreen_button">
+                            <a class="nav-link" href='#'>{% trans "Fullscreen" %}</a>
+                        </li>
+                        {% block navbarmenu %}{% endblock %}
+                    </ul>
                 </div>
-            </li>
-            <li class="nav-item" id="fullscreen_button">
-                <a class="nav-link" href='#'>{% trans "Fullscreen" %}</a>
-            </li>
-{% block navbarmenu %}{% endblock %}
-        </ul>
-   </div>
-</nav>
+            </div>
+        </nav>
+        {% block content %}{% endblock %}
+    </div>
+    <script src="{% static "js/jquery.js" %}"></script>
+    <script src="{% static "js/bootstrap.bundle.min.js" %}"></script>
 
-{% block content %}{% endblock %}
-</div>
-<script src="{% static "js/jquery.js" %}"></script>
-<script src="{% static "js/bootstrap.bundle.min.js" %}"></script>
-
-<script>
-    function log_message(msg,type) {
-        var exist=$('#status').is('div');
-        status_div=$('<div id="status" class="alert alert-'+type+' role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>'+msg+'</div>');
-        if (exist) {
-          $('#status').remove();
-          $('body').prepend(status_div);
+    <script>
+        function log_message(msg, type) {
+            var exist = $('#status').is('div');
+            status_div = $('<div id="status" class="alert alert-' + type + ' role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>' + msg + '</div>');
+            if (exist) {
+                $('#status').remove();
+                $('body').prepend(status_div);
+            }
+            else {
+                status_div.hide();
+                $('body').prepend(status_div);
+                status_div.fadeIn(200);
+            }
+            if (type != 'danger') {
+                status_div.delay(3000).fadeOut(200);
+            }
         }
-        else {
-          status_div.hide();
-          $('body').prepend(status_div);
-          status_div.fadeIn(200);
-        }
-        if (type!='danger') {
-          status_div.delay(3000).fadeOut(200);
-        }
-    }
 
-    function log_error(msg) {
-        log_message(msg,'danger');
-    }
+        function log_error(msg) {
+            log_message(msg, 'danger');
+        }
 
-    function log_info(msg) {
-        log_message(msg,'info');
-    }
-    {% if console_error %}
+        function log_info(msg) {
+            log_message(msg, 'info');
+        }
+        {% if console_error %}
         log_error('{{ console_error|escapejs }}');
-    {% endif %}
-</script>
+        {% endif %}
+    </script>
 
-{% block foot %}{% endblock %}
+    {% block foot %}{% endblock %}
 </body>
-</html>
+
+</html>
\ No newline at end of file
diff --git a/console/templates/console-spice-full.html b/console/templates/console-spice-full.html
index aac780d..6c3d635 100644
--- a/console/templates/console-spice-full.html
+++ b/console/templates/console-spice-full.html
@@ -27,138 +27,116 @@
 {% load staticfiles %}
 
 {% block head %}
-    <title>WebVirtCloud - Spice Client - Full</title>
-    <link rel="stylesheet" type="text/css" href="{% static "js/spice-html5/spice.css" %}" />
+<title>WebVirtCloud - Spice Client - Full</title>
+<link rel="stylesheet" type="text/css" href="{% static "js/spice-html5/spice.css" %}" />
 
-    <!-- ES2015/ES6 modules polyfill -->
-    <script type="module">
-        window._spice_has_module_support = true;
-    </script>
-    <script>
-        window.addEventListener("load", function() {
-            if (window._spice_has_module_support) return;
-            var loader = document.createElement("script");
-            loader.src = '{% static "thirdparty/browser-es-module-loader/dist/browser-es-module-loader.js" %}';
-            document.head.appendChild(loader);
-        });
-    </script>
+<!-- ES2015/ES6 modules polyfill -->
+<script type="module">
+    window._spice_has_module_support = true;
+</script>
+<script>
+    window.addEventListener("load", function () {
+        if (window._spice_has_module_support) return;
+        var loader = document.createElement("script");
+        loader.src = '{% static "thirdparty/browser-es-module-loader/dist/browser-es-module-loader.js" %}';
+        document.head.appendChild(loader);
+    });
+</script>
 
-    <script type="module" crossorigin="anonymous">
+<script type="module" crossorigin="anonymous">
 
-        import * as SpiceHtml5 from '{% static "js/spice-html5/main.js" %}';
+    import * as SpiceHtml5 from '{% static "js/spice-html5/main.js" %}';
 
-        var host = null, port = null;
-        var sc;
+    var host = null, port = null;
+    var sc;
 
-        function spice_error(e) {
+    function spice_error(e) {
+        disconnect();
+    }
+
+    function connect() {
+        var host, port, password, scheme = "ws://", uri;
+
+        host = document.getElementById("host").value;
+        port = document.getElementById("port").value;
+        password = document.getElementById("password").value;
+
+        if ((!host) || (!port)) {
+            console.log("must set host and port");
+            return;
+        }
+
+        if (sc) {
+            sc.stop();
+        }
+
+        uri = scheme + host + ":" + port;
+
+        document.getElementById('connectButton').innerHTML = "Stop";
+        document.getElementById('connectButton').onclick = disconnect;
+
+        try {
+            sc = new SpiceHtml5.SpiceMainConn({
+                uri: uri, screen_id: "spice-screen", dump_id: "debug-div",
+                message_id: "message-div", password: password, onerror: spice_error, onagent: agent_connected
+            });
+        }
+        catch (e) {
+            alert(e.toString());
             disconnect();
         }
+    }
 
-        function connect() {
-            var host, port, password, scheme = "ws://", uri;
-
-            host = document.getElementById("host").value;
-            port = document.getElementById("port").value;
-            password = document.getElementById("password").value;
-
-            if ((!host) || (!port)) {
-                console.log("must set host and port");
-                return;
+    function disconnect() {
+        console.log(">> disconnect");
+        if (sc) {
+            sc.stop();
+        }
+        document.getElementById('connectButton').innerHTML = "Start";
+        document.getElementById('connectButton').onclick = connect;
+        if (window.File && window.FileReader && window.FileList && window.Blob) {
+            var spice_xfer_area = document.getElementById('spice-xfer-area');
+            if (spice_xfer_area != null) {
+                document.getElementById('spice-area').removeChild(spice_xfer_area);
             }
+            document.getElementById('spice-area').removeEventListener('dragover', SpiceHtml5.handle_file_dragover, false);
+            document.getElementById('spice-area').removeEventListener('drop', SpiceHtml5.handle_file_drop, false);
+        }
+        console.log("<< disconnect");
+    }
 
-            if (sc) {
-                sc.stop();
-            }
+    function agent_connected(sc) {
+        window.addEventListener('resize', SpiceHtml5.handle_resize);
+        window.spice_connection = this;
 
-            uri = scheme + host + ":" + port;
+        SpiceHtml5.resize_helper(this);
 
-            document.getElementById('connectButton').innerHTML = "Stop";
-            document.getElementById('connectButton').onclick = disconnect;
+        if (window.File && window.FileReader && window.FileList && window.Blob) {
+            var spice_xfer_area = document.createElement("div");
+            spice_xfer_area.setAttribute('id', 'spice-xfer-area');
+            document.getElementById('spice-area').appendChild(spice_xfer_area);
+            document.getElementById('spice-area').addEventListener('dragover', SpiceHtml5.handle_file_dragover, false);
+            document.getElementById('spice-area').addEventListener('drop', SpiceHtml5.handle_file_drop, false);
+        }
+        else {
+            console.log("File API is not supported");
+        }
+    }
 
-            try {
-                sc = new SpiceHtml5.SpiceMainConn({uri: uri, screen_id: "spice-screen", dump_id: "debug-div",
-                            message_id: "message-div", password: password, onerror: spice_error, onagent: agent_connected });
-            }
-            catch (e) {
-                alert(e.toString());
-                disconnect();
-            }
+    function toggle_console() {
+        var checkbox = document.getElementById('show_console');
+        var m = document.getElementById('message-div');
+
+        if (checkbox.checked) {
+            m.style.display = 'block';
+        }
+        else {
+            m.style.display = 'none';
         }
 
-        function disconnect() {
-            console.log(">> disconnect");
-            if (sc) {
-                sc.stop();
-            }
-            document.getElementById('connectButton').innerHTML = "Start";
-            document.getElementById('connectButton').onclick = connect;
-            if (window.File && window.FileReader && window.FileList && window.Blob) {
-                var spice_xfer_area = document.getElementById('spice-xfer-area');
-                if (spice_xfer_area != null) {
-                  document.getElementById('spice-area').removeChild(spice_xfer_area);
-                }
-                document.getElementById('spice-area').removeEventListener('dragover', SpiceHtml5.handle_file_dragover, false);
-                document.getElementById('spice-area').removeEventListener('drop', SpiceHtml5.handle_file_drop, false);
-            }
-            console.log("<< disconnect");
-        }
-
-        function agent_connected(sc) {
-            window.addEventListener('resize', SpiceHtml5.handle_resize);
-            window.spice_connection = this;
-
-            SpiceHtml5.resize_helper(this);
-
-            if (window.File && window.FileReader && window.FileList && window.Blob) {
-                var spice_xfer_area = document.createElement("div");
-                spice_xfer_area.setAttribute('id', 'spice-xfer-area');
-                document.getElementById('spice-area').appendChild(spice_xfer_area);
-                document.getElementById('spice-area').addEventListener('dragover', SpiceHtml5.handle_file_dragover, false);
-                document.getElementById('spice-area').addEventListener('drop', SpiceHtml5.handle_file_drop, false);
-            }
-            else {
-                console.log("File API is not supported");
-            }
-        }
-
-        function toggle_console() {
-            var checkbox = document.getElementById('show_console');
-            var m = document.getElementById('message-div');
-
-            if (checkbox.checked) {
-                m.style.display = 'block';
-            }
-            else {
-                m.style.display = 'none';
-            }
-
-            window.addEventListener('resize', SpiceHtml5.handle_resize);
-            if (sc) {
-                SpiceHtml5.resize_helper(sc);
-            }
-        }
-        /* SPICE port event listeners
-        window.addEventListener('spice-port-data', function(event) {
-            // Here we convert data to text, but really we can obtain binary data also
-            var msg_text = arraybuffer_to_str(new Uint8Array(event.detail.data));
-            DEBUG > 0 && console.log('SPICE port', event.detail.channel.portName, 'message text:', msg_text);
-        });
-
-        window.addEventListener('spice-port-event', function(event) {
-            DEBUG > 0 && console.log('SPICE port', event.detail.channel.portName, 'event data:', event.detail.spiceEvent);
-        });
-        */
-
-        function fullscreen() {
-        var screen=document.getElementById('spice-screen');
-        if(screen.requestFullscreen) {
-            screen.requestFullscreen();
-        } else if(screen.mozRequestFullScreen) {
-            screen.mozRequestFullScreen();
-        } else if(screen.webkitRequestFullscreen) {
-            screen.webkitRequestFullscreen();
-        } else if(screen.msRequestFullscreen) {
-            screen.msRequestFullscreen();
+        window.addEventListener('resize', SpiceHtml5.handle_resize);
+        if (sc) {
+            SpiceHtml5.resize_helper(sc);
         }
     }
     /* SPICE port event listeners
@@ -168,24 +146,53 @@
         DEBUG > 0 && console.log('SPICE port', event.detail.channel.portName, 'message text:', msg_text);
     });
 
+    window.addEventListener('spice-port-event', function(event) {
+        DEBUG > 0 && console.log('SPICE port', event.detail.channel.portName, 'event data:', event.detail.spiceEvent);
+    });
+    */
+
+    function fullscreen() {
+        var screen = document.getElementById('spice-screen');
+        if (screen.requestFullscreen) {
+            screen.requestFullscreen();
+        } else if (screen.mozRequestFullScreen) {
+            screen.mozRequestFullScreen();
+        } else if (screen.webkitRequestFullscreen) {
+            screen.webkitRequestFullscreen();
+        } else if (screen.msRequestFullscreen) {
+            screen.msRequestFullscreen();
+        }
+    }
+
+    function sendctrlaltfn(f) {
+        SpiceHtml5.sendCtrlAltFN(sc, f);
+        return false;
+    }
+    /* SPICE port event listeners
+    window.addEventListener('spice-port-data', function(event) {
+        // Here we convert data to text, but really we can obtain binary data also
+        var msg_text = arraybuffer_to_str(new Uint8Array(event.detail.data));
+        DEBUG > 0 && console.log('SPICE port', event.detail.channel.portName, 'message text:', msg_text);
+    });
+
     window.addEventListener('spice-port-event', function(event) {
         DEBUG > 0 && console.log('SPICE port', event.detail.channel.portName, 'event data:', event.detail.spiceEvent);
     });
     */
     document.getElementById("fullscreen_button").addEventListener('click', fullscreen);
-    document.getElementById('ctrlaltdel').addEventListener('click', function(){sendCtrlAltDel(sc);});
-    document.getElementById('ctrlaltf1').addEventListener('click', function(){sendCtrlAltFN(0);});
-    document.getElementById('ctrlaltf2').addEventListener('click', function(){sendCtrlAltFN(1);});
-    document.getElementById('ctrlaltf3').addEventListener('click', function(){sendCtrlAltFN(2);});
-    document.getElementById('ctrlaltf4').addEventListener('click', function(){sendCtrlAltFN(3);});
-    document.getElementById('ctrlaltf5').addEventListener('click', function(){sendCtrlAltFN(4);});
-    document.getElementById('ctrlaltf6').addEventListener('click', function(){sendCtrlAltFN(5);});
-    document.getElementById('ctrlaltf7').addEventListener('click', function(){sendCtrlAltFN(6);});
-    document.getElementById('ctrlaltf8').addEventListener('click', function(){sendCtrlAltFN(7);});
-    document.getElementById('ctrlaltf9').addEventListener('click', function(){sendCtrlAltFN(8);});
-    document.getElementById('ctrlaltf10').addEventListener('click', function(){sendCtrlAltFN(9);});
-    document.getElementById('ctrlaltf11').addEventListener('click', function(){sendCtrlAltFN(10);});
-    document.getElementById('ctrlaltf12').addEventListener('click', function(){sendCtrlAltFN(11);});
+    document.getElementById('ctrlaltdel').addEventListener('click', function () { sendCtrlAltDel(sc); });
+    document.getElementById('ctrlaltf1').addEventListener('click', function () { sendctrlaltfn(0) });
+    document.getElementById('ctrlaltf2').addEventListener('click', function () { sendctrlaltfn(1) });
+    document.getElementById('ctrlaltf3').addEventListener('click', function () { sendctrlaltfn(2) });
+    document.getElementById('ctrlaltf4').addEventListener('click', function () { sendctrlaltfn(3) });
+    document.getElementById('ctrlaltf5').addEventListener('click', function () { sendctrlaltfn(4) });
+    document.getElementById('ctrlaltf6').addEventListener('click', function () { sendctrlaltfn(5) });
+    document.getElementById('ctrlaltf7').addEventListener('click', function () { sendctrlaltfn(6) });
+    document.getElementById('ctrlaltf8').addEventListener('click', function () { sendctrlaltfn(7) });
+    document.getElementById('ctrlaltf9').addEventListener('click', function () { sendctrlaltfn(8) });
+    document.getElementById('ctrlaltf10').addEventListener('click', function () { sendctrlaltfn(9) });
+    document.getElementById('ctrlaltf11').addEventListener('click', function () { sendctrlaltfn(10) });
+    document.getElementById('ctrlaltf12').addEventListener('click', function () { sendctrlaltfn(11) });
 
     document.getElementById('connectButton').onclick = connect;
     document.getElementById('show_console').onchange = toggle_console;
@@ -193,27 +200,29 @@
 {% endblock %}
 
 {% block content %}
-    <div id="login">
-        <span class="logo">SPICE</span>
-        <label for="host">{% trans 'Host' %}:</label> <input type='text' id='host' value='{{ ws_host }}'> <!-- localhost -->
-        <label for="port">{% trans 'Port' %}:</label> <input type='text' id='port' value='{{ ws_port }}'>
-        <label for="password">{% trans 'Password' %}:</label> <input type='password' id='password' value='{{ console_passwd }}'>
-        <label for="show_console">{% trans 'Show console' %}</label><input type="checkbox" id="show_console" value="1" onchange="toggle_console()" checked>
-        <button id="connectButton">{% trans 'Start' %}</button>
-    </div>
+<div id="login">
+    <span class="logo">SPICE</span>
+    <label for="host">{% trans 'Host' %}:</label> <input type='text' id='host' value='{{ ws_host }}'> <!-- localhost -->
+    <label for="port">{% trans 'Port' %}:</label> <input type='text' id='port' value='{{ ws_port }}'>
+    <label for="password">{% trans 'Password' %}:</label> <input type='password' id='password'
+        value='{{ console_passwd }}'>
+    <label for="show_console">{% trans 'Show console' %}</label><input type="checkbox" id="show_console" value="1"
+        onchange="toggle_console()" checked>
+    <button id="connectButton">{% trans 'Start' %}</button>
+</div>
 
-    <div id="spice-area">
-        <div id="spice-screen" class="spice-screen"></div>
-    </div>
+<div id="spice-area">
+    <div id="spice-screen" class="spice-screen"></div>
+</div>
 
-    <div id="message-div" class="spice-message"></div>
+<div id="message-div" class="spice-message"></div>
 
-    <div id="debug-div">
+<div id="debug-div">
     <!-- If DUMPXXX is turned on, dumped images will go here -->
-    </div>
+</div>
 
 {% endblock %}
 
 {% block foot %}
 
-{% endblock %}
+{% endblock %}
\ No newline at end of file
diff --git a/console/templates/console-spice-lite.html b/console/templates/console-spice-lite.html
index 1498b43..b03d7c2 100644
--- a/console/templates/console-spice-lite.html
+++ b/console/templates/console-spice-lite.html
@@ -27,198 +27,205 @@
 {% load staticfiles %}
 
 {% block head %}
-    <title>WebVirtCloud - Spice - Lite</title>
-    <link rel="stylesheet" type="text/css" href="{% static "js/spice-html5/spice.css" %}" />
+<title>WebVirtCloud - Spice - Lite</title>
+<link rel="stylesheet" type="text/css" href="{% static "js/spice-html5/spice.css" %}" />
 
-    <!-- ES2015/ES6 modules polyfill -->
-    <script type="module">
-        window._spice_has_module_support = true;
-    </script>
-    <script>
-        window.addEventListener("load", function() {
-            if (window._spice_has_module_support) return;
-            var loader = document.createElement("script");
-            loader.src = '{% static "thirdparty/browser-es-module-loader/dist/browser-es-module-loader.js" %}';
-            document.head.appendChild(loader);
-        });
-    </script>
+<!-- ES2015/ES6 modules polyfill -->
+<script type="module">
+    window._spice_has_module_support = true;
+</script>
+<script>
+    window.addEventListener("load", function () {
+        if (window._spice_has_module_support) return;
+        var loader = document.createElement("script");
+        loader.src = '{% static "thirdparty/browser-es-module-loader/dist/browser-es-module-loader.js" %}';
+        document.head.appendChild(loader);
+    });
+</script>
 
-    <script type="module" crossorigin="anonymous">
-        import * as SpiceHtml5 from '{% static "js/spice-html5/main.js" %}';
+<script type="module" crossorigin="anonymous">
+    import * as SpiceHtml5 from '{% static "js/spice-html5/main.js" %}';
 
-        var host = null, port = null;
-        var sc;
+    var host = null, port = null;
+    var sc;
 
-        function spice_set_cookie(name, value, days) {
-            var date, expires;
-            date = new Date();
-            date.setTime(date.getTime() + (days*24*60*60*1000));
-            expires = "; expires=" + date.toGMTString();
-            document.cookie = name + "=" + value + expires + "; path=/";
-        };
+    function spice_set_cookie(name, value, days) {
+        var date, expires;
+        date = new Date();
+        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
+        expires = "; expires=" + date.toGMTString();
+        document.cookie = name + "=" + value + expires + "; path=/";
+    };
 
-        function spice_query_var(name, defvalue) {
-            var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
-            return match ? decodeURIComponent(match[1].replace(/\+/g, ' ')) : defvalue;
+    function spice_query_var(name, defvalue) {
+        var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
+        return match ? decodeURIComponent(match[1].replace(/\+/g, ' ')) : defvalue;
+    }
+
+    function spice_error(e) {
+        disconnect();
+        if (e !== undefined && e.message === "Permission denied.") {
+            var pass = prompt("Password");
+            connect(pass);
+        }
+    }
+
+    function connect(password) {
+        var host, port, scheme = "ws://", uri;
+
+        // By default, use the host and port of server that served this file
+        // host = spice_query_var('host', window.location.hostname);
+        host = '{{ ws_host| safe }}';
+
+        // Note that using the web server port only makes sense
+        //  if your web server has a reverse proxy to relay the WebSocket
+        //  traffic to the correct destination port.
+        var default_port = window.location.port;
+        if (!default_port) {
+            if (window.location.protocol == 'http:') {
+                default_port = 80;
+            }
+            else if (window.location.protocol == 'https:') {
+                default_port = 443;
+            }
+        }
+        //port = spice_query_var('port', default_port);
+        port = '{{ ws_port| safe }}';
+        if (window.location.protocol == 'https:') {
+            scheme = "wss://";
         }
 
-        function spice_error(e) {
+        // If a token variable is passed in, set the parameter in a cookie.
+        // This is used by nova-spiceproxy.
+        var token = spice_query_var('token', null);
+        if (token) {
+            spice_set_cookie('token', token, 1)
+        }
+
+        if (password === undefined) {
+            password = spice_query_var('password', '');
+            password = '{{ console_passwd | safe }}';
+        }
+        if (password === 'None') password = '';
+
+        var path = spice_query_var('path', 'websockify');
+
+        if ((!host) || (!port)) {
+            console.log(_("must specify host and port in URL"));
+            return;
+        }
+
+        if (sc) {
+            sc.stop();
+        }
+
+        uri = scheme + host + ":" + port;
+
+        if (path) {
+            uri += path[0] == '/' ? path : ('/' + path);
+        }
+
+        try {
+            sc = new SpiceHtml5.SpiceMainConn({
+                uri: uri, screen_id: "spice-screen", dump_id: "debug-div",
+                message_id: "message-div", password: password, onerror: spice_error, onagent: agent_connected
+            });
+        }
+        catch (e) {
+            alert(e.toString());
             disconnect();
-            if (e !== undefined && e.message === "Permission denied.") {
-              var pass = prompt("Password");
-              connect(pass);
-            }
         }
 
-        function connect(password) {
-            var host, port, scheme = "ws://", uri;
-
-            // By default, use the host and port of server that served this file
-            // host = spice_query_var('host', window.location.hostname);
-            host = '{{ ws_host| safe }}';
-
-            // Note that using the web server port only makes sense
-            //  if your web server has a reverse proxy to relay the WebSocket
-            //  traffic to the correct destination port.
-            var default_port = window.location.port;
-            if (!default_port) {
-                if (window.location.protocol == 'http:') {
-                    default_port = 80;
-                }
-                else if (window.location.protocol == 'https:') {
-                    default_port = 443;
-                }
-            }
-            //port = spice_query_var('port', default_port);
-            port = '{{ ws_port| safe }}';
-            if (window.location.protocol == 'https:') {
-                scheme = "wss://";
-            }
-
-            // If a token variable is passed in, set the parameter in a cookie.
-            // This is used by nova-spiceproxy.
-            var token = spice_query_var('token', null);
-            if (token) {
-                spice_set_cookie('token', token, 1)
-            }
-
-            if (password === undefined) {
-                password = spice_query_var('password', '');
-                password = '{{ console_passwd | safe }}';
-            }
-            if (password === 'None') password = '';
-
-            var path = spice_query_var('path', 'websockify');
-
-            if ((!host) || (!port)) {
-                console.log(_("must specify host and port in URL"));
-                return;
-            }
-
-            if (sc) {
-                sc.stop();
-            }
-
-            uri = scheme + host + ":" + port;
-
-            if (path) {
-              uri += path[0] == '/' ? path : ('/' + path);
-            }
-
-            try {
-                sc = new SpiceHtml5.SpiceMainConn({uri: uri, screen_id: "spice-screen", dump_id: "debug-div",
-                            message_id: "message-div", password: password, onerror: spice_error, onagent: agent_connected });
-            }
-            catch (e) {
-                alert(e.toString());
-                disconnect();
-            }
+    }
 
+    function disconnect() {
+        console.log(">> disconnect");
+        if (sc) {
+            sc.stop();
         }
-
-        function disconnect() {
-            console.log(">> disconnect");
-            if (sc) {
-                sc.stop();
+        if (window.File && window.FileReader && window.FileList && window.Blob) {
+            var spice_xfer_area = document.getElementById('spice-xfer-area');
+            if (spice_xfer_area != null) {
+                document.getElementById('spice-area').removeChild(spice_xfer_area);
             }
-            if (window.File && window.FileReader && window.FileList && window.Blob) {
-                var spice_xfer_area = document.getElementById('spice-xfer-area');
-                if (spice_xfer_area != null) {
-                  document.getElementById('spice-area').removeChild(spice_xfer_area);
-                }
-                document.getElementById('spice-area').removeEventListener('dragover', SpiceHtml5.handle_file_dragover, false);
-                document.getElementById('spice-area').removeEventListener('drop', SpiceHtml5.handle_file_drop, false);
-            }
-            console.log("<< disconnect");
+            document.getElementById('spice-area').removeEventListener('dragover', SpiceHtml5.handle_file_dragover, false);
+            document.getElementById('spice-area').removeEventListener('drop', SpiceHtml5.handle_file_drop, false);
         }
+        console.log("<< disconnect");
+    }
 
-        function agent_connected(sc) {
-            window.addEventListener('resize', SpiceHtml5.handle_resize);
-            window.spice_connection = this;
+    function agent_connected(sc) {
+        window.addEventListener('resize', SpiceHtml5.handle_resize);
+        window.spice_connection = this;
 
-            SpiceHtml5.resize_helper(this);
+        SpiceHtml5.resize_helper(this);
 
-            if (window.File && window.FileReader && window.FileList && window.Blob) {
-                var spice_xfer_area = document.createElement("div");
-                spice_xfer_area.setAttribute('id', 'spice-xfer-area');
-                document.getElementById('spice-area').appendChild(spice_xfer_area);
-                document.getElementById('spice-area').addEventListener('dragover', SpiceHtml5.handle_file_dragover, false);
-                document.getElementById('spice-area').addEventListener('drop', SpiceHtml5.handle_file_drop, false);
-            }
-            else {
-                console.log("File API is not supported");
-            }
+        if (window.File && window.FileReader && window.FileList && window.Blob) {
+            var spice_xfer_area = document.createElement("div");
+            spice_xfer_area.setAttribute('id', 'spice-xfer-area');
+            document.getElementById('spice-area').appendChild(spice_xfer_area);
+            document.getElementById('spice-area').addEventListener('dragover', SpiceHtml5.handle_file_dragover, false);
+            document.getElementById('spice-area').addEventListener('drop', SpiceHtml5.handle_file_drop, false);
         }
-
-        function fullscreen() {
-            var screen=document.getElementById('spice-screen');
-            if(screen.requestFullscreen) {
-                screen.requestFullscreen();
-            } else if(screen.mozRequestFullScreen) {
-                screen.mozRequestFullScreen();
-            } else if(screen.webkitRequestFullscreen) {
-                screen.webkitRequestFullscreen();
-            } else if(screen.msRequestFullscreen) {
-                screen.msRequestFullscreen();
-            }
+        else {
+            console.log("File API is not supported");
         }
+    }
 
-        /* SPICE port event listeners
-        window.addEventListener('spice-port-data', function(event) {
-            // Here we convert data to text, but really we can obtain binary data also
-            var msg_text = arraybuffer_to_str(new Uint8Array(event.detail.data));
-            DEBUG > 0 && console.log('SPICE port', event.detail.channel.portName, 'message text:', msg_text);
-        });
+    function fullscreen() {
+        var screen = document.getElementById('spice-screen');
+        if (screen.requestFullscreen) {
+            screen.requestFullscreen();
+        } else if (screen.mozRequestFullScreen) {
+            screen.mozRequestFullScreen();
+        } else if (screen.webkitRequestFullscreen) {
+            screen.webkitRequestFullscreen();
+        } else if (screen.msRequestFullscreen) {
+            screen.msRequestFullscreen();
+        }
+    }
 
-        window.addEventListener('spice-port-event', function(event) {
-            DEBUG > 0 && console.log('SPICE port', event.detail.channel.portName, 'event data:', event.detail.spiceEvent);
-        });
-        */
-        document.getElementById("fullscreen_button").addEventListener('click', fullscreen);
-        document.getElementById('ctrlaltdel').addEventListener('click', function(){sendCtrlAltDel(sc);});
-        document.getElementById('ctrlaltf1').addEventListener('click', function(){sendCtrlAltFN(0);});
-        document.getElementById('ctrlaltf2').addEventListener('click', function(){sendCtrlAltFN(1);});
-        document.getElementById('ctrlaltf3').addEventListener('click', function(){sendCtrlAltFN(2);});
-        document.getElementById('ctrlaltf4').addEventListener('click', function(){sendCtrlAltFN(3);});
-        document.getElementById('ctrlaltf5').addEventListener('click', function(){sendCtrlAltFN(4);});
-        document.getElementById('ctrlaltf6').addEventListener('click', function(){sendCtrlAltFN(5);});
-        document.getElementById('ctrlaltf7').addEventListener('click', function(){sendCtrlAltFN(6);});
-        document.getElementById('ctrlaltf8').addEventListener('click', function(){sendCtrlAltFN(7);});
-        document.getElementById('ctrlaltf9').addEventListener('click', function(){sendCtrlAltFN(8);});
-        document.getElementById('ctrlaltf10').addEventListener('click', function(){sendCtrlAltFN(9);});
-        document.getElementById('ctrlaltf11').addEventListener('click', function(){sendCtrlAltFN(10);});
-        document.getElementById('ctrlaltf12').addEventListener('click', function(){sendCtrlAltFN(11);});
-        connect(undefined);
-    </script>
+    function sendctrlaltfn(f) {
+        SpiceHtml5.sendCtrlAltFN(sc, f);
+        return false;
+    }
+
+    /* SPICE port event listeners
+    window.addEventListener('spice-port-data', function(event) {
+        // Here we convert data to text, but really we can obtain binary data also
+        var msg_text = arraybuffer_to_str(new Uint8Array(event.detail.data));
+        DEBUG > 0 && console.log('SPICE port', event.detail.channel.portName, 'message text:', msg_text);
+    });
+
+    window.addEventListener('spice-port-event', function(event) {
+        DEBUG > 0 && console.log('SPICE port', event.detail.channel.portName, 'event data:', event.detail.spiceEvent);
+    });
+    */
+    document.getElementById("fullscreen_button").addEventListener('click', fullscreen);
+    document.getElementById('ctrlaltdel').addEventListener('click', function () { sendCtrlAltDel(sc); });
+    document.getElementById('ctrlaltf1').addEventListener('click', function () { sendctrlaltfn(0) });
+    document.getElementById('ctrlaltf2').addEventListener('click', function () { sendctrlaltfn(1) });
+    document.getElementById('ctrlaltf3').addEventListener('click', function () { sendctrlaltfn(2) });
+    document.getElementById('ctrlaltf4').addEventListener('click', function () { sendctrlaltfn(3) });
+    document.getElementById('ctrlaltf5').addEventListener('click', function () { sendctrlaltfn(4) });
+    document.getElementById('ctrlaltf6').addEventListener('click', function () { sendctrlaltfn(5) });
+    document.getElementById('ctrlaltf7').addEventListener('click', function () { sendctrlaltfn(6) });
+    document.getElementById('ctrlaltf8').addEventListener('click', function () { sendctrlaltfn(7) });
+    document.getElementById('ctrlaltf9').addEventListener('click', function () { sendctrlaltfn(8) });
+    document.getElementById('ctrlaltf10').addEventListener('click', function () { sendctrlaltfn(9) });
+    document.getElementById('ctrlaltf11').addEventListener('click', function () { sendctrlaltfn(10) });
+    document.getElementById('ctrlaltf12').addEventListener('click', function () { sendctrlaltfn(11) });
+    connect(undefined);
+</script>
 {% endblock %}
 {% block content %}
-        <div id="spice-area">
-            <div id="spice-screen" class="spice-screen"></div>
-        </div>
+<div id="spice-area">
+    <div id="spice-screen" class="spice-screen"></div>
+</div>
 
-        <div id="message-div" class="spice-message"></div>
+<div id="message-div" class="spice-message"></div>
 
-        <div id="debug-div">
-        <!-- If DUMPXXX is turned on, dumped images will go here -->
-        </div>
-{% endblock %}
+<div id="debug-div">
+    <!-- If DUMPXXX is turned on, dumped images will go here -->
+</div>
+{% endblock %}
\ No newline at end of file
diff --git a/console/templates/console-vnc-lite.html b/console/templates/console-vnc-lite.html
index 70e10e6..3fd7db2 100755
--- a/console/templates/console-vnc-lite.html
+++ b/console/templates/console-vnc-lite.html
@@ -3,306 +3,228 @@
 {% load staticfiles %}
 
 {% block head %}
-    <!--
+
+<!--
     noVNC example: lightweight example using minimal UI and features
-    Copyright (C) 2012 Joel Martin
-    Copyright (C) 2017 Samuel Mannehed for Cendio AB
+    This is a self-contained file which doesn't import WebUtil or external CSS.
+    Copyright (C) 2019 The noVNC Authors
     noVNC is licensed under the MPL 2.0 (see LICENSE.txt)
     This file is licensed under the 2-Clause BSD license (see LICENSE.txt).
-
     Connect parameters are provided in query string:
-        http://example.com/?host=HOST&port=PORT&encrypt=1
-    or the fragment:
-        http://example.com/#host=HOST&port=PORT&encrypt=1
-    -->
-    <title>WebVirtCloud - noVNC - Lite</title>
+        http://example.com/?host=HOST&port=PORT&scale=true
+-->
+<title>WebVirtCloud - noVNC - Lite</title>
 
-    <meta charset="utf-8">
+<meta charset="utf-8">
 
-    <!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame
-                Remove this if you use the .htaccess -->
-    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+<!-- Always force latest IE rendering engine (even in intranet) &
+                Chrome Frame. Remove this if you use the .htaccess -->
+<meta http-equiv="X-UA-Compatible" content="IE=edge" />
 
-    <!-- Icons (see Makefile for what the sizes are for) -->
-    <link rel="icon" sizes="16x16" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-16x16.png" %}">
-    <link rel="icon" sizes="24x24" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-24x24.png" %}">
-    <link rel="icon" sizes="32x32" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-32x32.png" %}">
-    <link rel="icon" sizes="48x48" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-48x48.png" %}">
-    <link rel="icon" sizes="60x60" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-60x60.png" %}">
-    <link rel="icon" sizes="64x64" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-64x64.png" %}">
-    <link rel="icon" sizes="72x72" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-72x72.png" %}">
-    <link rel="icon" sizes="76x76" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-76x76.png" %}">
-    <link rel="icon" sizes="96x96" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-96x96.png" %}">
-    <link rel="icon" sizes="120x120" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-120x120.png" %}">
-    <link rel="icon" sizes="144x144" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-144x144.png" %}">
-    <link rel="icon" sizes="152x152" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-152x152.png" %}">
-    <link rel="icon" sizes="192x192" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-192x192.png" %}">
-    <!-- Firefox currently mishandles SVG, see #1419039
-    <link rel="icon" sizes="any" type="image/svg+xml" href="{% static "js/novnc/app/images/icons/novnc-icon.svg" %}">
-    -->
-    <!-- Repeated last so that legacy handling will pick this -->
-    <link rel="icon" sizes="16x16" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-16x16.png" %}">
+<!-- Stylesheets -->
+<link rel="stylesheet" href='{% static "js/novnc/app/styles/lite.css" %}'>
 
-    <!-- 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="{% static "js/novnc/app/images/icons/novnc-60x60.png" %}">
-    <link rel="apple-touch-icon" sizes="76x76" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-76x76.png" %}">
-    <link rel="apple-touch-icon" sizes="120x120" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-120x120.png" %}">
-    <link rel="apple-touch-icon" sizes="152x152" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-152x152.png" %}">
+<!-- Promise polyfill for IE11 -->
+<script src="{% static 'js/novnc/vendor/promise.js' %}"></script>
 
-    <!-- Stylesheets -->
-    <link rel="stylesheet" href="{% static "js/novnc/app/styles/lite.css" %}">
+<!-- ES2015/ES6 modules polyfill -->
+<script nomodule
+    src="{% static 'js/novnc/vendor/browser-es-module-loader/dist/browser-es-module-loader.js' %}"></script>
 
-     <!--
-    <script type='text/javascript'
-        src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
-    -->
+<!-- actual script modules -->
+<script type="module" crossorigin="anonymous">
+    // RFB holds the API to connect and communicate with a VNC server
+    import RFB from '{% static "js/novnc/core/rfb.js" %}';
 
-    <!-- promise polyfills promises for IE11 -->
-    <script src="{% static "js/novnc/vendor/promise.js" %}"></script>
-    <!-- ES2015/ES6 modules polyfill -->
-    <script type="module"> window._noVNC_has_module_support = true;</script>
-    <script>
-        window.addEventListener("load", function() {
-            if (window._noVNC_has_module_support) return;
-            var loader = document.createElement("script");
-            loader.src = "{% static "js/novnc/vendor/browser-es-module-loader/dist/browser-es-module-loader.js" %}";
-            document.head.appendChild(loader);
-        });
-    </script>
+    let rfb;
+    let desktopName;
 
-            <!-- actual script modules -->
-    <script type="module" crossorigin="anonymous">
-        // Load supporting scripts
-        import * as WebUtil from '{% static "js/novnc/app/webutil.js" %}';
-        import RFB from '{% static "js/novnc/core/rfb.js" %}';
+    // When this function is called we have
+    // successfully connected to a server
+    function connectedToServer(e) {
+        status("Connected to " + desktopName);
+    }
 
-        var rfb;
-        var desktopName;
-
-        function updateDesktopName(e) {
-            desktopName = e.detail.name;
+    // This function is called when we are disconnected
+    function disconnectedFromServer(e) {
+        if (e.detail.clean) {
+            status("Disconnected");
+        } else {
+            status("Something went wrong, connection is closed");
         }
-        function credentials(e) {
-            var html;
+    }
 
-            var form = document.createElement('form');
-            form.innerHTML = '<label></label>';
-            form.innerHTML += '<input type=password size=10 id="password_input">';
-            form.onsubmit = setPassword;
+    // When this function is called, the server requires
+    // credentials to authenticate
+    function credentialsAreRequired(e) {
+        const password = prompt("Password Required:");
+        rfb.sendCredentials({ password: password });
+    }
 
-            // bypass status() because it sets text content
-            document.getElementById('noVNC_status_bar').setAttribute("class", "noVNC_status_warn");
-            document.getElementById('noVNC_status').innerHTML = '';
-            document.getElementById('noVNC_status').appendChild(form);
-            document.getElementById('noVNC_status').querySelector('label').textContent = 'Password Required: ';
-        }
-        function setPassword() {
-            rfb.sendCredentials({ password: document.getElementById('password_input').value });
-            return false;
-        }
-        function fullscreen() {
-            if (document.fullscreenElement || // alternative standard method
-                document.mozFullScreenElement || // currently working methods
-                document.webkitFullscreenElement ||
-                document.msFullscreenElement) {
-                if (document.exitFullscreen) {
-                    document.exitFullscreen();
-                } else if (document.mozCancelFullScreen) {
-                    document.mozCancelFullScreen();
-                } else if (document.webkitExitFullscreen) {
-                    document.webkitExitFullscreen();
-                } else if (document.msExitFullscreen) {
-                    document.msExitFullscreen();
-                }
-            } else {
-                if (document.documentElement.requestFullscreen) {
-                    document.documentElement.requestFullscreen();
-                } else if (document.documentElement.mozRequestFullScreen) {
-                    document.documentElement.mozRequestFullScreen();
-                } else if (document.documentElement.webkitRequestFullscreen) {
-                    document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
-                } else if (document.body.msRequestFullscreen) {
-                    document.body.msRequestFullscreen();
-                }
+    // When this function is called we have received
+    // a desktop name from the server
+    function updateDesktopName(e) {
+        desktopName = e.detail.name;
+    }
+
+    // Since most operating systems will catch Ctrl+Alt+Del
+    // before they get a chance to be intercepted by the browser,
+    // we provide a way to emulate this key sequence.
+    function sendCtrlAltDel() {
+        rfb.sendCtrlAltDel();
+        return false;
+    }
+
+    function fullscreen() {
+        if (document.fullscreenElement || // alternative standard method
+            document.mozFullScreenElement || // currently working methods
+            document.webkitFullscreenElement ||
+            document.msFullscreenElement) {
+            if (document.exitFullscreen) {
+                document.exitFullscreen();
+            } else if (document.mozCancelFullScreen) {
+                document.mozCancelFullScreen();
+            } else if (document.webkitExitFullscreen) {
+                document.webkitExitFullscreen();
+            } else if (document.msExitFullscreen) {
+                document.msExitFullscreen();
             }
-            return false;
-        }
-        function sendCtrlAltFN(f) {
-            rfb.sendCtrlAltFN(f);
-            return false;
-        }
-        function sendCtrlAltDel() {
-            rfb.sendCtrlAltDel();
-            return false;
-        }
-        function machineShutdown() {
-            rfb.machineShutdown();
-            return false;
-        }
-        function machineReboot() {
-            rfb.machineReboot();
-            return false;
-        }
-        function machineReset() {
-            rfb.machineReset();
-            return false;
-        }
-        function status(text, level) {
-            switch (level) {
-                case 'normal':
-                case 'warn':
-                case 'error':
-                    break;
-                default:
-                    level = "warn";
-            }
-            document.getElementById('noVNC_status_bar').className = "noVNC_status_" + level;
-            document.getElementById('noVNC_status').textContent = text;
-        }
-
-        function connected(e) {
-            document.getElementById('sendCtrlAltDelButton').disabled = false;
-            if (WebUtil.getConfigVar('encrypt', (window.location.protocol === "https:"))) {
-                status("Connected (encrypted) to " + desktopName, "normal");
-            } else {
-                status("Connected (unencrypted) to " + desktopName, "normal");
+        } else {
+            if (document.documentElement.requestFullscreen) {
+                document.documentElement.requestFullscreen();
+            } else if (document.documentElement.mozRequestFullScreen) {
+                document.documentElement.mozRequestFullScreen();
+            } else if (document.documentElement.webkitRequestFullscreen) {
+                document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
+            } else if (document.body.msRequestFullscreen) {
+                document.body.msRequestFullscreen();
             }
         }
+        return false;
+    }
+    function sendCtrlAltFN(f) {
+        rfb.sendCtrlAltFN(f);
+        return false;
+    }
+    function machineShutdown() {
+        rfb.machineShutdown();
+        return false;
+    }
+    function machineReboot() {
+        rfb.machineReboot();
+        return false;
+    }
+    function machineReset() {
+        rfb.machineReset();
+        return false;
+    }
 
-        function disconnected(e) {
-            document.getElementById('sendCtrlAltDelButton').disabled = true;
-            updatePowerButtons();
-            if (e.detail.clean) {
-                status("Disconnected", "normal");
-            } else {
-                status("Something went wrong, connection is closed", "error");
-            }
+    // Show a status text in the top bar
+    function status(text) {
+        document.getElementById('noVNC_status').textContent = text;
+    }
+
+    // This function extracts the value of one variable from the
+    // query string. If the variable isn't defined in the URL
+    // it returns the default value instead.
+    function readQueryVariable(name, defaultValue) {
+        // A URL with a query parameter can look like this:
+        // https://www.example.com?myqueryparam=myvalue
+        //
+        // Note that we use location.href instead of location.search
+        // because Firefox < 53 has a bug w.r.t location.search
+        const re = new RegExp('.*[?&]' + name + '=([^&#]*)'),
+            match = document.location.href.match(re);
+
+        if (match) {
+            // We have to decode the URL since want the cleartext value
+            return decodeURIComponent(match[1]);
         }
 
-        function updatePowerButtons() {
-            var powerbuttons;
-            powerbuttons = document.getElementById('noVNC_power_buttons');
-            if (rfb.capabilities.power) {
-                powerbuttons.className= "noVNC_shown";
-            } else {
-                powerbuttons.className = "noVNC_hidden";
-            }
-        }
+        return defaultValue;
+    }
 
-        document.getElementById('sendCtrlAltDelButton').onclick = sendCtrlAltDel;
-        document.getElementById('machineShutdownButton').onclick = machineShutdown;
-        document.getElementById('machineRebootButton').onclick = machineReboot;
-        document.getElementById('machineResetButton').onclick = machineReset;
-        document.getElementById('fullscreen_button').onclick = fullscreen;
+    document.getElementById('sendCtrlAltDelButton').onclick = sendCtrlAltDel;
+    document.getElementById('machineShutdownButton').onclick = machineShutdown;
+    document.getElementById('machineRebootButton').onclick = machineReboot;
+    document.getElementById('machineResetButton').onclick = machineReset;
+    document.getElementById('fullscreen_button').onclick = fullscreen;
 
-        document.getElementById('ctrlaltdel').addEventListener('click', sendCtrlAltDel);
-        document.getElementById('ctrlaltf1').addEventListener('click', function(){sendCtrlAltFN(0);});
-        document.getElementById('ctrlaltf2').addEventListener('click', function(){sendCtrlAltFN(1);});
-        document.getElementById('ctrlaltf3').addEventListener('click', function(){sendCtrlAltFN(2);});
-        document.getElementById('ctrlaltf4').addEventListener('click', function(){sendCtrlAltFN(3);});
-        document.getElementById('ctrlaltf5').addEventListener('click', function(){sendCtrlAltFN(4);});
-        document.getElementById('ctrlaltf6').addEventListener('click', function(){sendCtrlAltFN(5);});
-        document.getElementById('ctrlaltf7').addEventListener('click', function(){sendCtrlAltFN(6);});
-        document.getElementById('ctrlaltf8').addEventListener('click', function(){sendCtrlAltFN(7);});
-        document.getElementById('ctrlaltf9').addEventListener('click', function(){sendCtrlAltFN(8);});
-        document.getElementById('ctrlaltf10').addEventListener('click', function(){sendCtrlAltFN(9);});
-        document.getElementById('ctrlaltf11').addEventListener('click', function(){sendCtrlAltFN(10);});
-        document.getElementById('ctrlaltf12').addEventListener('click', function(){sendCtrlAltFN(11);});
+    document.getElementById('ctrlaltdel').addEventListener('click', sendCtrlAltDel);
+    document.getElementById('ctrlaltf1').addEventListener('click', function () { sendCtrlAltFN(0); });
+    document.getElementById('ctrlaltf2').addEventListener('click', function () { sendCtrlAltFN(1); });
+    document.getElementById('ctrlaltf3').addEventListener('click', function () { sendCtrlAltFN(2); });
+    document.getElementById('ctrlaltf4').addEventListener('click', function () { sendCtrlAltFN(3); });
+    document.getElementById('ctrlaltf5').addEventListener('click', function () { sendCtrlAltFN(4); });
+    document.getElementById('ctrlaltf6').addEventListener('click', function () { sendCtrlAltFN(5); });
+    document.getElementById('ctrlaltf7').addEventListener('click', function () { sendCtrlAltFN(6); });
+    document.getElementById('ctrlaltf8').addEventListener('click', function () { sendCtrlAltFN(7); });
+    document.getElementById('ctrlaltf9').addEventListener('click', function () { sendCtrlAltFN(8); });
+    document.getElementById('ctrlaltf10').addEventListener('click', function () { sendCtrlAltFN(9); });
+    document.getElementById('ctrlaltf11').addEventListener('click', function () { sendCtrlAltFN(10); });
+    document.getElementById('ctrlaltf12').addEventListener('click', function () { sendCtrlAltFN(11); });
 
-        WebUtil.init_logging(WebUtil.getConfigVar('logging', 'warn'));
-        document.title = WebUtil.getConfigVar('title', 'noVNC');
-        // By default, use the host and port of server that served this file
-        //var host = WebUtil.getConfigVar('host', window.location.hostname);
-        //var port = WebUtil.getConfigVar('port', window.location.port);
-        var host = '{{ ws_host }}';
-        var port = '{{ ws_port }}';
+    // Read parameters specified in the URL query string
+    // By default, use the host and port of server that served this file
+    const host = readQueryVariable('host', '{{ ws_host }}');
+    let port = readQueryVariable('port', '{{ ws_port }}');
+    const password = readQueryVariable('password');
+    const path = readQueryVariable('path', 'websockify');
 
-        // if port == 80 (or 443) then it won't be present and should be
-        // set manually
-        if (!port) {
-            if (window.location.protocol.substring(0,5) == 'https') {
-                port = 443;
-            }
-            else if (window.location.protocol.substring(0,4) == 'http') {
-                port = 80;
-            }
-        }
 
-        //var password = WebUtil.getConfigVar('password', '');
-        var password = '{{ console_passwd }}';
+    // | | |         | | |
+    // | | | Connect | | |
+    // v v v         v v v
 
-        var path = WebUtil.getConfigVar('path', 'websockify');
+    status("Connecting");
 
-        // If a token variable is passed in, set the parameter in a cookie.
-        // This is used by nova-novncproxy.
-        var token = WebUtil.getConfigVar('token', null);
-        if (token) {
-            // if token is already present in the path we should use it
-            path = WebUtil.injectParamIfMissing(path, "token", token);
+    // Build the websocket URL used to connect
+    let url;
+    if (window.location.protocol === "https:") {
+        url = 'wss';
+    } else {
+        url = 'ws';
+    }
+    url += '://' + host;
+    if (port) {
+        url += ':' + port;
+    }
+    url += '/' + path;
 
-            WebUtil.createCookie('token', token, 1)
-        }
+    // Creating a new RFB object will start a new connection
+    rfb = new RFB(document.getElementById('noVNC_container'), url,
+        { credentials: { password: password } });
 
-        (function() {
+    // Add listeners to important events from the RFB module
+    rfb.addEventListener("connect", connectedToServer);
+    rfb.addEventListener("disconnect", disconnectedFromServer);
+    rfb.addEventListener("credentialsrequired", credentialsAreRequired);
+    rfb.addEventListener("desktopname", updateDesktopName);
+    rfb.addEventListener("capabilities", function () { updatePowerButtons(); });
 
-            status("Connecting", "normal");
+    // Set parameters that can be changed on an active connection
+    rfb.viewOnly = readQueryVariable('view_only', {{ view_only }});
+    rfb.scaleViewport = readQueryVariable('scale', {{ scale }});
+    rfb.resizeSession = readQueryVariable('resize', {{ resize_session }});
+    rfb.clipViewport = readQueryVariable('clip_viewport', {{ clip_viewport }});
 
-            if ((!host) || (!port)) {
-                status('Must specify host and port in URL', 'error');
-            }
-
-            var url;
-
-            if (WebUtil.getConfigVar('encrypt', (window.location.protocol === "https:"))) {
-                url = 'wss';
-            } else {
-                url = 'ws';
-            }
-
-            url += '://' + host;
-            if(port) {
-                url += ':' + port;
-            }
-            url += '/' + path;
-
-          //rfb = new RFB(document.body, url,
-          //             { repeaterID: WebUtil.getConfigVar('repeaterID', ''),
-          //               shared: WebUtil.getConfigVar('shared', true),
-          //               credentials: { password: password } });
-            rfb = new RFB(document.getElementById('noVNC_container'), url,
-                         { repeaterID: WebUtil.getConfigVar('repeaterID', ''),
-                           shared: WebUtil.getConfigVar('shared', true),
-                           credentials: { password: password } });
-
-            rfb.viewOnly = WebUtil.getConfigVar('view_only', false);
-            rfb.addEventListener("connect",  connected);
-            rfb.addEventListener("disconnect", disconnected);
-            rfb.addEventListener("capabilities", function () { updatePowerButtons(); });
-            rfb.addEventListener("credentialsrequired", credentials);
-            rfb.addEventListener("desktopname", updateDesktopName);
-            rfb.scaleViewport = WebUtil.getConfigVar('scale', false);
-            rfb.resizeSession = WebUtil.getConfigVar('resize', false);
-        })();
-    </script>
+</script>
 {% endblock %}
 
-
 {% block content %}
-    <div id="noVNC_status_bar">
-        <div id="noVNC_left_dummy_elem"></div>
-        <div id="noVNC_status">{% trans 'Loading' %}</div>
-        <div id="noVNC_buttons">
-            <input type="button" value="Send CtrlAltDel" id="sendCtrlAltDelButton" class="noVNC_shown">
-            <span id="noVNC_power_buttons" class="noVNC_hidden">
-                <input type=button value="Shutdown" id="machineShutdownButton">
-                <input type=button value="Reboot" id="machineRebootButton">
-                <input type=button value="Reset" id="machineResetButton">
-            </span>
-        </div>
+<div id="noVNC_status_bar">
+    <div id="noVNC_left_dummy_elem"></div>
+    <div id="noVNC_status">{% trans 'Loading' %}</div>
+    <div id="noVNC_buttons">
+        <input type="button" value="Send CtrlAltDel" id="sendCtrlAltDelButton" class="noVNC_shown">
+        <span id="noVNC_power_buttons" class="noVNC_hidden">
+            <input type="button" value="Shutdown" id="machineShutdownButton">
+            <input type="button" value="Reboot" id="machineRebootButton">
+            <input type="button" value="Reset" id="machineResetButton">
+        </span>
     </div>
-    <div id='noVNC_container'></div>
-{% endblock %}
+</div>
+<div id="noVNC_container">
+    <!-- This is where the remote screen will appear -->
+</div>
+{% endblock %}
\ No newline at end of file
diff --git a/console/views.py b/console/views.py
index 27d864f..e7fc64a 100644
--- a/console/views.py
+++ b/console/views.py
@@ -16,6 +16,10 @@ def console(request):
     if request.method == 'GET':
         token = request.GET.get('token', '')
         view_type = request.GET.get('view', 'lite')
+        view_only = request.GET.get('view_only', 0)
+        scale = request.GET.get('scale', 0)
+        resize_session = request.GET.get('resize_session', 0)
+        clip_viewport = request.GET.get('clip_viewport', 0)
 
     try:
         temptoken = token.split('-', 1)
diff --git a/static/js/novnc/app/styles/lite.css b/static/js/novnc/app/styles/lite.css
index a6a9218..39d45ef 100755
--- a/static/js/novnc/app/styles/lite.css
+++ b/static/js/novnc/app/styles/lite.css
@@ -10,7 +10,7 @@ body {
   margin:0;
   background-color:#313131;
   border-bottom-right-radius: 800px 600px;
-  height:100%;
+  height: 100%;
   display: flex;
   flex-direction: column;
 }
diff --git a/static/js/spice-html5/inputs.js b/static/js/spice-html5/inputs.js
index c6fd3f7..ff9f3e6 100755
--- a/static/js/spice-html5/inputs.js
+++ b/static/js/spice-html5/inputs.js
@@ -38,8 +38,7 @@ var Meta_state = -1;
 **  SpiceInputsConn
 **      Drive the Spice Inputs channel (e.g. mouse + keyboard)
 **--------------------------------------------------------------------------*/
-function SpiceInputsConn()
-{
+function SpiceInputsConn() {
     SpiceConn.apply(this, arguments);
 
     this.mousex = undefined;
@@ -49,26 +48,22 @@ function SpiceInputsConn()
 }
 
 SpiceInputsConn.prototype = Object.create(SpiceConn.prototype);
-SpiceInputsConn.prototype.process_channel_message = function(msg)
-{
-    if (msg.type == Constants.SPICE_MSG_INPUTS_INIT)
-    {
+SpiceInputsConn.prototype.process_channel_message = function (msg) {
+    if (msg.type == Constants.SPICE_MSG_INPUTS_INIT) {
         var inputs_init = new Messages.SpiceMsgInputsInit(msg.data);
         this.keyboard_modifiers = inputs_init.keyboard_modifiers;
         DEBUG > 1 && console.log("MsgInputsInit - modifier " + this.keyboard_modifiers);
         // FIXME - We don't do anything with the keyboard modifiers...
         return true;
     }
-    if (msg.type == Constants.SPICE_MSG_INPUTS_KEY_MODIFIERS)
-    {
+    if (msg.type == Constants.SPICE_MSG_INPUTS_KEY_MODIFIERS) {
         var key = new Messages.SpiceMsgInputsKeyModifiers(msg.data);
         this.keyboard_modifiers = key.keyboard_modifiers;
         DEBUG > 1 && console.log("MsgInputsKeyModifiers - modifier " + this.keyboard_modifiers);
         // FIXME - We don't do anything with the keyboard modifiers...
         return true;
     }
-    if (msg.type == Constants.SPICE_MSG_INPUTS_MOUSE_MOTION_ACK)
-    {
+    if (msg.type == Constants.SPICE_MSG_INPUTS_MOUSE_MOTION_ACK) {
         DEBUG > 1 && console.log("mouse motion ack");
         this.waiting_for_ack -= Constants.SPICE_INPUT_MOTION_ACK_BUNCH;
         return true;
@@ -78,35 +73,28 @@ SpiceInputsConn.prototype.process_channel_message = function(msg)
 
 
 
-function handle_mousemove(e)
-{
+function handle_mousemove(e) {
     var msg = new Messages.SpiceMiniData();
     var move;
-    if (this.sc.mouse_mode == Constants.SPICE_MOUSE_MODE_CLIENT)
-    {
+    if (this.sc.mouse_mode == Constants.SPICE_MOUSE_MODE_CLIENT) {
         move = new Messages.SpiceMsgcMousePosition(this.sc, e)
         msg.build_msg(Constants.SPICE_MSGC_INPUTS_MOUSE_POSITION, move);
     }
-    else
-    {
+    else {
         move = new Messages.SpiceMsgcMouseMotion(this.sc, e)
         msg.build_msg(Constants.SPICE_MSGC_INPUTS_MOUSE_MOTION, move);
     }
-    if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
-    {
-        if (this.sc.inputs.waiting_for_ack < (2 * Constants.SPICE_INPUT_MOTION_ACK_BUNCH))
-        {
+    if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready") {
+        if (this.sc.inputs.waiting_for_ack < (2 * Constants.SPICE_INPUT_MOTION_ACK_BUNCH)) {
             this.sc.inputs.send_msg(msg);
             this.sc.inputs.waiting_for_ack++;
         }
-        else
-        {
+        else {
             DEBUG > 0 && this.sc.log_info("Discarding mouse motion");
         }
     }
 
-    if (this.sc && this.sc.cursor && this.sc.cursor.spice_simulated_cursor)
-    {
+    if (this.sc && this.sc.cursor && this.sc.cursor.spice_simulated_cursor) {
         this.sc.cursor.spice_simulated_cursor.style.display = 'block';
         this.sc.cursor.spice_simulated_cursor.style.left = e.pageX - this.sc.cursor.spice_simulated_cursor.spice_hot_x + 'px';
         this.sc.cursor.spice_simulated_cursor.style.top = e.pageY - this.sc.cursor.spice_simulated_cursor.spice_hot_y + 'px';
@@ -115,8 +103,7 @@ function handle_mousemove(e)
 
 }
 
-function handle_mousedown(e)
-{
+function handle_mousedown(e) {
     var press = new Messages.SpiceMsgcMousePress(this.sc, e)
     var msg = new Messages.SpiceMiniData();
     msg.build_msg(Constants.SPICE_MSGC_INPUTS_MOUSE_PRESS, press);
@@ -126,14 +113,12 @@ function handle_mousedown(e)
     e.preventDefault();
 }
 
-function handle_contextmenu(e)
-{
+function handle_contextmenu(e) {
     e.preventDefault();
     return false;
 }
 
-function handle_mouseup(e)
-{
+function handle_mouseup(e) {
     var release = new Messages.SpiceMsgcMouseRelease(this.sc, e)
     var msg = new Messages.SpiceMiniData();
     msg.build_msg(Constants.SPICE_MSGC_INPUTS_MOUSE_RELEASE, release);
@@ -143,8 +128,7 @@ function handle_mouseup(e)
     e.preventDefault();
 }
 
-function handle_mousewheel(e)
-{
+function handle_mousewheel(e) {
     var press = new Messages.SpiceMsgcMousePress;
     var release = new Messages.SpiceMsgcMouseRelease;
     if (e.deltaY < 0)
@@ -166,8 +150,7 @@ function handle_mousewheel(e)
     e.preventDefault();
 }
 
-function handle_keydown(e)
-{
+function handle_keydown(e) {
     var key = new Messages.SpiceMsgcKeyDown(e)
     var msg = new Messages.SpiceMiniData();
     check_and_update_modifiers(e, key.code, this.sc);
@@ -178,8 +161,7 @@ function handle_keydown(e)
     e.preventDefault();
 }
 
-function handle_keyup(e)
-{
+function handle_keyup(e) {
     var key = new Messages.SpiceMsgcKeyUp(e)
     var msg = new Messages.SpiceMiniData();
     check_and_update_modifiers(e, key.code, this.sc);
@@ -190,9 +172,8 @@ function handle_keyup(e)
     e.preventDefault();
 }
 
-function sendCtrlAltDel(sc)
-{
-    if (sc && sc.inputs && sc.inputs.state === "ready"){
+function sendCtrlAltDel(sc) {
+    if (sc && sc.inputs && sc.inputs.state === "ready") {
         var key = new Messages.SpiceMsgcKeyDown();
         var msg = new Messages.SpiceMiniData();
 
@@ -205,22 +186,55 @@ function sendCtrlAltDel(sc)
         msg.build_msg(Constants.SPICE_MSGC_INPUTS_KEY_UP, key);
         sc.inputs.send_msg(msg);
 
-        if(Ctrl_state == false) update_modifier(false, KeyNames.KEY_LCtrl, sc);
-        if(Alt_state == false) update_modifier(false, KeyNames.KEY_Alt, sc);
+        if (Ctrl_state == false) update_modifier(false, KeyNames.KEY_LCtrl, sc);
+        if (Alt_state == false) update_modifier(false, KeyNames.KEY_Alt, sc);
     }
 }
 
-function update_modifier(state, code, sc)
-{
+function sendCtrlAltFN(sc, f) {
+    if (sc && sc.inputs && sc.inputs.state === "ready") {
+        var keys_code = [
+            KeyNames.KEY_F1,
+            KeyNames.KEY_F2,
+            KeyNames.KEY_F3,
+            KeyNames.KEY_F4,
+            KeyNames.KEY_F5,
+            KeyNames.KEY_F6,
+            KeyNames.KEY_F7,
+            KeyNames.KEY_F8,
+            KeyNames.KEY_F9,
+            KeyNames.KEY_F10,
+            KeyNames.KEY_F11,
+            KeyNames.KEY_F12];
+
+        if (keys_code[f] == undefined) {
+            return;
+        }
+        var key = new Messages.SpiceMsgcKeyDown();
+        var msg = new Messages.SpiceMiniData();
+
+        update_modifier(true, KeyNames.KEY_LCtrl, sc);
+        update_modifier(true, KeyNames.KEY_Alt, sc);
+
+        key.code = keys_code[f];
+        msg.build_msg(Constants.SPICE_MSGC_INPUTS_KEY_DOWN, key);
+        sc.inputs.send_msg(msg);
+        msg.build_msg(Constants.SPICE_MSGC_INPUTS_KEY_UP, key);
+        sc.inputs.send_msg(msg);
+
+        if (Ctrl_state == false) update_modifier(false, KeyNames.KEY_LCtrl, sc);
+        if (Alt_state == false) update_modifier(false, KeyNames.KEY_Alt, sc);
+    }
+}
+
+function update_modifier(state, code, sc) {
     var msg = new Messages.SpiceMiniData();
-    if (!state)
-    {
+    if (!state) {
         var key = new Messages.SpiceMsgcKeyUp()
-        key.code =(0x80|code);
+        key.code = (0x80 | code);
         msg.build_msg(Constants.SPICE_MSGC_INPUTS_KEY_UP, key);
     }
-    else
-    {
+    else {
         var key = new Messages.SpiceMsgcKeyDown()
         key.code = code;
         msg.build_msg(Constants.SPICE_MSGC_INPUTS_KEY_DOWN, key);
@@ -229,10 +243,8 @@ function update_modifier(state, code, sc)
     sc.inputs.send_msg(msg);
 }
 
-function check_and_update_modifiers(e, code, sc)
-{
-    if (Shift_state === -1)
-    {
+function check_and_update_modifiers(e, code, sc) {
+    if (Shift_state === -1) {
         Shift_state = e.shiftKey;
         Ctrl_state = e.ctrlKey;
         Alt_state = e.altKey;
@@ -247,37 +259,32 @@ function check_and_update_modifiers(e, code, sc)
         Ctrl_state = true;
     else if (code === 0xE0B5)
         Meta_state = true;
-    else if (code === (0x80|KeyNames.KEY_ShiftL))
+    else if (code === (0x80 | KeyNames.KEY_ShiftL))
         Shift_state = false;
-    else if (code === (0x80|KeyNames.KEY_Alt))
+    else if (code === (0x80 | KeyNames.KEY_Alt))
         Alt_state = false;
-    else if (code === (0x80|KeyNames.KEY_LCtrl))
+    else if (code === (0x80 | KeyNames.KEY_LCtrl))
         Ctrl_state = false;
-    else if (code === (0x80|0xE0B5))
+    else if (code === (0x80 | 0xE0B5))
         Meta_state = false;
 
-    if (sc && sc.inputs && sc.inputs.state === "ready")
-    {
-        if (Shift_state != e.shiftKey)
-        {
+    if (sc && sc.inputs && sc.inputs.state === "ready") {
+        if (Shift_state != e.shiftKey) {
             console.log("Shift state out of sync");
             update_modifier(e.shiftKey, KeyNames.KEY_ShiftL, sc);
             Shift_state = e.shiftKey;
         }
-        if (Alt_state != e.altKey)
-        {
+        if (Alt_state != e.altKey) {
             console.log("Alt state out of sync");
             update_modifier(e.altKey, KeyNames.KEY_Alt, sc);
             Alt_state = e.altKey;
         }
-        if (Ctrl_state != e.ctrlKey)
-        {
+        if (Ctrl_state != e.ctrlKey) {
             console.log("Ctrl state out of sync");
             update_modifier(e.ctrlKey, KeyNames.KEY_LCtrl, sc);
             Ctrl_state = e.ctrlKey;
         }
-        if (Meta_state != e.metaKey)
-        {
+        if (Meta_state != e.metaKey) {
             console.log("Meta state out of sync");
             update_modifier(e.metaKey, 0xE0B5, sc);
             Meta_state = e.metaKey;
@@ -286,13 +293,14 @@ function check_and_update_modifiers(e, code, sc)
 }
 
 export {
-  SpiceInputsConn,
-  handle_mousemove,
-  handle_mousedown,
-  handle_contextmenu,
-  handle_mouseup,
-  handle_mousewheel,
-  handle_keydown,
-  handle_keyup,
-  sendCtrlAltDel,
+    SpiceInputsConn,
+    handle_mousemove,
+    handle_mousedown,
+    handle_contextmenu,
+    handle_mouseup,
+    handle_mousewheel,
+    handle_keydown,
+    handle_keyup,
+    sendCtrlAltDel,
+    sendCtrlAltFN
 };
diff --git a/static/js/spice-html5/main.js b/static/js/spice-html5/main.js
index 4a37b55..eac6f57 100755
--- a/static/js/spice-html5/main.js
+++ b/static/js/spice-html5/main.js
@@ -24,7 +24,7 @@ import { SpiceCursorConn } from './cursor.js';
 import { SpiceConn } from './spiceconn.js';
 import { DEBUG } from './utils.js';
 import { SpiceFileXferTask } from './filexfer.js';
-import { SpiceInputsConn, sendCtrlAltDel } from './inputs.js';
+import { SpiceInputsConn, sendCtrlAltDel, sendCtrlAltFN } from './inputs.js';
 import { SpiceDisplayConn } from './display.js';
 import { SpicePlaybackConn } from './playback.js';
 import { SpicePortConn } from './port.js';
@@ -63,8 +63,7 @@ import { resize_helper, handle_resize } from './resize.js';
 **      browser, including WebSocket and WebSocket.binaryType == arraybuffer
 **
 **--------------------------------------------------------------------------*/
-function SpiceMainConn()
-{
+function SpiceMainConn() {
     if (typeof WebSocket === "undefined")
         throw new Error("WebSocket unavailable.  You need to use a different browser.");
 
@@ -78,47 +77,42 @@ function SpiceMainConn()
 }
 
 SpiceMainConn.prototype = Object.create(SpiceConn.prototype);
-SpiceMainConn.prototype.process_channel_message = function(msg)
-{
-    if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_BEGIN)
-    {
+SpiceMainConn.prototype.process_channel_message = function (msg) {
+    if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_BEGIN) {
         this.known_unimplemented(msg.type, "Main Migrate Begin");
         return true;
     }
 
-    if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_CANCEL)
-    {
+    if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_CANCEL) {
         this.known_unimplemented(msg.type, "Main Migrate Cancel");
         return true;
     }
 
-    if (msg.type == Constants.SPICE_MSG_MAIN_INIT)
-    {
+    if (msg.type == Constants.SPICE_MSG_MAIN_INIT) {
         this.log_info("Connected to " + this.ws.url);
         this.report_success("Connected")
         this.main_init = new Messages.SpiceMsgMainInit(msg.data);
         this.connection_id = this.main_init.session_id;
         this.agent_tokens = this.main_init.agent_tokens;
 
-        if (DEBUG > 0)
-        {
+        if (DEBUG > 0) {
             // FIXME - there is a lot here we don't handle; mouse modes, agent,
             //          ram_hint, multi_media_time
-            this.log_info("session id "                 + this.main_init.session_id +
-                          " ; display_channels_hint "   + this.main_init.display_channels_hint +
-                          " ; supported_mouse_modes "   + this.main_init.supported_mouse_modes +
-                          " ; current_mouse_mode "      + this.main_init.current_mouse_mode +
-                          " ; agent_connected "         + this.main_init.agent_connected +
-                          " ; agent_tokens "            + this.main_init.agent_tokens +
-                          " ; multi_media_time "        + this.main_init.multi_media_time +
-                          " ; ram_hint "                + this.main_init.ram_hint);
+            this.log_info("session id " + this.main_init.session_id +
+                " ; display_channels_hint " + this.main_init.display_channels_hint +
+                " ; supported_mouse_modes " + this.main_init.supported_mouse_modes +
+                " ; current_mouse_mode " + this.main_init.current_mouse_mode +
+                " ; agent_connected " + this.main_init.agent_connected +
+                " ; agent_tokens " + this.main_init.agent_tokens +
+                " ; multi_media_time " + this.main_init.multi_media_time +
+                " ; ram_hint " + this.main_init.ram_hint);
         }
 
         this.our_mm_time = Date.now();
         this.mm_time = this.main_init.multi_media_time;
 
         this.handle_mouse_mode(this.main_init.current_mouse_mode,
-                               this.main_init.supported_mouse_modes);
+            this.main_init.supported_mouse_modes);
 
         if (this.main_init.agent_connected)
             this.connect_agent();
@@ -130,45 +124,39 @@ SpiceMainConn.prototype.process_channel_message = function(msg)
         return true;
     }
 
-    if (msg.type == Constants.SPICE_MSG_MAIN_MOUSE_MODE)
-    {
+    if (msg.type == Constants.SPICE_MSG_MAIN_MOUSE_MODE) {
         var mode = new Messages.SpiceMsgMainMouseMode(msg.data);
         DEBUG > 0 && this.log_info("Mouse supported modes " + mode.supported_modes + "; current " + mode.current_mode);
         this.handle_mouse_mode(mode.current_mode, mode.supported_modes);
         return true;
     }
 
-    if (msg.type == Constants.SPICE_MSG_MAIN_MULTI_MEDIA_TIME)
-    {
+    if (msg.type == Constants.SPICE_MSG_MAIN_MULTI_MEDIA_TIME) {
         this.known_unimplemented(msg.type, "Main Multi Media Time");
         return true;
     }
 
-    if (msg.type == Constants.SPICE_MSG_MAIN_CHANNELS_LIST)
-    {
+    if (msg.type == Constants.SPICE_MSG_MAIN_CHANNELS_LIST) {
         var i;
         var chans;
         DEBUG > 0 && console.log("channels");
         chans = new Messages.SpiceMsgChannels(msg.data);
-        for (i = 0; i < chans.channels.length; i++)
-        {
+        for (i = 0; i < chans.channels.length; i++) {
             var conn = {
-                        uri: this.ws.url,
-                        parent: this,
-                        connection_id : this.connection_id,
-                        type : chans.channels[i].type,
-                        chan_id : chans.channels[i].id
-                    };
-            if (chans.channels[i].type == Constants.SPICE_CHANNEL_DISPLAY)
-            {
+                uri: this.ws.url,
+                parent: this,
+                connection_id: this.connection_id,
+                type: chans.channels[i].type,
+                chan_id: chans.channels[i].id
+            };
+            if (chans.channels[i].type == Constants.SPICE_CHANNEL_DISPLAY) {
                 if (chans.channels[i].id == 0) {
                     this.display = new SpiceDisplayConn(conn);
                 } else {
                     this.log_warn("The spice-html5 client does not handle multiple heads.");
                 }
             }
-            else if (chans.channels[i].type == Constants.SPICE_CHANNEL_INPUTS)
-            {
+            else if (chans.channels[i].type == Constants.SPICE_CHANNEL_INPUTS) {
                 this.inputs = new SpiceInputsConn(conn);
                 this.inputs.mouse_mode = this.mouse_mode;
             }
@@ -178,9 +166,8 @@ SpiceMainConn.prototype.process_channel_message = function(msg)
                 this.cursor = new SpicePlaybackConn(conn);
             else if (chans.channels[i].type == Constants.SPICE_CHANNEL_PORT)
                 this.ports.push(new SpicePortConn(conn));
-            else
-            {
-                if (! ("extra_channels" in this))
+            else {
+                if (!("extra_channels" in this))
                     this.extra_channels = [];
                 this.extra_channels[i] = new SpiceConn(conn);
                 this.log_err("Channel type " + this.extra_channels[i].channel_type() + " not implemented");
@@ -191,29 +178,25 @@ SpiceMainConn.prototype.process_channel_message = function(msg)
         return true;
     }
 
-    if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_CONNECTED)
-    {
+    if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_CONNECTED) {
         this.connect_agent();
         return true;
     }
 
-    if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_CONNECTED_TOKENS)
-    {
+    if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_CONNECTED_TOKENS) {
         var connected_tokens = new Messages.SpiceMsgMainAgentTokens(msg.data);
         this.agent_tokens = connected_tokens.num_tokens;
         this.connect_agent();
         return true;
     }
 
-    if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_TOKEN)
-    {
+    if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_TOKEN) {
         var remaining_tokens, tokens = new Messages.SpiceMsgMainAgentTokens(msg.data);
         this.agent_tokens += tokens.num_tokens;
         this.send_agent_message_queue();
 
         remaining_tokens = this.agent_tokens;
-        while (remaining_tokens > 0 && this.file_xfer_read_queue.length > 0)
-        {
+        while (remaining_tokens > 0 && this.file_xfer_read_queue.length > 0) {
             var xfer_task = this.file_xfer_read_queue.shift();
             this.file_xfer_read(xfer_task, xfer_task.read_bytes);
             remaining_tokens--;
@@ -221,24 +204,20 @@ SpiceMainConn.prototype.process_channel_message = function(msg)
         return true;
     }
 
-    if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_DISCONNECTED)
-    {
+    if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_DISCONNECTED) {
         this.agent_connected = false;
         return true;
     }
 
-    if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_DATA)
-    {
+    if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_DATA) {
         var agent_data = new Messages.SpiceMsgMainAgentData(msg.data);
-        if (agent_data.type == Constants.VD_AGENT_ANNOUNCE_CAPABILITIES)
-        {
+        if (agent_data.type == Constants.VD_AGENT_ANNOUNCE_CAPABILITIES) {
             var agent_caps = new Messages.VDAgentAnnounceCapabilities(agent_data.data);
             if (agent_caps.request)
                 this.announce_agent_capabilities(0);
             return true;
         }
-        else if (agent_data.type == Constants.VD_AGENT_FILE_XFER_STATUS)
-        {
+        else if (agent_data.type == Constants.VD_AGENT_FILE_XFER_STATUS) {
             this.handle_file_xfer_status(new Messages.VDAgentFileXferStatusMessage(agent_data.data));
             return true;
         }
@@ -246,44 +225,37 @@ SpiceMainConn.prototype.process_channel_message = function(msg)
         return false;
     }
 
-    if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_SWITCH_HOST)
-    {
+    if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_SWITCH_HOST) {
         this.known_unimplemented(msg.type, "Main Migrate Switch Host");
         return true;
     }
 
-    if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_END)
-    {
+    if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_END) {
         this.known_unimplemented(msg.type, "Main Migrate End");
         return true;
     }
 
-    if (msg.type == Constants.SPICE_MSG_MAIN_NAME)
-    {
+    if (msg.type == Constants.SPICE_MSG_MAIN_NAME) {
         this.known_unimplemented(msg.type, "Main Name");
         return true;
     }
 
-    if (msg.type == Constants.SPICE_MSG_MAIN_UUID)
-    {
+    if (msg.type == Constants.SPICE_MSG_MAIN_UUID) {
         this.known_unimplemented(msg.type, "Main UUID");
         return true;
     }
 
-    if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_BEGIN_SEAMLESS)
-    {
+    if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_BEGIN_SEAMLESS) {
         this.known_unimplemented(msg.type, "Main Migrate Begin Seamless");
         return true;
     }
 
-    if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_ACK)
-    {
+    if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_ACK) {
         this.known_unimplemented(msg.type, "Main Migrate Dst Seamless ACK");
         return true;
     }
 
-    if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_NACK)
-    {
+    if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_NACK) {
         this.known_unimplemented(msg.type, "Main Migrate Dst Seamless NACK");
         return true;
     }
@@ -291,24 +263,20 @@ SpiceMainConn.prototype.process_channel_message = function(msg)
     return false;
 }
 
-SpiceMainConn.prototype.stop = function(msg)
-{
+SpiceMainConn.prototype.stop = function (msg) {
     this.state = "closing";
 
-    if (this.inputs)
-    {
+    if (this.inputs) {
         this.inputs.cleanup();
         this.inputs = undefined;
     }
 
-    if (this.cursor)
-    {
+    if (this.cursor) {
         this.cursor.cleanup();
         this.cursor = undefined;
     }
 
-    if (this.display)
-    {
+    if (this.display) {
         this.display.cleanup();
         this.display.destroy_surfaces();
         this.display = undefined;
@@ -322,30 +290,26 @@ SpiceMainConn.prototype.stop = function(msg)
     this.extra_channels = undefined;
 }
 
-SpiceMainConn.prototype.send_agent_message_queue = function(message)
-{
+SpiceMainConn.prototype.send_agent_message_queue = function (message) {
     if (!this.agent_connected)
         return;
 
     if (message)
         this.agent_msg_queue.push(message);
 
-    while (this.agent_tokens > 0 && this.agent_msg_queue.length > 0)
-    {
+    while (this.agent_tokens > 0 && this.agent_msg_queue.length > 0) {
         var mr = this.agent_msg_queue.shift();
         this.send_msg(mr);
         this.agent_tokens--;
     }
 }
 
-SpiceMainConn.prototype.send_agent_message = function(type, message)
-{
+SpiceMainConn.prototype.send_agent_message = function (type, message) {
     var agent_data = new Messages.SpiceMsgcMainAgentData(type, message);
     var sb = 0, maxsize = Constants.VD_AGENT_MAX_DATA_SIZE - Messages.SpiceMiniData.prototype.buffer_size();
     var data = new ArrayBuffer(agent_data.buffer_size());
     agent_data.to_buffer(data);
-    while (sb < agent_data.buffer_size())
-    {
+    while (sb < agent_data.buffer_size()) {
         var eb = Math.min(sb + maxsize, agent_data.buffer_size());
         var mr = new Messages.SpiceMiniData();
         mr.type = Constants.SPICE_MSGC_MAIN_AGENT_DATA;
@@ -356,22 +320,19 @@ SpiceMainConn.prototype.send_agent_message = function(type, message)
     }
 }
 
-SpiceMainConn.prototype.announce_agent_capabilities = function(request)
-{
+SpiceMainConn.prototype.announce_agent_capabilities = function (request) {
     var caps = new Messages.VDAgentAnnounceCapabilities(request, (1 << Constants.VD_AGENT_CAP_MOUSE_STATE) |
-                                                        (1 << Constants.VD_AGENT_CAP_MONITORS_CONFIG) |
-                                                        (1 << Constants.VD_AGENT_CAP_REPLY));
+        (1 << Constants.VD_AGENT_CAP_MONITORS_CONFIG) |
+        (1 << Constants.VD_AGENT_CAP_REPLY));
     this.send_agent_message(Constants.VD_AGENT_ANNOUNCE_CAPABILITIES, caps);
 }
 
-SpiceMainConn.prototype.resize_window = function(flags, width, height, depth, x, y)
-{
+SpiceMainConn.prototype.resize_window = function (flags, width, height, depth, x, y) {
     var monitors_config = new Messages.VDAgentMonitorsConfig(flags, width, height, depth, x, y);
     this.send_agent_message(Constants.VD_AGENT_MONITORS_CONFIG, monitors_config);
 }
 
-SpiceMainConn.prototype.file_xfer_start = function(file)
-{
+SpiceMainConn.prototype.file_xfer_start = function (file) {
     var task_id, xfer_start, task;
 
     task_id = this.file_xfer_task_id++;
@@ -382,16 +343,13 @@ SpiceMainConn.prototype.file_xfer_start = function(file)
     this.send_agent_message(Constants.VD_AGENT_FILE_XFER_START, xfer_start);
 }
 
-SpiceMainConn.prototype.handle_file_xfer_status = function(file_xfer_status)
-{
+SpiceMainConn.prototype.handle_file_xfer_status = function (file_xfer_status) {
     var xfer_error, xfer_task;
-    if (!this.file_xfer_tasks[file_xfer_status.id])
-    {
+    if (!this.file_xfer_tasks[file_xfer_status.id]) {
         return;
     }
     xfer_task = this.file_xfer_tasks[file_xfer_status.id];
-    switch (file_xfer_status.result)
-    {
+    switch (file_xfer_status.result) {
         case Constants.VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA:
             this.file_xfer_read(xfer_task);
             return;
@@ -411,8 +369,7 @@ SpiceMainConn.prototype.handle_file_xfer_status = function(file_xfer_status)
     this.file_xfer_completed(xfer_task, xfer_error)
 }
 
-SpiceMainConn.prototype.file_xfer_read = function(file_xfer_task, start_byte)
-{
+SpiceMainConn.prototype.file_xfer_read = function (file_xfer_task, start_byte) {
     var FILE_XFER_CHUNK_SIZE = 32 * Constants.VD_AGENT_MAX_DATA_SIZE;
     var _this = this;
     var sb, eb;
@@ -420,36 +377,32 @@ SpiceMainConn.prototype.file_xfer_read = function(file_xfer_task, start_byte)
 
     if (!file_xfer_task ||
         !this.file_xfer_tasks[file_xfer_task.id] ||
-        (start_byte > 0 && start_byte == file_xfer_task.file.size))
-    {
+        (start_byte > 0 && start_byte == file_xfer_task.file.size)) {
         return;
     }
 
-    if (file_xfer_task.cancelled)
-    {
+    if (file_xfer_task.cancelled) {
         var xfer_status = new Messages.VDAgentFileXferStatusMessage(file_xfer_task.id,
-                                                           Constants.VD_AGENT_FILE_XFER_STATUS_CANCELLED);
+            Constants.VD_AGENT_FILE_XFER_STATUS_CANCELLED);
         this.send_agent_message(Constants.VD_AGENT_FILE_XFER_STATUS, xfer_status);
         delete this.file_xfer_tasks[file_xfer_task.id];
         return;
     }
 
     sb = start_byte || 0,
-    eb = Math.min(sb + FILE_XFER_CHUNK_SIZE, file_xfer_task.file.size);
+        eb = Math.min(sb + FILE_XFER_CHUNK_SIZE, file_xfer_task.file.size);
 
-    if (!this.agent_tokens)
-    {
+    if (!this.agent_tokens) {
         file_xfer_task.read_bytes = sb;
         this.file_xfer_read_queue.push(file_xfer_task);
         return;
     }
 
     reader = new FileReader();
-    reader.onload = function(e)
-    {
+    reader.onload = function (e) {
         var xfer_data = new Messages.VDAgentFileXferDataMessage(file_xfer_task.id,
-                                                       e.target.result.byteLength,
-                                                       e.target.result);
+            e.target.result.byteLength,
+            e.target.result);
         _this.send_agent_message(Constants.VD_AGENT_FILE_XFER_DATA, xfer_data);
         _this.file_xfer_read(file_xfer_task, eb);
         file_xfer_task.update_progressbar(eb);
@@ -459,20 +412,18 @@ SpiceMainConn.prototype.file_xfer_read = function(file_xfer_task, start_byte)
     reader.readAsArrayBuffer(slice);
 }
 
-SpiceMainConn.prototype.file_xfer_completed = function(file_xfer_task, error)
-{
+SpiceMainConn.prototype.file_xfer_completed = function (file_xfer_task, error) {
     if (error)
         this.log_err(error);
     else
-        this.log_info("transfer of '" + file_xfer_task.file.name +"' was successful");
+        this.log_info("transfer of '" + file_xfer_task.file.name + "' was successful");
 
     file_xfer_task.remove_progressbar();
 
     delete this.file_xfer_tasks[file_xfer_task.id];
 }
 
-SpiceMainConn.prototype.connect_agent = function()
-{
+SpiceMainConn.prototype.connect_agent = function () {
     this.agent_connected = true;
 
     var agent_start = new Messages.SpiceMsgcMainAgentStart(~0);
@@ -487,11 +438,9 @@ SpiceMainConn.prototype.connect_agent = function()
 
 }
 
-SpiceMainConn.prototype.handle_mouse_mode = function(current, supported)
-{
+SpiceMainConn.prototype.handle_mouse_mode = function (current, supported) {
     this.mouse_mode = current;
-    if (current != Constants.SPICE_MOUSE_MODE_CLIENT && (supported & Constants.SPICE_MOUSE_MODE_CLIENT))
-    {
+    if (current != Constants.SPICE_MOUSE_MODE_CLIENT && (supported & Constants.SPICE_MOUSE_MODE_CLIENT)) {
         var mode_request = new Messages.SpiceMsgcMainMouseModeRequest(Constants.SPICE_MOUSE_MODE_CLIENT);
         var mr = new Messages.SpiceMiniData();
         mr.build_msg(Constants.SPICE_MSGC_MAIN_MOUSE_MODE_REQUEST, mode_request);
@@ -503,17 +452,17 @@ SpiceMainConn.prototype.handle_mouse_mode = function(current, supported)
 }
 
 /* Shift current time to attempt to get a time matching that of the server */
-SpiceMainConn.prototype.relative_now = function()
-{
+SpiceMainConn.prototype.relative_now = function () {
     var ret = (Date.now() - this.our_mm_time) + this.mm_time;
     return ret;
 }
 
 export {
-  SpiceMainConn,
-  handle_file_dragover,
-  handle_file_drop,
-  resize_helper,
-  handle_resize,
-  sendCtrlAltDel,
+    SpiceMainConn,
+    handle_file_dragover,
+    handle_file_drop,
+    resize_helper,
+    handle_resize,
+    sendCtrlAltDel,
+    sendCtrlAltFN,
 };
diff --git a/static/js/spice-html5/spice.css b/static/js/spice-html5/spice.css
index 968ba16..2ffe5e6 100755
--- a/static/js/spice-html5/spice.css
+++ b/static/js/spice-html5/spice.css
@@ -63,7 +63,6 @@ body
 
 #spice-area
 {
-    height: 100%;
     width: 95%;
     padding: 0;
     margin-left: auto;
@@ -74,13 +73,13 @@ body
     box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
     -moz-border-radius: 10px;
     -webkit-border-radius: 10px;
-    border-radius: 10px;
+    border-radius: 1px;
 }
 .spice-screen
 {
     min-height: 600px;
     height: 100%;
-    margin: 10px;
+    margin: 5px;
     padding: 0;
     background-color: #333333;
 }