fix(desktop): mouse jiggler unavailable

This commit is contained in:
Guoguo
2025-12-15 15:21:09 +08:00
parent 0016db40ee
commit e17be01ca0
5 changed files with 58 additions and 58 deletions

View File

@@ -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 => {

View File

@@ -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 => {

View 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
}
}

View File

@@ -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()

View File

@@ -9,9 +9,3 @@ export type MediaDevice = {
audioId?: string
audioName?: string
}
export type Mouse = {
left: boolean
right: boolean
mid: boolean
}