From b347a118fa0aa0d0d993f91a58436a09640a91b9 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 12 Aug 2021 16:12:03 -0700 Subject: [PATCH] GUACAMOLE-1386: Defer handling of "Meta" until it is known to be functioning as a modifier. Some platforms like ChromeOS use the Meta key as an alternative method for typing individual keys like Home (Meta+Left) and End (Meta+Right). In these cases, Meta does not function as a modifier and is actually implicitly released once the keyboard shortcut is identified. Since we cannot know whether Meta is actually Meta until it's confirmed to be used by itself or with another key, we need to defer handling of Meta keydown until either (1) Meta is released without having been used with another key or (2) Meta is used as a modifier with another key. --- .../src/main/webapp/modules/Keyboard.js | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/guacamole-common-js/src/main/webapp/modules/Keyboard.js b/guacamole-common-js/src/main/webapp/modules/Keyboard.js index 8f7dfe4f5..e0680ea4f 100644 --- a/guacamole-common-js/src/main/webapp/modules/Keyboard.js +++ b/guacamole-common-js/src/main/webapp/modules/Keyboard.js @@ -1148,6 +1148,26 @@ Guacamole.Keyboard = function Keyboard(element) { var keysym = null; var accepted_events = []; + // Defer handling of Meta until it is known to be functioning as a + // modifier (it may otherwise actually be an alternative method for + // pressing a single key, such as Meta+Left for Home on ChromeOS) + if (first.keysym === 0xFFE7 || first.keysym === 0xFFE8) { + + // Defer handling until further events exist to provide context + if (eventLog.length === 1) + return null; + + // Ignore keydown of Meta unless immediately followed by a + // reliable keyup of the same (it will instead be pressed + // implicitly if truly recognized as Meta in conjunction with + // another non-Meta keypress) + if (quirks.keyupUnreliable || !(eventLog[1] instanceof KeyupEvent) || eventLog[1].keysym !== first.keysym) { + eventLog.pop(); + return null; + } + + } + // If event itself is reliable, no need to wait for other events if (first.reliable) { keysym = first.keysym;