Skip to content

Commit 91555c3

Browse files
authored
feat: support configurable web terminal rendering (#10095)
* feat: support configurable web terminal rendering - Added a deployment option for configuring web terminal rendering. Valid values are 'webgl', 'canvas', and 'dom'.
1 parent 05a393c commit 91555c3

File tree

14 files changed

+59
-10
lines changed

14 files changed

+59
-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: canvas)
70+
The renderer to use when opening a web 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 renderer to use when opening a web terminal. Valid values are 'canvas',
415+
# 'webgl', or 'dom'.
416+
# (default: canvas, type: string)
417+
webTerminalRenderer: canvas
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"`
@@ -1762,7 +1763,18 @@ Write out the current server config as YAML to stdout.`,
17621763
Group: &deploymentGroupUserQuietHoursSchedule,
17631764
YAML: "defaultQuietHoursSchedule",
17641765
},
1766+
{
1767+
Name: "Web Terminal Renderer",
1768+
Description: "The renderer to use when opening a web terminal. Valid values are 'canvas', 'webgl', or 'dom'.",
1769+
Flag: "web-terminal-renderer",
1770+
Env: "CODER_WEB_TERMINAL_RENDERER",
1771+
Default: "canvas",
1772+
Value: &c.WebTerminalRenderer,
1773+
Group: &deploymentGroupClient,
1774+
YAML: "webTerminalRenderer",
1775+
},
17651776
}
1777+
17661778
return opts
17671779
}
17681780

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: canvas)
71+
The renderer to use when opening a web 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/e2e/playwright.config.ts

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export default defineConfig({
4949
`--dangerous-disable-rate-limits ` +
5050
`--provisioner-daemons 10 ` +
5151
`--provisioner-daemons-echo ` +
52+
`--web-terminal-renderer=dom ` +
5253
`--pprof-enable`,
5354
env: {
5455
...process.env,

site/src/AppRouter.tsx

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

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

+10-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 "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,10 @@ 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.web_terminal_renderer === "webgl") {
171171
terminal.loadAddon(new WebglAddon());
172+
} else if (config.data?.config.web_terminal_renderer === "canvas") {
173+
terminal.loadAddon(new CanvasAddon());
172174
}
173175
const fitAddon = new FitAddon();
174176
setFitAddon(fitAddon);
@@ -208,7 +210,7 @@ const TerminalPage: FC<TerminalPageProps> = ({ renderer }) => {
208210
window.removeEventListener("resize", listener);
209211
terminal.dispose();
210212
};
211-
}, [renderer, sendEvent, xtermRef, handleWebLink]);
213+
}, [config.data, sendEvent, xtermRef, handleWebLink]);
212214

213215
// Triggers the initial terminal connection using
214216
// the reconnection token and workspace name found

0 commit comments

Comments
 (0)