From 4fda2526f4265794ec16afdb769de05cc753eea5 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Thu, 10 Dec 2020 09:43:49 +0100 Subject: [PATCH] Send combination keysyms for some Japanese keys Windows doesn't give us stable symbols for a bunch of Japanese IM keys, instead alternating between two symbols. This state is not synchronised with the IM running on the remote server so to have stable behaviour we have to collapse these multiple symbols in to a single keysym. --- kasmweb/core/input/util.js | 15 +++++++++++++++ kasmweb/tests/test.helper.js | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/kasmweb/core/input/util.js b/kasmweb/core/input/util.js index 1b98040..2761069 100644 --- a/kasmweb/core/input/util.js +++ b/kasmweb/core/input/util.js @@ -189,6 +189,21 @@ export function getKeysym(evt) { } } + // Windows sends alternating symbols for some keys when using a + // Japanese layout. We have no way of synchronising with the IM + // running on the remote system, so we send some combined keysym + // instead and hope for the best. + if (browser.isWindows()) { + switch (key) { + case 'Zenkaku': + case 'Hankaku': + return KeyTable.XK_Zenkaku_Hankaku; + case 'Romaji': + case 'KanaMode': + return KeyTable.XK_Romaji; + } + } + return DOMKeyTable[key][location]; } diff --git a/kasmweb/tests/test.helper.js b/kasmweb/tests/test.helper.js index 0232819..0b00b93 100644 --- a/kasmweb/tests/test.helper.js +++ b/kasmweb/tests/test.helper.js @@ -248,5 +248,38 @@ describe('Helpers', function () { expect(KeyboardUtil.getKeysym({code: 'NumpadDecimal', key: ',', location: 3})).to.be.equal(0xFFAC); }); }); + + 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, + 'Romaji': 0xff24, 'KanaMode': 0xff24 }; + for (let [key, keysym] of Object.entries(keys)) { + it(`should fake combined key for ${key} on Windows`, function () { + expect(KeyboardUtil.getKeysym({code: 'FakeIM', key: key})).to.be.equal(keysym); + }); + } + }); }); });