Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Finalize function naming scheme. #4

Open
octalmage opened this issue Jan 29, 2015 · 35 comments
Open

Finalize function naming scheme. #4

octalmage opened this issue Jan 29, 2015 · 35 comments
Milestone

Comments

@octalmage
Copy link
Owner

Need to decide function names.

@octalmage octalmage changed the title Finalize function name scheme. Finalize function naming scheme. Jan 29, 2015
@octalmage octalmage modified the milestone: First Stable Release. Jan 29, 2015
@octalmage
Copy link
Owner Author

I'm thinking I'd like to separate each set of functions, so the code would be:

robot.mouse.click();

instead of:

robot.mouseClick();

octalmage added a commit that referenced this issue Jan 31, 2015
@sourcepirate
Copy link

that would be greate idea...we need to implement the native object factory..

@octalmage
Copy link
Owner Author

In e55e2d2 I did this in the index.js, are you suggesting we do it natively? I'd be ok with that!

@sourcepirate
Copy link

i would suggest javascript functions are better than native.

@octalmage
Copy link
Owner Author

I agree, seems like it would be easier to maintain.

@sourcepirate
Copy link

yup. it would be much easier . I have seen many native node.js libraries the author will write a primitive functional modules in c++/c and he implements his idea in native node.js

@octalmage
Copy link
Owner Author

I'm thinking for keyboard events I'd like to use, keyboard instead of key.

Like:

robot.keyboard.type("Hello World");
robot.keyboard.press("enter");

instead of:

robot.key.type("Hello World");
robot.key.press("enter");

I think it looks better, and it makes more sense.

@Multiply
Copy link

Multiply commented May 7, 2015

👍 for this. Then you can also just include the scope you need, so if you only need to control the mouse, simply just only have that.

@octalmage
Copy link
Owner Author

Good point @Multiply!

@d48
Copy link

d48 commented Jul 16, 2015

Just chiming in as I see would be great to chain, have the commands return the robot object so you can do:

robot
    .keyboard.type('Hello world')
    .mouse.click()
    .window.close()
...
    .<context>.<command>()

@RangerMauve
Copy link

Chaining would be pretty nice, actually.

@octalmage
Copy link
Owner Author

Chaining would be nice, but how would you do error handling?

@RangerMauve
Copy link

This might be controversial, but what about a promise-based API?

@ariporad
Copy link

(First of all, I'm new here. Sorry if I shouldn't just be jumping in. I really like the idea of this project, and have been looking for something to contribute to. I don't know C/C++, but I'm goodish with node).

@RangerMauve Promises would work, but they're hard to chain. The trouble with them is that they return a promise, not robot.

IMHO, the way to do it would be to throw an error. It seems like (especially if this is supposed to replace AutoHotKey), that most of the time there will be a human using in, to deal with an error. If not, try/catch. What jQuery does is they emit error events, which would work. Have a global error handler that prints and quits.

@RangerMauve
Copy link

@ariporad In terms of promises, it doesn't necessarily have to be a promise that gets returned outright. It just matters that it's a "thenable". So it could be an object that has all the same methods as robot but also has a .then() method. And whenever one of the methods get called, they get chained with something like return robot.wrapPromise(robot.then(dothething)) internally.

@ariporad
Copy link

Oh, really? (Promises are weird). That could work then. Although I feel like it'd be rather confusing. (but it's probably the best way to do it).

@RangerMauve
Copy link

Well, it's not so much promises as it'd be a fluent interface that relies on promises. One could probably do it without promises, too.

@octalmage
Copy link
Owner Author

I did some testing and for this code to work:

var robot = require("robotjs");

robot.moveMouse(5, 5);
var old = robot.getMousePos();
robot.moveMouse(50, 50);
var current = robot.getMousePos();
if (current.x !== old.x)
{
    console.log("Success!");
}

There needs to be a 50-100ms delay after the move. After I added the delay to the C++ code this code works without issue.

With the delay in the C code, is there anything wrong with the syntax above? I still want to separate the modules like in my second comment.

#14 and #27 are related.

@Multiply
Copy link

I don't like to block my app. I'd much rather have something like:

robot.moveMouse({ x: 50, y : 50}, function(err, success) {
  if (err) {
    return;
  }
  var current = robot.getMousePos();
});

@abhijeetpathak
Copy link

@Multiply +1 for callbacks.

Callbacks are nice for activities which take considerable amount of time to complete.
Keyboard and mouse activities should have OPTIONAL callbacks.

Callbacks would be really helpful in scenarios such as taking screenshots and saving them to a file. Those kind of activities will require large amount of time and hence callbacks.

@Akkuma
Copy link

Akkuma commented Jul 30, 2015

-1 for callbacks. What @RangerMauve suggested is part of the future of callback replacement.

