BlueM / cliclick

macOS CLI tool for emulating mouse and keyboard events
https://www.bluem.net
Other
1.62k stars 122 forks source link

FeatureRequest: Support Mouse Down, Mouse Up - Not "just" Mouse Click #59

Closed axgkl closed 7 years ago

axgkl commented 7 years ago

Hi Carsten,

After an upgrade to Sierra I had to realize that Karabiner/Seil are not working anymore, for the following use case: I could, before the update, bind a key to the left mouse button, e.g. in their config format:

  KeyCode::D, ModifierFlag::OPTION_R | ModifierFlag::NONE,
  PointingButton::LEFT

(and option-r was remapped to caps-lock via seil)

That enabled me to do this:

  1. caps-lock + d -> mouse down (e.g. on start of text to select, e.g. on window border, with left hand)
  2. trackpad move pointer to destination (with right hand)
  3. release d and caps lock

This was amazingly effective, far more precise then clicking on the trackpad and less strain, basically just like tapping - but without having to move the hand away from the default typing position....

With cliclick I can't get it, since you 'just' support a full click but not a seperate mouse down / mouse up and drag did also not really work, e.g.:

#!/usr/bin/env bash
while true; do
    sleep 1
    echo down
    ./cliclick dd:.
    sleep 1
    echo up
    ./cliclick du:.
done

and then moving the pointer over text did not select in the browser and also not move any window when I move over its border while the the script is running.


Note: Tried to mess around a few hours with swift and obj.c - but to no success, could not really emulate a left mouse button down / up only, at the current track pad position. Only managed to get same behaviour like pressing the '5' key on the numeric keyboard when the MouseEvents feature is on - but that allows not to drag, after 5 is down, dragging works then only with the other numeric keys. Crazy...

Maybe you find it trivial, sort of my last hope,

Cheers from Nr. 400 ;-)

axgkl commented 7 years ago

Addendum: biggest advantage of a mouse button on the keyboard and not the trackpad I realize only today in the office: Many people like me have built up huge screens in front of them, I personally have 4 monitors. I just constantly run out of trackpad boundaries when dragging stuff over a big distance.

=> w/o a keyboard button combi bound to a mouse down/ mouse up I must go back to USB mouse - all this simply does not work out anymore with a trackpad I'd say.

=> I'd personally pay a massive amount of bucks without a second thought for getting back that possibility and I'm not the only one I assume, hint hint ;-)

axgkl commented 7 years ago

Closing it, hacked a solution myself. 2 days of work but now I'm happy again :-) Thanks anyway!!

BlueM commented 7 years ago

Good to hear you found a solution.

Regarding your Bash cliclick example: I am not sure why you use a loop – and I also assume that’s the reason why it didn’t work. I tried it just myself with success (with the text being in BBEdit) using basically your approach, but without loop:

#!/usr/bin/env bash

# Bring the application under cursor to front (which is only required because
# I invoke the script from the shell. Would not be needed in "production",
# as I would then use a hotkey manager to trigger it.
cliclick c:.

# Start selection
cliclick dd:.

# Time to move the cursor yourself
sleep 2

# Finish selection
cliclick du:.

# This could have all been written like this:
# cliclick c:. dd:. w:2000 du:.

However, I guess it is not really usable anyway, due to the fixed 2 second time span, which may be too short or too long.

axgkl commented 7 years ago

@BlueM

Hey, thanks. For your amusement:

I am not sure why you use a loop

The loop was really just for somewhat effective testing - my tough luck was that I was using chrome based apps to check from the start, making me question my intelligence and cry for help ;-)

Trying to say: Your example moves windows and even selects - even in Firefox and all 'normal' apps. But at least with all chromium based apps fails, e.g. also atom (try select or tab detach).

-> To really get a full mouse down emulation with subsequent drag support one has to really intercept all subsequent mouse moves and, for chrome, not forward them into the app but emulate the right events, i.e. drags... Karabiner seemed to have been able to do this far more elegant, by "remapping a level lower, before user space apps see anything".

Here is my solution, found somebody who created a "vimouse" in a lua api, based on a framework called hammerspoon - from there it was try and error but finally got me there.... I'm one happy camper again :-)

BlueM commented 7 years ago

I was aware that applications behave differently, especially in respect to timing – but I didn’t know that it doesn’t work at all in Chrome (which I can reproduce).

axgkl commented 7 years ago

yes. the problem is that in cocoa a mouse move and a mouse drag seem to be 2 different kind of events (which makes sense). Most apps don't care, leave it to cocoa to e.g. get text selected, which selects on mouse move OR mouse drag if they are in between a mouse down or mouse up . Or move the window to the up position when they are off by position.

But apps could decide to handle drag and move specifically, i.e. "tap" the drag events and only then e.g. decide to mark text as selected or detach a browser tab.

All in all: I think it would be possible and may even make sense for your app to provide a flag to making it send drag events after a mouse down (dd) until a mouse up (du). E.g. by calculating the path between click down and up and send a few drag events in between by configurable time. Then people could automate and watch e.g. a browser tab detached, moving (redrawn) from position at cliclick dd to cliclick du ;-)