mirror of
https://github.com/sipeed/NanoKVM-USB.git
synced 2026-11-10 01:14:16 -06:00
fix(desktop): mouse jiggler unavailable
This commit is contained in:
@@ -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