mirror of
https://github.com/sipeed/NanoKVM-USB.git
synced 2026-09-11 05:59:57 -05:00
@@ -10,6 +10,7 @@ import {
|
||||
scrollDirectionAtom,
|
||||
scrollIntervalAtom
|
||||
} from '@/jotai/mouse.ts';
|
||||
import { mouseJiggler } from '@/libs/mouse-jiggler';
|
||||
import * as storage from '@/libs/storage';
|
||||
|
||||
import { Direction } from './direction.tsx';
|
||||
@@ -23,7 +24,7 @@ export const Mouse = () => {
|
||||
const [mouseMode, setMouseMode] = useAtom(mouseModeAtom);
|
||||
const setScrollDirection = useSetAtom(scrollDirectionAtom);
|
||||
const setScrollInterval = useSetAtom(scrollIntervalAtom);
|
||||
const [mouseJigglerMode, setMouseJigglerMode] = useAtom(mouseJigglerModeAtom);
|
||||
const setMouseJigglerMode = useSetAtom(mouseJigglerModeAtom);
|
||||
|
||||
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
|
||||
|
||||
@@ -53,9 +54,8 @@ export const Mouse = () => {
|
||||
}
|
||||
|
||||
const jiggler = storage.getMouseJigglerMode();
|
||||
if (mouseJigglerMode !== jiggler) {
|
||||
setMouseJigglerMode(jiggler);
|
||||
}
|
||||
mouseJiggler.setMode(jiggler);
|
||||
setMouseJigglerMode(jiggler);
|
||||
}
|
||||
|
||||
const content = (
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { useEffect } from 'react';
|
||||
import { Popover } from 'antd';
|
||||
import clsx from 'clsx';
|
||||
import { useAtom } from 'jotai';
|
||||
@@ -5,29 +6,35 @@ import { MousePointerIcon } from 'lucide-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { mouseJigglerModeAtom } from '@/jotai/mouse.ts';
|
||||
import { mouseJiggler } from '@/libs/mouse-jiggler';
|
||||
import * as storage from '@/libs/storage';
|
||||
|
||||
export const Jiggler = () => {
|
||||
const { t } = useTranslation();
|
||||
const [mouseJigglerMode, setMouseJigglerMode] = useAtom(mouseJigglerModeAtom);
|
||||
const mouseJigglerModes = [
|
||||
const [jigglerMode, setJigglerMode] = useAtom(mouseJigglerModeAtom);
|
||||
|
||||
const mouseJigglerModes: { name: string; value: 'enable' | 'disable' }[] = [
|
||||
{ name: t('mouse.jiggler.enable'), value: 'enable' },
|
||||
{ name: t('mouse.jiggler.disable'), value: 'disable' }
|
||||
];
|
||||
|
||||
function update(mode: string) {
|
||||
setMouseJigglerMode(mode);
|
||||
function update(mode: 'enable' | 'disable'): void {
|
||||
storage.setMouseJigglerMode(mode);
|
||||
setJigglerMode(mode);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
mouseJiggler.setMode(jigglerMode);
|
||||
}, [jigglerMode]);
|
||||
|
||||
const content = (
|
||||
<>
|
||||
{mouseJigglerModes.map((mode) => (
|
||||
<div
|
||||
key={mode.value}
|
||||
className={clsx(
|
||||
'my-1 flex cursor-pointer items-center space-x-1 rounded py-1 pl-2 pr-5 hover:bg-neutral-700/50',
|
||||
mode.value === mouseJigglerMode ? 'text-blue-500' : 'text-neutral-300'
|
||||
'my-1 flex cursor-pointer items-center space-x-1 rounded py-1 pr-5 pl-2 hover:bg-neutral-700/50',
|
||||
mode.value === jigglerMode ? 'text-blue-500' : 'text-neutral-300'
|
||||
)}
|
||||
onClick={() => update(mode.value)}
|
||||
>
|
||||
|
||||
@@ -1,22 +1,16 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { useAtomValue, useSetAtom } from 'jotai';
|
||||
import { useAtomValue } from 'jotai';
|
||||
|
||||
import { resolutionAtom } from '@/jotai/device.ts';
|
||||
import {
|
||||
mouseJigglerModeAtom,
|
||||
mouseLastMoveTimeAtom,
|
||||
scrollDirectionAtom,
|
||||
scrollIntervalAtom
|
||||
} from '@/jotai/mouse.ts';
|
||||
import { scrollDirectionAtom, scrollIntervalAtom } from '@/jotai/mouse.ts';
|
||||
import { device } from '@/libs/device';
|
||||
import { Key } from '@/libs/device/mouse.ts';
|
||||
import { mouseJiggler } from '@/libs/mouse-jiggler';
|
||||
|
||||
export const Absolute = () => {
|
||||
const resolution = useAtomValue(resolutionAtom);
|
||||
const scrollDirection = useAtomValue(scrollDirectionAtom);
|
||||
const scrollInterval = useAtomValue(scrollIntervalAtom);
|
||||
const mouseJigglerMode = useAtomValue(mouseJigglerModeAtom);
|
||||
const setMouseLastMoveTime = useSetAtom(mouseLastMoveTimeAtom);
|
||||
|
||||
const keyRef = useRef<Key>(new Key());
|
||||
const lastScrollTimeRef = useRef(0);
|
||||
@@ -82,10 +76,7 @@ export const Absolute = () => {
|
||||
disableEvent(event);
|
||||
await send(event);
|
||||
|
||||
// mouse jiggler record last move time
|
||||
if (mouseJigglerMode === 'enable') {
|
||||
setMouseLastMoveTime(Date.now());
|
||||
}
|
||||
mouseJiggler.moveEventCallback();
|
||||
}
|
||||
|
||||
// mouse scroll
|
||||
@@ -157,7 +148,7 @@ export const Absolute = () => {
|
||||
canvas.removeEventListener('click', disableEvent);
|
||||
canvas.removeEventListener('contextmenu', disableEvent);
|
||||
};
|
||||
}, [resolution, scrollDirection, scrollInterval, mouseJigglerMode, setMouseLastMoveTime]);
|
||||
}, [resolution, scrollDirection, scrollInterval]);
|
||||
|
||||
// disable default events
|
||||
function disableEvent(event: any) {
|
||||
|
||||
@@ -1,15 +1,6 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { useAtom, useAtomValue } from 'jotai';
|
||||
import { useAtomValue } from 'jotai';
|
||||
|
||||
import {
|
||||
mouseJigglerIntervalAtom,
|
||||
mouseJigglerModeAtom,
|
||||
mouseJigglerTimerAtom,
|
||||
mouseLastMoveTimeAtom,
|
||||
mouseModeAtom
|
||||
} from '@/jotai/mouse.ts';
|
||||
import { device } from '@/libs/device/index.ts';
|
||||
import { Key } from '@/libs/device/mouse.ts';
|
||||
import { mouseModeAtom } from '@/jotai/mouse.ts';
|
||||
|
||||
import { Absolute } from './absolute.tsx';
|
||||
import { Relative } from './relative.tsx';
|
||||
@@ -17,48 +8,5 @@ import { Relative } from './relative.tsx';
|
||||
export const Mouse = () => {
|
||||
const mouseMode = useAtomValue(mouseModeAtom);
|
||||
|
||||
// mouse jiggler
|
||||
const mouseJigglerMode = useAtomValue(mouseJigglerModeAtom);
|
||||
const [mouseJigglerTimer, setMouseJigglerTimer] = useAtom(mouseJigglerTimerAtom);
|
||||
const mouseJigglerInterval = useAtomValue(mouseJigglerIntervalAtom);
|
||||
const mouseLastMoveTime = useAtomValue(mouseLastMoveTimeAtom);
|
||||
const mouseLastMoveTimeRef = useRef(mouseLastMoveTime);
|
||||
const emptyKeyRef = useRef<Key>(new Key());
|
||||
useEffect(() => {
|
||||
// sync mouseLastMoveTime through ref
|
||||
mouseLastMoveTimeRef.current = mouseLastMoveTime;
|
||||
}, [mouseLastMoveTime]);
|
||||
useEffect(() => {
|
||||
async function jigglerTimerCallback() {
|
||||
if (Date.now() - mouseLastMoveTimeRef.current < mouseJigglerInterval) {
|
||||
return;
|
||||
}
|
||||
|
||||
const rect = document.getElementById('video')!.getBoundingClientRect();
|
||||
|
||||
await device.sendMouseAbsoluteData(
|
||||
emptyKeyRef.current,
|
||||
rect.width,
|
||||
rect.height,
|
||||
rect.width / 2,
|
||||
rect.height / 2,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
// configure interval timer
|
||||
if (mouseJigglerMode === 'enable') {
|
||||
if (mouseJigglerTimer === null) {
|
||||
const timer = setInterval(jigglerTimerCallback, mouseJigglerInterval);
|
||||
setMouseJigglerTimer(timer);
|
||||
}
|
||||
} else {
|
||||
if (mouseJigglerTimer) {
|
||||
clearInterval(mouseJigglerTimer);
|
||||
setMouseJigglerTimer(null);
|
||||
}
|
||||
}
|
||||
}, [mouseJigglerMode]);
|
||||
|
||||
return <>{mouseMode === 'relative' ? <Relative /> : <Absolute />}</>;
|
||||
};
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { message } from 'antd';
|
||||
import { useAtomValue, useSetAtom } from 'jotai';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { resolutionAtom } from '@/jotai/device.ts';
|
||||
import {
|
||||
mouseJigglerModeAtom,
|
||||
mouseLastMoveTimeAtom,
|
||||
scrollDirectionAtom,
|
||||
scrollIntervalAtom
|
||||
} from '@/jotai/mouse.ts';
|
||||
import { scrollDirectionAtom, scrollIntervalAtom } from '@/jotai/mouse.ts';
|
||||
import { device } from '@/libs/device';
|
||||
import { Key } from '@/libs/device/mouse.ts';
|
||||
import { mouseJiggler } from '@/libs/mouse-jiggler';
|
||||
|
||||
export const Relative = () => {
|
||||
const { t } = useTranslation();
|
||||
@@ -20,8 +16,6 @@ export const Relative = () => {
|
||||
const resolution = useAtomValue(resolutionAtom);
|
||||
const scrollDirection = useAtomValue(scrollDirectionAtom);
|
||||
const scrollInterval = useAtomValue(scrollIntervalAtom);
|
||||
const mouseJigglerMode = useAtomValue(mouseJigglerModeAtom);
|
||||
const setMouseLastMoveTime = useSetAtom(mouseLastMoveTimeAtom);
|
||||
|
||||
const isLockedRef = useRef(false);
|
||||
const keyRef = useRef<Key>(new Key());
|
||||
@@ -118,10 +112,7 @@ export const Relative = () => {
|
||||
|
||||
await send(Math.abs(x) < 10 ? x * 2 : x, Math.abs(y) < 10 ? y * 2 : y, 0);
|
||||
|
||||
// mouse jiggler record last move time
|
||||
if (mouseJigglerMode === 'enable') {
|
||||
setMouseLastMoveTime(Date.now());
|
||||
}
|
||||
mouseJiggler.moveEventCallback();
|
||||
}
|
||||
|
||||
// mouse scroll
|
||||
@@ -150,7 +141,7 @@ export const Relative = () => {
|
||||
canvas.removeEventListener('wheel', handleWheel);
|
||||
canvas.removeEventListener('contextmenu', disableEvent);
|
||||
};
|
||||
}, [resolution, scrollDirection, scrollInterval, mouseJigglerMode, setMouseLastMoveTime]);
|
||||
}, [resolution, scrollDirection, scrollInterval]);
|
||||
|
||||
async function send(x: number, y: number, scroll: number) {
|
||||
await device.sendMouseRelativeData(keyRef.current, x, y, scroll);
|
||||
|
||||
@@ -69,7 +69,7 @@ const zh = {
|
||||
slow: '慢',
|
||||
requestPointer: '正在使用鼠标相对模式,请点击桌面获取鼠标指针。',
|
||||
jiggler: {
|
||||
title: '闲时晃动',
|
||||
title: '空闲晃动',
|
||||
enable: '启用',
|
||||
disable: '禁用'
|
||||
}
|
||||
|
||||
@@ -9,17 +9,9 @@ export const mouseModeAtom = atom('absolute');
|
||||
// mouse scroll direction: 1 or -1
|
||||
export const scrollDirectionAtom = atom(1);
|
||||
|
||||
// mouse scroll interval (unit: ms)
|
||||
// mouse scroll interval (unit: ms)
|
||||
export const scrollIntervalAtom = atom(0);
|
||||
|
||||
// mouse jiggler mode: enable or disable
|
||||
export const mouseJigglerModeAtom = atom('disable');
|
||||
|
||||
// mouse jiggler timer id
|
||||
export const mouseJigglerTimerAtom = atom<number | null>(null);
|
||||
|
||||
// mouse jiggler interval (unit: ms)
|
||||
export const mouseJigglerIntervalAtom = atom(15_000);
|
||||
|
||||
// mouse jiggler last move time
|
||||
export const mouseLastMoveTimeAtom = atom(0);
|
||||
export const mouseJigglerModeAtom = atom<'enable' | 'disable'>('disable');
|
||||
|
||||
51
browser/src/libs/mouse-jiggler/index.ts
Normal file
51
browser/src/libs/mouse-jiggler/index.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import { device } from '@/libs/device';
|
||||
import { Key } from '@/libs/device/mouse.ts';
|
||||
|
||||
const MOUSE_JIGGLER_INTERVAL = 15_000;
|
||||
const EMPTY_KEY: Key = new Key(false, false, false);
|
||||
|
||||
class MouseJiggler {
|
||||
private lastMoveTime: number;
|
||||
private timer: number | null;
|
||||
private mode: 'enable' | 'disable';
|
||||
|
||||
constructor() {
|
||||
this.lastMoveTime = Date.now();
|
||||
this.timer = null;
|
||||
this.mode = 'disable';
|
||||
}
|
||||
|
||||
// enable or disable mouse jiggler
|
||||
setMode(mode: 'enable' | 'disable'): void {
|
||||
this.mode = mode;
|
||||
if (mode === 'disable' && this.timer !== null) {
|
||||
clearInterval(this.timer);
|
||||
this.timer = null;
|
||||
} else if (mode === 'enable' && this.timer === null) {
|
||||
this.timer = setInterval(() => {
|
||||
this.timeoutCallback();
|
||||
}, MOUSE_JIGGLER_INTERVAL / 5);
|
||||
}
|
||||
}
|
||||
|
||||
// addEventListener to canvas on 'mousemove' event
|
||||
moveEventCallback(): void {
|
||||
if (this.mode === 'enable') {
|
||||
this.lastMoveTime = Date.now();
|
||||
}
|
||||
}
|
||||
|
||||
timeoutCallback(): void {
|
||||
if (Date.now() - this.lastMoveTime > MOUSE_JIGGLER_INTERVAL) {
|
||||
this.lastMoveTime = Date.now() - 1_000;
|
||||
this.sendJiggle();
|
||||
}
|
||||
}
|
||||
|
||||
async sendJiggle(): Promise<void> {
|
||||
await device.sendMouseRelativeData(EMPTY_KEY, 10, 10, 0);
|
||||
await device.sendMouseRelativeData(EMPTY_KEY, -10, -10, 0);
|
||||
}
|
||||
}
|
||||
|
||||
export const mouseJiggler = new MouseJiggler();
|
||||
@@ -11,8 +11,8 @@ const MOUSE_STYLE_KEY = 'nanokvm-usb-mouse-style';
|
||||
const MOUSE_MODE_KEY = 'nanokvm-usb-mouse-mode';
|
||||
const MOUSE_SCROLL_DIRECTION_KEY = 'nanokvm-usb-mouse-scroll-direction';
|
||||
const MOUSE_SCROLL_INTERVAL_KEY = 'nanokvm-usb-mouse-scroll-interval';
|
||||
const MOUSE_JIGGLER_MODE_KEY = 'nanokvm-usb-mouse-jiggler-mode';
|
||||
const SHORTCUTS_KEY = 'nanokvm-usb-shortcuts';
|
||||
const MOUSE_JIGGLER_MODE_KEY = 'nanokvm-usb-mouse-jiggler-mode';
|
||||
|
||||
export function getLanguage() {
|
||||
return localStorage.getItem(LANGUAGE_KEY);
|
||||
@@ -124,15 +124,6 @@ export function setMouseScrollInterval(interval: number): void {
|
||||
localStorage.setItem(MOUSE_SCROLL_INTERVAL_KEY, String(interval));
|
||||
}
|
||||
|
||||
export function getMouseJigglerMode(): string {
|
||||
const jiggler = localStorage.getItem(MOUSE_JIGGLER_MODE_KEY);
|
||||
return jiggler && jiggler === 'enable' ? 'enable' : 'disable';
|
||||
}
|
||||
|
||||
export function setMouseJigglerMode(jiggler: string): void {
|
||||
localStorage.setItem(MOUSE_JIGGLER_MODE_KEY, jiggler);
|
||||
}
|
||||
|
||||
export function getShortcuts(): ShortcutProps[] {
|
||||
const shortcuts = localStorage.getItem(SHORTCUTS_KEY);
|
||||
if (!shortcuts) return [];
|
||||
@@ -142,3 +133,12 @@ export function getShortcuts(): ShortcutProps[] {
|
||||
export function setShortcuts(shortcuts: ShortcutProps[]): void {
|
||||
localStorage.setItem(SHORTCUTS_KEY, window.JSON.stringify(shortcuts));
|
||||
}
|
||||
|
||||
export function getMouseJigglerMode(): 'enable' | 'disable' {
|
||||
const jiggler = localStorage.getItem(MOUSE_JIGGLER_MODE_KEY);
|
||||
return jiggler && jiggler === 'enable' ? 'enable' : 'disable';
|
||||
}
|
||||
|
||||
export function setMouseJigglerMode(jiggler: 'enable' | 'disable'): void {
|
||||
localStorage.setItem(MOUSE_JIGGLER_MODE_KEY, jiggler);
|
||||
}
|
||||
|
||||
@@ -4,19 +4,15 @@ import { useAtomValue } from 'jotai'
|
||||
import { IpcEvents } from '@common/ipc-events'
|
||||
import { resolutionAtom } from '@renderer/jotai/device'
|
||||
import { scrollDirectionAtom, scrollIntervalAtom } from '@renderer/jotai/mouse'
|
||||
import { Key } from '@renderer/libs/device/mouse'
|
||||
import { mouseJiggler } from '@renderer/libs/mouse-jiggler'
|
||||
import type { Mouse as MouseKey } from '@renderer/types'
|
||||
|
||||
export const Absolute = (): ReactElement => {
|
||||
const resolution = useAtomValue(resolutionAtom)
|
||||
const scrollDirection = useAtomValue(scrollDirectionAtom)
|
||||
const scrollInterval = useAtomValue(scrollIntervalAtom)
|
||||
|
||||
const keyRef = useRef<MouseKey>({
|
||||
left: false,
|
||||
right: false,
|
||||
mid: false
|
||||
})
|
||||
const keyRef = useRef<Key>(new Key())
|
||||
const lastScrollTimeRef = useRef(0)
|
||||
|
||||
useEffect(() => {
|
||||
@@ -100,57 +96,50 @@ export const Absolute = (): ReactElement => {
|
||||
}
|
||||
|
||||
async function send(event: MouseEvent, scroll: number = 0): Promise<void> {
|
||||
const key =
|
||||
(keyRef.current.left ? 1 : 0) |
|
||||
(keyRef.current.right ? 2 : 0) |
|
||||
(keyRef.current.mid ? 4 : 0)
|
||||
|
||||
const {x, y} = getCorrectedCoords(event.clientX, event.clientY);
|
||||
|
||||
const { x, y } = getCorrectedCoords(event.clientX, event.clientY)
|
||||
await window.electron.ipcRenderer.invoke(
|
||||
IpcEvents.SEND_MOUSE_ABSOLUTE,
|
||||
key,
|
||||
1, 1, x, y, scroll
|
||||
keyRef.current.encode(), 1, 1, x, y, scroll
|
||||
)
|
||||
}
|
||||
|
||||
function getCorrectedCoords(clientX: number, clientY: number) {
|
||||
if (!canvas) {
|
||||
return { x: 0, y: 0 };
|
||||
return { x: 0, y: 0 }
|
||||
}
|
||||
|
||||
const rect = canvas.getBoundingClientRect();
|
||||
const videoElement = canvas as HTMLVideoElement;
|
||||
const rect = canvas.getBoundingClientRect()
|
||||
const videoElement = canvas as HTMLVideoElement
|
||||
|
||||
if (!videoElement.videoWidth || !videoElement.videoHeight) {
|
||||
const x = (clientX - rect.left) / rect.width;
|
||||
const y = (clientY - rect.top) / rect.height;
|
||||
return { x, y };
|
||||
const x = (clientX - rect.left) / rect.width
|
||||
const y = (clientY - rect.top) / rect.height
|
||||
return { x, y }
|
||||
}
|
||||
|
||||
const videoRatio = videoElement.videoWidth / videoElement.videoHeight;
|
||||
const elementRatio = rect.width / rect.height;
|
||||
const videoRatio = videoElement.videoWidth / videoElement.videoHeight
|
||||
const elementRatio = rect.width / rect.height
|
||||
|
||||
let renderedWidth = rect.width;
|
||||
let renderedHeight = rect.height;
|
||||
let offsetX = 0;
|
||||
let offsetY = 0;
|
||||
let renderedWidth = rect.width
|
||||
let renderedHeight = rect.height
|
||||
let offsetX = 0
|
||||
let offsetY = 0
|
||||
|
||||
if (videoRatio > elementRatio) {
|
||||
renderedHeight = rect.width / videoRatio;
|
||||
offsetY = (rect.height - renderedHeight) / 2;
|
||||
renderedHeight = rect.width / videoRatio
|
||||
offsetY = (rect.height - renderedHeight) / 2
|
||||
} else {
|
||||
renderedWidth = rect.height * videoRatio;
|
||||
offsetX = (rect.width - renderedWidth) / 2;
|
||||
renderedWidth = rect.height * videoRatio
|
||||
offsetX = (rect.width - renderedWidth) / 2
|
||||
}
|
||||
|
||||
const x = (clientX - rect.left - offsetX) / renderedWidth;
|
||||
const y = (clientY - rect.top - offsetY) / renderedHeight;
|
||||
const x = (clientX - rect.left - offsetX) / renderedWidth
|
||||
const y = (clientY - rect.top - offsetY) / renderedHeight
|
||||
|
||||
const finalX = Math.max(0, Math.min(1, x));
|
||||
const finalY = Math.max(0, Math.min(1, y));
|
||||
const finalX = Math.max(0, Math.min(1, x))
|
||||
const finalY = Math.max(0, Math.min(1, y))
|
||||
|
||||
return { x: finalX, y: finalY };
|
||||
return { x: finalX, y: finalY }
|
||||
}
|
||||
|
||||
return (): void => {
|
||||
|
||||
@@ -6,8 +6,8 @@ import { useTranslation } from 'react-i18next'
|
||||
import { IpcEvents } from '@common/ipc-events'
|
||||
import { resolutionAtom } from '@renderer/jotai/device'
|
||||
import { scrollDirectionAtom, scrollIntervalAtom } from '@renderer/jotai/mouse'
|
||||
import { Key } from '@renderer/libs/device/mouse'
|
||||
import { mouseJiggler } from '@renderer/libs/mouse-jiggler'
|
||||
import type { Mouse as MouseKey } from '@renderer/types'
|
||||
|
||||
export const Relative = (): ReactElement => {
|
||||
const { t } = useTranslation()
|
||||
@@ -18,11 +18,7 @@ export const Relative = (): ReactElement => {
|
||||
const scrollInterval = useAtomValue(scrollIntervalAtom)
|
||||
|
||||
const isLockedRef = useRef(false)
|
||||
const keyRef = useRef<MouseKey>({
|
||||
left: false,
|
||||
right: false,
|
||||
mid: false
|
||||
})
|
||||
const keyRef = useRef<Key>(new Key())
|
||||
const lastScrollTimeRef = useRef(0)
|
||||
|
||||
useEffect(() => {
|
||||
@@ -132,12 +128,7 @@ export const Relative = (): ReactElement => {
|
||||
}
|
||||
|
||||
async function send(x: number, y: number, scroll: number): Promise<void> {
|
||||
const key =
|
||||
(keyRef.current.left ? 1 : 0) |
|
||||
(keyRef.current.right ? 2 : 0) |
|
||||
(keyRef.current.mid ? 4 : 0)
|
||||
|
||||
await window.electron.ipcRenderer.invoke(IpcEvents.SEND_MOUSE_RELATIVE, key, x, y, scroll)
|
||||
await window.electron.ipcRenderer.invoke(IpcEvents.SEND_MOUSE_RELATIVE, keyRef.current.encode(), x, y, scroll)
|
||||
}
|
||||
|
||||
return (): void => {
|
||||
|
||||
26
desktop/src/renderer/src/libs/device/mouse.ts
Normal file
26
desktop/src/renderer/src/libs/device/mouse.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { setBit } from './utils'
|
||||
|
||||
export enum Mode {
|
||||
RELATIVE = 0x01,
|
||||
ABSOLUTE = 0x02
|
||||
}
|
||||
|
||||
export class Key {
|
||||
left: boolean
|
||||
right: boolean
|
||||
mid: boolean
|
||||
|
||||
constructor(left: boolean = false, right: boolean = false, mid: boolean = false) {
|
||||
this.left = left
|
||||
this.right = right
|
||||
this.mid = mid
|
||||
}
|
||||
|
||||
public encode(): number {
|
||||
let b = 0x00
|
||||
b = setBit(b, 0, this.left)
|
||||
b = setBit(b, 1, this.right)
|
||||
b = setBit(b, 2, this.mid)
|
||||
return b
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
import { IpcEvents } from '@common/ipc-events'
|
||||
import type { Mouse as MouseKey } from '@renderer/types'
|
||||
import { Key } from '@renderer/libs/device/mouse'
|
||||
|
||||
const MOUSE_JIGGLER_INTERVAL = 15_000
|
||||
const EMPTY_KEY: MouseKey = { left: false, right: false, mid: false }
|
||||
const EMPTY_KEY: Key = new Key(false, false, false)
|
||||
|
||||
class MouseJiggler {
|
||||
private lastMoveTime: number
|
||||
@@ -43,8 +43,8 @@ class MouseJiggler {
|
||||
}
|
||||
|
||||
async sendJiggle(): Promise<void> {
|
||||
await window.electron.ipcRenderer.invoke(IpcEvents.SEND_MOUSE_RELATIVE, EMPTY_KEY, 10, 10, 0)
|
||||
await window.electron.ipcRenderer.invoke(IpcEvents.SEND_MOUSE_RELATIVE, EMPTY_KEY, -10, -10, 0)
|
||||
await window.electron.ipcRenderer.invoke(IpcEvents.SEND_MOUSE_RELATIVE, EMPTY_KEY.encode(), 10, 10, 0)
|
||||
await window.electron.ipcRenderer.invoke(IpcEvents.SEND_MOUSE_RELATIVE, EMPTY_KEY.encode(), -10, -10, 0)
|
||||
}
|
||||
}
|
||||
export const mouseJiggler = new MouseJiggler()
|
||||
|
||||
@@ -9,9 +9,3 @@ export type MediaDevice = {
|
||||
audioId?: string
|
||||
audioName?: string
|
||||
}
|
||||
|
||||
export type Mouse = {
|
||||
left: boolean
|
||||
right: boolean
|
||||
mid: boolean
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user