Skip to content

Commit 9fbbf06

Browse files
committed
feat: support configurable web terminal rendering
- Added a deployment option for configuring web terminal rendering. Valid values are 'webgl', 'canvas', and 'dom'.
1 parent eb4826a commit 9fbbf06

File tree

13 files changed

+61
-10
lines changed

13 files changed

+61
-10
lines changed

cli/testdata/coder_server_--help.golden

+4
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ Clients include the coder cli, vs code extension, and the web UI.
6666
--ssh-hostname-prefix string, $CODER_SSH_HOSTNAME_PREFIX (default: coder.)
6767
The SSH deployment prefix is used in the Host of the ssh config.
6868

69+
--web-terminal-renderer string, $CODER_WEB_TERMINAL_RENDERER (default: webgl)
70+
The framework to use when rendering the terminal. Valid values are
71+
'canvas', 'webgl', or 'dom'.
72+
6973
CONFIG OPTIONS:
7074
Use a YAML configuration file when your server launch become unwieldy.
7175

cli/testdata/server-config.yaml.golden

+4
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,10 @@ client:
411411
# incorrectly can break SSH to your deployment, use cautiously.
412412
# (default: <unset>, type: string-array)
413413
sshConfigOptions: []
414+
# The framework to use when rendering the terminal. Valid values are 'canvas',
415+
# 'webgl', or 'dom'.
416+
# (default: webgl, type: string)
417+
webTerminalRenderer: webgl
414418
# Support links to display in the top right drop down menu.
415419
# (default: <unset>, type: struct[[]codersdk.LinkConfig])
416420
supportLinks: []

coderd/apidoc/docs.go

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

codersdk/deployment.go

