0

I want to swap L/R Shift with CapsLock/Enter keys in Windows 11. It used to work in Win 10 with a registry trick of redefining scancode map. See:

In above question it is also mentioned that if upgrading from Win 10 to 11, it still works, but my fresh installation of Win 11 does not respect this entry anymore. I guess the upgrade installation process was clever enough to copy this setting from registry to somewhere else for Win 11 to work properly, but with fresh installation, there's nothing to copy.

Now, what should be done to do the same key swapping? I don't want to use Autokey or other external applications, just registry trick/changing OS files/etc. It needs to work across user session(after restart) and in login screen.

4
  • If you could confirm this, do you have a possible solution? Where does this config go now?
    – WesternGun
    Commented Jan 25 at 13:49
  • I just tested the registry trick in Windows 11 after reboot, and it half-works: CapsLock works like Ctrl, but Ctrl keeps its functionality. AutoHotKey does it perfectly well, but it requires login. At this point I don't think that there is a solution that works in non-login contexts.
    – harrymc
    Commented Jan 25 at 16:41
  • As @John states, there are a number of third-party utilities that give complete control of key mapping, and combination of keys, which Registry hack does not. See autohotkey.com, gryder.org/software/clavier-plus, alternativeto.net/software/autohotkey Commented Jan 25 at 18:35
  • Thanks for suggestion. I am looking for a system level keyboard layout solution. autohotkey and clavier+ focus on hotkeys, while I need it to work also across OS and so.
    – WesternGun
    Commented Jan 25 at 18:58

1 Answer 1

0

After some trial and error I found out why. Not sure about other keys, but for R/L shift and CapsLock, Win 11 seems to change the 1st byte of their scan codes to 0xe0. Previously it was 0x00.


My previous solution is this:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"Scancode Map"=hex:00,00,00,00,00,00,00,00,05,00,00,00,3a,00,2a,00,2a,00,3a,00,36,00,1c,00,1c,00,36,00,00,00,00,00

Formatted with each 2 bytes on a line:

00,00,00,00,
00,00,00,00,
05,00,00,00,
3a,00,2a,00,
2a,00,3a,00,
36,00,1c,00,
1c,00,36,00,
00,00,00,00

Reading MS doc for mouse and keyboard driver, we know that this is interpreted like this:

enter image description here

So, we need to put scan code in two bytes, lower bytes first(little-endian), and byte 1 and 2 represent the new scan code, the old scan code to replace on bytes 3 and 4.

For example 3a,00,2a,00 means, find out the key who had 0x00 0x2a as scan code, and replace with new scan code 0x00 0x3a. The result is that the key L Shift works as CapsLock. 3a is CapsLock, and 2a is L Shift. And because I want to swap the two, so next line is 2a,00,3a,00, which means the opposite.

The next two lines are similar, swap 36(R SHIFT) and 1c(Enter).

Then, how do we find out the scan codes? In MS scan code specification, Appendix A: Windows Standard PS/2 Scan Codes, there is a table showing all scan codes:

enter image description here

, where you can find exactly the same scan codes as I said:

enter image description here

BUT, when we talk about the scan code, there are 2 bytes. 0036 means the higher byte is 0x00, and lower byte is 0x36. But in the table you also can see there are 2 values on 2 lines, first with higher byte 00(null), second line starts with E0, meaning 0xe0. Why?

I am not expert so I can only guess from what I read in the same file:

Prefixed Scan Codes Some keys on standard 101/102-key keyboards (and the Microsoft Natural keyboard amongst others) emit a sequence of two bytes, where the 1st byte is either 0xE0 or 0xE1. This method is used primarily to distinguish between left and right versions of the same key, e.g., Left Alt is 0x38 while Right Alt is 0xE0 0x38. The 0xE0 prefix is indicated as the “extended bit” (bit 24) in the lParam of messages such as WM_KEYDOWN. The 0xE1 prefix is much rarer, but operates similarly to the 0xE0 prefix. It’s presence or absence is not indicated through the API in any way.

So maybe the second value could be used but previously in Win 10 it is not. I am using the same keyboard for my Win 10 and Win 11, so it cannot be that the same keyboard suddenly starts to emit different higher byte; it can only be Win 11 changed something.


How did I find out? Well, along my investigation I found that SharpKey could detect the scan code, and while it is reading my previous solution in registry, it also thinks I am mapping right mostly correct; however, it shows one key(Enter) is unknown. When I remap in SharpKey, it tells me Enter is 0xe0 0x1c and gives me a .reg file like:

3a,00,2a,00, <<< SharpKey still thinks 0x00 is correct value for higher byte
2a,00,3a,00, <<< ditto
36,00,1c,e0, <<< set Enter to use scan code 0x00 0x36
1c,e0,36,00, <<< set R Shift to use scan code 0xe0 0x1c

But, only the last line works! R shift will do Enter's job but Enter does not switch case!

That leads me to think that, is it possible that now Win 11 only accepts 0xe0 as first byte? So I changed all first byte 00 to be e0 and all starts to work...

Is this a bug in Win 11 that it starts to take only 0xe0 as first byte????

1
  • Why are there two questions in this answer? There is no way to answer contained in an answer.
    – Ramhound
    Commented Jan 26 at 22:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .