Skip to content

Commit 7fe7257

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 d24d2d2 commit 7fe7257

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
@@ -7,6 +7,7 @@ import { colors } from "theme/colors";
77
import { v4 as uuidv4 } from "uuid";
88
import * as XTerm from "xterm";
99
import { WebglAddon } from "xterm-addon-webgl";
10+
import { CanvasAddon } from "xterm-addon-canvas";
1011
import { FitAddon } from "xterm-addon-fit";
1112
import { WebLinksAddon } from "xterm-addon-web-links";
1213
import { Unicode11Addon } from "xterm-addon-unicode11";
@@ -28,18 +29,16 @@ import {
2829
LoadedScriptsAlert,
2930
LoadingScriptsAlert,
3031
} from "./TerminalAlerts";
32+
import { useQuery } from "@tanstack/react-query";
33+
import { deploymentConfig } from "api/queries/deployment";
3134

3235
export const Language = {
3336
workspaceErrorMessagePrefix: "Unable to fetch workspace: ",
3437
workspaceAgentErrorMessagePrefix: "Unable to fetch workspace agent: ",
3538
websocketErrorMessagePrefix: "WebSocket failed: ",
3639
};
3740

38-
type TerminalPageProps = React.PropsWithChildren<{
39-
renderer: "webgl" | "dom";
40-
}>;
41-
42-
const TerminalPage: FC<TerminalPageProps> = ({ renderer }) => {
41+
const TerminalPage: FC = () => {
4342
const navigate = useNavigate();
4443
const styles = useStyles();
4544
const { proxy } = useProxy();
@@ -101,6 +100,8 @@ const TerminalPage: FC<TerminalPageProps> = ({ renderer }) => {
101100
prevLifecycleState.current = lifecycleState;
102101
}, [lifecycleState]);
103102

103+
const config = useQuery(deploymentConfig());
104+
104105
// handleWebLink handles opening of URLs in the terminal!
105106
const handleWebLink = useCallback(
106107
(uri: string) => {
@@ -166,9 +167,13 @@ const TerminalPage: FC<TerminalPageProps> = ({ renderer }) => {
166167
background: colors.gray[16],
167168
},
168169
});
169-
// DOM is the default renderer.
170-
if (renderer === "webgl") {
170+
if (config.data && config.data.config.web_terminal_renderer === "webgl") {
171171
terminal.loadAddon(new WebglAddon());
172+
} else if (
173+
config.data &&
174+
config.data.config.web_terminal_renderer === "canvas"
175+
) {
176+
terminal.loadAddon(new CanvasAddon());
172177
}
173178
const fitAddon = new FitAddon();
174179
setFitAddon(fitAddon);
@@ -208,7 +213,7 @@ const TerminalPage: FC<TerminalPageProps> = ({ renderer }) => {
208213
window.removeEventListener("resize", listener);
209214
terminal.dispose();
210215
};
211-
}, [renderer, sendEvent, xtermRef, handleWebLink]);
216+
}, [config.data, sendEvent, xtermRef, handleWebLink]);
212217

213218
// Triggers the initial terminal connection using
214219
// the reconnection token and workspace name found

0 commit comments

Comments
 (0)