Hammerspoon: newSystemKeyEvent with CAPS_LOCK is not working in Sierra

Created on 30 Sep 2016  路  9Comments  路  Source: Hammerspoon/hammerspoon

hs.eventtap.event.newSystemKeyEvent('CAPS_LOCK', true)
hs.eventtap.event.newSystemKeyEvent('CAPS_LOCK', false)

not work

However,

hs.eventtap.event.newSystemKeyEvent('MUTE', true)
hs.eventtap.event.newSystemKeyEvent('MUTE', false)

works

Most helpful comment

I don't know. It's something I'd like to fix if possible, but it requires a lot of experimentation because these events are not part of the Quartz Core Graphics environment. I'm hoping to work on this with the eventtap rewrite currently underway, but I don't expect that all of the system keys will ever be fully supported, at least not for generation of new events.

And no I don't know why some things which seemed to work in 10.10 don't in 10.11 or 10.12.

More detail if you want it:

hs.eventtap.event.newSystemKeyEvent has always been something of a half-working function. Access to these events relies on the NSEvent class and these events are properly posted through NSApplication's sendEvent: method which means we should only be able to post them to Hammerspoon itself and not to the system in general. Most of the other events are handled through Quartz CGEvents which we can post to any application or to the window server (user login session). Now there are some conversion functions/methods between the two, and this is what newSystemKeyEvent relies on, but... not all events which can be expressed as an NSEvent can be properly expressed as a CGEvent, and the documentation is vague as to why, just saying that the methods return nil if no conversion is possible.

If you or anyone else want to take a crack at it, or have some suggested resources which show how to work around these limitations or go into more detail than Apple's API docs, please let me know.

All 9 comments

I've found that only some of the system keys work properly and I'm not sure why... I'll add it to the things to look closer at when working on #1025 this weekend.

It doesn't seem to work in El Capitan either, so it is likely not specific to Sierra.

PREVIOUS and NEXT don't work either. tested on both El Capitan and Sierra.

update: not sure why REWIND and FAST are working as PREVIOUS and NEXT somehow. But CAPS_LOCK still doesn't work for me. Looking forward to the fix.

is there any chance that this issue could be fixed?

I don't know. It's something I'd like to fix if possible, but it requires a lot of experimentation because these events are not part of the Quartz Core Graphics environment. I'm hoping to work on this with the eventtap rewrite currently underway, but I don't expect that all of the system keys will ever be fully supported, at least not for generation of new events.

And no I don't know why some things which seemed to work in 10.10 don't in 10.11 or 10.12.

More detail if you want it:

hs.eventtap.event.newSystemKeyEvent has always been something of a half-working function. Access to these events relies on the NSEvent class and these events are properly posted through NSApplication's sendEvent: method which means we should only be able to post them to Hammerspoon itself and not to the system in general. Most of the other events are handled through Quartz CGEvents which we can post to any application or to the window server (user login session). Now there are some conversion functions/methods between the two, and this is what newSystemKeyEvent relies on, but... not all events which can be expressed as an NSEvent can be properly expressed as a CGEvent, and the documentation is vague as to why, just saying that the methods return nil if no conversion is possible.

If you or anyone else want to take a crack at it, or have some suggested resources which show how to work around these limitations or go into more detail than Apple's API docs, please let me know.

Not sure if my suggestion will help, but anyway, maybe it is worth inspecting the source code of Karabiner-Elements? I do remember, than in early version it had problems with capslock as well, but then it was fixed in the latest version.

Looks like associated code is here: https://github.com/tekezo/Karabiner-Elements/blob/master/src/core/grabber/include/event_tap_manager.hpp

Karabiner creates a virtual keyboard, so using eventtap might not be enough. Here's some more info: http://stackoverflow.com/questions/2935931/cant-block-capslock-with-cgeventtap

I've noticed that I can't block caps lock by returning true after intercepting an event with Hammerspoon either.

Karabiner runs in the kernel, its source is operating at a very different level than us. I have a very low estimation of success for us to be able to properly influence caps lock.

I'm going to close this issue out because it doesn't seem to be getting any traction. Anyone please feel free to re-open it if you want to work on this :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tomrbowden picture tomrbowden  路  3Comments

aaronjensen picture aaronjensen  路  3Comments

latenitefilms picture latenitefilms  路  3Comments

agzam picture agzam  路  3Comments

lazandrei19 picture lazandrei19  路  4Comments