12

I'm looking for a way to design a little panel with modifier keys on it (shift, command for example) and have to possibility to click on it like a virtual keyboard.

I'd like it to have this behavior :

  • click on the virtual key (shift).
  • the shift button holds, and keeps being pressed.
  • type something with my standard keyboard.
  • click another time on the virtual shift key to release it.

here is the code I'm using :

CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
CGEventRef shiftKeyDown = CGEventCreateKeyboardEvent(source, (CGKeyCode)56, YES);
CGEventRef shiftKeyUp = CGEventCreateKeyboardEvent(source, (CGKeyCode)56, NO);

CGEventPost(kCGAnnotatedSessionEventTap, shiftKeyDown);
CGEventPost(kCGAnnotatedSessionEventTap, shiftKeyUp);

CFRelease(shiftKeyUp);
CFRelease(shiftKeyDown);
CFRelease(source);

I can't find a way to keep it pressed until I click on it another time. I though "Push On Push Off" Button Cell type was the key but unfortunately no. :-)

any help ?

thanks in advance.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
user2604306
  • 121
  • 3
  • 2
    I have a similar problem with CGEventPost, I'm trying to simulate modifier keys holding down, but I found interestingly just when I moved my actual mouse or pressed any key on my actual keyboard, those modifier keys would be reset, proved by checking build-in keyboard viewer. Is it the same case for you? – Jerry May 22 '14 at 10:50
  • Were you able to resolve this issue? I'm seeing the same thing. – Jason Stallings Jun 04 '16 at 20:24
  • Having the same problem. – aristidesfl Mar 03 '17 at 02:04
  • @aristidesfl Like Sticky Keys? – Willeke Mar 04 '17 at 14:25
  • @Willeke if you mean the following, then no: "Sticky Keys serializes keystrokes instead of pressing multiple keys at a time, allowing the user to press and release a modifier key, such as Shift, Ctrl, Alt, or the Windows key, and have it remain active until any other key is pressed." – aristidesfl Mar 05 '17 at 17:04
  • @Willeke I mean that whenever a key down event is sent after a modifier down event, the modifier is not down anymore for subsequent keydown events. – aristidesfl Mar 05 '17 at 17:06
  • Press Shift twice and it will stick until pressed again. – Willeke Mar 06 '17 at 16:00
  • @Willeke that is not related to the question you are talking about different thing – aristidesfl Mar 08 '17 at 13:12

1 Answers1

4

A shift key virtually pressed that way, will get released automatically when followed by an event which doesn't contain a shift flag. This seems to be a limitation, or possibly a bug, considering the documentation sort of indicates otherwise: https://developer.apple.com/reference/coregraphics/cgevent/1456564-init#discussion

The only way I found to achieve what you are looking for, is to setup an event listener, and add the shift flag to every event which should be modified by the Shift key.

Example on how to listen to keyboard events: https://stackoverflow.com/a/31898592/1445812 (Swift)

Example on how to had the shift flag to intercepted events:

event?.flags.insert(.maskShift)

Hope this helps. If anyone knows how to do the same without having to add the flags to every event, please do tell.

Community
  • 1
  • 1
aristidesfl
  • 1,310
  • 10
  • 15
  • AppleScript: `tell application "System Events" to shift key down` and `tell application "System Events" to shift key up`. – Willeke Mar 11 '17 at 16:57
  • @Willeke aware of that, but how do you listen for key events in applescript? – aristidesfl Mar 12 '17 at 21:54
  • You don't have to listen, the shift key stays down. – Willeke Mar 13 '17 at 09:54
  • I understand, but the point of this application is to press and release modifiers in response to other key presses. Without the ability to do that in, can't use applescript for this app. – aristidesfl Mar 13 '17 at 16:24