mirror of
https://github.com/go-vgo/robotgo
synced 2026-05-24 02:08:33 +00:00
Fix macOS modifier state for key combos
This commit is contained in:
parent
e0f2ad88c0
commit
7d33bee757
2 changed files with 122 additions and 22 deletions
95
key.go
95
key.go
|
|
@ -372,19 +372,21 @@ func checkKeyCodes(k string) (key C.MMKeyCode, err error) {
|
|||
|
||||
func checkKeyFlags(f string) (flags C.MMKeyFlags) {
|
||||
m := map[string]C.MMKeyFlags{
|
||||
"alt": C.MOD_ALT,
|
||||
"ralt": C.MOD_ALT,
|
||||
"lalt": C.MOD_ALT,
|
||||
"cmd": C.MOD_META,
|
||||
"rcmd": C.MOD_META,
|
||||
"lcmd": C.MOD_META,
|
||||
"ctrl": C.MOD_CONTROL,
|
||||
"rctrl": C.MOD_CONTROL,
|
||||
"lctrl": C.MOD_CONTROL,
|
||||
"shift": C.MOD_SHIFT,
|
||||
"rshift": C.MOD_SHIFT,
|
||||
"lshift": C.MOD_SHIFT,
|
||||
"none": C.MOD_NONE,
|
||||
"alt": C.MOD_ALT,
|
||||
"ralt": C.MOD_ALT,
|
||||
"lalt": C.MOD_ALT,
|
||||
"cmd": C.MOD_META,
|
||||
"command": C.MOD_META,
|
||||
"rcmd": C.MOD_META,
|
||||
"lcmd": C.MOD_META,
|
||||
"ctrl": C.MOD_CONTROL,
|
||||
"control": C.MOD_CONTROL,
|
||||
"rctrl": C.MOD_CONTROL,
|
||||
"lctrl": C.MOD_CONTROL,
|
||||
"shift": C.MOD_SHIFT,
|
||||
"rshift": C.MOD_SHIFT,
|
||||
"lshift": C.MOD_SHIFT,
|
||||
"none": C.MOD_NONE,
|
||||
}
|
||||
|
||||
if v, ok := m[f]; ok {
|
||||
|
|
@ -408,6 +410,51 @@ func getFlagsFromValue(value []string) (flags C.MMKeyFlags) {
|
|||
return
|
||||
}
|
||||
|
||||
func modifierFlagForKeyName(key string) (C.MMKeyFlags, bool) {
|
||||
flag := checkKeyFlags(key)
|
||||
return flag, flag != C.MOD_NONE
|
||||
}
|
||||
|
||||
func modifierKeyEventDownDarwin(keyArr []string, pid int) C.MMKeyFlags {
|
||||
var active C.MMKeyFlags
|
||||
|
||||
for _, key := range keyArr {
|
||||
flag, ok := modifierFlagForKeyName(key)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
keyCode, err := checkKeyCodes(key)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
active |= flag
|
||||
C.toggleKeyCode(keyCode, true, active, C.uintptr(pid))
|
||||
MilliSleep(1)
|
||||
}
|
||||
|
||||
return active
|
||||
}
|
||||
|
||||
func modifierKeyEventUpDarwin(keyArr []string, pid int, active C.MMKeyFlags) {
|
||||
for i := len(keyArr) - 1; i >= 0; i-- {
|
||||
flag, ok := modifierFlagForKeyName(keyArr[i])
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
keyCode, err := checkKeyCodes(keyArr[i])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
active &^= flag
|
||||
C.toggleKeyCode(keyCode, false, active, C.uintptr(pid))
|
||||
MilliSleep(1)
|
||||
}
|
||||
}
|
||||
|
||||
func upKeyArr(keyArr []string, pid int) {
|
||||
for i := 0; i < len(keyArr); i++ {
|
||||
key1, _ := checkKeyCodes(keyArr[i])
|
||||
|
|
@ -422,6 +469,14 @@ func keyTaps(k string, keyArr []string, pid int) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if runtime.GOOS == "darwin" && len(keyArr) > 0 {
|
||||
active := modifierKeyEventDownDarwin(keyArr, pid)
|
||||
tapKeyCode(key, active, C.uintptr(pid))
|
||||
MilliSleep(KeySleep)
|
||||
modifierKeyEventUpDarwin(keyArr, pid, active)
|
||||
return nil
|
||||
}
|
||||
|
||||
tapKeyCode(key, flags, C.uintptr(pid))
|
||||
MilliSleep(KeySleep)
|
||||
upKeyArr(keyArr, pid)
|
||||
|
|
@ -451,6 +506,20 @@ func keyTogglesB(k string, down bool, keyArr []string, pid int) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if runtime.GOOS == "darwin" && len(keyArr) > 0 {
|
||||
if down {
|
||||
active := modifierKeyEventDownDarwin(keyArr, pid)
|
||||
C.toggleKeyCode(key, C.bool(down), active, C.uintptr(pid))
|
||||
MilliSleep(KeySleep)
|
||||
return nil
|
||||
}
|
||||
|
||||
C.toggleKeyCode(key, C.bool(down), flags, C.uintptr(pid))
|
||||
MilliSleep(KeySleep)
|
||||
modifierKeyEventUpDarwin(keyArr, pid, flags)
|
||||
return nil
|
||||
}
|
||||
|
||||
C.toggleKeyCode(key, C.bool(down), flags, C.uintptr(pid))
|
||||
MilliSleep(KeySleep)
|
||||
if !down {
|
||||
|
|
|
|||
|
|
@ -66,6 +66,29 @@
|
|||
return 0;
|
||||
}
|
||||
|
||||
static CGEventSourceRef CreateKeyboardEventSource(void) {
|
||||
return CGEventSourceCreate(kCGEventSourceStateCombinedSessionState);
|
||||
}
|
||||
|
||||
static CGEventFlags modifierFlagForKeyCode(MMKeyCode code) {
|
||||
if (code == K_META || code == K_LMETA || code == K_RMETA) {
|
||||
return kCGEventFlagMaskCommand;
|
||||
}
|
||||
if (code == K_ALT || code == K_LALT || code == K_RALT) {
|
||||
return kCGEventFlagMaskAlternate;
|
||||
}
|
||||
if (code == K_CONTROL || code == K_LCONTROL || code == K_RCONTROL) {
|
||||
return kCGEventFlagMaskControl;
|
||||
}
|
||||
if (code == K_SHIFT || code == K_LSHIFT || code == K_RSHIFT) {
|
||||
return kCGEventFlagMaskShift;
|
||||
}
|
||||
if (code == K_CAPSLOCK) {
|
||||
return kCGEventFlagMaskAlphaShift;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static io_connect_t _getAuxiliaryKeyDriver(void) {
|
||||
static mach_port_t sEventDrvrRef = 0;
|
||||
mach_port_t masterPort, service, iter;
|
||||
|
|
@ -176,19 +199,27 @@ void toggleKeyCode(MMKeyCode code, const bool down, MMKeyFlags flags, uintptr pi
|
|||
event.compound.subType = NX_SUBTYPE_AUX_CONTROL_BUTTONS;
|
||||
event.compound.misc.L[0] = evtInfo;
|
||||
|
||||
kr = IOHIDPostEvent(_getAuxiliaryKeyDriver(),
|
||||
kr = IOHIDPostEvent(_getAuxiliaryKeyDriver(),
|
||||
NX_SYSDEFINED, loc, &event, kNXEventDataVersion, 0, FALSE);
|
||||
assert(KERN_SUCCESS == kr);
|
||||
} else {
|
||||
CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
|
||||
CGEventFlags modifierFlag = modifierFlagForKeyCode(code);
|
||||
CGEventFlags eventFlags = (CGEventFlags)flags;
|
||||
CGEventType eventType = down ? kCGEventKeyDown : kCGEventKeyUp;
|
||||
if (modifierFlag != 0) {
|
||||
eventType = kCGEventFlagsChanged;
|
||||
if (eventFlags == 0 && down) {
|
||||
eventFlags = modifierFlag;
|
||||
}
|
||||
}
|
||||
|
||||
CGEventSourceRef source = CreateKeyboardEventSource();
|
||||
CGEventRef keyEvent = CGEventCreateKeyboardEvent(source, (CGKeyCode)code, down);
|
||||
assert(keyEvent != NULL);
|
||||
|
||||
CGEventSetType(keyEvent, down ? kCGEventKeyDown : kCGEventKeyUp);
|
||||
if (flags != 0) {
|
||||
CGEventSetFlags(keyEvent, (CGEventFlags) flags);
|
||||
}
|
||||
|
||||
CGEventSetType(keyEvent, eventType);
|
||||
CGEventSetFlags(keyEvent, eventFlags);
|
||||
|
||||
SendTo(pid, keyEvent);
|
||||
CFRelease(source);
|
||||
}
|
||||
|
|
@ -276,7 +307,7 @@ void toggleKey(char c, const bool down, MMKeyFlags flags, uintptr pid) {
|
|||
convert characters to a keycode, but does not support adding modifier flags.
|
||||
It is only used in typeString().
|
||||
-- if you need modifier keys, use the above functions instead. */
|
||||
CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
|
||||
CGEventSourceRef source = CreateKeyboardEventSource();
|
||||
CGEventRef keyEvent = CGEventCreateKeyboardEvent(source, 0, down);
|
||||
if (keyEvent == NULL) {
|
||||
fputs("Could not create keyboard event.\n", stderr);
|
||||
|
|
@ -357,4 +388,4 @@ void unicodeType(const unsigned value, uintptr pid, int8_t isPid) {
|
|||
int input_utf(const char *utf){
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue