cocoa: Check for capslock in -[NSResponder flagsChanged], not with IOKit. Using IOKit for this pops up a warning at startup on macOS 10.15 ("Catalina"), asking the user to authorize the app to listen to all keyboard input in the system, which is unacceptable. I _think_ we were using IOKit under incorrect presumptions here; the Stack Overflow link mentioned in it was complaining about not being able to use flagsChanged to differentiate between left and right mod keys, but that's not an issue for capslock. It's also possible this code was trying to deal with capslock changing when the window didn't have focus, but we handle this elsewhere now, if we didn't at the time.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
diff --git a/src/video/cocoa/SDL_cocoakeyboard.m b/src/video/cocoa/SDL_cocoakeyboard.m
index f986ded..574536b 100644
--- a/src/video/cocoa/SDL_cocoakeyboard.m
+++ b/src/video/cocoa/SDL_cocoakeyboard.m
@@ -29,7 +29,6 @@
#include "../../events/scancodes_darwin.h"
#include <Carbon/Carbon.h>
-#include <IOKit/hid/IOHIDLib.h>
/*#define DEBUG_IME NSLog */
#define DEBUG_IME(...)
@@ -187,115 +186,6 @@
@end
-/*------------------------------------------------------------------------------
-Set up a HID callback to properly detect Caps Lock up/down events.
-Derived from:
-http://stackoverflow.com/questions/7190852/using-iohidmanager-to-get-modifier-key-events
-*/
-
-static IOHIDManagerRef s_hidManager = NULL;
-
-static void
-HIDCallback(void *context, IOReturn result, void *sender, IOHIDValueRef value)
-{
- if (context != s_hidManager) {
- /* An old callback, ignore it (related to bug 2157 below) */
- return;
- }
-
- IOHIDElementRef elem = IOHIDValueGetElement(value);
- if (IOHIDElementGetUsagePage(elem) != kHIDPage_KeyboardOrKeypad
- || IOHIDElementGetUsage(elem) != kHIDUsage_KeyboardCapsLock) {
- return;
- }
- CFIndex pressed = IOHIDValueGetIntegerValue(value);
- SDL_SendKeyboardKey(pressed ? SDL_PRESSED : SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
-}
-
-static CFDictionaryRef
-CreateHIDDeviceMatchingDictionary(UInt32 usagePage, UInt32 usage)
-{
- CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault,
- 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- if (dict) {
- CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usagePage);
- if (number) {
- CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsagePageKey), number);
- CFRelease(number);
- number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage);
- if (number) {
- CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsageKey), number);
- CFRelease(number);
- return dict;
- }
- }
- CFRelease(dict);
- }
- return NULL;
-}
-
-static void
-QuitHIDCallback()
-{
- if (!s_hidManager) {
- return;
- }
-
-#if 0 /* Releasing here causes a crash on Mac OS X 10.10 and earlier,
- * so just leak it for now. See bug 2157 for details.
- */
- IOHIDManagerUnscheduleFromRunLoop(s_hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
- IOHIDManagerRegisterInputValueCallback(s_hidManager, NULL, NULL);
- IOHIDManagerClose(s_hidManager, 0);
-
- CFRelease(s_hidManager);
-#endif
- s_hidManager = NULL;
-}
-
-static void
-InitHIDCallback()
-{
- s_hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
- if (!s_hidManager) {
- return;
- }
- CFDictionaryRef keyboard = NULL, keypad = NULL;
- CFArrayRef matches = NULL;
- keyboard = CreateHIDDeviceMatchingDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard);
- if (!keyboard) {
- goto fail;
- }
- keypad = CreateHIDDeviceMatchingDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_Keypad);
- if (!keypad) {
- goto fail;
- }
- CFDictionaryRef matchesList[] = { keyboard, keypad };
- matches = CFArrayCreate(kCFAllocatorDefault, (const void **)matchesList, 2, NULL);
- if (!matches) {
- goto fail;
- }
- IOHIDManagerSetDeviceMatchingMultiple(s_hidManager, matches);
- IOHIDManagerRegisterInputValueCallback(s_hidManager, HIDCallback, s_hidManager);
- IOHIDManagerScheduleWithRunLoop(s_hidManager, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
- if (IOHIDManagerOpen(s_hidManager, kIOHIDOptionsTypeNone) == kIOReturnSuccess) {
- goto cleanup;
- }
-
-fail:
- QuitHIDCallback();
-
-cleanup:
- if (matches) {
- CFRelease(matches);
- }
- if (keypad) {
- CFRelease(keypad);
- }
- if (keyboard) {
- CFRelease(keyboard);
- }
-}
/* This is a helper function for HandleModifierSide. This
* function reverts back to behavior before the distinction between
@@ -585,8 +475,6 @@ Cocoa_InitKeyboard(_THIS)
data->modifierFlags = [NSEvent modifierFlags];
SDL_ToggleModState(KMOD_CAPS, (data->modifierFlags & NSEventModifierFlagCapsLock) != 0);
-
- InitHIDCallback();
}
void
@@ -712,7 +600,6 @@ Cocoa_HandleKeyEvent(_THIS, NSEvent *event)
void
Cocoa_QuitKeyboard(_THIS)
{
- QuitHIDCallback();
}
#endif /* SDL_VIDEO_DRIVER_COCOA */
diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m
index e922ef1..e030d9e 100644
--- a/src/video/cocoa/SDL_cocoawindow.m
+++ b/src/video/cocoa/SDL_cocoawindow.m
@@ -54,6 +54,9 @@
#define FULLSCREEN_MASK (SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN)
+#ifndef MAC_OS_X_VERSION_10_12
+#define NSEventModifierFlagCapsLock NSAlphaShiftKeyMask
+#endif
@interface SDLWindow : NSWindow <NSDraggingDestination>
/* These are needed for borderless/fullscreen windows */
@@ -849,14 +852,21 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
}
}
-
-/* We'll respond to key events by doing nothing so we don't beep.
+/* We'll respond to key events by mostly doing nothing so we don't beep.
* We could handle key messages here, but we lose some in the NSApp dispatch,
* where they get converted to action messages, etc.
*/
- (void)flagsChanged:(NSEvent *)theEvent
{
/*Cocoa_HandleKeyEvent(SDL_GetVideoDevice(), theEvent);*/
+
+ /* Catch capslock in here as a special case:
+ https://developer.apple.com/library/archive/qa/qa1519/_index.html
+ Note that technote's check of keyCode doesn't work. At least on the
+ 10.15 beta, capslock comes through here as keycode 255, but it's safe
+ to send duplicate key events; SDL filters them out quickly in
+ SDL_SendKeyboardKey(). */
+ SDL_SendKeyboardKey(([theEvent modifierFlags] & NSEventModifierFlagCapsLock) ? SDL_PRESSED : SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
}
- (void)keyDown:(NSEvent *)theEvent
{