Skip to content

Commit

Permalink
fix: Perform click action when necessary (#240)
Browse files Browse the repository at this point in the history
  • Loading branch information
mykola-mokhnach authored Feb 18, 2024
1 parent 53f9603 commit 8c7288f
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 36 deletions.
16 changes: 11 additions & 5 deletions lib/commands/gestures.js
Original file line number Diff line number Diff line change
Expand Up @@ -300,11 +300,13 @@ commands.windowsClick = async function windowsClick (opts) {
const [absoluteX, absoluteY] = await toAbsoluteCoordinates.bind(this)(elementId, x, y);
let clickDownInput;
let clickUpInput;
let clickInput;
let moveInput;
try {
[clickDownInput, clickUpInput, moveInput] = await B.all([
[clickDownInput, clickUpInput, clickInput, moveInput] = await B.all([
toMouseButtonInput({button, action: MOUSE_BUTTON_ACTION.DOWN}),
toMouseButtonInput({button, action: MOUSE_BUTTON_ACTION.UP}),
toMouseButtonInput({button, action: MOUSE_BUTTON_ACTION.CLICK}),
toMouseMoveInput({x: absoluteX, y: absoluteY}),
]);
} catch (e) {
Expand All @@ -316,13 +318,17 @@ commands.windowsClick = async function windowsClick (opts) {
await handleInputs(modifierKeyDownInputs);
}
await handleInputs(moveInput);
const hasDuration = _.isInteger(durationMs) && durationMs > 0;
const hasInterClickDelay = _.isInteger(interClickDelayMs) && interClickDelayMs > 0;
for (let i = 0; i < times; ++i) {
await handleInputs(clickDownInput);
if (_.isInteger(durationMs) && durationMs > 0) {
if (hasDuration) {
await handleInputs(clickDownInput);
await B.delay(durationMs);
await handleInputs(clickUpInput);
} else {
await handleInputs(clickInput);
}
await handleInputs(clickUpInput);
if (_.isInteger(interClickDelayMs) && interClickDelayMs > 0) {
if (hasInterClickDelay) {
await B.delay(interClickDelayMs);
}
}
Expand Down
74 changes: 43 additions & 31 deletions lib/commands/winapi/user32.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ export const MOUSE_BUTTON = Object.freeze({
export const MOUSE_BUTTON_ACTION = Object.freeze({
UP: 'up',
DOWN: 'down',
// This action is an intenal one
CLICK: 'click',
});
const MOUSEEVENTF_MOVE = 0x0001;
const MOUSEEVENTF_LEFTDOWN = 0x0002;
Expand Down Expand Up @@ -230,8 +232,8 @@ function createMouseInput (params = {}) {

/**
* @typedef {Object} MouseButtonOptions
* @property {'left' | 'middle' | 'right' | 'back' | 'forward'} button The desired button name to click
* @property {'up' | 'down'} action The desired button action
* @property {typeof MOUSE_BUTTON[keyof typeof MOUSE_BUTTON]} button The desired button name to click
* @property {typeof MOUSE_BUTTON_ACTION[keyof typeof MOUSE_BUTTON_ACTION]} action The desired button action
*/

/**
Expand All @@ -243,18 +245,6 @@ function createMouseInput (params = {}) {
* @throws {Error} If the input data is invalid
*/
export async function toMouseButtonInput({button, action}) {
let down = true;
switch (_.toLower(action)) {
case MOUSE_BUTTON_ACTION.UP:
down = false;
break;
case MOUSE_BUTTON_ACTION.DOWN:
break;
default:
throw createInvalidArgumentError(`Mouse button action '${action}' is unknown. ` +
`Only ${_.values(MOUSE_BUTTON_ACTION)} actions are supported`);
}

// If the host is configured to swap left & right buttons, inject swapped
// events to un-do that re-mapping.
if (await isLeftMouseButtonSwapped()) {
Expand All @@ -264,34 +254,56 @@ export async function toMouseButtonInput({button, action}) {
button = MOUSE_BUTTON.LEFT;
}
}

let evtDown;
let evtUp;
let mouseData;
switch (_.toLower(button)) {
case MOUSE_BUTTON.LEFT:
return createMouseInput({
dwFlags: down ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP,
});
[evtDown, evtUp] = [MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_LEFTUP];
break;
case MOUSE_BUTTON.RIGHT:
return createMouseInput({
dwFlags: down ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_RIGHTUP,
});
[evtDown, evtUp] = [MOUSEEVENTF_RIGHTDOWN, MOUSEEVENTF_RIGHTUP];
break;
case MOUSE_BUTTON.MIDDLE:
return createMouseInput({
dwFlags: down ? MOUSEEVENTF_MIDDLEDOWN : MOUSEEVENTF_MIDDLEUP,
});
[evtDown, evtUp] = [MOUSEEVENTF_MIDDLEDOWN, MOUSEEVENTF_MIDDLEUP];
break;
case MOUSE_BUTTON.BACK:
return createMouseInput({
dwFlags: down ? MOUSEEVENTF_XDOWN : MOUSEEVENTF_XUP,
mouseData: XBUTTON1,
});
[evtDown, evtUp] = [MOUSEEVENTF_XDOWN, MOUSEEVENTF_XUP];
mouseData = XBUTTON1;
break;
case MOUSE_BUTTON.FORWARD:
return createMouseInput({
dwFlags: down ? MOUSEEVENTF_XDOWN : MOUSEEVENTF_XUP,
mouseData: XBUTTON2,
});
[evtDown, evtUp] = [MOUSEEVENTF_XDOWN, MOUSEEVENTF_XUP];
mouseData = XBUTTON2;
break;
default:
throw createInvalidArgumentError(
`Mouse button '${button}' is unknown. Only ${_.values(MOUSE_BUTTON)} buttons are supported`
);
}

let dwFlags;
switch (_.toLower(action)) {
case MOUSE_BUTTON_ACTION.UP:
dwFlags = evtUp;
break;
case MOUSE_BUTTON_ACTION.DOWN:
dwFlags = evtDown;
break;
case MOUSE_BUTTON_ACTION.CLICK:
dwFlags = evtDown | evtUp;
break;
default:
throw createInvalidArgumentError(
`Mouse button action '${action}' is unknown. ` +
`Only ${[MOUSE_BUTTON_ACTION.UP, MOUSE_BUTTON_ACTION.DOWN]} actions are supported`
);
}

return createMouseInput({
dwFlags,
...(_.isNil(mouseData) ? {} : {mouseData}),
});
}

function clamp (num, min, max) {
Expand Down

0 comments on commit 8c7288f

Please sign in to comment.