I'd like to disable Hammerspoon while in Xcode. There's a lot of different keyboard shortcuts that I use in Xcode and some conflict with Hammerspoon. Additionally, I'd prefer that I didn't accidentally change my Xcode window by accident. So, I'd like to selectively disable Hammerspoon while in certain applications.
I'm pretty sure you should already be able to come up with a config that behaves like this:
What I would do is register an hs.application.watcher (http://www.hammerspoon.org/docs/hs.application.watcher.html) that checks to see if Xcode is being activated or deactivated - now you know when you want to disable/enable your hotkeys.
From there, you could either keep a reference to all of your hotkeys and call :enable()/:disable() on each, at the relevant moment, or probably more usefully, register all of your hotkeys with hs.hotkey.modal (http://www.hammerspoon.org/docs/hs.hotkey.modal.html), call :enter() on the modal state when Hammerspoon first starts, then just call :exit()/:enter() on the modal state object in your application watcher callback, depending on whether Xcode is being activated/deactivated.
So as an (admittedly untested) example, something like:
-- Create a modal hotkey object with an absurd triggering hotkey, since it will never be triggered from the keyboard
hotkeys = hs.hotkey.modal.new({"cmd", "shift", "alt"}, "F19")
-- Bind all your normal hotkeys to the modal state object
hotkeys:bind({"cmd"}, "f", function() doSomething() end)
hotkeys:bind({"cmd"}, "d", function() doSomethingElse() end)
-- Define a callback function to be called when application events happen
function applicationWatcherCallback(appName, eventType, appObject)
if (appName == "Xcode") then
if (eventType == hs.application.watcher.activated) then
-- Xcode just got focus, disable our hotkeys
hotkeys:exit()
elseif (eventType == hs.application.watcher.deactivated) then
-- Xcode just lost focus, enable our hotkeys
hotkeys:enter()
end
end
end
-- Create and start the application event watcher
watcher = hs.application.watcher.new(applicationWatcherCallback)
watcher:start()
-- Activate the modal state
hotkeys:enter()
Does that seem sufficient?
Thanks! I realized after I posted that there might be a way to do it where I disabled things when in the app, so I really appreciate laying out how to do it. This is great as the window managers I've seen don't really support disabling it in specific apps. There's a lot in Hammerspoon I like so this will allow me to give it a good try.
Awesome :)
I'll close out this issue, but feel free to re-open it if necessary!
I'll see if this solution (or something along this lines) works. If so, I'll put up a post describing it so it can be linked in the Wiki.
This script works great, thank you!
However, it generates a lot of errors in the console such as:
ERROR: hotkey: The hotkey was deleted, cannot enable it
Is there an easy way to prevent this error from happening? Sorry for digging up an old discussion.
The error is a known problem with 0.9.47, and while it seems to be merely noisy for some, others have reported that modal keys aren't closed out properly when the error occurs... in any event, a fix has been submitted that will be in the next release, but in the meantime, you can apply the fix yourself by following the instructions towards the end of issue #979.
Awesome - thanks so much! We'll await the next release.
Most helpful comment
I'm pretty sure you should already be able to come up with a config that behaves like this:
What I would do is register an hs.application.watcher (http://www.hammerspoon.org/docs/hs.application.watcher.html) that checks to see if Xcode is being activated or deactivated - now you know when you want to disable/enable your hotkeys.
From there, you could either keep a reference to all of your hotkeys and call :enable()/:disable() on each, at the relevant moment, or probably more usefully, register all of your hotkeys with hs.hotkey.modal (http://www.hammerspoon.org/docs/hs.hotkey.modal.html), call :enter() on the modal state when Hammerspoon first starts, then just call :exit()/:enter() on the modal state object in your application watcher callback, depending on whether Xcode is being activated/deactivated.
So as an (admittedly untested) example, something like:
Does that seem sufficient?