copy / v86

x86 PC emulator and x86-to-wasm JIT, running in the browser
https://copy.sh/v86/
BSD 2-Clause "Simplified" License
19.87k stars 1.41k forks source link

AltGr-Key under Windows #1127

Closed chschnell closed 2 months ago

chschnell commented 3 months ago

When using FreeDos's EDIT.EXE with European codepage CP858 and a german keyboard layout KEYB GR under Windows, all key-combinations using the AltGr-key are dead (AltGr is also called "right Alt" or "AltGraph", the key to the right of the spacebar). Due to the German keyboard layout this fatally deprives me of \ | { } [ ], amongst other keys. I found a fix, and this may be of interest to others.

The problem has to do with Windows, not with my german setup. A characteristic of browsers under Windows (tested Firefox, Chrome and Edge) is that pressing the AltGr key generates two KeyboardEvent events instead of one, first one with KeyboardEvent.code ControlLeft directly followed by another with code AltRight, instead of a single AltRight event like under Linux and Mac (AltRight is the KeyboardEvent.code value of the AltGr key).

You can quickly try out Mozilla's KeyboardEvent example to see which KeyboardEvent(s) your platform generates when pressing the AltGr key (what matters is the value shown at code=). Here's what I get (the sequence is identical when releasing AltGr, ControlLeft directly followed by AltRight, which is not shown there):

KeyboardEvent: key='Control'  | code='ControlLeft'
KeyboardEvent: key='AltGraph' | code='AltRight'

I figured maybe the extra ControlLeft-key was causing the problems observed in EDIT.EXE, and indeed, when replacing the key sequence ControlLeft+AltRight with a single AltRight (for both pressing and releasing), every single key on my keyboard works as it should, and for the first time I can edit text files properly under FreeDOS!

Here's the patch for src/browser/keyboard.js: v86-keyboard-altgr.patch. EDIT: Improved patch by using KeyboardEvent.getModifierState() to ensure that ControlLeft is only removed from the keyboard stream when AltGr is pressed.

I don't have enough information to know if this modification breaks expected behaviour under OSes other than FreeDOS when virtualized under Windows, maybe others can help out testing to see if this has any negative side effects.

Unfortunately the situation under MS-DOS 6.22 and CP850/KEYB-GR is utterly broken, it's actually so bad that I think MS-DOS is to blame. For example, by simply pressing and releasing the CTRL key, the CTRL-key is stuck forever, rendering everything unusable. MS-DOS works somewhat if I install it with CP437/KEYB-US, but that's too bothersome with a german keyboard.

chschnell commented 3 months ago

There was still a small bug, here's the fixed patch: v86-keyboard-altgr.patch.

The extra ControlLeft-key is a browser artifact under Windows which can interfere with applications reading the keyboard stream. What EDIT.EXE sees is not AltGr+KEY but Ctrl+AltGr+KEY, and it is treating these key combinations differently which is why they appeared dead to me.

To correct myself from yesterday, I think it's impossible that any application could break because that artifact is missing from the keyboard stream, so I think my patch is free of any side-effects and safe to apply.

chschnell commented 3 months ago

A few sources to confirm the mapping of AtlGr to ControlLeft + AltRight under Windows:

I came across this problem when testing PR #1123, this patch is neccessary for full international support in V86, else you will see the right symbols on the screen but be prevented from typing them properly on your keyboard.

Should I just lump it in with PR #1123?

copy commented 3 months ago

Should I just lump it in with PR https://github.com/copy/v86/pull/1123?

No, send it as a separate PR. I'm still catching up with other issues and PRs, but should be able to look at it soon.