2 Commits

Author SHA1 Message Date
yuanyuanxiang
707dcdbbb4 Fix(Web): exit remote-desktop fullscreen blocks device-list clicks 2026-05-19 22:20:58 +02:00
yuanyuanxiang
1c1bb3a5ff Fix(Go): notify browsers with device_offline so the webpage not frozen 2026-05-19 21:48:09 +02:00
2 changed files with 41 additions and 1 deletions

View File

@@ -229,8 +229,30 @@ func (h *wsHub) OnDeviceOnline(_ hub.DeviceInfo) {
h.broadcastAuthenticated(`{"cmd":"devices_changed"}`)
}
func (h *wsHub) OnDeviceOffline(_ string) {
func (h *wsHub) OnDeviceOffline(id string) {
// Tell everyone authenticated to refresh their device list (covers
// users sitting on the devices-page).
h.broadcastAuthenticated(`{"cmd":"devices_changed"}`)
// Also tell any browser actively viewing this device's screen — the
// devices_changed handler only refreshes the list page; viewers on the
// screen page would otherwise see a frozen frame with "Connected" status
// indefinitely. The browser handles this by showing "Device offline" and
// bouncing back to the device list after 2 s.
if id == "" {
return
}
msg := mustJSON(map[string]any{
"cmd": "device_offline",
"id": id,
})
h.mu.RLock()
defer h.mu.RUnlock()
for c := range h.clients {
if c.watching == id && c.token != "" {
c.queue(msg)
}
}
}
// OnCursorChange relays the remote cursor index to every viewer of this

View File

@@ -1873,6 +1873,24 @@
}
function showPage(pageId) {
// Leaving the remote-desktop page? Drop fullscreen first.
// #screen-page is the requestFullscreen target; while it remains
// the document.fullscreenElement the browser blocks pointer /
// keyboard interaction with anything outside its subtree —
// devices-page lives outside it, so without this exit a click
// ANYWHERE on the device list silently no-ops until the user
// hits ESC themselves. Same hazard for device_offline auto-
// navigation, manual Back, and any future navigation we add.
if (pageId !== 'screen-page') {
const sp = document.getElementById('screen-page');
if (sp && sp.classList.contains('active')) {
if (document.fullscreenElement || document.webkitFullscreenElement) {
const exit = document.exitFullscreen || document.webkitExitFullscreen;
if (exit) exit.call(document).catch(() => {});
}
sp.classList.remove('pseudo-fullscreen'); // iOS fallback path
}
}
document.querySelectorAll('.page').forEach(p => p.classList.remove('active'));
document.getElementById(pageId).classList.add('active');
}