Emulating FN Lock button
This is a post about emulating FN-Lock key to swap the default behavior of function keys when there is no such button on the keyboard. For example, if by default F5 is assigned to "music play and pause", and we want it to work as actual F5 button without being have to press fn+F5 combination. Skip to the "AutoHotKey" section to save time.
Background
While playing StarCraft 2, sometimes my selection system got broken. Every unit I choose was added to the selection and every move command was added to the queue, making my whole army dancing all around the map and destroyed like sitting ducks.
I'm not claiming that I wouldn't have lost if I was not experiencing this problem. Unfortunately I'm bad at gaming. However, I didn't like myself when I got angry at my keyboard and at the game (thinking that it was a bug caused by the game). Getting angry at inanimate entities is never helpful.
First I realized that this must be happening because of frozen key press. Which one could cause this? Of course! The SHIFT key gets frozen and swallows all units into the same selection. I did some online search about "Star Craft 2 shift key bug". Unfortunately, there were multiple posts on Battle Net forums with no solutions. Which made me keep thinking that this was a SC2 related problem until days later the key got frozen while I was typing in a text editor. My keyboard was left as the only culprit. Time to shop a new keyboard!
My older keyboard was an 2011 model "HP Wireless Elite Keyboard v2" which I bought because it was very silent. I searched for "silent/quiet keyboards" again. But looks like it is not a popular genre. :-( I ended up choosing 2018 model "HP Pavilion Wireless Keyboard Combo 800". Looks like there is not much change happened in keyboard design in those 7 years. :-) The shorter side of this one is even shorter, which gave me extra space on my small desk.
Immediately I opened a SC2 game with the faith that without this frozen shift key handicap I'll climb the ladder two steps at a time. I morphed my first drone, set my control group for my hatchery, centered the camera around the hatchery, and set my camera shortcut to F1. But, instead it muted the sound. I realized that unlike my previous keyboard, the defaults for function keys are action shortcuts and I've to press fn key to use F1-12 keys. Which forces me to press CTRL+fn+FX simultaneously to set a camera shortcut and fn+FX to visit the set camera location. And my hands do not have the acrobatic skills while suffering from brain freeze against opponent attacks.
I searched HP support forums and other sites to learn how to swap the default behavior of function keys. Is there FN-Lock button on the keyboard? No. Does Windows 10 operating system provide a keyboard setting related to fn key? No. Does HP provide a software solution? No. Apparently, the ability to change the defaults only exists for some HP laptops, for which the user has to update the behavior from the BIOS of the machine.
This time I got angry at HP keyboard designers and customer support. Because I remember reading customer questions on Amazon product page and an HP seller gave a positive response to the question of default setting changes. Two angers in a row. :-( Either I have to refund this keyboard, or have to figure out a custom software solution myself.
First I encountered SharpKeys a utility tool that swaps keys using Windows Registry. "If you press this key, trigger that key". Unfortunately, SharpKeys did not recognize media player keys. Hence, was not able to replace media keys with Function keys.
FN Key Lore
While doing online studies, I learned that fn
key is a special one. All other keys, when pressed (released) send a key code to to operating system, which allows software to use them. When multiple keys were pressed key codes from all are received simultaneously. That way we can have key combinations such as ALT+F4, CTRL+C etc. Software detects when CTRL and C are pressed at the same time or not.
The same mechanism does not apply to fn button. When I press fn+F1 the keyboard does not send key codes for fn and F1 at the same time. Actually fn key does not even have an associated key code. O_O For this keyboard specifically, fn+F1 key press sends key code for F1, and F1 key press sends Media Mute key code. This makes is impossible to detect whether fn key is pressed or not by itself.
I learned these from following SO answer: autohotkey - Finding the scan code of FN Key - Stack Overflow. Also see Wikipedia entries on fn and F-Lock keys.
One moment before all hope was lost AutoHotkey came to the rescue.
Swapping keys using AutoHotKey scripts
Enter AHK. Probably AHK is an overkill for this problem, but still it is a better option than writing my own Keyboard driver, or intercepting the behavior of the driver with my own code. It has advanced scripting functionalities but I'm using it only to detect key presses and what they trigger.
Looks like after you install AHK, you can write scripts that'll run in the background which will listen to the key strokes you configured in the script and run some custom callback functions. First I needed to figure out the key codes of these special action that are called by default. I created a new script. Added #InstallKeybdHook
to monitor key strokes. Double clicked on AHK icon in system tray (a capital H letter on green background). Then from the menu "View > Key history and script info Ctrl+K".
In this window, when you press F5 you'll get the information about most recently pressed keys. Using which I learned the scan codes and key names for these special actions. For example Volume_Mute
is 120
, Volume_Down
is 12E
etc. (I saw that some of them have two scan codes associated with them. But that wasn't important for the final script)
Now that I learned the key names (AHK understands key names and does not need scan codes), it was time to swap F1 with VolumeMute and VolumeMute with F1. My first attempt resulted in finite loops where they triggered each other :-) because I had two separate functions that are triggered for key presses which generate swapped key pressed. F1 -> VolumeMute -> F1 -> VolumeMute -> ...
Luckily, AHK has another, simpler mean of remapping: Remapping Keys (Keyboard, Mouse and Joystick) | AutoHotkey Here is my final script. First 3 lines were auto-added.
#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%
#InstallKeybdHook
Volume_Mute::F1
F1::Volume_Mute
Volume_Down::F2
F2::Volume_Down
Volume_Up::F3
F3::Volume_Up
Media_Prev::F4
F4::Media_Prev
Media_Play_Pause::F5
F5::Media_Play_Pause
Media_Next::F6
F6::Media_Next
return
Yay! I went back to SC2 to try my "fixed" default fn setting and use camera shortcuts they way I used to. And I lost miserably! It was a great day to learn more about how computer peripherals work.
published at: 2019-07-21 14:49 UTC-5tags: