Search code examples
windowswinapiraw-input

Raw Input keyboard with RIDEV_NOHOTKEYS causes weird behavior


When I register a Raw Input keyboard device and set the RIDEV_NOHOTKEYS flag, like this:

RAWINPUTDEVICE device = {};
device.usUsagePage = 0x01;
device.usUsage = 0x06;
device.dwFlags = RIDEV_NOHOTKEYS;
device.hwndTarget = hwnd;

While my window has focus, the left and right Windows keys stop working (they don't bring up the start menu). All other hotkeys I can think of still work. Alt-Tab works, but it doesn't bring up the "fancy" alt-tab menu with thumbnails, but the old classic menu with icons:

classic alt-tab menu

There is nothing unusual happening in WM_INPUT message processing; I look at the structures, and call DefWindowProc at the end. I also don't have any keyboard hooks installed, or any other form of input.

According to the documentation, RIDEV_NOHOTKEYS should only affect application-defined hotkeys. This happens even when I don't register any hotkeys myself, so there are no application-defined hotkeys, unless Windows itself registers some (but then, why are they not system hotkeys?).

Does anyone have some experience with this or some explanation why this is happening, and suggestions how to prevent it? (This is on Windows 10, version 1803)


Solution

  • According to the documentation, RIDEV_NOHOTKEYS should only affect application-defined hotkeys.

    Because it's not. Quoting the excellent article "Finding and Fixing a Five Second Stall" by Casey Muratori (mirrors: 1, 2; emphasis is mine):

    When I woke the next morning, for some reason I remembered the most important thing anyone programming Windows must remember: never, ever trust the documentation. It’s always either inaccurate or incomplete. So when I sat down at my keyboard, the first thing I did was try using the RIDEV_NOHOTKEYS flag when initializing Raw Input.

    You see, the previous day I hadn’t bothered to try this flag, because it explicitly says in the documentation that it does not block system-level hotkeys, only application-level hotkeys (like the kind you create yourself with RegisterHotKey). But why was I believing that? That was just something somebody wrote down when they needed to create a documentation page. They probably never even saw the actual code for Raw Input in the first place.

    Surprise surprise, RIDEV_NOHOTKEYS worked. After all the fussing, all that had to be done to make The Witness impervious to Windows Logo keys was one little flag during Raw Input initialization. No keyboard hook necessary.

    Moreover, discussions of this article on Hacker News (1, 2) reveal a tweet from 2014 from the same author about an identical problem in Windows 8:

    By the way, regarding http://mollyrocket.com/casey/stream_0007.html, I believe there was yet another problem with Windows keys that Ignacio had to fix later...
    Apparently you can no longer specify RIDEV_NOHOTKEYS in Windows 8 without it removing ALT-TAB support completely :(