From b20348908f0525093169524b99db5088199d85d8 Mon Sep 17 00:00:00 2001 From: Mauricio Siu Date: Sun, 9 Aug 2026 01:29:42 -0600 Subject: [PATCH] fix: allow Option/Alt composed characters in terminals on macOS --- .../docker/terminal/docker-terminal.tsx | 2 ++ .../settings/web-server/terminal.tsx | 2 ++ apps/dokploy/lib/terminal-keyboard.ts | 25 +++++++++++++++++++ 3 files changed, 29 insertions(+) create mode 100644 apps/dokploy/lib/terminal-keyboard.ts diff --git a/apps/dokploy/components/dashboard/docker/terminal/docker-terminal.tsx b/apps/dokploy/components/dashboard/docker/terminal/docker-terminal.tsx index b4f5e845d..d185e65b1 100644 --- a/apps/dokploy/components/dashboard/docker/terminal/docker-terminal.tsx +++ b/apps/dokploy/components/dashboard/docker/terminal/docker-terminal.tsx @@ -5,6 +5,7 @@ import "@xterm/xterm/css/xterm.css"; import { AttachAddon } from "@xterm/addon-attach"; import { useTheme } from "next-themes"; import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { fixMacOsAltKeys } from "@/lib/terminal-keyboard"; interface Props { id: string; @@ -45,6 +46,7 @@ export const DockerTerminal: React.FC = ({ const ws = new WebSocket(wsUrl); const addonAttach = new AttachAddon(ws); + fixMacOsAltKeys(term); // @ts-ignore term.open(termRef.current); // @ts-ignore diff --git a/apps/dokploy/components/dashboard/settings/web-server/terminal.tsx b/apps/dokploy/components/dashboard/settings/web-server/terminal.tsx index dccdec003..ceb09b2e7 100644 --- a/apps/dokploy/components/dashboard/settings/web-server/terminal.tsx +++ b/apps/dokploy/components/dashboard/settings/web-server/terminal.tsx @@ -6,6 +6,7 @@ import "@xterm/xterm/css/xterm.css"; import { AttachAddon } from "@xterm/addon-attach"; import { ClipboardAddon } from "@xterm/addon-clipboard"; import { useTheme } from "next-themes"; +import { fixMacOsAltKeys } from "@/lib/terminal-keyboard"; import { getLocalServerData } from "./local-server-config"; interface Props { @@ -58,6 +59,7 @@ export const Terminal: React.FC = ({ id, serverId }) => { const addonAttach = new AttachAddon(ws); const clipboardAddon = new ClipboardAddon(); term.loadAddon(clipboardAddon); + fixMacOsAltKeys(term); // @ts-ignore term.open(termRef.current); diff --git a/apps/dokploy/lib/terminal-keyboard.ts b/apps/dokploy/lib/terminal-keyboard.ts new file mode 100644 index 000000000..534ea9814 --- /dev/null +++ b/apps/dokploy/lib/terminal-keyboard.ts @@ -0,0 +1,25 @@ +import type { Terminal } from "@xterm/xterm"; + +// xterm's platform detection mistakes the bundled Next.js `process` polyfill +// for Node.js, so it never treats Option/Alt as third-level shift on macOS and +// swallows composed characters like Option+L (@ on German layouts). +// https://github.com/Dokploy/dokploy/issues/4297 +export const fixMacOsAltKeys = (term: Terminal) => { + if (!/Mac/.test(navigator.platform)) { + return; + } + term.attachCustomKeyEventHandler((event) => { + if ( + event.type === "keydown" && + event.altKey && + !event.ctrlKey && + !event.metaKey && + event.key.length === 1 + ) { + event.preventDefault(); + term.input(event.key); + return false; + } + return true; + }); +};