adding special keys, changing clipboard to write text function

This commit is contained in:
Pawel Raczyk 2019-04-10 10:35:00 +02:00
parent 9a9645829a
commit fdfc5e36dd
2 changed files with 407 additions and 199 deletions

167
app/ui.js
View File

@ -53,7 +53,6 @@ const UI = {
// Render default UI and initialize settings menu // Render default UI and initialize settings menu
start() { start() {
UI.initSettings(); UI.initSettings();
// Translate the DOM // Translate the DOM
@ -77,6 +76,7 @@ const UI = {
UI.addControlbarHandlers(); UI.addControlbarHandlers();
UI.addTouchSpecificHandlers(); UI.addTouchSpecificHandlers();
UI.addExtraKeysHandlers(); UI.addExtraKeysHandlers();
UI.addSpecialKeysHandlers();
UI.addMachineHandlers(); UI.addMachineHandlers();
UI.addConnectionControlHandlers(); UI.addConnectionControlHandlers();
UI.addClipboardHandlers(); UI.addClipboardHandlers();
@ -103,7 +103,9 @@ const UI = {
UI.openConnectPanel(); UI.openConnectPanel();
} }
UI.connect();
return Promise.resolve(UI.rfb); return Promise.resolve(UI.rfb);
}, },
initFullscreen() { initFullscreen() {
@ -283,6 +285,34 @@ const UI = {
document.getElementById("noVNC_send_ctrl_alt_del_button") document.getElementById("noVNC_send_ctrl_alt_del_button")
.addEventListener('click', UI.sendCtrlAltDel); .addEventListener('click', UI.sendCtrlAltDel);
}, },
addSpecialKeysHandlers() {
document.getElementById("noVNC_toggle_special_keys_button")
.addEventListener('click', UI.toggleSpecialKeys);
document.getElementById("noVNC_send_f1_button")
.addEventListener('click', UI.sendF1);
document.getElementById("noVNC_send_f2_button")
.addEventListener('click', UI.sendF2);
document.getElementById("noVNC_send_f3_button")
.addEventListener('click', UI.sendF3);
document.getElementById("noVNC_send_f4_button")
.addEventListener('click', UI.sendF4);
document.getElementById("noVNC_send_f5_button")
.addEventListener('click', UI.sendF5);
document.getElementById("noVNC_send_f6_button")
.addEventListener('click', UI.sendF6);
document.getElementById("noVNC_send_f7_button")
.addEventListener('click', UI.sendF7);
document.getElementById("noVNC_send_f8_button")
.addEventListener('click', UI.sendF8);
document.getElementById("noVNC_send_f9_button")
.addEventListener('click', UI.sendF9);
document.getElementById("noVNC_send_f10_button")
.addEventListener('click', UI.sendF10);
document.getElementById("noVNC_send_f11_button")
.addEventListener('click', UI.sendF11);
document.getElementById("noVNC_send_f12_button")
.addEventListener('click', UI.sendF12);
},
addMachineHandlers() { addMachineHandlers() {
document.getElementById("noVNC_shutdown_button") document.getElementById("noVNC_shutdown_button")
@ -310,8 +340,8 @@ const UI = {
addClipboardHandlers() { addClipboardHandlers() {
document.getElementById("noVNC_clipboard_button") document.getElementById("noVNC_clipboard_button")
.addEventListener('click', UI.toggleClipboardPanel); .addEventListener('click', UI.toggleClipboardPanel);
document.getElementById("noVNC_clipboard_text") document.getElementById("noVNC_clipboard_send_button")
.addEventListener('change', UI.clipboardSend); .addEventListener('click', UI.writeText);
document.getElementById("noVNC_clipboard_clear_button") document.getElementById("noVNC_clipboard_clear_button")
.addEventListener('click', UI.clipboardClear); .addEventListener('click', UI.clipboardClear);
}, },
@ -414,7 +444,7 @@ const UI = {
UI.setMouseButton(1); UI.setMouseButton(1);
// Hide the controlbar after 2 seconds // Hide the controlbar after 2 seconds
UI.closeControlbarTimeout = setTimeout(UI.closeControlbar, 2000); // UI.closeControlbarTimeout = setTimeout(UI.closeControlbar, 2000);
} else { } else {
UI.enableSetting('encrypt'); UI.enableSetting('encrypt');
UI.enableSetting('shared'); UI.enableSetting('shared');
@ -805,6 +835,7 @@ const UI = {
UI.closePowerPanel(); UI.closePowerPanel();
UI.closeClipboardPanel(); UI.closeClipboardPanel();
UI.closeExtraKeys(); UI.closeExtraKeys();
UI.closeSpecialKeys();
}, },
/* ------^------- /* ------^-------
@ -930,21 +961,46 @@ const UI = {
} }
}, },
clipboardReceive(e) {
Log.Debug(">> UI.clipboardReceive: " + e.detail.text.substr(0, 40) + "...");
document.getElementById('noVNC_clipboard_text').value = e.detail.text;
Log.Debug("<< UI.clipboardReceive");
},
clipboardClear() { clipboardClear() {
document.getElementById('noVNC_clipboard_text').value = ""; document.getElementById('noVNC_clipboard_text').value = "";
UI.rfb.clipboardPasteFrom(""); UI.rfb.clipboardPasteFrom("");
}, },
clipboardSend() { writeText() {
const text = document.getElementById('noVNC_clipboard_text').value; const text = document.getElementById('noVNC_clipboard_text').value;
Log.Debug(">> UI.clipboardSend: " + text.substr(0, 40) + "..."); Log.Debug(">> UI.clipboardSend: " + text.substr(0, 40) + "...");
UI.rfb.clipboardPasteFrom(text);
const textClip = text.split("");
function f(t) {
const character = t.shift();
if (character === undefined) return;
const code = character.charCodeAt();
const needs_shift = '[A-Z!@#$%^&*()_+{}:"<>?~|]'.indexOf(character) !== -1;
const enter = '[\n]'.indexOf(character) !== -1;
if (enter) {
UI.rfb.sendKey(KeyTable.XK_Return, 'XK_Return', true);
}
if (!enter) {
if (needs_shift) {
UI.rfb.sendKey(KeyTable.XK_Shift_L, "ShiftLeft", true);
}
UI.rfb.sendKey(code, "keysym", true);
UI.rfb.sendKey(code, "keysym", false);
if (needs_shift) {
UI.rfb.sendKey(KeyTable.XK_Shift_L, "ShiftLeft", false);
}
}
if (t.length > 0) {
setTimeout( () => {
f(t);
}, 10);
}
}
f(textClip);
Log.Debug("<< UI.clipboardSend"); Log.Debug("<< UI.clipboardSend");
}, },
@ -965,7 +1021,6 @@ const UI = {
}, },
connect(event, password) { connect(event, password) {
// Ignore when rfb already exists // Ignore when rfb already exists
if (typeof UI.rfb !== 'undefined') { if (typeof UI.rfb !== 'undefined') {
return; return;
@ -1025,6 +1080,7 @@ const UI = {
UI.rfb.resizeSession = UI.getSetting('resize') === 'remote'; UI.rfb.resizeSession = UI.getSetting('resize') === 'remote';
UI.updateViewOnly(); // requires UI.rfb UI.updateViewOnly(); // requires UI.rfb
}, },
disconnect() { disconnect() {
@ -1548,6 +1604,87 @@ const UI = {
/* ------^------- /* ------^-------
* /EXTRA KEYS * /EXTRA KEYS
* ============== * ==============
* EXTRA SPECIAL KEYS
* ------v------*/
openSpecialKeys() {
UI.closeAllPanels();
UI.openControlbar();
document.getElementById('noVNC_special_modifiers')
.classList.add("noVNC_open");
document.getElementById('noVNC_toggle_special_keys_button')
.classList.add("noVNC_selected");
},
closeSpecialKeys() {
document.getElementById('noVNC_special_modifiers')
.classList.remove("noVNC_open");
document.getElementById('noVNC_toggle_special_keys_button')
.classList.remove("noVNC_selected");
},
toggleSpecialKeys() {
if (document.getElementById('noVNC_special_modifiers')
.classList.contains("noVNC_open")) {
UI.closeSpecialKeys();
} else {
UI.openSpecialKeys();
}
},
sendF1() {
UI.rfb.sendKey(KeyTable.XK_F1, "F1");
},
sendF2() {
UI.rfb.sendKey(KeyTable.XK_F2, "F2");
},
sendF3() {
UI.rfb.sendKey(KeyTable.XK_F3, "F3");
},
sendF4() {
UI.rfb.sendKey(KeyTable.XK_F4, "F4");
},
sendF5() {
UI.rfb.sendKey(KeyTable.XK_F5, "F5");
},
sendF6() {
UI.rfb.sendKey(KeyTable.XK_F6, "F6");
},
sendF7() {
UI.rfb.sendKey(KeyTable.XK_F7, "F7");
},
sendF8() {
UI.rfb.sendKey(KeyTable.XK_F8, "F8");
},
sendF9() {
UI.rfb.sendKey(KeyTable.XK_F9, "F9");
},
sendF10() {
UI.rfb.sendKey(KeyTable.XK_F10, "F10");
},
sendF11() {
UI.rfb.sendKey(KeyTable.XK_F11, "F11");
},
sendF12() {
UI.rfb.sendKey(KeyTable.XK_F12, "F12");
},
/* ------^-------
* /EXTRA SPECIAL KEYS
* ============== * ==============
* MISC * MISC
* ------v------*/ * ------v------*/
@ -1580,6 +1717,8 @@ const UI = {
.classList.add('noVNC_hidden'); .classList.add('noVNC_hidden');
document.getElementById('noVNC_toggle_extra_keys_button') document.getElementById('noVNC_toggle_extra_keys_button')
.classList.add('noVNC_hidden'); .classList.add('noVNC_hidden');
document.getElementById('noVNC_toggle_special_keys_button')
.classList.add('noVNC_hidden');
document.getElementById('noVNC_mouse_button' + UI.rfb.touchButton) document.getElementById('noVNC_mouse_button' + UI.rfb.touchButton)
.classList.add('noVNC_hidden'); .classList.add('noVNC_hidden');
} else { } else {
@ -1587,6 +1726,8 @@ const UI = {
.classList.remove('noVNC_hidden'); .classList.remove('noVNC_hidden');
document.getElementById('noVNC_toggle_extra_keys_button') document.getElementById('noVNC_toggle_extra_keys_button')
.classList.remove('noVNC_hidden'); .classList.remove('noVNC_hidden');
document.getElementById('noVNC_toggle_special_keys_button')
.classList.remove('noVNC_hidden');
document.getElementById('noVNC_mouse_button' + UI.rfb.touchButton) document.getElementById('noVNC_mouse_button' + UI.rfb.touchButton)
.classList.remove('noVNC_hidden'); .classList.remove('noVNC_hidden');
} }

109
vnc.html
View File

@ -86,13 +86,13 @@
<!-- noVNC Control Bar --> <!-- noVNC Control Bar -->
<div id="noVNC_control_bar_anchor" class="noVNC_vcenter"> <div id="noVNC_control_bar_anchor" class="noVNC_vcenter">
<div id="noVNC_control_bar"> <div id="noVNC_control_bar" class="noVNC_open">
<div id="noVNC_control_bar_handle" title="Hide/Show the control bar"><div></div></div> <div id="noVNC_control_bar_handle" title="Hide/Show the control bar">
<div></div>
</div>
<div class="noVNC_scroll"> <div class="noVNC_scroll">
<h1 class="noVNC_logo" translate="no"><span>no</span><br>VNC</h1>
<!-- Drag/Pan the viewport --> <!-- Drag/Pan the viewport -->
<input type="image" alt="viewport drag" src="app/images/drag.svg" <input type="image" alt="viewport drag" src="app/images/drag.svg"
id="noVNC_view_drag_button" class="noVNC_button noVNC_hidden" id="noVNC_view_drag_button" class="noVNC_button noVNC_hidden"
@ -145,6 +145,53 @@
</div> </div>
</div> </div>
<!-- Extra F1-F12 keys -->
<div id="noVNC_special_keys">
<input type="image" alt="Extra keys F1-F12" src="app/images/togglespecialkeys.svg"
id="noVNC_toggle_special_keys_button" class="noVNC_button"
title="Show F1-F12 Keys">
<div class="noVNC_vcenter">
<div id="noVNC_special_modifiers" class="noVNC_panel">
<input type="image" alt="F1" src="app/images/f1.svg"
id="noVNC_send_f1_button" class="noVNC_button"
title="Send F1">
<input type="image" alt="F2" src="app/images/f2.svg"
id="noVNC_send_f2_button" class="noVNC_button"
title="Send F2">
<input type="image" alt="F3" src="app/images/f3.svg"
id="noVNC_send_f3_button" class="noVNC_button"
title="Send F3">
<input type="image" alt="F4" src="app/images/f4.svg"
id="noVNC_send_f4_button" class="noVNC_button"
title="Send F4">
<input type="image" alt="F5" src="app/images/f5.svg"
id="noVNC_send_f5_button" class="noVNC_button"
title="Send F5">
<input type="image" alt="F6" src="app/images/f6.svg"
id="noVNC_send_f6_button" class="noVNC_button"
title="Send F6">
<input type="image" alt="F7" src="app/images/f7.svg"
id="noVNC_send_f7_button" class="noVNC_button"
title="Send F7">
<input type="image" alt="F8" src="app/images/f8.svg"
id="noVNC_send_f8_button" class="noVNC_button"
title="Send F8">
<input type="image" alt="F9" src="app/images/f9.svg"
id="noVNC_send_f9_button" class="noVNC_button"
title="Send F9">
<input type="image" alt="F10" src="app/images/f10.svg"
id="noVNC_send_f10_button" class="noVNC_button"
title="Send F10">
<input type="image" alt="F11" src="app/images/f11.svg"
id="noVNC_send_f11_button" class="noVNC_button"
title="Send F11">
<input type="image" alt="F12" src="app/images/f12.svg"
id="noVNC_send_f12_button" class="noVNC_button"
title="Send F12">
</div>
</div>
</div>
<!-- Shutdown/Reboot --> <!-- Shutdown/Reboot -->
<input type="image" alt="Shutdown/Reboot" src="app/images/power.svg" <input type="image" alt="Shutdown/Reboot" src="app/images/power.svg"
id="noVNC_power_button" class="noVNC_button" id="noVNC_power_button" class="noVNC_button"
@ -173,6 +220,8 @@
<br> <br>
<input id="noVNC_clipboard_clear_button" type="button" <input id="noVNC_clipboard_clear_button" type="button"
value="Clear" class="noVNC_submit"> value="Clear" class="noVNC_submit">
<input id="noVNC_clipboard_send_button" type="button"
value="Send" class="noVNC_submit">
</div> </div>
</div> </div>
@ -191,13 +240,12 @@
<li class="noVNC_heading"> <li class="noVNC_heading">
<img alt="" src="app/images/settings.svg"> Settings <img alt="" src="app/images/settings.svg"> Settings
</li> </li>
<li> <li style="display: none;">
<label><input id="noVNC_setting_shared" type="checkbox"> Shared Mode</label> <label><input id="noVNC_setting_shared" type="checkbox"> Shared Mode</label>
</li> </li>
<li> <li style="display: none;">
<label><input id="noVNC_setting_view_only" type="checkbox"> View Only</label> <label><input id="noVNC_setting_view_only" type="checkbox"> View Only</label>
</li> </li>
<li><hr></li>
<li> <li>
<label><input id="noVNC_setting_view_clip" type="checkbox"> Clip to Window</label> <label><input id="noVNC_setting_view_clip" type="checkbox"> Clip to Window</label>
</li> </li>
@ -209,19 +257,24 @@
<option value="remote">Remote Resizing</option> <option value="remote">Remote Resizing</option>
</select> </select>
</li> </li>
<li><hr></li>
<li> <li>
<hr>
</li>
<li style="display: none;">
<div class="noVNC_expander">Advanced</div> <div class="noVNC_expander">Advanced</div>
<div><ul> <div>
<ul>
<li> <li>
<label for="noVNC_setting_repeaterID">Repeater ID:</label> <label for="noVNC_setting_repeaterID">Repeater ID:</label>
<input id="noVNC_setting_repeaterID" type="text" value=""> <input id="noVNC_setting_repeaterID" type="text" value="">
</li> </li>
<li> <li>
<div class="noVNC_expander">WebSocket</div> <div class="noVNC_expander">WebSocket</div>
<div><ul> <div>
<ul>
<li> <li>
<label><input id="noVNC_setting_encrypt" type="checkbox"> Encrypt</label> <label><input id="noVNC_setting_encrypt" type="checkbox">
Encrypt</label>
</li> </li>
<li> <li>
<label for="noVNC_setting_host">Host:</label> <label for="noVNC_setting_host">Host:</label>
@ -235,9 +288,12 @@
<label for="noVNC_setting_path">Path:</label> <label for="noVNC_setting_path">Path:</label>
<input id="noVNC_setting_path" type="text" value="websockify"> <input id="noVNC_setting_path" type="text" value="websockify">
</li> </li>
</ul></div> </ul>
</div>
</li>
<li>
<hr>
</li> </li>
<li><hr></li>
<li> <li>
<label><input id="noVNC_setting_reconnect" type="checkbox"> Automatic Reconnect</label> <label><input id="noVNC_setting_reconnect" type="checkbox"> Automatic Reconnect</label>
</li> </li>
@ -245,11 +301,16 @@
<label for="noVNC_setting_reconnect_delay">Reconnect Delay (ms):</label> <label for="noVNC_setting_reconnect_delay">Reconnect Delay (ms):</label>
<input id="noVNC_setting_reconnect_delay" type="number"> <input id="noVNC_setting_reconnect_delay" type="number">
</li> </li>
<li><hr></li>
<li> <li>
<label><input id="noVNC_setting_show_dot" type="checkbox"> Show Dot when No Cursor</label> <hr>
</li>
<li>
<label><input id="noVNC_setting_show_dot" type="checkbox"> Show Dot when No
Cursor</label>
</li>
<li>
<hr>
</li> </li>
<li><hr></li>
<!-- Logging selection dropdown --> <!-- Logging selection dropdown -->
<li> <li>
<label>Logging: <label>Logging:
@ -257,7 +318,8 @@
</select> </select>
</label> </label>
</li> </li>
</ul></div> </ul>
</div>
</li> </li>
</ul> </ul>
</div> </div>
@ -282,15 +344,18 @@
<div class="noVNC_center"> <div class="noVNC_center">
<div id="noVNC_connect_dlg"> <div id="noVNC_connect_dlg">
<div class="noVNC_logo" translate="no"><span>no</span>VNC</div> <div class="noVNC_logo" translate="no"><span>no</span>VNC</div>
<div id="noVNC_connect_button"><div> <div id="noVNC_connect_button">
<div>
<img alt="" src="app/images/connect.svg"> Connect <img alt="" src="app/images/connect.svg"> Connect
</div></div> </div>
</div>
</div> </div>
</div> </div>
<!-- Password Dialog --> <!-- Password Dialog -->
<div class="noVNC_center noVNC_connect_layer"> <div class="noVNC_center noVNC_connect_layer">
<div id="noVNC_password_dlg" class="noVNC_panel"><form> <div id="noVNC_password_dlg" class="noVNC_panel">
<form>
<ul> <ul>
<li> <li>
<label>Password:</label> <label>Password:</label>
@ -300,7 +365,8 @@
<input id="noVNC_password_button" type="submit" value="Send Password" class="noVNC_submit"> <input id="noVNC_password_button" type="submit" value="Send Password" class="noVNC_submit">
</li> </li>
</ul> </ul>
</form></div> </form>
</div>
</div> </div>
<!-- Transition Screens --> <!-- Transition Screens -->
@ -326,5 +392,6 @@
<source src="app/sounds/bell.oga" type="audio/ogg"> <source src="app/sounds/bell.oga" type="audio/ogg">
<source src="app/sounds/bell.mp3" type="audio/mpeg"> <source src="app/sounds/bell.mp3" type="audio/mpeg">
</audio> </audio>
</body> </body>
</html> </html>