diff --git a/static/client.html b/static/client.html index d1db3e9..6131c22 100644 --- a/static/client.html +++ b/static/client.html @@ -674,6 +674,7 @@ var clipboardPanel = null; var clipboardTextarea = null; var clipboardStatusEl = null; + var lockKeyboardCheckbox = null; function setClipboardStatus(msg) { if (!clipboardStatusEl) return; @@ -691,11 +692,16 @@ clipboardPanel.style.cssText = 'display:none;position:fixed;top:0;left:0;bottom:0;width:380px;background:var(--bg);border-right:2px solid var(--primary);z-index:3000;font-family:monospace;color:var(--text);flex-direction:column;'; clipboardPanel.innerHTML = - '
' + - '

Session

' + - '' + - '' + - '' + + '
' + + '
' + + '

Session

' + + '' + + '
' + + '
' + + '' + + '' + + '' + + '
' + '
' + '
' + '
Shared clipboard. Paste text below and click Send, or copy text received from the remote session.
' + @@ -712,6 +718,14 @@ document.body.appendChild(clipboardPanel); clipboardTextarea = document.getElementById('cp-text'); clipboardStatusEl = document.getElementById('cp-status'); + lockKeyboardCheckbox = document.getElementById('cp-lock-keyboard'); + if (!navigator.keyboard || !navigator.keyboard.lock) { + lockKeyboardCheckbox.disabled = true; + lockKeyboardCheckbox.title = 'Keyboard Lock is not supported by this browser.'; + } + lockKeyboardCheckbox.addEventListener('change', function() { + rgRequestKeyboardLock(lockKeyboardCheckbox.checked); + }); document.getElementById('cp-close').addEventListener('click', function() { toggleClipboardPanel(); @@ -1611,11 +1625,44 @@ // (e.g. no user activation on load): the caller decides whether to // wait for a gesture or give up and show the windowed session. var fsKeyboardLocked = false; + function rgRequestKeyboardLock(lockAll) { + if (!navigator.keyboard || !navigator.keyboard.lock) { + if (lockKeyboardCheckbox) lockKeyboardCheckbox.checked = false; + setClipboardStatus('Keyboard Lock is not supported by this browser.'); + return; + } + if (!rgFullscreenEl()) { + setClipboardStatus(lockAll + ? 'Keyboard lock will apply when fullscreen is entered.' + : 'Keyboard lock applies only in fullscreen.'); + return; + } + var request; + try { + request = lockAll + ? navigator.keyboard.lock() + : navigator.keyboard.lock(['Escape']); + } catch (e) { + if (lockAll && lockKeyboardCheckbox) lockKeyboardCheckbox.checked = false; + setClipboardStatus('Could not lock the keyboard.'); + if (!lockAll) rgShowEscNoticeOnce(); + return; + } + request.then(function() { + if (lockKeyboardCheckbox) { + setClipboardStatus(lockAll ? 'Keyboard locked.' : 'Additional keyboard lock disabled.'); + } + }).catch(function() { + if (lockAll && lockKeyboardCheckbox) lockKeyboardCheckbox.checked = false; + setClipboardStatus('Could not lock the keyboard.'); + if (!lockAll) rgShowEscNoticeOnce(); + }); + } function rgOnFullscreenEntered() { if (fsKeyboardLocked) return; fsKeyboardLocked = true; if (navigator.keyboard && navigator.keyboard.lock) { - navigator.keyboard.lock(['Escape']).catch(rgShowEscNoticeOnce); + rgRequestKeyboardLock(!!(lockKeyboardCheckbox && lockKeyboardCheckbox.checked)); } else { rgShowEscNoticeOnce(); } @@ -1774,7 +1821,7 @@ function rgOnFullscreenChange() { var inFs = !!rgFullscreenEl(); var bar = document.getElementById('fs-bar'); - if (inFs) { fsEverEntered = true; rgDisarmFullscreenGesture(); rgOnFullscreenEntered(); rgReleaseAllInput(); rgMaybeReveal(); } else { rgHideConnectCover(); } + if (inFs) { fsEverEntered = true; rgDisarmFullscreenGesture(); rgOnFullscreenEntered(); rgReleaseAllInput(); rgMaybeReveal(); } else { fsKeyboardLocked = false; rgHideConnectCover(); } if (bar) { if (inFs) { bar.classList.add('visible');