kwhat / jnativehook

Global keyboard and mouse listeners for Java.
Other
1.73k stars 344 forks source link

JNativeHook doesn't read HP Keyboard function key #345

Open mainul35 opened 3 years ago

mainul35 commented 3 years ago

I am using HP ZBook G2, and in windows 10 build 19042.1110, Fn + F9 is supposed to decrease brightness and Fn + F10 is supposed to increase brightness. Unfortunately the Fn button keypress is not listened by jnativehook.

kwhat commented 3 years ago

Hi @mainul35

So usually the FN key does not produce a keyboard input event until you press the secondary key, its kind of like a jumper, not a modifier. There is probably no way to get just the FN press over the wire without making some keyboard firmware modifications. Hope that helps.

mainul35 commented 3 years ago

@kwhat , thank you for the information. I later cloned the repository and found that there is no Enum value for Brightness Up and Brightness Down. I thought to add these 2, but I have less knowledge on JNI. I am trying to understand and write a C code for this purpose. If I have further issues, I will request your guidelines.

kwhat commented 3 years ago

If the key produces a key code, you should be getting it with the library, even if the library doesn't support it. Check the debug level logs and see what happens when you press the FN + F9. More than likely what is happening is your brightness key corresponds to something like "OEM specific" or "Varies by keyboard" in the enum you are looking at. If that is the case, fixing it for you will break it for someone else. This is because a lot of these keys are non-standard and manufactures just make up what they mean based on what they are bound to.

Sometimes these buttons are really HW control and do not even get to the OS like the FN button itself. If that is the case, there will be no OS event and you will not be able to get this key press for the same reason you cant get the fn key press.

Check the logs first, bring me back some output for that event and we will see if this can be supported.

mainul35 commented 3 years ago

From the logs, the key code I receive is 0 and it's string keyText value is undefined. A month ago when I was using Linux on the same machine, it was working flawlessly. But it started to fail to work after I migrated to windows.

I couldn't be sure which log to count on, so I copied the logs before and after my key event. Here

0
Undefined

are the outputs for Fn + F9 key press.

Jul 24, 2021 1:36:15 PM org.jnativehook.GlobalScreen$NativeHookThread enable
SEVERE: refresh_locale_list [628]: Could not find keyboard map for locale 0X0000000004090409!

0
Undefined
Jul 24, 2021 1:36:15 PM org.jnativehook.GlobalScreen$NativeHookThread enable
INFO: process_key_released [286]: Key 0 released. (0XFF)
kwhat commented 3 years ago

Oh, awesome. It seems everyone can duplicate the SEVERE: refresh_locale_list [628]: Could not find keyboard map for locale 0X0000000004090409! problem but me

kwhat commented 3 years ago

The fact that the rawcode is 0xFF is interesting.

The problem maybe at: https://github.com/kwhat/libuiohook/blob/f4bb19be8aee7d7ee5ead89b5a89dbf440e2a71a/src/windows/input_hook.c#L275

I need to do some digging but I have zero time this weekend.

mainul35 commented 3 years ago

I wish I could go through it to understand what's happening inside. But due to lack of knowledge in JNI and long gap in C, I failed.

kwhat commented 3 years ago

It's not that complicated, the JNI bit is the easiest part.

    event.data.keyboard.keycode = keycode_to_scancode(kbhook->vkCode, kbhook->flags);
    event.data.keyboard.rawcode = (uint16_t) kbhook->vkCode;
    event.data.keyboard.keychar = CHAR_UNDEFINED;

    logger(LOG_LEVEL_DEBUG, "%s [%u]: Key %#X released. (%#X)\n",
            __FUNCTION__, __LINE__, event.data.keyboard.keycode, event.data.keyboard.rawcode);

(uint16_t) kbhook->vkCode; truncated our size down which could be too small for this key. What we want to see is

logger(LOG_LEVEL_DEBUG, "%s [%u]: Key %#X released. (%#X)\n",
        __FUNCTION__, __LINE__, event.data.keyboard.keycode, event.data.keyboard.rawcode);

changed to

logger(LOG_LEVEL_DEBUG, "%s [%u]: Key %#X released. (%#X)\n",
        __FUNCTION__, __LINE__, event.data.keyboard.keycode, kbhook->vkCode);

I really need to do some work on this so I'll create a branch and make a build so you can test this hack and we can see what the code really is... I probably should be logging the original values but ill come back and figure it out later.

I am just really slammed for this next week with a number of things that are totally unrelated.