From b9ce54c961017e8c0f3297c1a3e05a9803fa28c1 Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Mon, 29 Aug 2022 14:16:42 -0400 Subject: [PATCH] [v10] Backport #1148 and #1153 (#1156) * adds (preview) to Share Directory menu item (#1148) * Adds special handling for CapsLock on MacOS (#1153) --- .../src/DesktopSession/ActionMenu.tsx | 2 +- .../src/DesktopSession/useTdpClientCanvas.tsx | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/web/packages/teleport/src/DesktopSession/ActionMenu.tsx b/web/packages/teleport/src/DesktopSession/ActionMenu.tsx index 138d5a6f9eb97..9818714d2dcfb 100644 --- a/web/packages/teleport/src/DesktopSession/ActionMenu.tsx +++ b/web/packages/teleport/src/DesktopSession/ActionMenu.tsx @@ -36,7 +36,7 @@ export default function ActionMenu(props: Props) { {showShareDirectory && ( - Share Directory + Share Directory (preview) )} diff --git a/web/packages/teleport/src/DesktopSession/useTdpClientCanvas.tsx b/web/packages/teleport/src/DesktopSession/useTdpClientCanvas.tsx index 8065c4bc77577..71ab66a28c62b 100644 --- a/web/packages/teleport/src/DesktopSession/useTdpClientCanvas.tsx +++ b/web/packages/teleport/src/DesktopSession/useTdpClientCanvas.tsx @@ -16,6 +16,9 @@ limitations under the License. import { useState, useEffect, useRef, Dispatch, SetStateAction } from 'react'; import { Attempt } from 'shared/hooks/useAttemptNext'; + +import { getPlatform } from 'design/theme/utils'; + import { TdpClient, ButtonState, ScrollAxis } from 'teleport/lib/tdp'; import { ClipboardData, PngFrame } from 'teleport/lib/tdp/codec'; import { getAccessToken, getHostName } from 'teleport/services/api'; @@ -23,6 +26,12 @@ import cfg from 'teleport/config'; import { TopBarHeight } from './TopBar'; import { ClipboardPermissionStatus } from './useClipboard'; +declare global { + interface Navigator { + userAgentData?: { platform: any }; + } +} + export default function useTdpClientCanvas(props: Props) { const { username, @@ -102,13 +111,36 @@ export default function useTdpClientCanvas(props: Props) { setWsConnection('open'); }; + const { isMac } = getPlatform(); + /** + * On MacOS Edge/Chrome/Safari, each physical CapsLock DOWN-UP registers + * as either a single DOWN or single UP, with DOWN corresponding to + * "CapsLock on" and UP to "CapsLock off". On MacOS Firefox, it always + * registers as a DOWN. + * + * On Windows and Linux, all browsers treat CapsLock like a normal key. + * + * The remote Windows machine also treats CapsLock like a normal key, and + * expects a DOWN-UP whenever it's pressed. + */ + const handleCapsLock = (cli: TdpClient, e: KeyboardEvent): boolean => { + if (e.code === 'CapsLock' && isMac) { + cli.sendKeyboardInput(e.code, ButtonState.DOWN); + cli.sendKeyboardInput(e.code, ButtonState.UP); + return true; + } + return false; + }; + const onKeyDown = (cli: TdpClient, e: KeyboardEvent) => { e.preventDefault(); + if (handleCapsLock(cli, e)) return; cli.sendKeyboardInput(e.code, ButtonState.DOWN); }; const onKeyUp = (cli: TdpClient, e: KeyboardEvent) => { e.preventDefault(); + if (handleCapsLock(cli, e)) return; cli.sendKeyboardInput(e.code, ButtonState.UP); };