mirror of
https://github.com/sol1/rustguac.git
synced 2026-09-10 01:26:06 +00:00
fix(client): move fullscreen control into session menu (#156)
The v1.7.2 floating "⛶ Fullscreen" corner button at 0.45 opacity was still 80px of permanent clutter in the top-right of the remote session display before fullscreen was entered. This PR moves the manual fullscreen action into the existing Ctrl+Alt+Shift session-menu panel (next to the Home button), removing the floating overlay entirely. The per-entry `fullscreen_on_connect` flag and the in-fullscreen top bar (entry name + Exit + Disconnect) are unchanged. Esc-key forwarding via navigator.keyboard.lock still applies. Also adds an "In-session keyboard shortcuts" section to docs/web-sessions.md documenting the Ctrl+Alt+Shift panel toggle, Ctrl+V clipboard paste-sync, Esc behaviour, and the disable_copy / disable_paste interaction. Closes #156.
This commit is contained in:
@@ -75,6 +75,7 @@ guacd (C, from guacamole-server)
|
||||
- **Connections** with folder-based organisation and OIDC group access control
|
||||
- **Active Sessions** section with live thumbnail previews
|
||||
- **Session ended overlay** with Reconnect/Close buttons
|
||||
- **Clipboard panel controls** (Home + Fullscreen)
|
||||
- **8 built-in themes** with CSS gradient backgrounds, or configure your own
|
||||
- **Reports page** with session analytics, history, and CSV export
|
||||
|
||||
|
||||
@@ -431,6 +431,22 @@ Clipboard copy and paste can be independently disabled per connections entry. Th
|
||||
|
||||
These work for all session types (SSH, RDP, VNC, Web), not just web sessions. See [Security: Clipboard control](security.md#clipboard-control) for details.
|
||||
|
||||
## In-session keyboard shortcuts
|
||||
|
||||
The session page supports a small set of browser-side shortcuts:
|
||||
|
||||
| Shortcut | Action | Notes |
|
||||
|----------|--------|-------|
|
||||
| `Ctrl+Alt+Shift` | Toggle the clipboard side panel | Works globally on the session page (capture phase), including when the remote display is focused. |
|
||||
| `Ctrl+V` (Windows/Linux) or `Cmd+V` (macOS) | Sync browser clipboard text to the remote session, then send paste | If clipboard API access is available, rustguac reads local clipboard text and sends it to the remote before forwarding the paste key event. |
|
||||
| `Esc` (browser fullscreen) | Exit fullscreen | Browser-native fullscreen key. rustguac may request keyboard lock while in fullscreen; if lock is unavailable, an on-screen notice reminds users to press Esc. |
|
||||
|
||||
Additional behavior:
|
||||
|
||||
- No dedicated keyboard combo is currently assigned for entering fullscreen. Users can use entry-level fullscreen-on-connect, or open the `Ctrl+Alt+Shift` clipboard panel and click its **Fullscreen** button (next to **Home**).
|
||||
- All other key presses are passed through to the remote host by Guacamole keyboard handling.
|
||||
- Clipboard policy flags still apply: `disable_copy` and `disable_paste` can block corresponding clipboard flows regardless of local shortcuts.
|
||||
|
||||
## URL placeholders
|
||||
|
||||
The entry URL supports credential placeholders that are URL-encoded and substituted before Chromium navigates:
|
||||
|
||||
+8
-28
@@ -118,24 +118,6 @@
|
||||
border: 1px solid var(--border) !important;
|
||||
}
|
||||
#btn-reconnect:hover { background: var(--border); }
|
||||
#fs-toggle {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
z-index: 1500;
|
||||
background: rgba(0,0,0,0.55);
|
||||
color: var(--text-muted);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 4px;
|
||||
padding: 4px 10px;
|
||||
font-family: monospace;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
opacity: 0.45;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
#fs-toggle:hover { opacity: 1; color: var(--accent); }
|
||||
#fs-bar {
|
||||
display: none;
|
||||
position: fixed;
|
||||
@@ -247,7 +229,6 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="status">Loading...</div>
|
||||
<button id="fs-toggle" title="Enter fullscreen">⛶ Fullscreen</button>
|
||||
<div id="fs-bar">
|
||||
<div id="fs-bar-title"></div>
|
||||
<div id="fs-bar-buttons">
|
||||
@@ -528,6 +509,7 @@
|
||||
'<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;">' +
|
||||
@@ -557,6 +539,10 @@
|
||||
// Connections' active-session card.
|
||||
window.location.href = '/connections.html';
|
||||
});
|
||||
document.getElementById('cp-fullscreen').addEventListener('click', function() {
|
||||
rgEnterFullscreen();
|
||||
if (panelOpen) toggleClipboardPanel();
|
||||
});
|
||||
document.getElementById('cp-send').addEventListener('click', function() {
|
||||
if (clipboardTextarea.value) sendClipboardToRemote(clipboardTextarea.value);
|
||||
});
|
||||
@@ -1043,9 +1029,9 @@
|
||||
// the prior gesture. So when the entry is marked
|
||||
// fullscreen-on-connect we don't try to fire on page load.
|
||||
// Instead we arm a one-shot listener for the next mousedown
|
||||
// or keydown after CONNECTED. The manual gear-toggle button
|
||||
// in the corner uses its own click gesture and works at any
|
||||
// time once shown.
|
||||
// or keydown after CONNECTED. The Ctrl+Alt+Shift menu's
|
||||
// fullscreen button uses its own click gesture and works at
|
||||
// any time once shown.
|
||||
function rgFullscreenEl() {
|
||||
return document.fullscreenElement
|
||||
|| document.webkitFullscreenElement
|
||||
@@ -1138,9 +1124,7 @@
|
||||
}
|
||||
function rgOnFullscreenChange() {
|
||||
var inFs = !!rgFullscreenEl();
|
||||
var tg = document.getElementById('fs-toggle');
|
||||
var bar = document.getElementById('fs-bar');
|
||||
if (tg) tg.style.display = inFs ? 'none' : 'block';
|
||||
if (bar) {
|
||||
if (inFs) {
|
||||
bar.classList.add('visible');
|
||||
@@ -1159,7 +1143,6 @@
|
||||
}
|
||||
['fullscreenchange','webkitfullscreenchange','mozfullscreenchange','MSFullscreenChange']
|
||||
.forEach(function(ev){ document.addEventListener(ev, rgOnFullscreenChange); });
|
||||
document.getElementById('fs-toggle').addEventListener('click', rgEnterFullscreen);
|
||||
document.getElementById('fs-exit').addEventListener('click', rgExitFullscreen);
|
||||
document.getElementById('fs-disconnect').addEventListener('click', function() {
|
||||
rgExitFullscreen();
|
||||
@@ -1179,7 +1162,6 @@
|
||||
// First capture after 3s (let display render)
|
||||
setTimeout(captureAndUploadThumbnail, 3000);
|
||||
}
|
||||
document.getElementById('fs-toggle').style.display = 'block';
|
||||
document.getElementById('fs-bar-title').textContent =
|
||||
entryDisplayName || ('Session ' + sessionId.substring(0,8));
|
||||
if (wantFullscreen) rgArmFullscreenGesture();
|
||||
@@ -1197,7 +1179,6 @@
|
||||
statusEl.textContent = 'Disconnected'; statusEl.className = '';
|
||||
if (_thumbInterval) { clearInterval(_thumbInterval); _thumbInterval = null; }
|
||||
document.getElementById('disconnected-overlay').className = 'visible';
|
||||
document.getElementById('fs-toggle').style.display = 'none';
|
||||
if (rgFullscreenEl()) rgExitFullscreen();
|
||||
break;
|
||||
}
|
||||
@@ -1212,7 +1193,6 @@
|
||||
document.getElementById('disconnected-title').textContent = 'Connection Error';
|
||||
document.getElementById('disconnected-message').textContent = status.message || 'An error occurred.';
|
||||
document.getElementById('disconnected-overlay').className = 'visible';
|
||||
document.getElementById('fs-toggle').style.display = 'none';
|
||||
if (rgFullscreenEl()) rgExitFullscreen();
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user