]> git.proxmox.com Git - mirror_novnc.git/commitdiff
Fake key releases for some Japanese IM keys
authorPierre Ossman <ossman@cendio.se>
Thu, 10 Dec 2020 09:01:04 +0000 (10:01 +0100)
committerPierre Ossman <ossman@cendio.se>
Thu, 10 Dec 2020 09:21:21 +0000 (10:21 +0100)
Windows behaves very oddly for some Japanese IM keys in that it won't
send a key release event when the key is released. In some keys it never
sends the event, and in some cases it sends the release as the key is
pressed the subsequent time.

core/input/keyboard.js
tests/test.keyboard.js

index ed3b1bf18ca3d2a1a13382dfd3b0d7fa93b3643b..48f65cf6817f682d52f2d24c71cd68c50c2e5e94 100644 (file)
@@ -164,6 +164,20 @@ export default class Keyboard {
             return;
         }
 
+        // Windows doesn't send proper key releases for a bunch of
+        // Japanese IM keys so we have to fake the release right away
+        const jpBadKeys = [ KeyTable.XK_Zenkaku_Hankaku,
+                            KeyTable.XK_Eisu_toggle,
+                            KeyTable.XK_Katakana,
+                            KeyTable.XK_Hiragana,
+                            KeyTable.XK_Romaji ];
+        if (browser.isWindows() && jpBadKeys.includes(keysym)) {
+            this._sendKeyEvent(keysym, code, true);
+            this._sendKeyEvent(keysym, code, false);
+            stopEvent(e);
+            return;
+        }
+
         stopEvent(e);
 
         // Possible start of AltGr sequence? (see above)
index 940769e6ff77e4b06fc37820447463c55e9d04c4..f460eb3bfacd8de89445e9937ca71c5f5f80f15b 100644 (file)
@@ -268,6 +268,47 @@ describe('Key Event Handling', function () {
         });
     });
 
+    describe('Japanese IM keys on Windows', function () {
+        let origNavigator;
+        beforeEach(function () {
+            // window.navigator is a protected read-only property in many
+            // environments, so we need to redefine it whilst running these
+            // tests.
+            origNavigator = Object.getOwnPropertyDescriptor(window, "navigator");
+
+            Object.defineProperty(window, "navigator", {value: {}});
+            if (window.navigator.platform !== undefined) {
+                // Object.defineProperty() doesn't work properly in old
+                // versions of Chrome
+                this.skip();
+            }
+
+            window.navigator.platform = "Windows";
+        });
+
+        afterEach(function () {
+            if (origNavigator !== undefined) {
+                Object.defineProperty(window, "navigator", origNavigator);
+            }
+        });
+
+        const keys = { 'Zenkaku': 0xff2a, 'Hankaku': 0xff2a,
+                       'Alphanumeric': 0xff30, 'Katakana': 0xff26,
+                       'Hiragana': 0xff25, 'Romaji': 0xff24,
+                       'KanaMode': 0xff24 };
+        for (let [key, keysym] of Object.entries(keys)) {
+            it(`should fake key release for ${key} on Windows`, function () {
+                let kbd = new Keyboard(document);
+                kbd.onkeyevent = sinon.spy();
+                kbd._handleKeyDown(keyevent('keydown', {code: 'FakeIM', key: key}));
+
+                expect(kbd.onkeyevent).to.have.been.calledTwice;
+                expect(kbd.onkeyevent.firstCall).to.have.been.calledWith(keysym, "FakeIM", true);
+                expect(kbd.onkeyevent.secondCall).to.have.been.calledWith(keysym, "FakeIM", false);
+            });
+        }
+    });
+
     describe('Escape AltGraph on Windows', function () {
         let origNavigator;
         beforeEach(function () {