Hammerspoon / hammerspoon

Staggeringly powerful macOS desktop automation with Lua
http://www.hammerspoon.org
MIT License
12.07k stars 583 forks source link

Focus follow mouse #959

Closed ygstr closed 8 years ago

ygstr commented 8 years ago

I'm wondering if it's possible to get focus follow mouse in hammerspoon? If it's not possible to any applications exist that allow me to do this?

asmagill commented 8 years ago

Short answer, no.

Long answer... it depends on what you really mean, which applications you want, and how much effort you're willing to put into it... to my knowledge, no one has done this yet with Hammerspoon, though I think you might be able to get to something close... Apple doesn't really support FFM, so even with the notes that follow, expect it to be buggy and for some applications to simply not work no matter what you try.

There is a (long), but informative write up on this at http://steve-yegge.blogspot.com/2008/04/settling-osx-focus-follows-mouse-debate.html. If you want to go forward, I strongly suggest reading it, but I'll summarize a bit here...

First, Focus-Follow-Mouse means different things to different people. For some it really should be called "Auto-Raise"... in this type, you move your mouse over a window, it hovers for a time, and if it hovers long enough, then the other application is brought to the front and made the Active application. This is usually not what people mean/want, especially if they're coming from Linux backgrounds, because it can have the effect of things popping forward and backwards, or introducing a noticeable delay that takes just as long as a mouse click would.

The other flavor leaves the windows where they are, but switches keyboard focus to the application under the mouse pointer. The Mac doesn't do well with this because only the front-most application (active application) has an active menubar which means only it can receive command keys (shortcuts), etc. And if the other window is in the same application (think multiple terminal windows)... well, only one window in a given application can be key, and only the key window can receive text, and Hammerspoon can't change the key window of an application without raising it.

For me, the only application I really cared about being able to manipulate without having to bring it forward was the Apple Terminal application... luckily this supports accepting text input without being focused by typing defaults write com.apple.Terminal FocusFollowsMouse -bool YES into a terminal window and restarting the Terminal application... now I can hover over a terminal window and type into it... I can't use Cmd-V to paste things, but I can live with that.

However, if you really want to try something more applicable across all applications, I would read the above link well, especially the section where he talks about event-taps... then check out the docs for hs.eventtap in hammerspoon...

Decide which flavor you want.

For Auto-Raise, I think you'd need to do something like:

  1. use eventtap to track mouse movement, checking the window under the mouse pointer against the frontmost window
  2. if the windows differ, then start a timer (hs.timer.doAfter) for however long you want to hover. If the mouse moves again, any currently running timer should be stopped. If the mouse doesn't move, and the timer runs out, then call the focus method on the new window

For Focus without Raise, something more like:

  1. use eventtap to track mouse movement, checking the window under the mouse pointer against the frontmost window
  2. if the windows differ, then check the applications.
  3. if the applications differ, then start a new eventtap to track keyboard events. In this new eventtap, all keyup and keydown events would need to be redirected to the destination application (see hs.eventtap.event:post(app), but you'll want to wait for the next Hammerspoon release or use a development build of your own -- we recently found a bug which will cause this to crash in the current release).
  4. if the applications do not differ, then stop any currently running keyboard event watcher

You'll probably also need to use an application watcher (hs.application.watcher) so that any time you actually switch to another application, any currently running keyboard watcher is reset, and I'm sure I've forgotten some other things you'll need to watch for, but this should give you an idea of how to start.

cmsj commented 8 years ago

(excellent response by @asmagill. I don't think there is any work to be done here in Hammerspoon - I don't see myself writing it, but if someone else wants to do the work, please feel free to re-open this issue)

jasha-hrp commented 2 months ago

The yabai project has a focus_follows_mouse setting that I believe achieves what the OP is asking about.