Feature: Web remote desktop cursor sync with remote host
This commit is contained in:
@@ -1232,6 +1232,18 @@ inline std::string GetWebPageHTML() {
|
||||
updateScreenStatus('connected');
|
||||
initDecoder(msg.width, msg.height);
|
||||
break;
|
||||
case 'cursor':
|
||||
// Update remote cursor style (only for desktop in control mode)
|
||||
currentCursorIndex = msg.index;
|
||||
if (controlEnabled && !isTouchDevice) {
|
||||
const canvas = document.getElementById('screen-canvas');
|
||||
// 254=custom cursor (not supported in web), 255=unsupported -> default
|
||||
const cssCursor = (msg.index >= 0 && msg.index < cursorMap.length)
|
||||
? cursorMap[msg.index]
|
||||
: 'default';
|
||||
canvas.style.cursor = cssCursor;
|
||||
}
|
||||
break;
|
||||
case 'device_offline':
|
||||
// Only handle if this is the device we're currently viewing
|
||||
if (!token) break;
|
||||
@@ -1748,6 +1760,28 @@ inline std::string GetWebPageHTML() {
|
||||
// Control mode state (mouse/keyboard control)
|
||||
let controlEnabled = false;
|
||||
|
||||
// Remote cursor mapping (Windows cursor index -> CSS cursor)
|
||||
// Index matches CursorInfo.h: IDC_APPSTARTING(0) to IDC_WAIT(15), 254=custom, 255=unsupported
|
||||
const cursorMap = [
|
||||
'progress', // 0: IDC_APPSTARTING
|
||||
'default', // 1: IDC_ARROW
|
||||
'crosshair', // 2: IDC_CROSS
|
||||
'pointer', // 3: IDC_HAND
|
||||
'help', // 4: IDC_HELP
|
||||
'text', // 5: IDC_IBEAM
|
||||
'default', // 6: IDC_ICON (no direct CSS equivalent)
|
||||
'not-allowed', // 7: IDC_NO
|
||||
'default', // 8: IDC_SIZE (deprecated, use default)
|
||||
'move', // 9: IDC_SIZEALL
|
||||
'nesw-resize', // 10: IDC_SIZENESW
|
||||
'ns-resize', // 11: IDC_SIZENS
|
||||
'nwse-resize', // 12: IDC_SIZENWSE
|
||||
'ew-resize', // 13: IDC_SIZEWE
|
||||
'default', // 14: IDC_UPARROW (no direct CSS equivalent)
|
||||
'wait' // 15: IDC_WAIT
|
||||
];
|
||||
let currentCursorIndex = 1; // Default: arrow
|
||||
|
||||
// Floating toolbar state
|
||||
let toolbarVisible = false;
|
||||
let toolbarHideTimer = null;
|
||||
@@ -1899,8 +1933,18 @@ inline std::string GetWebPageHTML() {
|
||||
const canvas = document.getElementById('screen-canvas');
|
||||
const cursorOverlay = document.getElementById('cursor-overlay');
|
||||
// Touch devices: hide browser cursor, show overlay (touchpad mode)
|
||||
// Desktop: keep browser cursor visible, no overlay needed (remote shows cursor)
|
||||
canvas.style.cursor = (controlEnabled && isTouchDevice) ? 'none' : 'default';
|
||||
// Desktop: use remote cursor style when control enabled
|
||||
if (controlEnabled && isTouchDevice) {
|
||||
canvas.style.cursor = 'none';
|
||||
} else if (controlEnabled && !isTouchDevice) {
|
||||
// Apply current remote cursor
|
||||
const cssCursor = (currentCursorIndex >= 0 && currentCursorIndex < cursorMap.length)
|
||||
? cursorMap[currentCursorIndex]
|
||||
: 'default';
|
||||
canvas.style.cursor = cssCursor;
|
||||
} else {
|
||||
canvas.style.cursor = 'default';
|
||||
}
|
||||
cursorOverlay.classList.toggle('active', controlEnabled && isTouchDevice);
|
||||
}
|
||||
|
||||
@@ -2726,6 +2770,7 @@ inline std::string GetWebPageHTML() {
|
||||
if (qcMouse) qcMouse.classList.remove('active');
|
||||
document.getElementById('screen-canvas').style.cursor = 'default';
|
||||
document.getElementById('cursor-overlay').classList.remove('active');
|
||||
currentCursorIndex = 1; // Reset to default arrow
|
||||
|
||||
// Reset zoom state
|
||||
zoomState.scale = 1;
|
||||
|
||||
Reference in New Issue
Block a user