+12
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ type DeploymentValues struct {
180180
ProxyHealthStatusInterval clibase.Duration `json:"proxy_health_status_interval,omitempty" typescript:",notnull"`
181181
EnableTerraformDebugMode clibase.Bool `json:"enable_terraform_debug_mode,omitempty" typescript:",notnull"`
182182
UserQuietHoursSchedule UserQuietHoursScheduleConfig `json:"user_quiet_hours_schedule,omitempty" typescript:",notnull"`
183+
WebTerminalRenderer clibase.String `json:"web_terminal_renderer,omitempty" typescript:",notnull"`
183184

184185
Config clibase.YAMLConfigPath `json:"config,omitempty" typescript:",notnull"`
185186
WriteConfig clibase.Bool `json:"write_config,omitempty" typescript:",notnull"`
@@ -1761,7 +1762,18 @@ Write out the current server config as YAML to stdout.`,
17611762
Group: &deploymentGroupUserQuietHoursSchedule,
17621763
YAML: "defaultQuietHoursSchedule",
17631764
},
1765+
{
1766+
Name: "Web Terminal Renderer",
1767+
Description: "The framework to use when rendering the terminal. Valid values are 'canvas', 'webgl', or 'dom'.",
1768+
Flag: "web-terminal-renderer",
1769+
Env: "CODER_WEB_TERMINAL_RENDERER",
1770+
Default: "webgl",
1771+
Value: &c.WebTerminalRenderer,
1772+
Group: &deploymentGroupClient,
1773+
YAML: "webTerminalRenderer",
1774+
},
17641775
}
1776+
17651777
return opts
17661778
}
17671779

docs/api/general.md

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/api/schemas.md

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/cli/server.md

+11
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

enterprise/cli/testdata/coder_server_--help.golden

+4
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ Clients include the coder cli, vs code extension, and the web UI.
6767
--ssh-hostname-prefix string, $CODER_SSH_HOSTNAME_PREFIX (default: coder.)
6868
The SSH deployment prefix is used in the Host of the ssh config.
6969

70+
--web-terminal-renderer string, $CODER_WEB_TERMINAL_RENDERER (default: webgl)
71+
The framework to use when rendering the terminal. Valid values are
72+
'canvas', 'webgl', or 'dom'.
73+
7074
CONFIG OPTIONS:
7175
Use a YAML configuration file when your server launch become unwieldy.
7276

site/src/AppRouter.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ export const AppRouter: FC = () => {
338338
{/* Terminal and CLI auth pages don't have the dashboard layout */}
339339
<Route
340340
path="/:username/:workspace/terminal"
341-
element={<TerminalPage renderer="webgl" />}
341+
element={<TerminalPage />}
342342
/>
343343
<Route path="cli-auth" element={<CliAuthenticationPage />} />
344344
</Route>

site/src/api/typesGenerated.ts

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

site/src/pages/TerminalPage/TerminalPage.test.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Object.defineProperty(window, "TextEncoder", {
3737
const renderTerminal = async (
3838
route = `/${MockUser.username}/${MockWorkspace.name}/terminal`,
3939
) => {
40-
const utils = renderWithAuth(<TerminalPage renderer="dom" />, {
40+
const utils = renderWithAuth(<TerminalPage />, {
4141
route,
4242
path: "/:username/:workspace/terminal",
4343
});

site/src/pages/TerminalPage/TerminalPage.tsx

+13-8
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { colors } from "theme/colors";
88
import { v4 as uuidv4 } from "uuid";
99
import * as XTerm from "xterm";
1010
import { WebglAddon } from "xterm-addon-webgl";
11+
import { CanvasAddon } from "xterm-addon-canvas";
1112
import { FitAddon } from "xterm-addon-fit";
1213
import { WebLinksAddon } from "xterm-addon-web-links";
1314
import { Unicode11Addon } from "xterm-addon-unicode11";
@@ -24,6 +25,8 @@ import Popover from "@mui/material/Popover";
2425
import { ProxyStatusLatency } from "components/ProxyStatusLatency/ProxyStatusLatency";
2526
import TerminalPageAlert, { TerminalPageAlertType } from "./TerminalPageAlert";
2627
import { portForwardURL } from "utils/portForward";
28+
import { useQuery } from "@tanstack/react-query";
29+
import { deploymentConfig } from "api/queries/deployment";
2730

2831
export const Language = {
2932
workspaceErrorMessagePrefix: "Unable to fetch workspace: ",
@@ -57,11 +60,7 @@ const useTerminalWarning = ({ agent }: { agent?: WorkspaceAgent }) => {
5760
};
5861
};
5962

60-
type TerminalPageProps = React.PropsWithChildren<{
61-
renderer: "webgl" | "dom";
62-
}>;
63-
64-
const TerminalPage: FC<TerminalPageProps> = ({ renderer }) => {
63+
const TerminalPage: FC = () => {
6564
const navigate = useNavigate();
6665
const styles = useStyles();
6766
const { proxy } = useProxy();
@@ -121,6 +120,8 @@ const TerminalPage: FC<TerminalPageProps> = ({ renderer }) => {
121120
agent: workspaceAgent,
122121
});
123122

123+
const config = useQuery(deploymentConfig());
124+
124125
// handleWebLink handles opening of URLs in the terminal!
125126
const handleWebLink = useCallback(
126127
(uri: string) => {
@@ -186,9 +187,13 @@ const TerminalPage: FC<TerminalPageProps> = ({ renderer }) => {
186187
background: colors.gray[16],
187188
},
188189
});
189-
// DOM is the default renderer.
190-
if (renderer === "webgl") {
190+
if (config.data && config.data.config.web_terminal_renderer === "webgl") {
191191
terminal.loadAddon(new WebglAddon());
192+
} else if (
193+
config.data &&
194+
config.data.config.web_terminal_renderer === "canvas"
195+
) {
196+
terminal.loadAddon(new CanvasAddon());
192197
}
193198
const fitAddon = new FitAddon();
194199
setFitAddon(fitAddon);
@@ -228,7 +233,7 @@ const TerminalPage: FC<TerminalPageProps> = ({ renderer }) => {
228233
window.removeEventListener("resize", listener);
229234
terminal.dispose();
230235
};
231-
}, [renderer, sendEvent, xtermRef, handleWebLink]);
236+
}, [config.data, sendEvent, xtermRef, handleWebLink]);
232237

233238
// Triggers the initial terminal connection using
234239
// the reconnection token and workspace name found

0 commit comments

Comments
 (0)