diff options
author | Maxim Devaev <[email protected]> | 2021-04-12 15:26:32 +0300 |
---|---|---|
committer | GitHub <[email protected]> | 2021-04-12 15:26:32 +0300 |
commit | 3af4a8b852019993ee31becd5651734377da6ec9 (patch) | |
tree | 499b77bfaa0c6f939175ea167d5ccb3956be95f0 /web | |
parent | 8158941833bd8a50278b61967e00d23522e633d7 (diff) |
Rework of #39 (#40)
* Rework of #39 patch from @arykov (thanks)
* styled resize corner
* fixed squashing of resizaable window on moving
* keep window size and opsition after full screen
* not necessary
* attempt to fix desktop overflow
* improved
* ios fixes
* refactoring
Diffstat (limited to 'web')
-rw-r--r-- | web/kvm/index.html | 2460 | ||||
-rw-r--r-- | web/kvm/navbar-system.pug | 6 | ||||
-rw-r--r-- | web/kvm/window-about.pug | 6 | ||||
-rw-r--r-- | web/kvm/window-keyboard.pug | 6 | ||||
-rw-r--r-- | web/kvm/window-stream.pug | 17 | ||||
-rw-r--r-- | web/kvm/windows.pug | 7 | ||||
-rw-r--r-- | web/share/css/kvm/stream.css | 18 | ||||
-rw-r--r-- | web/share/css/vars.css | 2 | ||||
-rw-r--r-- | web/share/css/window.css | 51 | ||||
-rw-r--r-- | web/share/js/keypad.js | 10 | ||||
-rw-r--r-- | web/share/js/kvm/mouse.js | 31 | ||||
-rw-r--r-- | web/share/js/kvm/session.js | 2 | ||||
-rw-r--r-- | web/share/js/kvm/stream.js | 64 | ||||
-rw-r--r-- | web/share/js/tools.js | 2 | ||||
-rw-r--r-- | web/share/js/wm.js | 124 |
15 files changed, 1476 insertions, 1330 deletions
diff --git a/web/kvm/index.html b/web/kvm/index.html index 7aa3d05a..fdfb5dd9 100644 --- a/web/kvm/index.html +++ b/web/kvm/index.html @@ -131,25 +131,8 @@ </td> <td class="value" id="stream-desired-fps-value">0</td> </tr> - <tr> - <td>Stream size:</td> - <td> - <input class="slider" type="range" id="stream-size-slider"> - </td> - <td class="value" id="stream-size-value" style="width: 4em">100%</td> - </tr> </table> <hr> - <table class="kv"> - <td>Auto-resize stream window:</td> - <td align="right"> - <div class="switch-box"> - <input checked type="checkbox" id="stream-auto-resize-switch"> - <label for="stream-auto-resize-switch"><span class="switch-inner"></span><span class="switch"></span></label> - </div> - </td> - </table> - <hr> <div class="buttons buttons-row"> <button class="row33" data-force-hide-menu id="show-stream-button">• Show stream</button> <button class="row33" disabled data-force-hide-menu id="stream-screenshot-button">• Screenshot</button> @@ -473,1239 +456,1248 @@ </div> </li> </ul> - <div class="window" id="stream-window" data-close-confirm="Do you want to close the stream? This action will temporarily stop<br>the video transmission until you open the broadcast again.<br>This can be useful for saving traffic."> - <div class="window-header" id="stream-window-header"> - <div class="window-grab">Stream</div> - <button class="window-button-close">×</button> + <div class="window window-resizable" id="stream-window" data-close-confirm="Do you want to close the stream? This action will temporarily stop<br>the video transmission until you open the broadcast again.<br>This can be useful for saving traffic."> + <div class="window-header" id="stream-window-header"> + <div class="window-grab">Stream</div> + <button class="window-button-close">×</button> + <button class="window-button-maximize">☐</button> + <button class="window-button-full-screen">⤢</button> + </div> + <div id="stream-info"></div> + <div class="stream-box-inactive" id="stream-box"> + <div class="window-lock-alert hidden"><b>Failed to acquire keyboard lock.<br>Shortcuts like Alt+Tab, Ctrl+W, Ctrl+N might not be captured.</b><br> + <br> + For best keyboard handling use a <a href="https://developer.mozilla.org/en-US/docs/Web/API/Keyboard_API#Browser_compatibility">browser with keyboard lock support API</a>.<br> + In Chrome use HTTPS and enable <i>system-keyboard-lock</i> by putting at URL <i>chrome://flags/#system-keyboard-lock</i>.<br> + More details on keyboard lock API are <a href="https://wicg.github.io/keyboard-lock/" target="_blank">here</a>. + </div><img class="stream-image-inactive" id="stream-image" src="/share/png/blank-stream.png"> + </div> + <div class="keypad" id="stream-mouse-buttons" align="center"> + <div class="keypad-block"> + <div class="keypad-row"> + <div class="key wide-4 left small" data-code="left"><span>Mouse<br>Left</span></div> + <div class="modifier wide-2 left small" data-code="left"><span><b>•</b><br>← Hold</span></div> + <div class="empty-key" style="width:10px"></div> + <div class="key wide-2 left small" data-code="middle"><span>Mouse<br>Middle</span></div> + <div class="modifier wide-2 left small" data-code="middle"><span><b>•</b><br>← Hold</span></div> + <div class="empty-key" style="width:10px"></div> + <div class="modifier wide-2 right small" data-code="right"><span><b>•</b><br>Hold →</span></div> + <div class="key wide-4 right small" data-code="right"><span>Mouse<br>Right</span></div> </div> - <div id="stream-info"></div> - <div class="stream-box-inactive" id="stream-box"><img class="stream-image-inactive" id="stream-image" src="/share/png/blank-stream.png"></div> - <div class="keypad" id="stream-mouse-buttons" align="center"> - <div class="keypad-block"> - <div class="keypad-row"> - <div class="key wide-4 left small" data-code="left"><span>Mouse<br>Left</span></div> - <div class="modifier wide-2 left small" data-code="left"><span><b>•</b><br>← Hold</span></div> - <div class="empty-key" style="width:10px"></div> - <div class="key wide-2 left small" data-code="middle"><span>Mouse<br>Middle</span></div> - <div class="modifier wide-2 left small" data-code="middle"><span><b>•</b><br>← Hold</span></div> + <div class="keypad-row" style="display:none"> + <div class="key wide-4 left small" data-code="up"><span>Mouse<br>Up/Back</span></div> + <div class="modifier wide-2 left small" data-code="up"><span><b>•</b><br>← Hold</span></div> + <div class="empty-key" style="width:10px"></div> + <div class="modifier wide-2 right small" data-code="down"><span><b>•</b><br>Hold →</span></div> + <div class="key wide-4 right small" data-code="down"><span>Mouse<br>Down/Fw</span></div> + </div> + </div> + </div> + </div> + <div class="window" id="keyboard-window"> + <div class="window-header" id="keyboard-window-header"> + <div class="window-grab">Virtual Keyboard</div> + <button class="window-button-close">×</button> + </div> + <div class="keypad" id="keyboard-desktop" align="center"> + <div class="keypad-block"> + <div class="keypad-row"> + <div class="key small" data-code="Escape"> + <div class="label">Esc + </div> + </div> + <div class="empty-key" style="width:24px"></div> + <div class="key small" data-code="F1"> + <div class="label">F1 + </div> + </div> + <div class="key small" data-code="F2"> + <div class="label">F2 + </div> + </div> + <div class="key small" data-code="F3"> + <div class="label">F3 + </div> + </div> + <div class="key small" data-code="F4"> + <div class="label">F4 + </div> + </div> <div class="empty-key" style="width:10px"></div> - <div class="modifier wide-2 right small" data-code="right"><span><b>•</b><br>Hold →</span></div> - <div class="key wide-4 right small" data-code="right"><span>Mouse<br>Right</span></div> - </div> - <div class="keypad-row" style="display:none"> - <div class="key wide-4 left small" data-code="up"><span>Mouse<br>Up/Back</span></div> - <div class="modifier wide-2 left small" data-code="up"><span><b>•</b><br>← Hold</span></div> + <div class="key small" data-code="F5"> + <div class="label">F5 + </div> + </div> + <div class="key small" data-code="F6"> + <div class="label">F6 + </div> + </div> + <div class="key small" data-code="F7"> + <div class="label">F7 + </div> + </div> + <div class="key small" data-code="F8"> + <div class="label">F8 + </div> + </div> <div class="empty-key" style="width:10px"></div> - <div class="modifier wide-2 right small" data-code="down"><span><b>•</b><br>Hold →</span></div> - <div class="key wide-4 right small" data-code="down"><span>Mouse<br>Down/Fw</span></div> - </div> - </div> + <div class="key small" data-code="F9"> + <div class="label">F9 + </div> + </div> + <div class="key small" data-code="F10"> + <div class="label">F10 + </div> + </div> + <div class="key small" data-code="F11"> + <div class="label">F11 + </div> + </div> + <div class="key small" data-code="F12"> + <div class="label">F12 + </div> + </div> + </div> + <hr> + <div class="keypad-row"> + <div class="key " data-code="Backquote"> + <div class="label">~<br>` + </div> + </div> + <div class="key " data-code="Digit1"> + <div class="label">!<br>1 + </div> + </div> + <div class="key " data-code="Digit2"> + <div class="label">@<br>2 + </div> + </div> + <div class="key " data-code="Digit3"> + <div class="label">#<br>3 + </div> + </div> + <div class="key " data-code="Digit4"> + <div class="label">$<br>4 + </div> + </div> + <div class="key " data-code="Digit5"> + <div class="label">%<br>5 + </div> + </div> + <div class="key " data-code="Digit6"> + <div class="label">^<br>6 + </div> + </div> + <div class="key " data-code="Digit7"> + <div class="label">&<br>7 + </div> + </div> + <div class="key " data-code="Digit8"> + <div class="label">*<br>8 + </div> + </div> + <div class="key " data-code="Digit9"> + <div class="label">(<br>9 + </div> + </div> + <div class="key " data-code="Digit0"> + <div class="label">)<br>0 + </div> + </div> + <div class="key " data-code="Minus"> + <div class="label">_<br>- + </div> + </div> + <div class="key " data-code="Equal"> + <div class="label">+<br>= + </div> + </div> + <div class="key wide-2 right" data-code="Backspace"> + <div class="label">↤ + </div> + </div> + </div> + <div class="keypad-row"> + <div class="key wide-2 left" data-code="Tab"> + <div class="label">⇤<br>⇥ + </div> + </div> + <div class="key single" data-code="KeyQ"> + <div class="label">Q + </div> + </div> + <div class="key single" data-code="KeyW"> + <div class="label">W + </div> + </div> + <div class="key single" data-code="KeyE"> + <div class="label">E + </div> + </div> + <div class="key single" data-code="KeyR"> + <div class="label">R + </div> + </div> + <div class="key single" data-code="KeyT"> + <div class="label">T + </div> + </div> + <div class="key single" data-code="KeyY"> + <div class="label">Y + </div> + </div> + <div class="key single" data-code="KeyU"> + <div class="label">U + </div> + </div> + <div class="key single" data-code="KeyI"> + <div class="label">I + </div> + </div> + <div class="key single" data-code="KeyO"> + <div class="label">O + </div> + </div> + <div class="key single" data-code="KeyP"> + <div class="label">P + </div> + </div> + <div class="key " data-code="BracketLeft"> + <div class="label">{<br>[ + </div> + </div> + <div class="key " data-code="BracketRight"> + <div class="label">}<br>] + </div> + </div> + <div class="key " data-code="Backslash"> + <div class="label">|<br>\ + </div> + </div> + </div> + <div class="keypad-row"> + <div class="key wide-3 left small" data-code="CapsLock"> + <div class="label"><img class="inline-lamp hid-keyboard-caps-led led-gray" src="/share/svg/led-square.svg"><br> Caps Lock + </div> + </div> + <div class="key single" data-code="KeyA"> + <div class="label">A + </div> + </div> + <div class="key single" data-code="KeyS"> + <div class="label">S + </div> + </div> + <div class="key single" data-code="KeyD"> + <div class="label">D + </div> + </div> + <div class="key single" data-code="KeyF"> + <div class="label">F + </div> + </div> + <div class="key single" data-code="KeyG"> + <div class="label">G + </div> + </div> + <div class="key single" data-code="KeyH"> + <div class="label">H + </div> + </div> + <div class="key single" data-code="KeyJ"> + <div class="label">J + </div> + </div> + <div class="key single" data-code="KeyK"> + <div class="label">K + </div> + </div> + <div class="key single" data-code="KeyL"> + <div class="label">L + </div> + </div> + <div class="key " data-code="Semicolon"> + <div class="label">:<br>; + </div> + </div> + <div class="key " data-code="Quote"> + <div class="label">"<br>' + </div> + </div> + <div class="key wide-3 right small" data-code="Enter"> + <div class="label">Enter<br>↵ + </div> + </div> + </div> + <div class="keypad-row"> + <div class="modifier wide-4 left small" data-code="ShiftLeft"> + <div class="label"><b>•</b><br>Shift + </div> + </div> + <div class="key single" data-code="KeyZ"> + <div class="label">Z + </div> + </div> + <div class="key single" data-code="KeyX"> + <div class="label">X + </div> + </div> + <div class="key single" data-code="KeyC"> + <div class="label">C + </div> + </div> + <div class="key single" data-code="KeyV"> + <div class="label">V + </div> + </div> + <div class="key single" data-code="KeyB"> + <div class="label">B + </div> + </div> + <div class="key single" data-code="KeyN"> + <div class="label">N + </div> + </div> + <div class="key single" data-code="KeyM"> + <div class="label">M + </div> + </div> + <div class="key " data-code="Comma"> + <div class="label"><<br>, + </div> + </div> + <div class="key " data-code="Period"> + <div class="label">><br>. + </div> + </div> + <div class="key " data-code="Slash"> + <div class="label">?<br>/ + </div> + </div> + <div class="modifier wide-4 right small" data-code="ShiftRight"> + <div class="label"><b>•</b><br>Shift + </div> + </div> + </div> + <div class="keypad-row"> + <div class="modifier wide-1 left small" data-code="ControlLeft"> + <div class="label"><b>•</b><br>Ctrl + </div> + </div> + <div class="modifier wide-1 left small" data-code="MetaLeft"> + <div class="label"><b>•</b><br>Win + </div> + </div> + <div class="modifier wide-1 left small" data-code="AltLeft"> + <div class="label"><b>•</b><br>Alt + </div> + </div> + <div class="key wide-5" data-code="Space"> + <div class="label"> + </div> + </div> + <div class="modifier wide-1 right small" data-code="AltRight"> + <div class="label"><b>•</b><br>Alt + </div> + </div> + <div class="modifier wide-1 right small" data-code="MetaRight"> + <div class="label"><b>•</b><br>Win + </div> + </div> + <div class="modifier wide-1 right small" data-code="ControlRight"> + <div class="label"><b>•</b><br>Ctrl + </div> + </div> </div> </div> - <div class="window" id="keyboard-window" data-close-confirm=""> - <div class="window-header" id="keyboard-window-header"> - <div class="window-grab">Virtual Keyboard</div> - <button class="window-button-close">×</button> + <div class="keypad-block"> + <div class="keypad-row"> + <div class="modifier small" data-code="PrintScreen"> + <div class="label"><b>•</b><br>Pt/Sq + </div> + </div> + <div class="key small" data-code="ScrollLock"> + <div class="label"><img class="inline-lamp hid-keyboard-scroll-led led-gray" src="/share/svg/led-square.svg"><br> ScrLk + </div> + </div> + <div class="key small" data-code="Pause"> + <div class="label">P/Brk + </div> + </div> </div> - <div class="keypad" id="keyboard-desktop" align="center"> - <div class="keypad-block"> - <div class="keypad-row"> - <div class="key small" data-code="Escape"> - <div class="label">Esc - </div> - </div> - <div class="empty-key" style="width:24px"></div> - <div class="key small" data-code="F1"> - <div class="label">F1 - </div> - </div> - <div class="key small" data-code="F2"> - <div class="label">F2 - </div> - </div> - <div class="key small" data-code="F3"> - <div class="label">F3 - </div> - </div> - <div class="key small" data-code="F4"> - <div class="label">F4 - </div> - </div> - <div class="empty-key" style="width:10px"></div> - <div class="key small" data-code="F5"> - <div class="label">F5 - </div> - </div> - <div class="key small" data-code="F6"> - <div class="label">F6 - </div> - </div> - <div class="key small" data-code="F7"> - <div class="label">F7 - </div> - </div> - <div class="key small" data-code="F8"> - <div class="label">F8 - </div> - </div> - <div class="empty-key" style="width:10px"></div> - <div class="key small" data-code="F9"> - <div class="label">F9 - </div> - </div> - <div class="key small" data-code="F10"> - <div class="label">F10 - </div> - </div> - <div class="key small" data-code="F11"> - <div class="label">F11 - </div> - </div> - <div class="key small" data-code="F12"> - <div class="label">F12 - </div> - </div> - </div> - <hr> - <div class="keypad-row"> - <div class="key " data-code="Backquote"> - <div class="label">~<br>` - </div> - </div> - <div class="key " data-code="Digit1"> - <div class="label">!<br>1 - </div> - </div> - <div class="key " data-code="Digit2"> - <div class="label">@<br>2 - </div> - </div> - <div class="key " data-code="Digit3"> - <div class="label">#<br>3 - </div> - </div> - <div class="key " data-code="Digit4"> - <div class="label">$<br>4 - </div> - </div> - <div class="key " data-code="Digit5"> - <div class="label">%<br>5 - </div> - </div> - <div class="key " data-code="Digit6"> - <div class="label">^<br>6 - </div> - </div> - <div class="key " data-code="Digit7"> - <div class="label">&<br>7 - </div> - </div> - <div class="key " data-code="Digit8"> - <div class="label">*<br>8 - </div> - </div> - <div class="key " data-code="Digit9"> - <div class="label">(<br>9 - </div> - </div> - <div class="key " data-code="Digit0"> - <div class="label">)<br>0 - </div> - </div> - <div class="key " data-code="Minus"> - <div class="label">_<br>- - </div> - </div> - <div class="key " data-code="Equal"> - <div class="label">+<br>= - </div> - </div> - <div class="key wide-2 right" data-code="Backspace"> - <div class="label">↤ - </div> - </div> - </div> - <div class="keypad-row"> - <div class="key wide-2 left" data-code="Tab"> - <div class="label">⇤<br>⇥ - </div> - </div> - <div class="key single" data-code="KeyQ"> - <div class="label">Q - </div> - </div> - <div class="key single" data-code="KeyW"> - <div class="label">W - </div> - </div> - <div class="key single" data-code="KeyE"> - <div class="label">E - </div> - </div> - <div class="key single" data-code="KeyR"> - <div class="label">R - </div> - </div> - <div class="key single" data-code="KeyT"> - <div class="label">T - </div> - </div> - <div class="key single" data-code="KeyY"> - <div class="label">Y - </div> - </div> - <div class="key single" data-code="KeyU"> - <div class="label">U - </div> - </div> - <div class="key single" data-code="KeyI"> - <div class="label">I - </div> - </div> - <div class="key single" data-code="KeyO"> - <div class="label">O - </div> - </div> - <div class="key single" data-code="KeyP"> - <div class="label">P - </div> - </div> - <div class="key " data-code="BracketLeft"> - <div class="label">{<br>[ - </div> - </div> - <div class="key " data-code="BracketRight"> - <div class="label">}<br>] - </div> - </div> - <div class="key " data-code="Backslash"> - <div class="label">|<br>\ - </div> - </div> - </div> - <div class="keypad-row"> - <div class="key wide-3 left small" data-code="CapsLock"> - <div class="label"><img class="inline-lamp hid-keyboard-caps-led led-gray" src="/share/svg/led-square.svg"><br> Caps Lock - </div> - </div> - <div class="key single" data-code="KeyA"> - <div class="label">A - </div> - </div> - <div class="key single" data-code="KeyS"> - <div class="label">S - </div> - </div> - <div class="key single" data-code="KeyD"> - <div class="label">D - </div> - </div> - <div class="key single" data-code="KeyF"> - <div class="label">F - </div> - </div> - <div class="key single" data-code="KeyG"> - <div class="label">G - </div> - </div> - <div class="key single" data-code="KeyH"> - <div class="label">H - </div> - </div> - <div class="key single" data-code="KeyJ"> - <div class="label">J - </div> - </div> - <div class="key single" data-code="KeyK"> - <div class="label">K - </div> - </div> - <div class="key single" data-code="KeyL"> - <div class="label">L - </div> - </div> - <div class="key " data-code="Semicolon"> - <div class="label">:<br>; - </div> - </div> - <div class="key " data-code="Quote"> - <div class="label">"<br>' - </div> - </div> - <div class="key wide-3 right small" data-code="Enter"> - <div class="label">Enter<br>↵ - </div> - </div> - </div> - <div class="keypad-row"> - <div class="modifier wide-4 left small" data-code="ShiftLeft"> - <div class="label"><b>•</b><br>Shift - </div> - </div> - <div class="key single" data-code="KeyZ"> - <div class="label">Z - </div> - </div> - <div class="key single" data-code="KeyX"> - <div class="label">X - </div> - </div> - <div class="key single" data-code="KeyC"> - <div class="label">C - </div> - </div> - <div class="key single" data-code="KeyV"> - <div class="label">V - </div> - </div> - <div class="key single" data-code="KeyB"> - <div class="label">B - </div> - </div> - <div class="key single" data-code="KeyN"> - <div class="label">N - </div> - </div> - <div class="key single" data-code="KeyM"> - <div class="label">M - </div> - </div> - <div class="key " data-code="Comma"> - <div class="label"><<br>, - </div> - </div> - <div class="key " data-code="Period"> - <div class="label">><br>. - </div> - </div> - <div class="key " data-code="Slash"> - <div class="label">?<br>/ - </div> - </div> - <div class="modifier wide-4 right small" data-code="ShiftRight"> - <div class="label"><b>•</b><br>Shift - </div> - </div> - </div> - <div class="keypad-row"> - <div class="modifier wide-1 left small" data-code="ControlLeft"> - <div class="label"><b>•</b><br>Ctrl - </div> - </div> - <div class="modifier wide-1 left small" data-code="MetaLeft"> - <div class="label"><b>•</b><br>Win - </div> - </div> - <div class="modifier wide-1 left small" data-code="AltLeft"> - <div class="label"><b>•</b><br>Alt - </div> - </div> - <div class="key wide-5" data-code="Space"> - <div class="label"> - </div> - </div> - <div class="modifier wide-1 right small" data-code="AltRight"> - <div class="label"><b>•</b><br>Alt - </div> - </div> - <div class="modifier wide-1 right small" data-code="MetaRight"> - <div class="label"><b>•</b><br>Win - </div> - </div> - <div class="modifier wide-1 right small" data-code="ControlRight"> - <div class="label"><b>•</b><br>Ctrl - </div> - </div> - </div> - </div> - <div class="keypad-block"> - <div class="keypad-row"> - <div class="modifier small" data-code="PrintScreen"> - <div class="label"><b>•</b><br>Pt/Sq - </div> - </div> - <div class="key small" data-code="ScrollLock"> - <div class="label"><img class="inline-lamp hid-keyboard-scroll-led led-gray" src="/share/svg/led-square.svg"><br> ScrLk - </div> - </div> - <div class="key small" data-code="Pause"> - <div class="label">P/Brk - </div> - </div> - </div> - <hr> - <div class="keypad-row"> - <div class="key small" data-code="Insert"> - <div class="label">Ins - </div> - </div> - <div class="key small" data-code="Home"> - <div class="label">Home - </div> - </div> - <div class="key small" data-code="PageUp"> - <div class="label">PgUp - </div> - </div> - </div> - <div class="keypad-row"> - <div class="key small" data-code="Delete"> - <div class="label">Del - </div> - </div> - <div class="key small" data-code="End"> - <div class="label">End - </div> - </div> - <div class="key small" data-code="PageDown"> - <div class="label">PgDn - </div> - </div> - </div> - <div class="keypad-row"></div> - <div class="keypad-row"> - <div class="empty-key"></div> - <div class="key " data-code="ArrowUp"> - <div class="label">↑ - </div> - </div> - <div class="empty-key"></div> - </div> - <div class="keypad-row"> - <div class="key " data-code="ArrowLeft"> - <div class="label">← - </div> - </div> - <div class="key " data-code="ArrowDown"> - <div class="label">↓ - </div> - </div> - <div class="key " data-code="ArrowRight"> - <div class="label">→ - </div> - </div> - </div> - </div> - <div class="keypad-block"> - <div class="keypad-row"> - <div class="empty-key"></div> - <div class="empty-key"></div> - <div class="key small" data-code="IntlBackslash"> - <div class="label">N/US - </div> - </div> - <div class="key small" data-code="Power"> - <div class="label">PWR - </div> - </div> - </div> - <hr> - <div class="keypad-row"> - <div class="key small" data-code="NumLock"> - <div class="label"><img class="inline-lamp hid-keyboard-num-led led-gray" src="/share/svg/led-square.svg"><br> NmLk - </div> - </div> - <div class="key " data-code="NumpadDivide"> - <div class="label">/ - </div> - </div> - <div class="key " data-code="NumpadMultiply"> - <div class="label">* - </div> - </div> - <div class="key " data-code="NumpadSubtract"> - <div class="label">- - </div> - </div> - </div> - <div class="keypad-row"> - <div class="key small" data-code="Numpad7"> - <div class="label">7<br>Home - </div> - </div> - <div class="key small" data-code="Numpad8"> - <div class="label">8<br>↑ - </div> - </div> - <div class="key small" data-code="Numpad9"> - <div class="label">9<br>PgUp - </div> - </div> - <div class="empty-key"></div> - </div> - <div class="keypad-row"> - <div class="key small" data-code="Numpad4"> - <div class="label">4<br>← - </div> - </div> - <div class="key small" data-code="Numpad5"> - <div class="label">5<br><br> - </div> - </div> - <div class="key small" data-code="Numpad6"> - <div class="label">6<br>→ - </div> - </div> - <div class="key " data-code="NumpadAdd"> - <div class="label">+ - </div> - </div> - </div> - <div class="keypad-row"> - <div class="key small" data-code="Numpad1"> - <div class="label">1<br>End - </div> - </div> - <div class="key small" data-code="Numpad2"> - <div class="label">2<br>↓ - </div> - </div> - <div class="key small" data-code="Numpad3"> - <div class="label">3<br>PgDn - </div> - </div> - <div class="empty-key"></div> - </div> - <div class="keypad-row"> - <div class="key small" data-code="Numpad0"> - <div class="label">0<br>Ins - </div> - </div> - <div class="empty-key"></div> - <div class="key small" data-code="NumpadDecimal"> - <div class="label">.<br>Del - </div> - </div> - <div class="key small" data-code="NumpadEnter"> - <div class="label">Ent - </div> - </div> - </div> - </div> + <hr> + <div class="keypad-row"> + <div class="key small" data-code="Insert"> + <div class="label">Ins + </div> + </div> + <div class="key small" data-code="Home"> + <div class="label">Home + </div> + </div> + <div class="key small" data-code="PageUp"> + <div class="label">PgUp + </div> + </div> </div> - <div class="keypad" id="keyboard-mobile" align="center"> - <div class="keypad-block"> - <div class="keypad-row"> - <div class="key margin-0 small" data-code="Escape"> - <div class="label">Esc - </div> - </div> - <div class="empty-key" style="width:1px"></div> - <div class="key wide-0 margin-0 small" data-code="F1"> - <div class="label">F1 - </div> - </div> - <div class="key wide-0 margin-0 small" data-code="F2"> - <div class="label">F2 - </div> - </div> - <div class="key wide-0 margin-0 small" data-code="F3"> - <div class="label">F3 - </div> - </div> - <div class="key wide-0 margin-0 small" data-code="F4"> - <div class="label">F4 - </div> - </div> - <div class="key wide-0 margin-0 small" data-code="F5"> - <div class="label">F5 - </div> - </div> - <div class="key wide-0 margin-0 small" data-code="F6"> - <div class="label">F6 - </div> - </div> - <div class="key wide-0 margin-0 small" data-code="F7"> - <div class="label">F7 - </div> - </div> - <div class="key wide-0 margin-0 small" data-code="F8"> - <div class="label">F8 - </div> - </div> - <div class="key wide-0 margin-0 small" data-code="F9"> - <div class="label">F9 - </div> - </div> - <div class="key wide-0 margin-0 small" data-code="F10"> - <div class="label">F10 - </div> - </div> - <div class="key wide-0 margin-0 small" data-code="F11"> - <div class="label">F11 - </div> - </div> - <div class="key wide-0 margin-0 small" data-code="F12"> - <div class="label">F12 - </div> - </div> - <div class="empty-key" style="width:2px"></div> - <div class="modifier margin-0 small" data-code="PrintScreen"> - <div class="label"><b>•</b><br>Pt/Sq - </div> - </div> - <div class="key margin-0 small" data-code="ScrollLock"> - <div class="label"><img class="inline-lamp hid-keyboard-scroll-led led-gray" src="/share/svg/led-square.svg"><br> ScrLk - </div> - </div> - <div class="key margin-0 small" data-code="Pause"> - <div class="label">P/Brk - </div> - </div> - <div class="key margin-0 small" data-code="Insert"> - <div class="label">Ins - </div> - </div> - <div class="key margin-0 small" data-code="Home"> - <div class="label">Home - </div> - </div> - <div class="key margin-0 small" data-code="End"> - <div class="label">End - </div> - </div> - <div class="key margin-0 small" data-code="Delete"> - <div class="label">Del - </div> - </div> - </div> - <div class="keypad-row"> - <div class="key " data-code="Backquote"> - <div class="label">~<br>` - </div> - </div> - <div class="key " data-code="Digit1"> - <div class="label">!<br>1 - </div> - </div> - <div class="key " data-code="Digit2"> - <div class="label">@<br>2 - </div> - </div> - <div class="key " data-code="Digit3"> - <div class="label">#<br>3 - </div> - </div> - <div class="key " data-code="Digit4"> - <div class="label">$<br>4 - </div> - </div> - <div class="key " data-code="Digit5"> - <div class="label">%<br>5 - </div> - </div> - <div class="key " data-code="Digit6"> - <div class="label">^<br>6 - </div> - </div> - <div class="key " data-code="Digit7"> - <div class="label">&<br>7 - </div> - </div> - <div class="key " data-code="Digit8"> - <div class="label">*<br>8 - </div> - </div> - <div class="key " data-code="Digit9"> - <div class="label">(<br>9 - </div> - </div> - <div class="key " data-code="Digit0"> - <div class="label">)<br>0 - </div> - </div> - <div class="key " data-code="Minus"> - <div class="label">_<br>- - </div> - </div> - <div class="key " data-code="Equal"> - <div class="label">+<br>= - </div> - </div> - <div class="key wide-3 right" data-code="Backspace" style="width:101px"> - <div class="label">↤ - </div> - </div> - </div> - <div class="keypad-row"> - <div class="key wide-2 left" data-code="Tab"> - <div class="label">⇤<br>⇥ - </div> - </div> - <div class="key single" data-code="KeyQ"> - <div class="label">Q - </div> - </div> - <div class="key single" data-code="KeyW"> - <div class="label">W - </div> - </div> - <div class="key single" data-code="KeyE"> - <div class="label">E - </div> - </div> - <div class="key single" data-code="KeyR"> - <div class="label">R - </div> - </div> - <div class="key single" data-code="KeyT"> - <div class="label">T - </div> - </div> - <div class="key single" data-code="KeyY"> - <div class="label">Y - </div> - </div> - <div class="key single" data-code="KeyU"> - <div class="label">U - </div> - </div> - <div class="key single" data-code="KeyI"> - <div class="label">I - </div> - </div> - <div class="key single" data-code="KeyO"> - <div class="label">O - </div> - </div> - <div class="key single" data-code="KeyP"> - <div class="label">P - </div> - </div> - <div class="key " data-code="BracketLeft"> - <div class="label">{<br>[ - </div> - </div> - <div class="key " data-code="BracketRight"> - <div class="label">}<br>] - </div> - </div> - <div class="key wide-2 left" data-code="Backslash" style="width:78px"> - <div class="label">|<br>\ - </div> - </div> - </div> - <div class="keypad-row"> - <div class="key wide-3 left small" data-code="CapsLock"> - <div class="label"><img class="inline-lamp hid-keyboard-caps-led led-gray" src="/share/svg/led-square.svg"><br> Caps Lock - </div> - </div> - <div class="key single" data-code="KeyA"> - <div class="label">A - </div> - </div> - <div class="key single" data-code="KeyS"> - <div class="label">S - </div> - </div> - <div class="key single" data-code="KeyD"> - <div class="label">D - </div> - </div> - <div class="key single" data-code="KeyF"> - <div class="label">F - </div> - </div> - <div class="key single" data-code="KeyG"> - <div class="label">G - </div> - </div> - <div class="key single" data-code="KeyH"> - <div class="label">H - </div> - </div> - <div class="key single" data-code="KeyJ"> - <div class="label">J - </div> - </div> - <div class="key single" data-code="KeyK"> - <div class="label">K - </div> - </div> - <div class="key single" data-code="KeyL"> - <div class="label">L - </div> - </div> - <div class="key " data-code="Semicolon"> - <div class="label">:<br>; - </div> - </div> - <div class="key " data-code="Quote"> - <div class="label">`<br>' - </div> - </div> - <div class="key wide-4 right small" data-code="Enter" style="width:116px"> - <div class="label">Enter<br>↵ - </div> - </div> - </div> - <div class="keypad-row"> - <div class="modifier wide-4 left small" data-code="ShiftLeft"> - <div class="label"><b>•</b><br>Shift - </div> - </div> - <div class="key single" data-code="KeyZ"> - <div class="label">Z - </div> - </div> - <div class="key single" data-code="KeyX"> - <div class="label">X - </div> - </div> - <div class="key single" data-code="KeyC"> - <div class="label">C - </div> - </div> - <div class="key single" data-code="KeyV"> - <div class="label">V - </div> - </div> - <div class="key single" data-code="KeyB"> - <div class="label">B - </div> - </div> - <div class="key single" data-code="KeyN"> - <div class="label">N - </div> - </div> - <div class="key single" data-code="KeyM"> - <div class="label">M - </div> - </div> - <div class="key " data-code="Comma"> - <div class="label">lt;<br>, - </div> - </div> - <div class="key " data-code="Period"> - <div class="label">><br>. - </div> - </div> - <div class="key " data-code="Slash"> - <div class="label">?<br>/ - </div> - </div> - <div class="key small" data-code="PageUp"> - <div class="label">PgUp - </div> - </div> - <div class="key " data-code="ArrowUp"> - <div class="label">↑ - </div> - </div> - <div class="key small" data-code="PageDown"> - <div class="label">PgDn - </div> - </div> - </div> - <div class="keypad-row"> - <div class="modifier wide-1 left small" data-code="ControlLeft"> - <div class="label"><b>•</b><br>Ctrl - </div> - </div> - <div class="modifier wide-1 left small" data-code="MetaLeft"> - <div class="label"><b>•</b><br>Win - </div> - </div> - <div class="modifier wide-1 left small" data-code="AltLeft"> - <div class="label"><b>•</b><br>Alt - </div> - </div> - <div class="key " data-code="Space" style="width:190px"> - <div class="label"> - </div> - </div> - <div class="modifier right small" data-code="AltRight"> - <div class="label"><b>•</b><br>Alt - </div> - </div> - <div class="modifier right small" data-code="MetaRight"> - <div class="label"><b>•</b><br>Win - </div> - </div> - <div class="modifier right small" data-code="ShiftRight"> - <div class="label"><b>•</b><br>Shift - </div> - </div> - <div class="modifier right small" data-code="ControlRight"> - <div class="label"><b>•</b><br>Ctrl - </div> - </div> - <div class="key " data-code="ArrowLeft"> - <div class="label">← - </div> - </div> - <div class="key " data-code="ArrowDown"> - <div class="label">↓ - </div> - </div> - <div class="key " data-code="ArrowRight"> - <div class="label">→ - </div> - </div> - </div> - </div> + <div class="keypad-row"> + <div class="key small" data-code="Delete"> + <div class="label">Del + </div> + </div> + <div class="key small" data-code="End"> + <div class="label">End + </div> + </div> + <div class="key small" data-code="PageDown"> + <div class="label">PgDn + </div> + </div> + </div> + <div class="keypad-row"></div> + <div class="keypad-row"> + <div class="empty-key"></div> + <div class="key " data-code="ArrowUp"> + <div class="label">↑ + </div> + </div> + <div class="empty-key"></div> + </div> + <div class="keypad-row"> + <div class="key " data-code="ArrowLeft"> + <div class="label">← + </div> + </div> + <div class="key " data-code="ArrowDown"> + <div class="label">↓ + </div> + </div> + <div class="key " data-code="ArrowRight"> + <div class="label">→ + </div> + </div> </div> </div> - <div class="window" id="about-window" data-close-confirm=""> - <div class="window-header" id=""> - <div class="window-grab">About</div> - <button class="window-button-close">×</button> + <div class="keypad-block"> + <div class="keypad-row"> + <div class="empty-key"></div> + <div class="empty-key"></div> + <div class="key small" data-code="IntlBackslash"> + <div class="label">N/US + </div> + </div> + <div class="key small" data-code="Power"> + <div class="label">PWR + </div> + </div> </div> - <div id="about"> - <table> - <tr> - <td class="logo" valign="top"><img class="svg-gray" src="../share/svg/logo.svg" alt="Pi-KVM" height="40"></td> - <td valign="top"> - <table> - <tr> - <td class="title" colspan="2">The Open Source IP-KVM</td> - </tr> - <tr> - <td class="copyright" colspan="2">Copyright © 2018-2021 <a target="_blank" href="mailto:[email protected]">Maxim Devaev</a></td> - </tr> - </table> - </td> - </tr> - </table><br> - <div class="tabs-box"> - <input checked type="radio" name="about-tab-button" id="about-tab-meta-button"> - <label for="about-tab-meta-button">Meta</label> - <div class="tab"> - <div class="code" id="about-meta"><span class="code-comment">No data</span> - </div> + <hr> + <div class="keypad-row"> + <div class="key small" data-code="NumLock"> + <div class="label"><img class="inline-lamp hid-keyboard-num-led led-gray" src="/share/svg/led-square.svg"><br> NmLk </div> - <input type="radio" name="about-tab-button" id="about-tab-hw-button"> - <label for="about-tab-hw-button">Hardware</label> - <div class="tab"> - <div class="code" id="about-hw"><span class="code-comment">No data</span> - </div> + </div> + <div class="key " data-code="NumpadDivide"> + <div class="label">/ </div> - <input type="radio" name="about-tab-button" id="about-tab-version-button"> - <label for="about-tab-version-button">Version</label> - <div class="tab"> - <div class="code" id="about-version"><span class="code-comment">No data</span> - </div> + </div> + <div class="key " data-code="NumpadMultiply"> + <div class="label">* </div> - <input type="radio" name="about-tab-button" id="about-tab-thanks-button"> - <label for="about-tab-thanks-button">Thanks</label> - <div class="tab"> - <div class="code" id="about-thanks"><span class="code-comment">// These kind people donated money to the Pi-KVM project<br> - // and supported the work on it. We are very grateful<br> - // for their help, and memorializing their names<br> - // is the least we can do in gratitude.<br> - // If you also want to support this project,<br> - // you can use one of these services: - <a target="_blank" href="https://www.patreon.com/pikvm">Patreon</a> - or <a target="_blank" href="https://www.paypal.me/mdevaev">PayPal</a>.</span> - <ul> - <li>A. Isenring</li> - <li>Aaron Heise</li> - <li>Accalia</li> - <li>adipisicing</li> - <li>Adrian Basham</li> - <li>Alberto Bassi</li> - <li>Aleksei Brusianskii</li> - <li>Alessio Curri</li> - <li>Alexandre Jablonski</li> - <li>Alucard</li> - <li>Andreas Marufke</li> - <li>Andrew Reusch</li> - <li>Andrew Ruan</li> - <li>Andrzej V</li> - <li>Anish Patel</li> - <li>Anix</li> - <li>anonymous</li> - <li>Anton Kovalenko</li> - <li>Aron Green</li> - <li>Aron Perelman</li> - <li>Arthur Woimbée</li> - <li>Ashlesh Chaudhari</li> - <li>Augusto Becciu</li> - <li>AVS Computer</li> - <li>baddog</li> - <li>Bao Tin Hoang</li> - <li>Belf Igor</li> - <li>Ben Gordon</li> - <li>Ben Scott</li> - <li>Benedikt Heine</li> - <li>Benjamin Melancon</li> - <li>Benni Stauder</li> - <li>Bernhard Fitzke</li> - <li>bitjoe</li> - <li>Bits and Bytes Computers LLC</li> - <li>Blue Frog LLC</li> - <li>Bootstrapper - Programmierung erklärt</li> - <li>Bosco</li> - <li>Bradford King</li> - <li>Brainspore Networks</li> - <li>Branden Shaulis</li> - <li>Brian Moses</li> - <li>Brian Vecchiarelli</li> - <li>Brian White</li> - <li>Bruno Gomes</li> - <li>Bryan Adams</li> - <li>C P ELSE</li> - <li>Cameron Tacklind</li> - <li>Carl Mercier</li> - <li>Carl-Fredrik Johansson</li> - <li>cbad536</li> - <li>Chris Burton</li> - <li>Chris Lewis</li> - <li>Chris Rizio</li> - <li>Christian Schlögl</li> - <li>Christian Svensson</li> - <li>Christof Maluck</li> - <li>Christoph Dette</li> - <li>Christoffer Lund</li> - <li>Christopher Mandlbaur</li> - <li>Chucktastic</li> - <li>Clifford Coleman</li> - <li>Clinton Lee Taylor</li> - <li>Cole Imhoff</li> - <li>Corey Layton</li> - <li>Corey Lista</li> - <li>Crossfactor</li> - <li>ctag</li> - <li>CyB0rgg</li> - <li>DeMentor</li> - <li>Desmond Whitt</li> - <li>Damon Meledones</li> - <li>Dan Berkowitz</li> - <li>Dan Brakeley</li> - <li>David</li> - <li>David Godibadze</li> - <li>David Howell</li> - <li>David Ye</li> - <li>David York</li> - <li>Denis</li> - <li>Denis Andreev</li> - <li>Denis Yatsenko</li> - <li>Dennis Becker</li> - <li>Derek Yap</li> - <li>Didrik</li> - <li>dixon wong</li> - <li>dizztrukshin</li> - <li>Dmitry Shilov</li> - <li>Egan Ford</li> - <li>Elliot Woo</li> - <li>Eric Phenix</li> - <li>ewook</li> - <li>eye-catcher.com</li> - <li>Fabiano Sidler</li> - <li>Far Pin Solutions, LLC</li> - <li>Felyx Gabryel</li> - <li>Fergus McKay</li> - <li>fo0bar</li> - <li>Foamy</li> - <li>Francisco Pavon</li> - <li>Frank</li> - <li>Frederick Czajka</li> - <li>Fredrik Idréus</li> - <li>Ge Men</li> - <li>Genkinger Andreas</li> - <li>Georgy Brodsky</li> - <li>Gernot Neuschröer</li> - <li>Glen Dragon</li> - <li>Gregory Smith</li> - <li>Gregory Treantos</li> - <li>Grey Cynic</li> - <li>Guido Bernacchi</li> - <li>Gustin Johnson</li> - <li>Heikki Tiittanen</li> - <li>Helio Leonardo Pinheiro e Mota</li> - <li>Henrik Ählström</li> - <li>Henry Hood</li> - <li>HimKo</li> - <li>HouseFPV</li> - <li>Icculus</li> - <li>iks</li> - <li>IT Lifesaver</li> - <li>Ivan Shapovalov</li> - <li>J L</li> - <li>Jaanus</li> - <li>Jackson Wyatt</li> - <li>Jacob Morgan</li> - <li>James Cadd</li> - <li>James Cobb</li> - <li>James Edwards</li> - <li>James Kocher</li> - <li>James Mayhugh</li> - <li>Jamie Murphy</li> - <li>Jan Niehusmann</li> - <li>Jari Hiltunen</li> - <li>Jason Downey</li> - <li>Jason Toland</li> - <li>Jay Davis</li> - <li>Jay Isaacs</li> - <li>Jean-Philippe Guilbault</li> - <li>Jeff Bowman</li> - <li>Jeff Urlwin</li> - <li>Jennifer Rowlett</li> - <li>Jerremy Holland</li> - <li>Joachim Bruening</li> - <li>Joe Ventura</li> - <li>Joel Jacobs</li> - <li>John Andersen</li> - <li>John F Glenn</li> - <li>John Kelley</li> - <li>John McGovern</li> - <li>Johnny Henson</li> - <li>Jonathan Vaughn</li> - <li>Jordi Pakey-Rodriguez</li> - <li>Joris van Embden</li> - <li>Josh Ricker</li> - <li>Joshua Futterer</li> - <li>Jozef Riha</li> - <li>Julian Forero</li> - <li>Justin Waters</li> - <li>Karl Dunne</li> - <li>Keith Muggleton</li> - <li>Ken Lee</li> - <li>Kenny Hui</li> - <li>Kevin Bajohr</li> - <li>Kevin Schwartz</li> - <li>Krzysztof Żelaśkiewicz</li> - <li>Lars</li> - <li>Lee Wilkinson</li> - <li>LeeNX</li> - <li>Lordbob75</li> - <li>Lothar Schweikle-Droll</li> - <li>Louis Müller</li> - <li>Lucio De Carli</li> - <li>Lukas Söder</li> - <li>Malcolm Cameron</li> - <li>Marcos Wolf</li> - <li>Mark Gilbert</li> - <li>Mark Robinson</li> - <li>Markrosoft</li> - <li>Markus Halm</li> - <li>Markus Schicker</li> - <li>Markus Sobczack</li> - <li>Marten Hermans</li> - <li>Martin Gasser</li> - <li>Mateusz Grabowski</li> - <li>Matthew Cameron</li> - <li>Mauricio Allende</li> - <li>Mehmet Aydoğdu</li> - <li>Michael Kovacs</li> - <li>Michael Lynch</li> - <li>Michael Pennington</li> - <li>Michael Sage</li> - <li>MichaelZ</li> - <li>Michel Bissonnette</li> - <li>Milan Múčka</li> - <li>Miles Davis</li> - <li>Moez Tharani</li> - <li>Morgan Helton</li> - <li>Nelson Lee</li> - <li>Nicholas Jeppson</li> - <li>Nicholas Kopas</li> - <li>Nick Leffler</li> - <li>Nick Roethemeier</li> - <li>Nicolai Kragh-Hansen</li> - <li>Nils Orbat</li> - <li>Nithin Philips</li> - <li>Nod Swal</li> - <li>nubbn</li> - <li>nybble</li> - <li>Oh Be</li> - <li>Oliver Schwarz</li> - <li>Oliver Zimmer</li> - <li>Patrick McDowell</li> - <li>Patrick Wagstrom</li> - <li>Paul Bishop</li> - <li>Pawel Trofimiuk</li> - <li>Peder Madsen</li> - <li>Peter Drayton</li> - <li>Peter Farrelly</li> - <li>Petri Heiskanen</li> - <li>Philip Merricks</li> - <li>posicat</li> - <li>pozitron03</li> - <li>Qteal</li> - <li>Quentin Peten</li> - <li>Ralph Borchers</li> - <li>Ranc1d</li> - <li>Richard Bernarts</li> - <li>Richard Fancher</li> - <li>Richard Freemantle</li> - <li>Richard Michael</li> - <li>Rob Tongue</li> - <li>Robin Gfatter</li> - <li>Rodion DENISYUK</li> - <li>Rohit Priyadarshi</li> - <li>Rolfs 3D UG</li> - <li>Ronald LeBaron</li> - <li>rotx</li> - <li>Russell Scott</li> - <li>Samed Ozoglu</li> - <li>Sameul Davies</li> - <li>Samuel Vetsch</li> - <li>Satish Alwani</li> - <li>Scott</li> - <li>Scott Spicola</li> - <li>Scott Tusing</li> - <li>Sean</li> - <li>Seonwoo Lee</li> - <li>Sergey Lukjanov</li> - <li>Shichun Chen</li> - <li>Simon Evans</li> - <li>Simon Sundgaard</li> - <li>Simplistic Realities</li> - <li>srepac</li> - <li>Stefan Bautz</li> - <li>Stefan Müller</li> - <li>Stefan Stemmer</li> - <li>Stephan Schmidt</li> - <li>Steve Kerr</li> - <li>Steve Ovens</li> - <li>Steven Richter</li> - <li>sudo34</li> - <li>Tarlak Desaydrone</li> - <li>Ted</li> - <li>Tejun Heo</li> - <li>TheTechGiant</li> - <li>Thomas Price</li> - <li>Thomas Søfteland</li> - <li>Tim Wilkinson</li> - <li>Timo Brinkmann</li> - <li>Timothee Besset</li> - <li>Tobias Schafferhans</li> - <li>Tom Lawson</li> - <li>Tom York</li> - <li>Tomas Kuchta</li> - <li>Tomáš hrubý</li> - <li>Tristan Schoening</li> - <li>Truman Kilen</li> - <li>turbochris</li> - <li>Tyler</li> - <li>Udo Schroeter</li> - <li>Uli Fahrer</li> - <li>Vasily Lazarev</li> - <li>Vicente Salvador Cubedo</li> - <li>Viktor Aschenbrenner</li> - <li>Viktor Ekmark</li> - <li>Walter_Ego</li> - <li>William Hooper</li> - <li>William Stearns</li> - <li>Yethal</li> - <li>Yevgeniy Kuksenko</li> - <li>Yigal Dar</li> - <li>Yogi</li> - <li>YURI LEE</li> - <li>Yurii Ostapchuk</li> - <li>zgen</li> - <li>Zsombor Vari</li> - </ul> - </div> + </div> + <div class="key " data-code="NumpadSubtract"> + <div class="label">- </div> - </div><br> - <p class="text"> - Full documentation, source code, hardware schematics and legal information - can be found in our <a target="_blank" href="https://pikvm.org">official website</a>. - </p> + </div> + </div> + <div class="keypad-row"> + <div class="key small" data-code="Numpad7"> + <div class="label">7<br>Home + </div> + </div> + <div class="key small" data-code="Numpad8"> + <div class="label">8<br>↑ + </div> + </div> + <div class="key small" data-code="Numpad9"> + <div class="label">9<br>PgUp + </div> + </div> + <div class="empty-key"></div> + </div> + <div class="keypad-row"> + <div class="key small" data-code="Numpad4"> + <div class="label">4<br>← + </div> + </div> + <div class="key small" data-code="Numpad5"> + <div class="label">5<br><br> + </div> + </div> + <div class="key small" data-code="Numpad6"> + <div class="label">6<br>→ + </div> + </div> + <div class="key " data-code="NumpadAdd"> + <div class="label">+ + </div> + </div> + </div> + <div class="keypad-row"> + <div class="key small" data-code="Numpad1"> + <div class="label">1<br>End + </div> + </div> + <div class="key small" data-code="Numpad2"> + <div class="label">2<br>↓ + </div> + </div> + <div class="key small" data-code="Numpad3"> + <div class="label">3<br>PgDn + </div> + </div> + <div class="empty-key"></div> + </div> + <div class="keypad-row"> + <div class="key small" data-code="Numpad0"> + <div class="label">0<br>Ins + </div> + </div> + <div class="empty-key"></div> + <div class="key small" data-code="NumpadDecimal"> + <div class="label">.<br>Del + </div> + </div> + <div class="key small" data-code="NumpadEnter"> + <div class="label">Ent + </div> + </div> </div> </div> + </div> + <div class="keypad" id="keyboard-mobile" align="center"> + <div class="keypad-block"> + <div class="keypad-row"> + <div class="key margin-0 small" data-code="Escape"> + <div class="label">Esc + </div> + </div> + <div class="empty-key" style="width:1px"></div> + <div class="key wide-0 margin-0 small" data-code="F1"> + <div class="label">F1 + </div> + </div> + <div class="key wide-0 margin-0 small" data-code="F2"> + <div class="label">F2 + </div> + </div> + <div class="key wide-0 margin-0 small" data-code="F3"> + <div class="label">F3 + </div> + </div> + <div class="key wide-0 margin-0 small" data-code="F4"> + <div class="label">F4 + </div> + </div> + <div class="key wide-0 margin-0 small" data-code="F5"> + <div class="label">F5 + </div> + </div> + <div class="key wide-0 margin-0 small" data-code="F6"> + <div class="label">F6 + </div> + </div> + <div class="key wide-0 margin-0 small" data-code="F7"> + <div class="label">F7 + </div> + </div> + <div class="key wide-0 margin-0 small" data-code="F8"> + <div class="label">F8 + </div> + </div> + <div class="key wide-0 margin-0 small" data-code="F9"> + <div class="label">F9 + </div> + </div> + <div class="key wide-0 margin-0 small" data-code="F10"> + <div class="label">F10 + </div> + </div> + <div class="key wide-0 margin-0 small" data-code="F11"> + <div class="label">F11 + </div> + </div> + <div class="key wide-0 margin-0 small" data-code="F12"> + <div class="label">F12 + </div> + </div> + <div class="empty-key" style="width:2px"></div> + <div class="modifier margin-0 small" data-code="PrintScreen"> + <div class="label"><b>•</b><br>Pt/Sq + </div> + </div> + <div class="key margin-0 small" data-code="ScrollLock"> + <div class="label"><img class="inline-lamp hid-keyboard-scroll-led led-gray" src="/share/svg/led-square.svg"><br> ScrLk + </div> + </div> + <div class="key margin-0 small" data-code="Pause"> + <div class="label">P/Brk + </div> + </div> + <div class="key margin-0 small" data-code="Insert"> + <div class="label">Ins + </div> + </div> + <div class="key margin-0 small" data-code="Home"> + <div class="label">Home + </div> + </div> + <div class="key margin-0 small" data-code="End"> + <div class="label">End + </div> + </div> + <div class="key margin-0 small" data-code="Delete"> + <div class="label">Del + </div> + </div> + </div> + <div class="keypad-row"> + <div class="key " data-code="Backquote"> + <div class="label">~<br>` + </div> + </div> + <div class="key " data-code="Digit1"> + <div class="label">!<br>1 + </div> + </div> + <div class="key " data-code="Digit2"> + <div class="label">@<br>2 + </div> + </div> + <div class="key " data-code="Digit3"> + <div class="label">#<br>3 + </div> + </div> + <div class="key " data-code="Digit4"> + <div class="label">$<br>4 + </div> + </div> + <div class="key " data-code="Digit5"> + <div class="label">%<br>5 + </div> + </div> + <div class="key " data-code="Digit6"> + <div class="label">^<br>6 + </div> + </div> + <div class="key " data-code="Digit7"> + <div class="label">&<br>7 + </div> + </div> + <div class="key " data-code="Digit8"> + <div class="label">*<br>8 + </div> + </div> + <div class="key " data-code="Digit9"> + <div class="label">(<br>9 + </div> + </div> + <div class="key " data-code="Digit0"> + <div class="label">)<br>0 + </div> + </div> + <div class="key " data-code="Minus"> + <div class="label">_<br>- + </div> + </div> + <div class="key " data-code="Equal"> + <div class="label">+<br>= + </div> + </div> + <div class="key wide-3 right" data-code="Backspace" style="width:101px"> + <div class="label">↤ + </div> + </div> + </div> + <div class="keypad-row"> + <div class="key wide-2 left" data-code="Tab"> + <div class="label">⇤<br>⇥ + </div> + </div> + <div class="key single" data-code="KeyQ"> + <div class="label">Q + </div> + </div> + <div class="key single" data-code="KeyW"> + <div class="label">W + </div> + </div> + <div class="key single" data-code="KeyE"> + <div class="label">E + </div> + </div> + <div class="key single" data-code="KeyR"> + <div class="label">R + </div> + </div> + <div class="key single" data-code="KeyT"> + <div class="label">T + </div> + </div> + <div class="key single" data-code="KeyY"> + <div class="label">Y + </div> + </div> + <div class="key single" data-code="KeyU"> + <div class="label">U + </div> + </div> + <div class="key single" data-code="KeyI"> + <div class="label">I + </div> + </div> + <div class="key single" data-code="KeyO"> + <div class="label">O + </div> + </div> + <div class="key single" data-code="KeyP"> + <div class="label">P + </div> + </div> + <div class="key " data-code="BracketLeft"> + <div class="label">{<br>[ + </div> + </div> + <div class="key " data-code="BracketRight"> + <div class="label">}<br>] + </div> + </div> + <div class="key wide-2 left" data-code="Backslash" style="width:78px"> + <div class="label">|<br>\ + </div> + </div> + </div> + <div class="keypad-row"> + <div class="key wide-3 left small" data-code="CapsLock"> + <div class="label"><img class="inline-lamp hid-keyboard-caps-led led-gray" src="/share/svg/led-square.svg"><br> Caps Lock + </div> + </div> + <div class="key single" data-code="KeyA"> + <div class="label">A + </div> + </div> + <div class="key single" data-code="KeyS"> + <div class="label">S + </div> + </div> + <div class="key single" data-code="KeyD"> + <div class="label">D + </div> + </div> + <div class="key single" data-code="KeyF"> + <div class="label">F + </div> + </div> + <div class="key single" data-code="KeyG"> + <div class="label">G + </div> + </div> + <div class="key single" data-code="KeyH"> + <div class="label">H + </div> + </div> + <div class="key single" data-code="KeyJ"> + <div class="label">J + </div> + </div> + <div class="key single" data-code="KeyK"> + <div class="label">K + </div> + </div> + <div class="key single" data-code="KeyL"> + <div class="label">L + </div> + </div> + <div class="key " data-code="Semicolon"> + <div class="label">:<br>; + </div> + </div> + <div class="key " data-code="Quote"> + <div class="label">`<br>' + </div> + </div> + <div class="key wide-4 right small" data-code="Enter" style="width:116px"> + <div class="label">Enter<br>↵ + </div> + </div> + </div> + <div class="keypad-row"> + <div class="modifier wide-4 left small" data-code="ShiftLeft"> + <div class="label"><b>•</b><br>Shift + </div> + </div> + <div class="key single" data-code="KeyZ"> + <div class="label">Z + </div> + </div> + <div class="key single" data-code="KeyX"> + <div class="label">X + </div> + </div> + <div class="key single" data-code="KeyC"> + <div class="label">C + </div> + </div> + <div class="key single" data-code="KeyV"> + <div class="label">V + </div> + </div> + <div class="key single" data-code="KeyB"> + <div class="label">B + </div> + </div> + <div class="key single" data-code="KeyN"> + <div class="label">N + </div> + </div> + <div class="key single" data-code="KeyM"> + <div class="label">M + </div> + </div> + <div class="key " data-code="Comma"> + <div class="label">lt;<br>, + </div> + </div> + <div class="key " data-code="Period"> + <div class="label">><br>. + </div> + </div> + <div class="key " data-code="Slash"> + <div class="label">?<br>/ + </div> + </div> + <div class="key small" data-code="PageUp"> + <div class="label">PgUp + </div> + </div> + <div class="key " data-code="ArrowUp"> + <div class="label">↑ + </div> + </div> + <div class="key small" data-code="PageDown"> + <div class="label">PgDn + </div> + </div> + </div> + <div class="keypad-row"> + <div class="modifier wide-1 left small" data-code="ControlLeft"> + <div class="label"><b>•</b><br>Ctrl + </div> + </div> + <div class="modifier wide-1 left small" data-code="MetaLeft"> + <div class="label"><b>•</b><br>Win + </div> + </div> + <div class="modifier wide-1 left small" data-code="AltLeft"> + <div class="label"><b>•</b><br>Alt + </div> + </div> + <div class="key " data-code="Space" style="width:190px"> + <div class="label"> + </div> + </div> + <div class="modifier right small" data-code="AltRight"> + <div class="label"><b>•</b><br>Alt + </div> + </div> + <div class="modifier right small" data-code="MetaRight"> + <div class="label"><b>•</b><br>Win + </div> + </div> + <div class="modifier right small" data-code="ShiftRight"> + <div class="label"><b>•</b><br>Shift + </div> + </div> + <div class="modifier right small" data-code="ControlRight"> + <div class="label"><b>•</b><br>Ctrl + </div> + </div> + <div class="key " data-code="ArrowLeft"> + <div class="label">← + </div> + </div> + <div class="key " data-code="ArrowDown"> + <div class="label">↓ + </div> + </div> + <div class="key " data-code="ArrowRight"> + <div class="label">→ + </div> + </div> + </div> + </div> + </div> + </div> + <div class="window" id="about-window"> + <div class="window-header"> + <div class="window-grab">About</div> + <button class="window-button-close">×</button> + </div> + <div id="about"> + <table> + <tr> + <td class="logo" valign="top"><img class="svg-gray" src="../share/svg/logo.svg" alt="Pi-KVM" height="40"></td> + <td valign="top"> + <table> + <tr> + <td class="title" colspan="2">The Open Source IP-KVM</td> + </tr> + <tr> + <td class="copyright" colspan="2">Copyright © 2018-2021 <a target="_blank" href="mailto:[email protected]">Maxim Devaev</a></td> + </tr> + </table> + </td> + </tr> + </table><br> + <div class="tabs-box"> + <input checked type="radio" name="about-tab-button" id="about-tab-meta-button"> + <label for="about-tab-meta-button">Meta</label> + <div class="tab"> + <div class="code" id="about-meta"><span class="code-comment">No data</span> + </div> + </div> + <input type="radio" name="about-tab-button" id="about-tab-hw-button"> + <label for="about-tab-hw-button">Hardware</label> + <div class="tab"> + <div class="code" id="about-hw"><span class="code-comment">No data</span> + </div> + </div> + <input type="radio" name="about-tab-button" id="about-tab-version-button"> + <label for="about-tab-version-button">Version</label> + <div class="tab"> + <div class="code" id="about-version"><span class="code-comment">No data</span> + </div> + </div> + <input type="radio" name="about-tab-button" id="about-tab-thanks-button"> + <label for="about-tab-thanks-button">Thanks</label> + <div class="tab"> + <div class="code" id="about-thanks"><span class="code-comment">// These kind people donated money to the Pi-KVM project<br> + // and supported the work on it. We are very grateful<br> + // for their help, and memorializing their names<br> + // is the least we can do in gratitude.<br> + // If you also want to support this project,<br> + // you can use one of these services: + <a target="_blank" href="https://www.patreon.com/pikvm">Patreon</a> + or <a target="_blank" href="https://www.paypal.me/mdevaev">PayPal</a>.</span> + <ul> + <li>A. Isenring</li> + <li>Aaron Heise</li> + <li>Accalia</li> + <li>adipisicing</li> + <li>Adrian Basham</li> + <li>Alberto Bassi</li> + <li>Aleksei Brusianskii</li> + <li>Alessio Curri</li> + <li>Alexandre Jablonski</li> + <li>Alucard</li> + <li>Andreas Marufke</li> + <li>Andrew Reusch</li> + <li>Andrew Ruan</li> + <li>Andrzej V</li> + <li>Anish Patel</li> + <li>Anix</li> + <li>anonymous</li> + <li>Anton Kovalenko</li> + <li>Aron Green</li> + <li>Aron Perelman</li> + <li>Arthur Woimbée</li> + <li>Ashlesh Chaudhari</li> + <li>Augusto Becciu</li> + <li>AVS Computer</li> + <li>baddog</li> + <li>Bao Tin Hoang</li> + <li>Belf Igor</li> + <li>Ben Gordon</li> + <li>Ben Scott</li> + <li>Benedikt Heine</li> + <li>Benjamin Melancon</li> + <li>Benni Stauder</li> + <li>Bernhard Fitzke</li> + <li>bitjoe</li> + <li>Bits and Bytes Computers LLC</li> + <li>Blue Frog LLC</li> + <li>Bootstrapper - Programmierung erklärt</li> + <li>Bosco</li> + <li>Bradford King</li> + <li>Brainspore Networks</li> + <li>Branden Shaulis</li> + <li>Brian Moses</li> + <li>Brian Vecchiarelli</li> + <li>Brian White</li> + <li>Bruno Gomes</li> + <li>Bryan Adams</li> + <li>C P ELSE</li> + <li>Cameron Tacklind</li> + <li>Carl Mercier</li> + <li>Carl-Fredrik Johansson</li> + <li>cbad536</li> + <li>Chris Burton</li> + <li>Chris Lewis</li> + <li>Chris Rizio</li> + <li>Christian Schlögl</li> + <li>Christian Svensson</li> + <li>Christof Maluck</li> + <li>Christoph Dette</li> + <li>Christoffer Lund</li> + <li>Christopher Mandlbaur</li> + <li>Chucktastic</li> + <li>Clifford Coleman</li> + <li>Clinton Lee Taylor</li> + <li>Cole Imhoff</li> + <li>Corey Layton</li> + <li>Corey Lista</li> + <li>Crossfactor</li> + <li>ctag</li> + <li>CyB0rgg</li> + <li>DeMentor</li> + <li>Desmond Whitt</li> + <li>Damon Meledones</li> + <li>Dan Berkowitz</li> + <li>Dan Brakeley</li> + <li>David</li> + <li>David Godibadze</li> + <li>David Howell</li> + <li>David Ye</li> + <li>David York</li> + <li>Denis</li> + <li>Denis Andreev</li> + <li>Denis Yatsenko</li> + <li>Dennis Becker</li> + <li>Derek Yap</li> + <li>Didrik</li> + <li>dixon wong</li> + <li>dizztrukshin</li> + <li>Dmitry Shilov</li> + <li>Egan Ford</li> + <li>Elliot Woo</li> + <li>Eric Phenix</li> + <li>ewook</li> + <li>eye-catcher.com</li> + <li>Fabiano Sidler</li> + <li>Far Pin Solutions, LLC</li> + <li>Felyx Gabryel</li> + <li>Fergus McKay</li> + <li>fo0bar</li> + <li>Foamy</li> + <li>Francisco Pavon</li> + <li>Frank</li> + <li>Frederick Czajka</li> + <li>Fredrik Idréus</li> + <li>Ge Men</li> + <li>Genkinger Andreas</li> + <li>Georgy Brodsky</li> + <li>Gernot Neuschröer</li> + <li>Glen Dragon</li> + <li>Gregory Smith</li> + <li>Gregory Treantos</li> + <li>Grey Cynic</li> + <li>Guido Bernacchi</li> + <li>Gustin Johnson</li> + <li>Heikki Tiittanen</li> + <li>Helio Leonardo Pinheiro e Mota</li> + <li>Henrik Ählström</li> + <li>Henry Hood</li> + <li>HimKo</li> + <li>HouseFPV</li> + <li>Icculus</li> + <li>iks</li> + <li>IT Lifesaver</li> + <li>Ivan Shapovalov</li> + <li>J L</li> + <li>Jaanus</li> + <li>Jackson Wyatt</li> + <li>Jacob Morgan</li> + <li>James Cadd</li> + <li>James Cobb</li> + <li>James Edwards</li> + <li>James Kocher</li> + <li>James Mayhugh</li> + <li>Jamie Murphy</li> + <li>Jan Niehusmann</li> + <li>Jari Hiltunen</li> + <li>Jason Downey</li> + <li>Jason Toland</li> + <li>Jay Davis</li> + <li>Jay Isaacs</li> + <li>Jean-Philippe Guilbault</li> + <li>Jeff Bowman</li> + <li>Jeff Urlwin</li> + <li>Jennifer Rowlett</li> + <li>Jerremy Holland</li> + <li>Joachim Bruening</li> + <li>Joe Ventura</li> + <li>Joel Jacobs</li> + <li>John Andersen</li> + <li>John F Glenn</li> + <li>John Kelley</li> + <li>John McGovern</li> + <li>Johnny Henson</li> + <li>Jonathan Vaughn</li> + <li>Jordi Pakey-Rodriguez</li> + <li>Joris van Embden</li> + <li>Josh Ricker</li> + <li>Joshua Futterer</li> + <li>Jozef Riha</li> + <li>Julian Forero</li> + <li>Justin Waters</li> + <li>Karl Dunne</li> + <li>Keith Muggleton</li> + <li>Ken Lee</li> + <li>Kenny Hui</li> + <li>Kevin Bajohr</li> + <li>Kevin Schwartz</li> + <li>Krzysztof Żelaśkiewicz</li> + <li>Lars</li> + <li>Lee Wilkinson</li> + <li>LeeNX</li> + <li>Lordbob75</li> + <li>Lothar Schweikle-Droll</li> + <li>Louis Müller</li> + <li>Lucio De Carli</li> + <li>Lukas Söder</li> + <li>Malcolm Cameron</li> + <li>Marcos Wolf</li> + <li>Mark Gilbert</li> + <li>Mark Robinson</li> + <li>Markrosoft</li> + <li>Markus Halm</li> + <li>Markus Schicker</li> + <li>Markus Sobczack</li> + <li>Marten Hermans</li> + <li>Martin Gasser</li> + <li>Mateusz Grabowski</li> + <li>Matthew Cameron</li> + <li>Mauricio Allende</li> + <li>Mehmet Aydoğdu</li> + <li>Michael Kovacs</li> + <li>Michael Lynch</li> + <li>Michael Pennington</li> + <li>Michael Sage</li> + <li>MichaelZ</li> + <li>Michel Bissonnette</li> + <li>Milan Múčka</li> + <li>Miles Davis</li> + <li>Moez Tharani</li> + <li>Morgan Helton</li> + <li>Nelson Lee</li> + <li>Nicholas Jeppson</li> + <li>Nicholas Kopas</li> + <li>Nick Leffler</li> + <li>Nick Roethemeier</li> + <li>Nicolai Kragh-Hansen</li> + <li>Nils Orbat</li> + <li>Nithin Philips</li> + <li>Nod Swal</li> + <li>nubbn</li> + <li>nybble</li> + <li>Oh Be</li> + <li>Oliver Schwarz</li> + <li>Oliver Zimmer</li> + <li>Patrick McDowell</li> + <li>Patrick Wagstrom</li> + <li>Paul Bishop</li> + <li>Pawel Trofimiuk</li> + <li>Peder Madsen</li> + <li>Peter Drayton</li> + <li>Peter Farrelly</li> + <li>Petri Heiskanen</li> + <li>Philip Merricks</li> + <li>posicat</li> + <li>pozitron03</li> + <li>Qteal</li> + <li>Quentin Peten</li> + <li>Ralph Borchers</li> + <li>Ranc1d</li> + <li>Richard Bernarts</li> + <li>Richard Fancher</li> + <li>Richard Freemantle</li> + <li>Richard Michael</li> + <li>Rob Tongue</li> + <li>Robin Gfatter</li> + <li>Rodion DENISYUK</li> + <li>Rohit Priyadarshi</li> + <li>Rolfs 3D UG</li> + <li>Ronald LeBaron</li> + <li>rotx</li> + <li>Russell Scott</li> + <li>Samed Ozoglu</li> + <li>Sameul Davies</li> + <li>Samuel Vetsch</li> + <li>Satish Alwani</li> + <li>Scott</li> + <li>Scott Spicola</li> + <li>Scott Tusing</li> + <li>Sean</li> + <li>Seonwoo Lee</li> + <li>Sergey Lukjanov</li> + <li>Shichun Chen</li> + <li>Simon Evans</li> + <li>Simon Sundgaard</li> + <li>Simplistic Realities</li> + <li>srepac</li> + <li>Stefan Bautz</li> + <li>Stefan Müller</li> + <li>Stefan Stemmer</li> + <li>Stephan Schmidt</li> + <li>Steve Kerr</li> + <li>Steve Ovens</li> + <li>Steven Richter</li> + <li>sudo34</li> + <li>Tarlak Desaydrone</li> + <li>Ted</li> + <li>Tejun Heo</li> + <li>TheTechGiant</li> + <li>Thomas Price</li> + <li>Thomas Søfteland</li> + <li>Tim Wilkinson</li> + <li>Timo Brinkmann</li> + <li>Timothee Besset</li> + <li>Tobias Schafferhans</li> + <li>Tom Lawson</li> + <li>Tom York</li> + <li>Tomas Kuchta</li> + <li>Tomáš hrubý</li> + <li>Tristan Schoening</li> + <li>Truman Kilen</li> + <li>turbochris</li> + <li>Tyler</li> + <li>Udo Schroeter</li> + <li>Uli Fahrer</li> + <li>Vasily Lazarev</li> + <li>Vicente Salvador Cubedo</li> + <li>Viktor Aschenbrenner</li> + <li>Viktor Ekmark</li> + <li>Walter_Ego</li> + <li>William Hooper</li> + <li>William Stearns</li> + <li>Yethal</li> + <li>Yevgeniy Kuksenko</li> + <li>Yigal Dar</li> + <li>Yogi</li> + <li>YURI LEE</li> + <li>Yurii Ostapchuk</li> + <li>zgen</li> + <li>Zsombor Vari</li> + </ul> + </div> + </div> + </div><br> + <p class="text"> + Full documentation, source code, hardware schematics and legal information + can be found in our <a target="_blank" href="https://pikvm.org">official website</a>. + </p> + </div> + </div> <ul class="footer"> <li class="footer-left" id="kvmd-meta-server-host"></li> <li class="footer-right"><a target="_blank" href="https://pikvm.org">Pi-KVM Project</a></li> diff --git a/web/kvm/navbar-system.pug b/web/kvm/navbar-system.pug index 26876cab..2f85416c 100644 --- a/web/kvm/navbar-system.pug +++ b/web/kvm/navbar-system.pug @@ -22,12 +22,6 @@ li(class="right") td Max FPS: td #[input(disabled type="range" id="stream-desired-fps-slider" class="slider")] td(id="stream-desired-fps-value" class="value") 0 - tr - td Stream size: - td #[input(type="range" id="stream-size-slider" class="slider")] - td(id="stream-size-value" class="value" style="width: 4em") 100% - hr - +menu_switch("stream-auto-resize-switch", "Auto-resize stream window", true, true) hr div(class="buttons buttons-row") button(data-force-hide-menu id="show-stream-button" class="row33") • Show stream diff --git a/web/kvm/window-about.pug b/web/kvm/window-about.pug index e841e17d..17d1c04b 100644 --- a/web/kvm/window-about.pug +++ b/web/kvm/window-about.pug @@ -9,7 +9,11 @@ mixin about_tab(name, title, checked=false) else span(class="code-comment") No data -+window("about-window", "About", false) +div(id="about-window" class="window") + div(class="window-header") + div(class="window-grab") About + button(class="window-button-close") × + div(id="about") table tr diff --git a/web/kvm/window-keyboard.pug b/web/kvm/window-keyboard.pug index 1354726c..986ca91f 100644 --- a/web/kvm/window-keyboard.pug +++ b/web/kvm/window-keyboard.pug @@ -15,7 +15,11 @@ mixin empty_key(width=0) mixin lamp(cls) img(class=`inline-lamp ${cls} led-gray` src=`${svg_dir}/led-square.svg`) -+window("keyboard-window", "Virtual Keyboard", true) +div(id="keyboard-window" class="window") + div(id="keyboard-window-header" class="window-header") + div(class="window-grab") Virtual Keyboard + button(class="window-button-close") × + div(id="keyboard-desktop" class="keypad" align="center") div(class="keypad-block") div(class="keypad-row") diff --git a/web/kvm/window-stream.pug b/web/kvm/window-stream.pug index 84f1d4dc..2595fe3b 100644 --- a/web/kvm/window-stream.pug +++ b/web/kvm/window-stream.pug @@ -1,10 +1,25 @@ - let confirm_msg = "Do you want to close the stream? This action will temporarily stop<br>"; - confirm_msg += "the video transmission until you open the broadcast again.<br>"; - confirm_msg += "This can be useful for saving traffic."; -+window("stream-window", "Stream", true, confirm_msg) + +div(id="stream-window" class="window window-resizable" data-close-confirm=confirm_msg) + div(id="stream-window-header" class="window-header") + div(class="window-grab") Stream + button(class="window-button-close") × + button(class="window-button-maximize") ☐ + button(class="window-button-full-screen") ⤢ + div(id="stream-info") + div(id="stream-box" class="stream-box-inactive") + div(class="window-lock-alert hidden") + | #[b Failed to acquire keyboard lock.#[br]Shortcuts like Alt+Tab, Ctrl+W, Ctrl+N might not be captured.]#[br] + | #[br] + | For best keyboard handling use a #[a(href="https://developer.mozilla.org/en-US/docs/Web/API/Keyboard_API#Browser_compatibility") browser with keyboard lock support API].#[br] + | In Chrome use HTTPS and enable #[i system-keyboard-lock] by putting at URL #[i chrome://flags/#system-keyboard-lock].#[br] + | More details on keyboard lock API are #[a(href="https://wicg.github.io/keyboard-lock/" target="_blank") here]. img(id="stream-image" class="stream-image-inactive" src=`${png_dir}/blank-stream.png`) + div(id="stream-mouse-buttons" class="keypad" align="center") div(class="keypad-block") div(class="keypad-row") diff --git a/web/kvm/windows.pug b/web/kvm/windows.pug index d735b65d..898a8562 100644 --- a/web/kvm/windows.pug +++ b/web/kvm/windows.pug @@ -1,10 +1,3 @@ -mixin window(id, title, with_header_id=false, close_confirm_msg="") - div(id=id class="window" data-close-confirm=close_confirm_msg) - div(id=(with_header_id ? `${id}-header` : "") class="window-header") - div(class="window-grab") #{title} - button(class="window-button-close") × - block - include window-stream.pug include window-keyboard.pug include window-about.pug diff --git a/web/share/css/kvm/stream.css b/web/share/css/kvm/stream.css index 189867a7..cd202eea 100644 --- a/web/share/css/kvm/stream.css +++ b/web/share/css/kvm/stream.css @@ -20,11 +20,19 @@ *****************************************************************************/ +div#stream-window { + min-width: 400px; + min-height: 200px; +} + div#stream-info { display: none; } div#stream-box { + width: 100%; + height: 100%; + object-fit: contain; position: relative; display: inline-block; border: var(--border-window-thin); @@ -45,8 +53,9 @@ div.stream-box-mouse-enabled { } img#stream-image { - width: 640px; - height: 480px; + width: 100%; + height: 100%; + object-fit: contain; display: block; background-color: black; } @@ -69,9 +78,12 @@ div#stream-mouse-buttons { div#stream-window { padding-top: 3px !important; border-top: 0 !important; - border-radius: 0 0 8px 8px !important; + border-left: 0 !important; + border-right: 0 !important; + border-radius: 0 !important; top: 50px !important; left: 50% !important; + width: 100% !important; -webkit-transform: translateX(-50%) !important; transform: translateX(-50%) !important; } diff --git a/web/share/css/vars.css b/web/share/css/vars.css index bec1f10e..f49f40cc 100644 --- a/web/share/css/vars.css +++ b/web/share/css/vars.css @@ -66,6 +66,8 @@ --cs-key-pressed-fg: #6c7481; --cs-key-holded-bg: #436a8a; + --cs-corner-bg: #5b90bb; + --shadow-micro: 1px 2px 4px 0 rgba(0, 0, 0, 0.4); --shadow-small: 0 2px 4px 0 rgba(0, 0, 0, 0.2); --shadow-big: 0 8px 16px 0 rgba(0, 0, 0, 0.4); diff --git a/web/share/css/window.css b/web/share/css/window.css index 3af2eb0c..e50db8ba 100644 --- a/web/share/css/window.css +++ b/web/share/css/window.css @@ -34,9 +34,31 @@ div.window { background-color: var(--cs-window-default-bg); padding: 30px 9px 9px 9px; } +div.window-resizable { + resize: both; +} div.window-active { border: var(--border-intensive-2px) !important; } +div.window-resizable.window-active::-webkit-resizer { + width: 0; + height: 0; + border-style: solid; + border-width: 0 0 20px 20px; + border-color: transparent transparent var(--cs-corner-bg) transparent; + /* border-bottom-right-radius: 8px; */ + /* Size does not work */ + display:block; + width: 20px !important; + height: 20px !important; +} +div.window-full-screen { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} div.window div.window-header { overflow: hidden; @@ -68,17 +90,43 @@ div.window div.window-header-grabbed { border-bottom: var(--border-intensive-thin); } +div.window div.window-header button.window-button-full-screen, +div.window div.window-header button.window-button-maximize, div.window div.window-header button.window-button-close { border: none; position: absolute; top: -2px; - right: -6px; width: 44px; height: 24px; padding-left: 0; + padding-right: 0; color: var(--cs-window-closer-default-fg); display: inline-block; } +div.window div.window-header button.window-button-full-screen { + right: 90px; +} +div.window div.window-header button.window-button-close { + right: 0px; +} +div.window div.window-header button.window-button-maximize { + right: 45px; +} + +div.window div.window-lock-alert { + white-space: normal; + text-align: justify; + border: var(--border-window-thin); + border-radius: 8px; + box-sizing: border-box; + padding: 5px 5px 5px 5px; + background-color: var(--cs-window-default-bg); + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + z-index: 10000; +} @media only screen and (min-device-width: 768px) and (max-device-width: 1024px) { /* iPad */ @@ -91,6 +139,7 @@ div.window div.window-header button.window-button-close { div.window div.window-header div.window-grab { height: 35px !important; } + div.window div.window-header button.window-button-full-screen, div.window div.window-header button.window-button-close { height: 40px !important; } diff --git a/web/share/js/keypad.js b/web/share/js/keypad.js index 554e43cf..23ed0620 100644 --- a/web/share/js/keypad.js +++ b/web/share/js/keypad.js @@ -138,7 +138,7 @@ export function Keypad(keys_parent, key_callback) { var __isPressed = function(el_key) { let is_pressed = false; let el_keys = __resolveKeys(el_key); - for (let el_key of el_keys) { + for (el_key of el_keys) { is_pressed = (is_pressed || el_key.classList.contains("pressed")); } return is_pressed; @@ -147,7 +147,7 @@ export function Keypad(keys_parent, key_callback) { var __isHolded = function(el_key) { let is_holded = false; let el_keys = __resolveKeys(el_key); - for (let el_key of el_keys) { + for (el_key of el_keys) { is_holded = (is_holded || el_key.classList.contains("holded")); } return is_holded; @@ -156,7 +156,7 @@ export function Keypad(keys_parent, key_callback) { var __isActive = function(el_key) { let is_active = false; let el_keys = __resolveKeys(el_key); - for (let el_key of el_keys) { + for (el_key of el_keys) { is_active = (is_active || el_key.classList.contains("pressed") || el_key.classList.contains("holded")); } return is_active; @@ -164,14 +164,14 @@ export function Keypad(keys_parent, key_callback) { var __activate = function(el_key, cls) { let el_keys = __resolveKeys(el_key); - for (let el_key of el_keys) { + for (el_key of el_keys) { el_key.classList.add(cls); } }; var __deactivate = function(el_key) { let el_keys = __resolveKeys(el_key); - for (let el_key of el_keys) { + for (el_key of el_keys) { el_key.classList.remove("pressed"); el_key.classList.remove("holded"); } diff --git a/web/share/js/kvm/mouse.js b/web/share/js/kvm/mouse.js index 3ac7935e..2893a5ae 100644 --- a/web/share/js/kvm/mouse.js +++ b/web/share/js/kvm/mouse.js @@ -40,8 +40,8 @@ export function Mouse(record_callback) { var __keypad = null; - var __current_pos = {x: 0, y:0}; - var __sent_pos = {x: 0, y:0}; + var __current_pos = {x: 0, y: 0}; + var __sent_pos = {x: 0, y: 0}; var __wheel_delta = {x: 0, y: 0}; var __relative_deltas = []; @@ -210,15 +210,16 @@ export function Mouse(record_callback) { if (__absolute) { let pos = __current_pos; if (pos.x !== __sent_pos.x || pos.y !== __sent_pos.y) { - let el_stream_image = $("stream-image"); - let to = { - x: __translate(pos.x, 0, el_stream_image.clientWidth, -32768, 32767), - y: __translate(pos.y, 0, el_stream_image.clientHeight, -32768, 32767), - }; - - tools.debug("Mouse: moved:", to); - __sendEvent("mouse_move", {"to": to}); - __sent_pos = pos; + let geometry = $("stream-box").stream_geometry; + if (geometry) { + let to = { + x: __translate(pos.x, geometry.x, geometry.width, -32768, 32767), + y: __translate(pos.y, geometry.y, geometry.height, -32768, 32767), + }; + tools.debug("Mouse: moved:", to); + __sendEvent("mouse_move", {"to": to}); + __sent_pos = pos; + } } } else if (__relative_deltas.length) { tools.debug("Mouse: relative:", __relative_deltas); @@ -228,7 +229,13 @@ export function Mouse(record_callback) { }; var __translate = function(x, a, b, c, d) { - return Math.round((x - a) / (b - a) * (d - c) + c); + let translated = Math.round((x - a) / b * (d - c) + c); + if (translated < c) { + return c; + } else if (translated > d) { + return d; + } + return translated; }; var __streamWheelHandler = function(event) { diff --git a/web/share/js/kvm/session.js b/web/share/js/kvm/session.js index 2e4c4f6d..5aa0a6a0 100644 --- a/web/share/js/kvm/session.js +++ b/web/share/js/kvm/session.js @@ -47,7 +47,7 @@ export function Session() { var __hid = new Hid(); var __atx = new Atx(); var __msd = new Msd(); - var __streamer = new Streamer(); + var __streamer = new Streamer(__hid); var __wol = new WakeOnLan(); var __gpio = new Gpio(); diff --git a/web/share/js/kvm/stream.js b/web/share/js/kvm/stream.js index 83e3c4d4..2db37608 100644 --- a/web/share/js/kvm/stream.js +++ b/web/share/js/kvm/stream.js @@ -34,8 +34,6 @@ export function Streamer() { var __resolution = {width: 640, height: 480}; - var __size_factor = 1; - var __mjpeg_key = tools.makeId(); var __mjpeg_id = ""; var __mjpeg_fps = -1; @@ -53,10 +51,6 @@ export function Streamer() { $("stream-resolution-selector").onchange = (() => __sendParam("resolution", $("stream-resolution-selector").value)); - tools.sliderSetParams($("stream-size-slider"), 20, 200, 5, 100); - $("stream-size-slider").oninput = () => __resize(); - $("stream-size-slider").onchange = () => __resize(); - tools.setOnClick($("stream-screenshot-button"), __clickScreenshotButton); tools.setOnClick($("stream-reset-button"), __clickResetButton); @@ -65,6 +59,7 @@ export function Streamer() { self.setState(__state_for_invisible); } }; + $("stream-window").resize_hook = __resizeHook; }; /************************************************************************/ @@ -88,6 +83,11 @@ export function Streamer() { } if (state && state.streamer) { + if (!window.ResizeObserver) { + // Browsers that don't support this API(on lower versions of iOS for example) + __resizeHook(); + } + if (!$("stream-quality-slider").activated) { wm.setElementEnabled($("stream-quality-slider"), true); if ($("stream-quality-slider").value !== state.streamer.encoder.quality) { @@ -107,13 +107,8 @@ export function Streamer() { } let resolution_str = __makeStringResolution(state.streamer.source.resolution); - if (__makeStringResolution(__resolution) != resolution_str) { + if (__makeStringResolution(__resolution) !== resolution_str) { __resolution = state.streamer.source.resolution; - if ($("stream-auto-resize-switch").checked) { - __adjustSizeFactor(); - } else { - __applySizeFactor(); - } } if (state.features.resolution) { @@ -260,40 +255,17 @@ export function Streamer() { }); }; - var __resize = function() { - let size = $("stream-size-slider").value; - $("stream-size-value").innerHTML = `${size}%`; - __size_factor = size / 100; - __applySizeFactor(); - }; - - var __adjustSizeFactor = function() { - let el_window = $("stream-window"); - let el_slider = $("stream-size-slider"); - let view = wm.getViewGeometry(); - - for (let size = 100; size >= el_slider.min; size -= el_slider.step) { - tools.info("Stream: adjusting size:", size); - $("stream-size-slider").value = size; - __resize(); - - let rect = el_window.getBoundingClientRect(); - if ( - rect.bottom <= view.bottom - && rect.top >= view.top - && rect.left >= view.left - && rect.right <= view.right - ) { - break; - } - } - }; - - var __applySizeFactor = function() { - let el = $("stream-image"); - el.style.width = __resolution.width * __size_factor + "px"; - el.style.height = __resolution.height * __size_factor + "px"; - wm.showWindow($("stream-window"), false); + var __resizeHook = function() { + let rect = $("stream-image").getBoundingClientRect(); + let width = $("stream-image").naturalWidth; + let height = $("stream-image").naturalHeight; + let ratio = Math.min(rect.width / width, rect.height / height); + $("stream-box").stream_geometry = { + "x": Math.round((rect.width - ratio * width) / 2), + "y": Math.round((rect.height - ratio * height) / 2), + "width": Math.round(ratio * width), + "height": Math.round(ratio * height), + }; }; var __makeStringResolution = function(resolution) { diff --git a/web/share/js/tools.js b/web/share/js/tools.js index d6965803..521cb1a0 100644 --- a/web/share/js/tools.js +++ b/web/share/js/tools.js @@ -243,5 +243,5 @@ export var tools = new function() { }; export var $ = (id) => document.getElementById(id); -export var $$ = (cls) => document.getElementsByClassName(cls); +export var $$ = (cls) => [].slice.call(document.getElementsByClassName(cls)); export var $$$ = (selector) => document.querySelectorAll(selector); diff --git a/web/share/js/wm.js b/web/share/js/wm.js index f879e3e8..49e79ecb 100644 --- a/web/share/js/wm.js +++ b/web/share/js/wm.js @@ -54,14 +54,37 @@ function __WindowManager() { __menu_buttons.push(el_button); } + if (!window.ResizeObserver) { + tools.error("ResizeObserver not supported"); + } + for (let el_window of $$("window")) { el_window.setAttribute("tabindex", "-1"); __makeWindowMovable(el_window); __windows.push(el_window); - let el_button = el_window.querySelector(".window-header .window-button-close"); - if (el_button) { - tools.setOnClick(el_button, function() { + if (el_window.classList.contains("window-resizable") && window.ResizeObserver) { + new ResizeObserver(function() { + // При переполнении рабочей области сократить размер окна по высоте. + // По ширине оно настраивается само в CSS. + let view = self.getViewGeometry(); + let rect = el_window.getBoundingClientRect(); + if ((rect.bottom - rect.top) > (view.bottom - view.top)) { + el_window.style.height = view.bottom - view.top + "px"; + } + + if (el_window.hasAttribute("data-centered")) { + __centerWindow(el_window); + } + if (el_window.resize_hook) { + el_window.resize_hook(); + } + }).observe(el_window); + } + + let el_close_button = el_window.querySelector(".window-header .window-button-close"); + if (el_close_button) { + tools.setOnClick(el_close_button, function() { let close_window = function() { __closeWindow(el_window); __activateLastWindow(el_window); @@ -78,6 +101,22 @@ function __WindowManager() { } }); } + + let el_maximize_button = el_window.querySelector(".window-header .window-button-maximize"); + if (el_maximize_button) { + tools.setOnClick(el_maximize_button, function() { + __maximizeWindow(el_window); + __activateLastWindow(el_window); + }); + } + + let el_full_screen_button = el_window.querySelector(".window-header .window-button-full-screen"); + if (el_full_screen_button) { + tools.setOnClick(el_full_screen_button, function() { + __fullScreenWindow(el_window); + __activateLastWindow(el_window); + }); + } } window.onmouseup = __globalMouseButtonHandler; @@ -86,8 +125,10 @@ function __WindowManager() { window.addEventListener("focusin", __focusIn); window.addEventListener("focusout", __focusOut); - window.addEventListener("resize", __organizeWindowsOnResize); - window.addEventListener("orientationchange", __organizeWindowsOnResize); + window.addEventListener("resize", __organizeWindowsOnBrowserResize); + window.addEventListener("orientationchange", __organizeWindowsOnBrowserResize); + + document.onfullscreenchange = __onFullScreenChange; }; /************************************************************************/ @@ -205,7 +246,7 @@ function __WindowManager() { if (activate) { __activateWindow(el_window); } - if (Object.prototype.hasOwnProperty.call(el_window, "show_hook")) { + if (el_window.show_hook) { if (showed) { el_window.show_hook(); } @@ -239,7 +280,7 @@ function __WindowManager() { let el_menu = el_button.parentElement.querySelector(".menu"); if (el_button === el_a && window.getComputedStyle(el_menu, null).visibility === "hidden") { let rect = el_menu.getBoundingClientRect(); - let offset = self.getViewGeometry().right - (rect.x + el_menu.clientWidth + 2); // + 2 is ugly hack + let offset = self.getViewGeometry().right - (rect.left + el_menu.clientWidth + 2); // + 2 is ugly hack if (offset < 0) { el_menu.style.right = "0px"; } else { @@ -319,7 +360,7 @@ function __WindowManager() { } }; - var __organizeWindowsOnResize = function() { + var __organizeWindowsOnBrowserResize = function() { for (let el_window of $$("window")) { if (el_window.style.visibility === "visible") { __organizeWindow(el_window); @@ -331,10 +372,19 @@ function __WindowManager() { let view = self.getViewGeometry(); let rect = el_window.getBoundingClientRect(); + if (el_window.classList.contains("window-resizable")) { + // При переполнении рабочей области сократить размер окна + if ((rect.bottom - rect.top) > (view.bottom - view.top)) { + el_window.style.height = view.bottom - view.top + "px"; + } + if ((rect.right - rect.left) > (view.right - view.left)) { + el_window.style.width = view.right - view.left + "px"; + } + rect = el_window.getBoundingClientRect(); + } + if (el_window.hasAttribute("data-centered") || center) { - el_window.style.top = Math.max(view.top, Math.round((view.bottom - rect.height) / 2)) + "px"; - el_window.style.left = Math.round((view.right - rect.width) / 2) + "px"; - el_window.setAttribute("data-centered", ""); + __centerWindow(el_window); } else { if (rect.top <= view.top) { el_window.style.top = view.top + "px"; @@ -350,6 +400,14 @@ function __WindowManager() { } }; + var __centerWindow = function(el_window) { + let view = self.getViewGeometry(); + let rect = el_window.getBoundingClientRect(); + el_window.style.top = Math.max(view.top, Math.round((view.bottom - rect.height) / 2)) + "px"; + el_window.style.left = Math.round((view.right - rect.width) / 2) + "px"; + el_window.setAttribute("data-centered", ""); + }; + var __activateLastWindow = function(el_except_window=null) { let el_last_window = null; @@ -415,6 +473,10 @@ function __WindowManager() { let prev_pos = {x: 0, y: 0}; function startMoving(event) { + // При перетаскивании resizable-окна за правый кран экрана оно ужимается. + // Этот костыль фиксит это. + el_window.style.width = el_window.offsetWidth + "px"; + __closeAllMenues(); __activateWindow(el_window); event = (event || window.event); @@ -474,5 +536,45 @@ function __WindowManager() { el_grab.ontouchstart = startMoving; }; + var __onFullScreenChange = function(event) { + let el_window = event.target; + if (!document.fullscreenElement) { + el_window.style.padding = ""; + let rect = el_window.before_full_screen; + if (rect) { + el_window.style.width = rect.width + "px"; + el_window.style.height = rect.height + "px"; + el_window.style.top = rect.top + "px"; + el_window.style.left = rect.left + "px"; + } + } else { + el_window.style.padding = "0px 0px 0px 0px"; + } + }; + + var __fullScreenWindow = function(el_window) { + el_window.before_full_screen = el_window.getBoundingClientRect(); + el_window.requestFullscreen(); + if ("keyboard" in navigator && "lock" in navigator.keyboard) { + navigator.keyboard.lock(); + } else { + let el_lock_alert = el_window.querySelector(".window-lock-alert"); + if (el_lock_alert) { + tools.hiddenSetVisible(el_lock_alert, true); + setTimeout(function() { + tools.hiddenSetVisible(el_lock_alert, false); + }, 7000); + } + } + }; + + var __maximizeWindow = function(el_window) { + let vertical_offset = $("navbar").offsetHeight; + el_window.style.left = "0px"; + el_window.style.top = vertical_offset + "px"; + el_window.style.width = window.innerWidth + "px"; + el_window.style.height = window.innerHeight - vertical_offset + "px"; + }; + __init__(); } |