Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DriverKit-VirtualHIDDevice does not completely hide the true underlying keyboard devices (unlike the legacy kernel extension / kext), which leads to broken functionality in certain apps (such as Discord) #2895

Open
akemin-dayo opened this issue Nov 21, 2021 · 4 comments

Comments

@akemin-dayo
Copy link

akemin-dayo commented Nov 21, 2021

While testing/staging an upgrade of my main machine from macOS 10.14 to macOS 12, I discovered a bug in the DriverKit-VirtualHIDDevice component of Karabiner-Elements.

DriverKit-VirtualHIDDevice does not completely hide the true underlying keyboard devices to certain applications (such as Discord), which can lead to broken functionality in such apps.

In the case of Discord, hotkey functionality is affected — setting hotkeys becomes impossible unless Karabiner is disabled, because Discord is reading keypresses from both the Karabiner virtual keyboard, as well as the underlying true keyboard.

Entertainingly, this also lets you set otherwise-impossible hotkey combinations, such as "A+A" which you can achieve by simply pressing A on a Karabiner'd keyboard when setting a hotkey.

This is in contrast to the legacy kernel extension / kext (which I have been using on macOS 10.14.6 18G9323), which does not exhibit this broken behaviour at all (tested with kext version 6.10.0, shipped with Karabiner-Elements 12.10.0).

These versions of DriverKit-VirtualHIDDevice exhibit broken behaviour, tested on macOS 12.0.1 21A559 (arm64e):

  • DriverKit-VirtualHIDDevice 1.6.0 (shipped with Karabiner-Elements 14.3.0, latest version as of this writing)
  • DriverKit-VirtualHIDDevice 1.5.0 (shipped with Karabiner-Elements 14.2.0)
  • DriverKit-VirtualHIDDevice 1.0.0 (shipped with Karabiner-Elements 13.7.0)
  • DriverKit-VirtualHIDDevice 1.0.0 (shipped with Karabiner-Elements 13.0.0)

UPDATE: I have discovered something that may be of interest — the broken hotkey behaviour in Discord at least can be temporarily partially fixed by going to Karabiner-Elements preferences → Devices and turning the "Modify events from this device" option for the relevant device (the internal MacBook keyboard for me) off and then back on.

After doing this, Discord hotkeys will behave correctly until either you open the Hotkeys preferences in Discord again, or if you quit and re-open Discord.

@tekezo
Copy link
Member

tekezo commented Nov 21, 2021

Karabiner-Elements uses the following options to open the device in exclusive mode.
So, if other apps can read input events, it's a macOS bug and should be fixed by Apple.

https://developer.apple.com/documentation/iokit/1556660-anonymous/kiohidoptionstypeseizedevice

I'm guessing that the problem probably occurs when Karabiner-Elements and Discord open the device at the same time.
If Discord starts automatically when you log in, does turning it off avoid the issue?

@akemin-dayo
Copy link
Author

akemin-dayo commented Nov 22, 2021

I'm guessing that the problem probably occurs when Karabiner-Elements and Discord open the device at the same time.
If Discord starts automatically when you log in, does turning it off avoid the issue?

Discord does not start automatically when I log in — just manually launching Discord is enough to cause the issue to occur, and the only temporary "solution" is the weird disable-then-re-enable workaround I mentioned above.

So, if other apps can read input events, it's a macOS bug and should be fixed by Apple.

Hmn, if this is the case then I think it might be worth filing a Radar bug report to Apple. I'll need to investigate more first.

I'm wondering if I can find and disassemble the specific native component that Discord is using for its hotkey functionality to see what APIs they're using, as that will be very helpful in getting more information regarding this issue, as well as making it more easily reproducible.

@akemin-dayo
Copy link
Author

After locating the IOKit/IOHIDManager API calls that Discord is using to handle global hotkey functionality (via nm -um), I've confirmed that this does seem be an issue with macOS — I've filed a Radar bug report to Apple and hopefully this can be fixed on their end soon.

If you are interested, here is my writeup of the bug: macOS issue writeup: When kIOHIDOptionsTypeSeizeDevice is used in a DriverKit system extension (dext), the seized device fails to be hidden from IOHIDManager functions such as IOHIDManagerSetDeviceMatchingMultiple.

And the custom test code that I wrote to help diagnose and understand this issue: akemin-dayo/IOKitHIDKeyboardTester.

I'm not going to close this GitHub issue though, just in case anyone comes across the same problem and wants information on what is happening.

@agnesnutter
Copy link

Is this the same issue causing the (incorrectly closed) issue #447?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants