diff --git a/ui/src/components/WebRTCVideo.tsx b/ui/src/components/WebRTCVideo.tsx
index c3c22f4..fff858f 100644
--- a/ui/src/components/WebRTCVideo.tsx
+++ b/ui/src/components/WebRTCVideo.tsx
@@ -67,6 +67,8 @@ export default function WebRTCVideo() {
const hdmiError = ["no_lock", "no_signal", "out_of_range"].includes(hdmiState);
const isVideoLoading = !isPlaying;
+ const [blockWheelEvent, setBlockWheelEvent] = useState(false);
+
// Misc states and hooks
const disableVideoFocusTrap = useUiStore(state => state.disableVideoFocusTrap);
const [send] = useJsonRpc();
@@ -281,6 +283,11 @@ export default function WebRTCVideo() {
const mouseWheelHandler = useCallback(
(e: WheelEvent) => {
+
+ if (settings.scrollThrottling && blockWheelEvent) {
+ return;
+ }
+
// Determine if the wheel event is an accel scroll value
const isAccel = Math.abs(e.deltaY) >= 100;
@@ -300,8 +307,14 @@ export default function WebRTCVideo() {
const invertedScrollValue = -clampedScrollValue;
send("wheelReport", { wheelY: invertedScrollValue });
+
+ // Apply blocking delay based of throttling settings
+ if (settings.scrollThrottling && !blockWheelEvent) {
+ setBlockWheelEvent(true);
+ setTimeout(() => setBlockWheelEvent(false), settings.scrollThrottling);
+ }
},
- [send],
+ [send, blockWheelEvent, settings],
);
const resetMousePosition = useCallback(() => {
diff --git a/ui/src/hooks/stores.ts b/ui/src/hooks/stores.ts
index 43b9273..9475316 100644
--- a/ui/src/hooks/stores.ts
+++ b/ui/src/hooks/stores.ts
@@ -314,6 +314,9 @@ interface SettingsState {
keyboardLedSync: KeyboardLedSync;
setKeyboardLedSync: (sync: KeyboardLedSync) => void;
+ scrollThrottling: number;
+ setScrollThrottling: (value: number) => void;
+
showPressedKeys: boolean;
setShowPressedKeys: (show: boolean) => void;
}
@@ -354,6 +357,9 @@ export const useSettingsStore = create(
keyboardLedSync: "auto",
setKeyboardLedSync: sync => set({ keyboardLedSync: sync }),
+ scrollThrottling: 0,
+ setScrollThrottling: value => set({ scrollThrottling: value }),
+
showPressedKeys: true,
setShowPressedKeys: show => set({ showPressedKeys: show }),
}),
diff --git a/ui/src/routes/devices.$id.settings.mouse.tsx b/ui/src/routes/devices.$id.settings.mouse.tsx
index 0c710ce..0fecef0 100644
--- a/ui/src/routes/devices.$id.settings.mouse.tsx
+++ b/ui/src/routes/devices.$id.settings.mouse.tsx
@@ -14,6 +14,7 @@ import { useFeatureFlag } from "../hooks/useFeatureFlag";
import { cx } from "../cva.config";
import { SettingsItem } from "./devices.$id.settings";
+import { SelectMenuBasic } from "@components/SelectMenuBasic";
export default function SettingsMouseRoute() {
const hideCursor = useSettingsStore(state => state.isCursorHidden);
@@ -26,6 +27,19 @@ export default function SettingsMouseRoute() {
const [jiggler, setJiggler] = useState(false);
+ const scrollThrottling = useSettingsStore(state => state.scrollThrottling);
+ const setScrollThrottling = useSettingsStore(
+ state => state.setScrollThrottling,
+ );
+
+ const scrollThrottlingOptions = [
+ { value: "0", label: "Off" },
+ { value: "10", label: "Low" },
+ { value: "25", label: "Medium" },
+ { value: "50", label: "High" },
+ { value: "100", label: "Very High" },
+ ];
+
const [send] = useJsonRpc();
useEffect(() => {
@@ -65,6 +79,21 @@ export default function SettingsMouseRoute() {
/>
+
+ setScrollThrottling(parseInt(e.target.value))}
+ options={scrollThrottlingOptions}
+ />
+
+