mirror of
https://github.com/sol1/rustguac.git
synced 2026-10-25 13:09:56 +00:00
client: lock all keys from the Controls panel, remembered per browser
Follows #319. The option moves out of the Session panel header into the Controls panel's new Keyboard section, beside View, and is remembered in the browser like the View choice. The lock follows the setting whenever fullscreen is entered, and switching it while fullscreen applies at once. Browsers without the Keyboard Lock API show it disabled with a note.
This commit is contained in:
+42
-50
@@ -674,7 +674,6 @@
|
||||
var clipboardPanel = null;
|
||||
var clipboardTextarea = null;
|
||||
var clipboardStatusEl = null;
|
||||
var lockKeyboardCheckbox = null;
|
||||
|
||||
function setClipboardStatus(msg) {
|
||||
if (!clipboardStatusEl) return;
|
||||
@@ -692,16 +691,11 @@
|
||||
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 =
|
||||
'<div style="padding:0.65em 1em;border-bottom:1px solid var(--border);background:var(--surface);">' +
|
||||
'<div style="display:flex;align-items:center;gap:0.6em;margin-bottom:0.65em;">' +
|
||||
'<h3 style="margin:0;flex:1;color:var(--primary);font-size:1.1em;">Session</h3>' +
|
||||
'<button id="cp-close" style="background:none;border:none;color:var(--text-dim);font-size:1.6em;cursor:pointer;font-family:monospace;padding:0 0.3em;">×</button>' +
|
||||
'</div>' +
|
||||
'<div style="display:flex;align-items:stretch;gap:0.45em;">' +
|
||||
'<button id="cp-home" style="flex:1;min-width:0;display:flex;align-items:center;justify-content:center;gap:0.35em;background:var(--input);border:1px solid var(--border);color:var(--accent);font-family:monospace;font-size:0.85em;padding:0.5em 0.35em;border-radius:3px;cursor:pointer;" title="Return to the Connections page">🏠 Home</button>' +
|
||||
'<button id="cp-fullscreen" style="flex:1;min-width:0;display:flex;align-items:center;justify-content:center;gap:0.35em;background:var(--input);border:1px solid var(--border);color:var(--accent);font-family:monospace;font-size:0.85em;padding:0.5em 0.35em;border-radius:3px;cursor:pointer;" title="Enter fullscreen">⛶ Fullscreen</button>' +
|
||||
'<label style="flex:1.25;min-width:0;display:flex;align-items:center;justify-content:center;gap:0.4em;white-space:nowrap;background:var(--input);border:1px solid var(--border);color:var(--accent);font-family:monospace;font-size:0.8em;padding:0.5em 0.35em;border-radius:3px;cursor:pointer;" title="Lock keyboard while in fullscreen"><input id="cp-lock-keyboard" type="checkbox" style="margin:0;accent-color:var(--accent);"> Lock keyboard</label>' +
|
||||
'</div>' +
|
||||
'<div style="display:flex;align-items:center;gap:0.6em;padding:0.8em 1em;border-bottom:1px solid var(--border);background:var(--surface);">' +
|
||||
'<h3 style="margin:0;flex:1;color:var(--primary);font-size:1.1em;">Session</h3>' +
|
||||
'<button id="cp-home" style="background:var(--input);border:1px solid var(--border);color:var(--accent);font-family:monospace;font-size:0.9em;padding:0.35em 0.8em;border-radius:3px;cursor:pointer;" title="Return to the Connections page">🏠 Home</button>' +
|
||||
'<button id="cp-fullscreen" style="background:var(--input);border:1px solid var(--border);color:var(--accent);font-family:monospace;font-size:0.9em;padding:0.35em 0.8em;border-radius:3px;cursor:pointer;" title="Enter fullscreen">⛶ Fullscreen</button>' +
|
||||
'<button id="cp-close" style="background:none;border:none;color:var(--text-dim);font-size:1.6em;cursor:pointer;font-family:monospace;padding:0 0.3em;">×</button>' +
|
||||
'</div>' +
|
||||
'<div style="flex:1;display:flex;flex-direction:column;padding:1em;gap:0.8em;overflow-y:auto;min-height:0;">' +
|
||||
'<div style="color:var(--text-muted);font-size:0.95em;">Shared clipboard. Paste text below and click Send, or copy text received from the remote session.</div>' +
|
||||
@@ -718,14 +712,6 @@
|
||||
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();
|
||||
@@ -959,6 +945,11 @@
|
||||
'<div style="color:var(--text-muted);font-size:0.85em;margin-bottom:0.5em;letter-spacing:0.05em;">SEND KEYS</div>' +
|
||||
'<div id="ctrl-keys" style="display:flex;flex-wrap:wrap;gap:0.4em;"></div>' +
|
||||
'</div>' +
|
||||
'<div style="padding:0.8em 1em;border-top:1px solid var(--border);">' +
|
||||
'<div style="color:var(--text-muted);font-size:0.85em;margin-bottom:0.5em;letter-spacing:0.05em;">KEYBOARD</div>' +
|
||||
'<label style="display:flex;align-items:center;gap:0.5em;padding:0.25em 0;font-size:0.9em;cursor:pointer;"><input type="checkbox" id="ctrl-lock-keys"><span>Lock all keys in fullscreen</span></label>' +
|
||||
'<div id="ctrl-lock-keys-hint" style="color:var(--text-dim);font-size:0.75em;margin-top:0.4em;">In fullscreen, Win, Alt+Tab and other shortcuts go to the remote desktop instead of this computer. Hold Esc to leave fullscreen.</div>' +
|
||||
'</div>' +
|
||||
'<div style="padding:0.8em 1em;border-top:1px solid var(--border);">' +
|
||||
'<div style="color:var(--text-muted);font-size:0.85em;margin-bottom:0.5em;letter-spacing:0.05em;">VIEW</div>' +
|
||||
'<label style="display:flex;align-items:center;gap:0.5em;padding:0.25em 0;font-size:0.9em;cursor:pointer;"><input type="radio" name="ctrl-view" id="ctrl-view-fit" value="fit"><span>Fit to window</span></label>' +
|
||||
@@ -979,6 +970,14 @@
|
||||
b.addEventListener('click', function() { sendKeyCombo(k.keys); });
|
||||
keysEl.appendChild(b);
|
||||
});
|
||||
var lockKeys = document.getElementById('ctrl-lock-keys');
|
||||
lockKeys.checked = lockAllKeys;
|
||||
if (!rgKeyboardLockSupported()) {
|
||||
lockKeys.checked = false;
|
||||
lockKeys.disabled = true;
|
||||
document.getElementById('ctrl-lock-keys-hint').textContent = 'This browser can\'t capture system shortcuts. Chrome and Edge can.';
|
||||
}
|
||||
lockKeys.addEventListener('change', function() { rgSetLockAllKeys(lockKeys.checked); });
|
||||
document.getElementById('ctrl-view-' + viewMode).checked = true;
|
||||
['fit', 'actual'].forEach(function(m) {
|
||||
document.getElementById('ctrl-view-' + m).addEventListener('change', function(e) {
|
||||
@@ -1626,47 +1625,40 @@
|
||||
// (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;
|
||||
}
|
||||
// Lock all keys (#319): in fullscreen, send Win, Alt+Tab and the
|
||||
// like to the remote desktop instead of this computer. Off, only
|
||||
// Escape is locked, so a single press doesn't leave fullscreen.
|
||||
// Remembered per browser; set from the Controls panel.
|
||||
var lockAllKeys = false;
|
||||
try { lockAllKeys = localStorage.getItem('rustguac_lock_all_keys') === '1'; } catch (e) {}
|
||||
function rgKeyboardLockSupported() {
|
||||
return !!(navigator.keyboard && navigator.keyboard.lock);
|
||||
}
|
||||
function rgSetLockAllKeys(on) {
|
||||
lockAllKeys = !!on;
|
||||
try {
|
||||
if (lockAllKeys) localStorage.setItem('rustguac_lock_all_keys', '1');
|
||||
else localStorage.removeItem('rustguac_lock_all_keys');
|
||||
} catch (e) {}
|
||||
if (rgFullscreenEl()) rgRequestKeyboardLock();
|
||||
}
|
||||
function rgRequestKeyboardLock() {
|
||||
if (!rgKeyboardLockSupported()) { rgShowEscNoticeOnce(); return; }
|
||||
var lockAll = lockAllKeys;
|
||||
var request;
|
||||
try {
|
||||
request = lockAll
|
||||
? navigator.keyboard.lock()
|
||||
: navigator.keyboard.lock(['Escape']);
|
||||
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 = Promise.reject(e);
|
||||
}
|
||||
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.');
|
||||
request.catch(function() {
|
||||
if (!lockAll) rgShowEscNoticeOnce();
|
||||
});
|
||||
}
|
||||
function rgOnFullscreenEntered() {
|
||||
if (fsKeyboardLocked) return;
|
||||
fsKeyboardLocked = true;
|
||||
if (navigator.keyboard && navigator.keyboard.lock) {
|
||||
rgRequestKeyboardLock(!!(lockKeyboardCheckbox && lockKeyboardCheckbox.checked));
|
||||
} else {
|
||||
rgShowEscNoticeOnce();
|
||||
}
|
||||
rgRequestKeyboardLock();
|
||||
}
|
||||
function rgEnterFullscreen(onReject) {
|
||||
var el = document.documentElement;
|
||||
|
||||
Reference in New Issue
Block a user