We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 2157

Summary: Caps Lock key produces key down & key up events while key is still pressed.
Product: SDL Reporter: Tim McDaniel <timmcd101>
Component: eventsAssignee: Sam Lantinga <slouken>
Status: ASSIGNED --- QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2 CC: ewasylishen, sezeroz, tmcdaniel
Version: 2.0.3   
Hardware: All   
OS: Mac OS X (All)   
Attachments: Properly detect Caps Lock up/down events.

Description Tim McDaniel 2013-10-16 21:54:50 UTC
Using checkkeys test app:
* Press and hold Caps Lock key.
* checkkeys reports a CapsLock key pressed event and a CapsLock key released event.
* Release Caps Lock key.
* checkkeys reports no further events.

Note: This is using a non-Mac USB keyboard. Have not tried with a true Mac keyboard.
Comment 1 Sam Lantinga 2013-10-18 06:51:53 UTC
This is because the capslock key is special on different operating systems, and that's the event we actually see from Mac OS X.

If you do find an application that reports that differently, please let me know so we can find out how it does it.
Comment 2 Tim McDaniel 2014-08-22 00:13:26 UTC
Created attachment 1837 [details]
Properly detect Caps Lock up/down events.

This patch fixes OSX Caps Lock up/down event detection by installing a HID callback.
Comment 3 Tim McDaniel 2014-08-22 00:17:47 UTC
Reopened to submit patch.
Comment 4 Ryan C. Gordon 2015-02-19 06:32:15 UTC
Marking a large number of bugs with the "triage-2.0.4" keyword at once. Sorry
if you got a lot of email from this. This is to help me sort through some bugs
in regards to a 2.0.4 release. We may or may not fix this bug for 2.0.4,
though!
Comment 5 Sam Lantinga 2016-10-04 17:04:19 UTC
Patch applied for 2.0.5, thanks!
https://hg.libsdl.org/SDL/rev/d19f7d2b6ec8
Comment 6 Ozkan Sezer 2016-10-16 08:42:53 UTC
(In reply to Sam Lantinga from comment #5)
> Patch applied for 2.0.5, thanks!
> https://hg.libsdl.org/SDL/rev/d19f7d2b6ec8

This changeset crashes badly on 10.6, both i386 and x86_64.
Comment 7 Eric Wasylishen 2016-10-16 17:55:27 UTC
To reproduce the crash Ozkan mentioned, add these lines to the beginning of main() in testgl2.c:

SDL_InitSubSystem(SDL_INIT_VIDEO);
SDL_QuitSubSystem(SDL_INIT_VIDEO);

Compile using the SDLTest.xcodeproj, copy the testgl2 binary to a 10.6 machine, and run it a few times. It should crash on launch. The stack traces differ, here are two examples:

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: 13 at address: 0x0000000000000000
0x00007fff85c1a500 in CFSetApplyFunction ()
(gdb) bt
#0  0x00007fff85c1a500 in CFSetApplyFunction ()
#1  0x00007fff85d884c4 in __IOHIDManagerInitialEnumCallback ()
#2  0x00007fff85c3127d in __CFRunLoopDoSources0 ()
#3  0x00007fff85c2f5c9 in __CFRunLoopRun ()
#4  0x00007fff85c2ed8f in CFRunLoopRunSpecific ()
#5  0x00007fff883627ee in RunCurrentEventLoopInMode ()
#6  0x00007fff88362551 in ReceiveNextEventCommon ()
#7  0x00007fff883624ac in BlockUntilNextEventMatchingListInMode ()
#8  0x00007fff841d9eb2 in _DPSNextEvent ()
#9  0x00007fff841d9801 in -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] ()
#10 0x000000019af04b22 in Cocoa_PumpEvents ()
#11 0x000000019aee585d in SDL_PumpEvents_REAL ()
#12 0x000000019aee58e5 in SDL_WaitEventTimeout_REAL ()
#13 0x000000019aee58a7 in SDL_PollEvent_REAL ()
#14 0x000000019afb8474 in SDL_PollEvent ()
#15 0x000000019aea025e in main ()

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000010
0x00007fff85c32d2f in CFRunLoopRemoveSource ()
(gdb) bt
#0  0x00007fff85c32d2f in CFRunLoopRemoveSource ()
#1  0x00007fff85d884d5 in __IOHIDManagerInitialEnumCallback ()
#2  0x00007fff85c3127d in __CFRunLoopDoSources0 ()
#3  0x00007fff85c2f5c9 in __CFRunLoopRun ()
#4  0x00007fff85c2ed8f in CFRunLoopRunSpecific ()
#5  0x00007fff883627ee in RunCurrentEventLoopInMode ()
#6  0x00007fff88362551 in ReceiveNextEventCommon ()
#7  0x00007fff883624ac in BlockUntilNextEventMatchingListInMode ()
#8  0x00007fff841d9eb2 in _DPSNextEvent ()
#9  0x00007fff841d9801 in -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] ()
#10 0x00000001c8690b22 in Cocoa_PumpEvents ()
#11 0x00000001c867185d in SDL_PumpEvents_REAL ()
#12 0x00000001c86718e5 in SDL_WaitEventTimeout_REAL ()
#13 0x00000001c86718a7 in SDL_PollEvent_REAL ()
#14 0x00000001c8744474 in SDL_PollEvent ()
#15 0x00000001c862c25e in main ()
Comment 8 Sam Lantinga 2016-10-18 04:55:07 UTC
Does commenting out this call in QuitHIDCallback() fix it?
IOHIDManagerRegisterInputValueCallback(s_hidManager, NULL, NULL);
Comment 9 Eric Wasylishen 2016-10-18 07:30:10 UTC
No luck with commenting out IOHIDManagerRegisterInputValueCallback(s_hidManager, NULL, NULL);.

I think I see the bug in: http://opensource.apple.com//source/IOKitUser/IOKitUser-388/hid.subproj/IOHIDManager.c ; the __IOHIDManagerInitialEnumCallback callback (called by the manager->initEnumRunLoopSource runloop source) is only unregistered within __IOHIDManagerInitialEnumCallback itself, so it's unsafe to create and the immediately destroy an IOHIDManager because that callback will still run and try to use the deallocated IOHIDManager.

Browsing the opensource.apple.com a bit, it looks like OS X 10.11 was the first version with this fixed; they added something to __IOHIDManagerRelease to unregister the manager->initEnumRunLoopSource.


Not sure what the best workaround is. Running the runloop once in  QuitHIDCallback (using [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: [NSDate distantPast]];) fixes the crash for me, but this doesn't seem like a good idea, who knows what other callbacks will run.

Could just never release the IOHIDManager (only open/close), but this is also kind of ugly.
Comment 10 Sam Lantinga 2016-10-19 06:13:53 UTC
Can you confirm this fixes the crash?
https://hg.libsdl.org/SDL/rev/221d4601ab8c

I'm okay with this leak, since it normally will only happen on exit. I thought about reusing the hid manager, but I don't know if that's safe and don't have a setup where I can test it.
Comment 11 Eric Wasylishen 2016-10-19 19:38:59 UTC
Argh..still crashing. :(  It seems that calling IOHIDManagerUnscheduleFromRunLoop before the initial callback fires is unsafe, too.

Moving the IOHIDManagerUnscheduleFromRunLoop inside the "#if 0" does fix the crash for me on 10.6.
Comment 12 Ozkan Sezer 2016-10-19 20:59:09 UTC
I wonder what side effects would these band aids would cause,
i.e. both changeset 10552 and the addidional one suggested in
comment #11.

(Eric: I suggest that we keep the SDL2 build in quakespasm with
changeset 10459 removed, until the fixes are tested properly.)
Comment 13 Sam Lantinga 2016-10-20 03:40:11 UTC
Okay, this fixes the issue, safely leaking a HID manager object on video subsystem shutdown.
https://hg.libsdl.org/SDL/rev/6c07c69fb842
Comment 14 Sam Lantinga 2016-10-20 03:40:59 UTC
Leaving this bug open so we can address the leak in a future release.
Comment 15 Eric Wasylishen 2016-10-20 05:54:08 UTC
Thanks! I confirmed on 10.6 that the crash is fixed.
Comment 16 Sam Lantinga 2016-10-20 06:15:27 UTC
Thanks!
Comment 17 Ozkan Sezer 2017-10-07 08:28:08 UTC
(In reply to Sam Lantinga from comment #14)
> Leaving this bug open so we can address the leak in a future release.

Bumping this so that it doesn't get forgotten.