|
1 | 1 | /* |
2 | | - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. |
| 2 | + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. |
3 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | 4 | * |
5 | 5 | * This code is free software; you can redistribute it and/or modify it |
|
63 | 63 | static int gsEventNumber; |
64 | 64 | static int* gsButtonEventNumber; |
65 | 65 | static NSTimeInterval gNextKeyEventTime; |
| 66 | +static CGEventFlags initFlags; |
| 67 | +static CGEventFlags allModifiersMask = kCGEventFlagMaskShift | kCGEventFlagMaskControl |
| 68 | + | kCGEventFlagMaskAlternate | kCGEventFlagMaskCommand |
| 69 | + | kCGEventFlagMaskAlphaShift | kCGEventFlagMaskSecondaryFn; |
66 | 70 |
|
67 | 71 | static inline CGKeyCode GetCGKeyCode(jint javaKeyCode); |
| 72 | +static inline int GetCGKeyMask(int cgKeyCode); |
68 | 73 |
|
69 | 74 | static void PostMouseEvent(const CGPoint point, CGMouseButton button, |
70 | 75 | CGEventType type, int clickCount, int eventNumber); |
@@ -121,6 +126,13 @@ static inline void autoDelay(BOOL isMove) { |
121 | 126 | jboolean copy = JNI_FALSE; |
122 | 127 |
|
123 | 128 | setupDone = 1; |
| 129 | + // initialize CGEventFlags here - which is used in keyEvent |
| 130 | + initFlags = CGEventSourceFlagsState(kCGEventSourceStateHIDSystemState); |
| 131 | + |
| 132 | + // Clear Function flag bits if they are set |
| 133 | + if ((initFlags & kCGEventFlagMaskSecondaryFn) != 0) { |
| 134 | + initFlags ^= kCGEventFlagMaskSecondaryFn; |
| 135 | + } |
124 | 136 | // Don't block local events after posting ours |
125 | 137 | CGSetLocalEventsSuppressionInterval(0.0); |
126 | 138 |
|
@@ -291,12 +303,25 @@ static inline void autoDelay(BOOL isMove) { |
291 | 303 | CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); |
292 | 304 | CGKeyCode keyCode = GetCGKeyCode(javaKeyCode); |
293 | 305 | CGEventRef event = CGEventCreateKeyboardEvent(source, keyCode, keyPressed); |
| 306 | + |
294 | 307 | if (event != NULL) { |
295 | | - CGEventFlags flags = CGEventSourceFlagsState(kCGEventSourceStateHIDSystemState); |
296 | | - if ((flags & kCGEventFlagMaskSecondaryFn) != 0) { |
297 | | - flags ^= kCGEventFlagMaskSecondaryFn; |
298 | | - CGEventSetFlags(event, flags); |
| 308 | + int flagMaskValue = GetCGKeyMask(keyCode); |
| 309 | + if (OSX_Undefined != flagMaskValue) { |
| 310 | + if (keyCode == OSX_CapsLock) { |
| 311 | + if (keyPressed) { |
| 312 | + initFlags ^= flagMaskValue; |
| 313 | + } |
| 314 | + } else { |
| 315 | + initFlags = keyPressed |
| 316 | + ? (initFlags | flagMaskValue) // add flag bits if modifier key pressed |
| 317 | + : (initFlags & ~flagMaskValue); // clear flag bits if modifier key released |
| 318 | + } |
299 | 319 | } |
| 320 | + |
| 321 | + CGEventFlags flags = CGEventSourceFlagsState(kCGEventSourceStateHIDSystemState); |
| 322 | + flags = (initFlags & allModifiersMask) | (flags & (~allModifiersMask)); |
| 323 | + CGEventSetFlags(event, flags); |
| 324 | + |
300 | 325 | CGEventPost(kCGHIDEventTap, event); |
301 | 326 | CFRelease(event); |
302 | 327 | } |
@@ -398,6 +423,12 @@ static inline CGKeyCode GetCGKeyCode(jint javaKeyCode) |
398 | 423 | return [keyCodeMapping getOSXKeyCodeForJavaKey:javaKeyCode]; |
399 | 424 | } |
400 | 425 |
|
| 426 | +static inline int GetCGKeyMask(int cgKeyCode) |
| 427 | +{ |
| 428 | + CRobotKeyCodeMapping *keyCodeMapping = [CRobotKeyCodeMapping sharedInstance]; |
| 429 | + return [keyCodeMapping getFlagMaskForCGKey:cgKeyCode]; |
| 430 | +} |
| 431 | + |
401 | 432 | static int GetClickCount(BOOL isDown) { |
402 | 433 | NSTimeInterval now = [[NSDate date] timeIntervalSinceReferenceDate]; |
403 | 434 | NSTimeInterval clickInterval = now - gsLastClickTime; |
|
0 commit comments