Hi, thanks a lot for hammerspoon! It's great! I'm a newb, but looking through the issues, I didn't find something related to the problem I have encountered. I'm using Karabiner-Elements to "Change caps_lock to command+control+option+shift", and defined in init.lua as local hyper = { "cmd", "alt", "ctrl", "shift"}. It works for all the keys I've defined (see below) except for the comma, (and I haven't tried all the keys on the keyboard, like dot, backslash, and so on). When I press hyper+, it just makes the screen go bright for a second, as though it were trying to tell me there was some kind of error ;)
The reason I wanted to use the comma is that I'm trying to have symmetry in the keys I'm using for organising the windows. So, "g", "h", "j", "k", "l", and ";" move the window from left-30, left-50, left-70, right-70, right-50, right-30; and then I wanted to have "y" and "i" to define the top left and right quarters, and "n" and "," to define the bottom left and right quarters. Anyway, here's the init.lua. Any help would be appreciated.
local hyper = { "cmd", "alt", "ctrl", "shift"}
-- Reload config
hs.hotkey.bind(hyper, "0", function()
hs.reload()
end)
hs.notify.new({title="Hammerspoon", informativeText="Config loaded"}):send()
-- Disable animations
hs.window.animationDuration = 0
-- Active window control
-- Left upper quarter
hs.hotkey.bind(hyper, "y", function()
local win = hs.window.focusedWindow();
if not win then return end
win:moveToUnit(hs.geometry({x=0, y=0, w=0.5, h=0.5}))
end)
-- Right upper quarter
hs.hotkey.bind(hyper, "i", function()
local win = hs.window.focusedWindow();
if not win then return end
win:moveToUnit(hs.geometry({x=0.5, y=0, w=0.5, h=0.5}))
end)
-- Left bottom quarter
hs.hotkey.bind(hyper, "n", function()
local win = hs.window.focusedWindow();
if not win then return end
win:moveToUnit(hs.geometry({x=0, y=0.5, w=0.5, h=0.5}))
end)
-- Right bottom quarter
hs.hotkey.bind(hyper, ",", function()
local win = hs.window.focusedWindow();
if not win then return end
win:moveToUnit(hs.geometry.rect({x=0.5, y=0.5, w=0.5, h=0.5}))
end)
-- Left half of screen 30%
hs.hotkey.bind(hyper, "g", function()
local win = hs.window.focusedWindow();
if not win then return end
win:moveToUnit(hs.layout.left25)
end)
-- Left half of screen 50%
hs.hotkey.bind(hyper, "h", function()
local win = hs.window.focusedWindow();
if not win then return end
win:moveToUnit(hs.layout.left50)
end)
-- Left half of screen 70%
hs.hotkey.bind(hyper, "j", function()
local win = hs.window.focusedWindow();
if not win then return end
win:moveToUnit(hs.layout.left75)
end)
-- Right half of screen 70%
hs.hotkey.bind(hyper, "k", function()
local win = hs.window.focusedWindow();
if not win then return end
win:moveToUnit(hs.layout.right75)
end)
-- Right half of screen 50%
hs.hotkey.bind(hyper, "l", function()
local win = hs.window.focusedWindow();
if not win then return end
win:moveToUnit(hs.layout.right50)
end)
-- Right half of screen 30%
hs.hotkey.bind(hyper, ";", function()
local win = hs.window.focusedWindow();
if not win then return end
win:moveToUnit(hs.layout.right25)
end)
-- Applications
local applicationHotkeys = {
b = 'Sublime Text',
c = 'Calendar',
e = 'Mail',
f = 'Finder',
m = 'Messages',
o = 'OmniFocus',
p = 'Preview',
s = 'Safari',
t = 'TextEdit',
x = 'Terminal',
r = 'TogglDesktop'
}
for key, app in pairs(applicationHotkeys) do
hs.hotkey.bind(hyper, key, function()
hs.application.launchOrFocus(app)
end)
end
Using this simple test:
hs.hotkey.bind({"cmd", "alt", "ctrl", "shift"}, ",", function()
print("test")
end)
...also produces a "flash" on the screen. I believe this is because CONTROL+OPTION+COMMAND+SHIFT+COMMA starts generating a system diagnostic report.
Unfortunately I can't think of a good way around this, apart from maybe using a different hyper key for this shortcut?
http://krypted.com/tag/control-option-command-shift-period/
When I use your combination with the comma, however, in the Console app the following showed up in the system logs:
~
default 02:18:26.089658-0500 sysdiagnose request: sysdiagnose (tailspin only) keychord: Cmd-Opt-Ctrl-Shift-Comma
default 02:18:26.089792-0500 sysdiagnose Increased diagnostic atomic count to 1.
default 02:18:26.089895-0500 sysdiagnose Screen flash
default 02:18:26.089925-0500 sysdiagnose tailspin key chord pressed
default 02:18:26.090198-0500 sysdiagnose Dumping tailspin to '
default 02:18:26.134042-0500 sysdiagnose Executing '
default 02:18:26.134516-0500 sysdiagnose Failed to create error file for writing at path:
default 02:18:26.142745-0500 sysdiagnose Child process '
default 02:18:26.142868-0500 sysdiagnose
default 02:18:26.143014-0500 sysdiagnose Elapsed time: 0.009062 seconds for task '
default 02:18:26.143146-0500 sysdiagnose Finished serial execution.
default 02:18:26.143227-0500 sysdiagnose OK, all tasks done.
default 02:18:26.143359-0500 sysdiagnose Decreased diagnostic atomic count to 0.
default 02:18:26.143385-0500 sysdiagnose Current client TAILSPIN KEYCHORD
~
So, apparently the comma with the full combination of modifiers is also off limits as well.
You can use hs.eventtap to capture these, but you'll probably start to see keyboard dropouts when Hammerspoon gets busy or is too slow to respond... it's why we haven't moved hs.hotkey to an eventtap model -- we can't guarantee a fast enough response time all of the time to prevent random periods where the keyboard just seems to stop working, then all of a sudden does, spewing about half of what you typed while it was locked up.
You guys are blazingly fast! Thank you!
Is the conclusion that using the hyper+comma is off limits, then, and I should just forget about it? Is there an easy way to get a complete set of off-limits keys which could be added to the docs to avoid the raising of issues like this one?
Unless you want to experiment with hs.eventtap I would consider hyper-, and hyper-. off limits.
I don't want to scare you away from checking out hs.eventtap -- using an eventtap to capture keyUp/keyDown events has its place and works fine for short periods if you can write your logic to know when to enable or disable it, say when a specific application is in the foreground, or when you've entered a modal hotkey state, for example. It's just that watching keyUp/keyDown events is an all or nothing thing -- you get all keys and have to write your code such that it returns with no change to the event when it's not a key you care about... it adds up and if you're always watching for the keys, keyboard input to everything on your system is dependent upon Hammerspoon not being slow at any time for any reason.
As to detecting them... not reliably... There are the functions hs.hotkey.assignable and hs.hotkey.systemAssigned that you can check out at http://www.hammerspoon.org/docs/hs.hotkey.html but as noted in the docs, they're best guesses and not 100% reliable, probably because some keys combinations don't use the same CoreFoundation framework that we do for our hotkeys... but that's a guess. The fact is that they're just not always reliable.
~~~lua
hs.hotkey.systemAssigned({"cmd", "alt", "shift", "ctrl"}, "."), hs.hotkey.assignable({"cmd", "alt", "shift", "ctrl"}, ".")
false true
hs.hotkey.systemAssigned({"cmd", "alt", "shift", "ctrl"}, ","), hs.hotkey.assignable({"cmd", "alt", "shift", "ctrl"}, ",")
false true
~~~
which by all accounts means that we should be able to use them... but as you've discovered, we can't.
Thanks a lot for you help. I really appreciate the speed of your response, and the thoroughness of your understanding and explanations.