add scroll wheel support to remote desktop

This commit is contained in:
KingKDot
2026-04-22 16:15:53 -05:00
parent 55a346e39b
commit 8c3c6de1c3
5 changed files with 37 additions and 1 deletions
@@ -888,6 +888,22 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
sendMouseUp(btn) sendMouseUp(btn)
sendCommandResultAsync(env, cmdID) sendCommandResultAsync(env, cmdID)
return nil return nil
case "desktop_mouse_wheel":
if !env.MouseControl {
sendCommandResultAsync(env, cmdID)
return nil
}
payload := payloadAsMap(envelope["payload"])
delta, _ := payloadInt32(payload, "delta")
if x, okX := payloadInt32(payload, "x"); okX {
if y, okY := payloadInt32(payload, "y"); okY {
absX, absY := resolveDesktopPoint(env.SelectedDisplay, x, y)
setCursorPos(absX, absY)
}
}
sendMouseWheel(delta)
sendCommandResultAsync(env, cmdID)
return nil
case "desktop_key_down": case "desktop_key_down":
if !env.KeyboardControl { if !env.KeyboardControl {
sendCommandResultAsync(env, cmdID) sendCommandResultAsync(env, cmdID)
@@ -44,7 +44,7 @@ func (d *Dispatcher) Dispatch(ctx context.Context, envelope map[string]interface
case "command": case "command":
cmdType, _ := envelope["commandType"].(string) cmdType, _ := envelope["commandType"].(string)
switch cmdType { switch cmdType {
case "desktop_mouse_move", "desktop_mouse_down", "desktop_mouse_up", case "desktop_mouse_move", "desktop_mouse_down", "desktop_mouse_up", "desktop_mouse_wheel",
"desktop_key_down", "desktop_key_up", "desktop_text", "desktop_key_down", "desktop_key_up", "desktop_text",
"hvnc_mouse_move", "hvnc_mouse_down", "hvnc_mouse_up", "hvnc_mouse_move", "hvnc_mouse_down", "hvnc_mouse_up",
"hvnc_mouse_wheel", "hvnc_key_down", "hvnc_key_up": "hvnc_mouse_wheel", "hvnc_key_down", "hvnc_key_up":
@@ -23,6 +23,7 @@ const (
MOUSEEVENTF_RIGHTUP = 0x0010 MOUSEEVENTF_RIGHTUP = 0x0010
MOUSEEVENTF_MIDDLEDOWN = 0x0020 MOUSEEVENTF_MIDDLEDOWN = 0x0020
MOUSEEVENTF_MIDDLEUP = 0x0040 MOUSEEVENTF_MIDDLEUP = 0x0040
MOUSEEVENTF_WHEEL = 0x0800
MOUSEEVENTF_ABSOLUTE = 0x8000 MOUSEEVENTF_ABSOLUTE = 0x8000
MOUSEEVENTF_VIRTUALDESK = 0x4000 MOUSEEVENTF_VIRTUALDESK = 0x4000
@@ -97,6 +98,10 @@ func sendMouseUp(button int) {
} }
} }
func sendMouseWheel(delta int32) {
sendMouseInput(MOUSEEVENTF_WHEEL, uint32(delta))
}
func sendMouseInput(flags uint32, mouseData uint32) { func sendMouseInput(flags uint32, mouseData uint32) {
//garble:controlflow block_splits=10 junk_jumps=10 flatten_passes=2 //garble:controlflow block_splits=10 junk_jumps=10 flatten_passes=2
var inp input var inp input
@@ -1318,6 +1318,14 @@ import { checkFeatureAccess } from "./feature-gate.js";
canvas.addEventListener("contextmenu", function (e) { canvas.addEventListener("contextmenu", function (e) {
e.preventDefault(); e.preventDefault();
}); });
canvas.addEventListener("wheel", function (e) {
if (!mouseCtrl.checked) return;
const pt = getCanvasPoint(e);
if (!pt) return;
const delta = Math.max(-120, Math.min(120, Math.round(-e.deltaY)));
sendCmd("mouse_wheel", { delta, x: pt.x, y: pt.y });
e.preventDefault();
}, { passive: false });
canvas.setAttribute("tabindex", "0"); canvas.setAttribute("tabindex", "0");
canvas.addEventListener("click", function () { canvas.addEventListener("click", function () {
@@ -497,6 +497,13 @@ export function handleRemoteDesktopViewerMessage(ws: ServerWebSocket<SocketData>
sendDesktopCommandWithId(target, "desktop_mouse_up", { button: Number(payload.button) || 0 }, commandId); sendDesktopCommandWithId(target, "desktop_mouse_up", { button: Number(payload.button) || 0 }, commandId);
break; break;
} }
case "mouse_wheel": {
if (!state.isStreaming) break;
const commandId = uuidv4();
recordRdInput(commandId, clientId, "mouse_wheel");
sendDesktopCommandWithId(target, "desktop_mouse_wheel", { delta: Number(payload.delta) || 0, x: Number((payload as any).x) || 0, y: Number((payload as any).y) || 0 }, commandId);
break;
}
case "key_down": { case "key_down": {
if (!state.isStreaming) break; if (!state.isStreaming) break;
const commandId = uuidv4(); const commandId = uuidv4();