My suggestion is go all in on ES7 async/await so you can instead do the following

var robot = require("robotjs");

await robot.moveMouse(5, 5);
var old = robot.getMousePos();
await robot.moveMouse(50, 50);
var current = robot.getMousePos();
if (current.x !== old.x)
{
    console.log("Success!");
}

Now some real API suggestions is that move could return an object containing the old and/or current position rather than nothing.

var robot = require("robotjs");

await robot.moveMouse(5, 5);
var { old, current } = await robot.moveMouse(50, 50);
if (current.x !== old.x)
{
    console.log("Success!");
}

Additionally, I think going with robot.mouse.x makes a lot of sense. I'd personally would opt for robot.kb.x as I like terseness.

@RangerMauve
Copy link

If you don't want to go with es7, then async/await is really just nice sugar on top of waiting for promises to resolve and returning promises from async functions, so if you wrote it in es5 with Promises being returned from the various functions, it'd be forward-compatible for when async/await becomes a thing.

@summivox
Copy link

+1 for promises. They naturally suit the "async sequence of actions" paradigm.

@neilgoldman
Copy link

+1 for promises.

What about actions where you need to wait some time before doing the next action? Or until some condition is true, like successfully finding an image on the screen.

robot.mouse.move(5, 5);
robot.mouse.click();
// Wait 2 seconds for some animation to complete
robot.mouse.move(50, 50);
robot.mouse.click();
// Wait until image of some button exists on screen
robot.mouse.move(200, 100);
robot.mouse.click();

@danprime
Copy link

Is there thoughts on syntax for multiple key presses (e.g. if I needed to do CTRL SHIFT L)?
Or,
If I needed to do a combo between a keypress and a mouse clicks (e.g. CTRL, LEFT-CLICK, (move mouse to x,y) LEFT-CLICK) to simulate multiple selections while holding down a key.

@octalmage
Copy link
Owner Author

@danprime multiple keypresses are implemented with keyTap. Something like

robot.keyTap("c", "command"); 

Should work. I'll get the documentation updated soon.

Also keyToggle can hold keys down. So you can hold down control while clicking.

@octalmage
Copy link
Owner Author

I guess we could just have sync and async versions of the functions. I'll at least start working on non-blocking functions using libuv in a branch.

@Akkuma
Copy link

Akkuma commented Jul 31, 2015

Here are some alternate apis that could address both.

robot.kb.key('c').key('ctrl').hold()
robot.kb.key('c').key('ctrl').press()
robot.kb.keys('c', 'ctrl').hold()
robot.kb.keys(['c', 'ctrl']).hold()
robot.kb.async.key('c').key('ctrl').press()
robot.kb.async().key('c').key('ctrl').press()

@steelbrain
Copy link

I was thinking about creating a typo-corrector in nodejs that observes text typed in every window a few days ago, Your project could serve as a base. It already provides a way to do keypresses, but does it provide a way to listen them?

@Deltatiger
Copy link
Collaborator

@steelbrain as of now it doesn't support that feature. Since its a desktop automation tool there wouldn't be much of a use for event listening (that's my honest opinion). But if the feature is requested maybe it can be done. It all depends on @octalmage

@steelbrain
Copy link

The README of the project states that the project started because there was no AutoHotKey for mac, and that's actually the basic usage of AutoHotKey that it transforms brb in to be right back. Really looking forward to have this implemented in here.

@Deltatiger
Copy link
Collaborator

@steelbrain Sorry I am yet to try out AHK. Till yesterday was thinking it was only for Mac (or something similar)

@octalmage
Copy link
Owner Author

@steelbrain this wasn't something I ever planned to implement because I use aText for this on Mac and I don't have a need, but I started work on a separate module. See #55.

@octalmage octalmage modified the milestone: First Stable Release. Sep 22, 2015
@octalmage octalmage mentioned this issue Jan 6, 2016
2 tasks
@octalmage octalmage removed the ready label Jun 12, 2016
@ghost
Copy link

ghost commented Oct 28, 2017

I run X11 in Docker containers on my Mac, I'd love to be able to do this:

var Robot = require("robot");

var robotOne = new Robot({xDisplay:"/tmp/x11-1"});
robotOne.keys("a");

var robotTwo = new Robot({xDisplay:"/tmp/x11-1"});
robotTwo.keys("a");

Also, imo, all commands should be promise-based. That's the direction JS is taking going forward (promises are the basis of async/await)

async function myFunc(){
   await robot.keys("a");
}

octalmage pushed a commit that referenced this issue Jan 24, 2019
@mo9a7i
Copy link

mo9a7i commented Aug 12, 2021

add detect click of mouse or keyboard function, part of an event listener maybe?

if someone click x button, then move mouse by 300 px

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

15 participants