From 3cfcc5cdd313829b91c1772e2566efb0ca270bfe Mon Sep 17 00:00:00 2001 From: Zoran Regvart Date: Tue, 20 Oct 2026 17:44:33 +0200 Subject: [PATCH] client: option to lock the keyboard When entering full screen mode and if the check box to lock the keyboard has been checked, all keyboard events will be sent to the client. For example when connecting to a Windows machine Win+R would open the Run dialog on the remote machine, not on the local. --- static/client.html | 61 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 7 deletions(-) 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');