2021-01-20

Remap one key to another in Windows, like Capslock to Control

There's three options to consider for remapping keys on Windows.

(1) Manually edit the Windows Registry

You can directly edit the Windows registry to remap keys, for example to Map capslock to control.  You'll need to know the keyboard hex scan codes involved though.

(2) Edit the Windows Registry with SharpKeys

If you have many keys to remap, or don't want to manually mess with the registry, there's an App for that!  SharpKeys looks pretty good.  You can use it to remap the Right Alt to the Left Windows key for example.

(3) Don't edit the Registry but run a background app like PT or AHK

Some common remappings like Capslock to control can be easily done without editing the registry at all!  You can run an app that stays in the background, listening for the keys you want changed, then they'll inject the key you want for it to change to.

Microsoft's PowerToys has a module for that sort of usage, and it comes with other toys like advanced file name changer, etc.  The kind of key remapping allowed is extremely limited though.

Another option is AutoHotKey (AHK).  It'll give you extreme customization beyond remapping a single key to a single key.  It'll let you script keys and combos to do pretty much arbitrary things to the keyboard and mouse.

Don't run both PowerToys keyboard remapping module and AHK key remappings together as they may interfere with each other!

Remap Capslock to Control with AutoHotKey

Make a text file and copy the script below into it, then save the text file with a .ahk file extension.  Double click the .ahk script file and AutoHotKey will run it to give you this 3FTD behaviour.

If you want the script to run every time you log in to Windows, you'll need to move the script or add a shortcut to it into the Windows startup folder.  See detailed instructions for that.

CapslockAsControl.ahk

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

#SingleInstance force

Capslock::Ctrl



Limitations to all methods

Some Windows hotkeys cannot be remapped!

Key combos like Windows key + L are dealt with by the Windows OS at a much lower level and treated specially.  Those cannot be remapped by PowerToys or AHK, at least not normally or usefully.

You could disable Win+L completely by disabling the Windows lock screen function [1].  But then your computer will never lock... ever.  Not when waking from sleep, not from the Control + Alt + Delete menu.  It's all or nothing.

Some apps don't allow / respect the remappings

Also apps that access the keyboard at a lower level, like some games and VirtualBox, don't play nice with AHK remappings.

Games access keyboards in a way that reduces latency to increase gaming responsiveness. And some games have anti-scripting functionality to discourage cheating.

VirtualBox is virtualizing your PC for another OS so a Windows background app messing with the keyboard of course won't play nice with VirtualBox.  And yes, Win+L will lock Windows even if you're inside a Linux guest in VirtualBox!

Vendor hotkeys can't be remapped

There are vendor specific keys and combos that your PC maker may have added via their keyboard drivers.  Like Lenovo's Fn+Tab starts the Windows magnifier key combo.  Press that while in a VirtualBox guest OS and it'll still run the magnifier!

Neither AHK nor PowerToys can remap the Fn+Tab combo either.  In fact, remapping the Fn key is usually tough if not impossible.  It's something handled specially by vendor's drivers on laptops to provide special functionality.

 

 

Compared to Macs

Scripting with AppleScript

Coming from the Mac world where AppleScript lets you implement customized and scripted automation of tasks, AutoHotKey (AHK) is similar in many ways.  Since AppleScript can be substituted with JavaScript, then the scripting language itself is better than AHK.

However, AppleScript doesn't provide hooks to customize or remap keys and key combos, so AHK does have this feature AppleScript doesn't.

On the flip side, Mac apps that make extensive use of Apple's Open Scripting Architecture allow AppleScripts to directly access certain data inside those apps for better integration.  Not every or many apps support advanced OSA usage, but it gives AppleScript an edge.

Remapping with Karabiner

As for providing key and combo remapping, I'm finding Karabiner-Elements on Macs to be better for that job than AHK.

Karabiner is more intuitive, purpose built for remapping keys, with many of the same AHK features for multi-key remapping.  It can also run scripts on key triggers like AHK, so Karabiner + AppleScript is roughly equivalent to AHK's functionality.

Less limitations

Macs have less limitations than Windows on the key remapping front too.  You'll have no problems using Karabiner-Elements to remap the "Apple key" (command key) vs the difficulties of remapping the Windows key (especially special combos like Win+L).

Key remappings with Karabiner on Macs are also respected by VirtualBox unlike remappings done via AHK on Windows.  To be fair, some AHK key remappings do work with VirtualBox, but I had trouble with modifier keys and special Windows hotkeys.


References

[1] How to disable Windows 10 Workstation Lock (Window + L) Functionality

2021-01-12

My app uses only java.base, but actually jdeps missed the jdk.crypto.cryptoki module!

I was building a small app and I purposely used only the java.base module.  That way when I build a custom Java Runtime for it, I can build the smallest possible runtime with jlink.

Java's jdeps lets you know which module your app depends on, and it said my app only uses the java.base module. 

Build the runtime with jlink and run my app with it and oops, an error having to do with cryptoki.

Turns out jdeps made a mistake and did not identify the jdk.crypto.cryptoki module!

I suspect my use of the java.net.URI class was to blame, as it was used to access an https URL.

Anyway, if you purposely depend only on the java.base module, but also use the URI class, note that it may actually also depend on the jdk.crypto.cryptoki module!


2021-01-06

Build your own custom Java Runtime with jlink and jdeps

Since Java 9, the way Java programs are supposed to be distributed changed.

It used to be that users would install a Java Runtime Environment (JRE) on their system.  The user then gets the Java app from the app developer.  The Java app then runs on the JRE that's installed.

Some OS like Macs used to even have a "system" JRE installed as part of the OS.

The world's moved on from that style of app distribution.  Nowadays, many users want statically compiled programs, or a single executable file with no dependencies.  For better or worse.

That means when you develop a Java app and want to distribute it, it's on you as the developer to create your own custom Java Runtime and package that runtime together with the rest of your app for distribution.

The upshot is that if you don't use too much of the Java standard library and customize your Java Runtime, then you pay for only what you use in terms of the size of the Java runtime you need to package with your app.

You can find what Java modules your app depends on using jdeps easily: jdeps my.jar

Then you can use jlink to create the Java Runtime your app needs: jlink --output my-custom-runtime --add-modules java.base,and.other.modules

Then you can run your app with the custom Java Runtime: /path/to/my-custom-runtime/bin/java -jar my.jar

The Java Runtime that jlink creates is specific to the OS platform you ran jlink on.  So on Windows, you'll have to substitute java.exe for java in the path above.

There's a way to cross-compile a Java Runtime for a different OS platform with jlink, but you'll need to download the target platform's JDK.  It was easier to run the target platform's OS in a virtual machine and run jlink on it instead.

A thorough and detailed tutorial is How to Create Java Runtime Images with jlink.