152 lines
4.3 KiB
JavaScript
152 lines
4.3 KiB
JavaScript
'use strict';
|
|
|
|
const { getPanelPoint, listWindows, pickWindow, sleep } = require('./electron-tools');
|
|
|
|
function normalizeButton(button) {
|
|
const value = String(button || 'left').toLowerCase();
|
|
return ['left', 'right', 'middle'].includes(value) ? value : 'left';
|
|
}
|
|
|
|
function normalizeModifiers(modifiers) {
|
|
return Array.isArray(modifiers) ? modifiers.map((item) => String(item)) : [];
|
|
}
|
|
|
|
async function focusTarget(window, panel, x, y) {
|
|
if (typeof window.focus === 'function') {
|
|
window.focus();
|
|
}
|
|
if (panel) {
|
|
return await getPanelPoint(window, panel, x, y);
|
|
}
|
|
return { x: Math.floor(x || 0), y: Math.floor(y || 0) };
|
|
}
|
|
|
|
async function resolvePoint(window, panel, x, y) {
|
|
if (panel) {
|
|
return await getPanelPoint(window, panel, x, y);
|
|
}
|
|
return { x: Math.floor(x || 0), y: Math.floor(y || 0) };
|
|
}
|
|
|
|
async function sendMouseClick(options = {}) {
|
|
const window = pickWindow(options);
|
|
const point = await focusTarget(window, options.panel, options.x, options.y);
|
|
const button = normalizeButton(options.button);
|
|
const clickCount = Number.isFinite(options.clickCount) ? Math.max(1, options.clickCount) : 1;
|
|
const modifiers = normalizeModifiers(options.modifiers);
|
|
|
|
window.webContents.sendInputEvent({
|
|
type: 'mouseMove',
|
|
x: point.x,
|
|
y: point.y,
|
|
button,
|
|
modifiers,
|
|
});
|
|
window.webContents.sendInputEvent({
|
|
type: 'mouseDown',
|
|
x: point.x,
|
|
y: point.y,
|
|
button,
|
|
clickCount,
|
|
modifiers,
|
|
});
|
|
window.webContents.sendInputEvent({
|
|
type: 'mouseUp',
|
|
x: point.x,
|
|
y: point.y,
|
|
button,
|
|
clickCount,
|
|
modifiers,
|
|
});
|
|
|
|
return {
|
|
sent: true,
|
|
type: 'mouse_click',
|
|
point,
|
|
button,
|
|
clickCount,
|
|
windowTitle: typeof window.getTitle === 'function' ? window.getTitle() : '',
|
|
};
|
|
}
|
|
|
|
async function sendMouseDrag(options = {}) {
|
|
const window = pickWindow(options);
|
|
const start = await focusTarget(window, options.panel, options.startX, options.startY);
|
|
const end = await resolvePoint(window, options.panel, options.endX ?? 0, options.endY ?? 0);
|
|
const steps = Number.isFinite(options.steps) ? Math.max(1, Math.min(60, options.steps)) : 10;
|
|
const button = normalizeButton(options.button);
|
|
const modifiers = normalizeModifiers(options.modifiers);
|
|
|
|
window.webContents.sendInputEvent({ type: 'mouseMove', x: start.x, y: start.y, button, modifiers });
|
|
window.webContents.sendInputEvent({ type: 'mouseDown', x: start.x, y: start.y, button, clickCount: 1, modifiers });
|
|
for (let step = 1; step <= steps; step += 1) {
|
|
const x = Math.round(start.x + ((end.x - start.x) * step) / steps);
|
|
const y = Math.round(start.y + ((end.y - start.y) * step) / steps);
|
|
window.webContents.sendInputEvent({ type: 'mouseMove', x, y, button, modifiers });
|
|
if (options.stepDelayMs) {
|
|
await sleep(options.stepDelayMs);
|
|
}
|
|
}
|
|
window.webContents.sendInputEvent({ type: 'mouseUp', x: end.x, y: end.y, button, clickCount: 1, modifiers });
|
|
|
|
return {
|
|
sent: true,
|
|
type: 'mouse_drag',
|
|
from: start,
|
|
to: end,
|
|
steps,
|
|
windowTitle: typeof window.getTitle === 'function' ? window.getTitle() : '',
|
|
};
|
|
}
|
|
|
|
async function sendKeyPress(options = {}) {
|
|
const window = pickWindow(options);
|
|
if (typeof window.focus === 'function') {
|
|
window.focus();
|
|
}
|
|
if (options.panel) {
|
|
await getPanelPoint(window, options.panel, 0, 0);
|
|
}
|
|
|
|
const keyCode = String(options.keyCode || '').trim();
|
|
if (!keyCode) {
|
|
throw new Error('keyCode is required.');
|
|
}
|
|
|
|
const modifiers = normalizeModifiers(options.modifiers);
|
|
window.webContents.sendInputEvent({ type: 'keyDown', keyCode, modifiers });
|
|
if (options.text) {
|
|
window.webContents.sendInputEvent({ type: 'char', keyCode: String(options.text), modifiers });
|
|
}
|
|
window.webContents.sendInputEvent({ type: 'keyUp', keyCode, modifiers });
|
|
|
|
return {
|
|
sent: true,
|
|
type: 'key_press',
|
|
keyCode,
|
|
modifiers,
|
|
windowTitle: typeof window.getTitle === 'function' ? window.getTitle() : '',
|
|
};
|
|
}
|
|
|
|
async function sendKeyCombo(options = {}) {
|
|
const modifiers = normalizeModifiers(options.modifiers);
|
|
const keyCode = String(options.keyCode || '').trim();
|
|
if (!keyCode) {
|
|
throw new Error('keyCode is required.');
|
|
}
|
|
return await sendKeyPress({
|
|
...options,
|
|
keyCode,
|
|
modifiers,
|
|
});
|
|
}
|
|
|
|
module.exports = {
|
|
listWindows,
|
|
sendKeyCombo,
|
|
sendKeyPress,
|
|
sendMouseClick,
|
|
sendMouseDrag,
|
|
};
|