Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions news/changelog-1.6.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ All changes included in 1.6:

- ([#9134](https://github.com/quarto-dev/quarto-cli/issues/9134)): Add proper fix for `multiprocessing` in notebooks with the Python kernel.

## Chromium support

- ([#11135](https://github.com/quarto-dev/quarto-cli/issues/11135)): Use `--headless=old` mode for Chromium to avoid recent issues with the new `--headless` mode. Setting `--headless=new` can be configured with `QUARTO_CHROMIUM_HEADLESS_MODE=new` environment variable, however it is not recommended new headless mode seems to be unstable. Only use to be unblocked of a situation (like `QUARTO_CHROMIUM_HEADLESS_MODE="none"` if you use an old chrome version somehow that don't support `--headless=old`).
- ([#10170](https://github.com/quarto-dev/quarto-cli/issues/10170)): Quarto should find chrome executable automatically on most OS. If this is does not find it, or a specific version is needed, set `QUARTO_CHROMIUM` environment variable to the executable path.

## Other Fixes and Improvements

- Upgrade `mermaidjs` to 11.2.0.
Expand Down
17 changes: 16 additions & 1 deletion src/core/cri/cri.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ import { findOpenPort } from "../port.ts";
import { getNamedLifetime, ObjectWithLifetime } from "../lifetimes.ts";
import { sleep } from "../async.ts";
import { InternalError } from "../lib/error.ts";
import { getenv } from "../env.ts";
import { kRenderFileLifetime } from "../../config/constants.ts";
import { debug } from "../../deno_ral/log.ts";

async function waitForServer(port: number, timeout = 3000) {
const interval = 50;
Expand Down Expand Up @@ -78,9 +80,20 @@ export async function criClient(appPath?: string, port?: number) {
}
const app: string = appPath || await getBrowserExecutablePath();

// Allow to adapt the headless mode depending on the Chrome version
const headlessMode = getenv("QUARTO_CHROMIUM_HEADLESS_MODE", "old");

const cmd = [
app,
"--headless",
// TODO: Chrome v128 changed the default from --headless=old to --headless=new
// in 2024-08. Old headless mode was effectively a separate browser render,
// and while more performant did not share the same browser implementation as
// headful Chrome. New headless mode will likely be useful to some, but in Quarto use cases
// like printing to PDF or screenshoting, we need more work to
// move to the new mode. We'll use `--headless=old` as the default for now
// until the new mode is more stable, or until we really pin a version as default to be used.
// This is also impacting in chromote and pagedown R packages and we could keep syncing with them.
`--headless${headlessMode == "none" ? "" : "=" + headlessMode}`,
"--no-sandbox",
"--disable-gpu",
"--renderer-process-limit=1",
Expand All @@ -92,6 +105,8 @@ export async function criClient(appPath?: string, port?: number) {
let msg = "Couldn't find open server.";
// Printing more error information if chrome process errored
if (!(await browser.status()).success) {
debug(`[CHROMIUM path] : ${app}`);
debug(`[CHROMIUM cmd] : ${cmd}`);
const rawError = await browser.stderrOutput();
const errorString = new TextDecoder().decode(rawError);
msg = msg + "\n" + `Chrome process error: ${errorString}`;
Expand Down
20 changes: 17 additions & 3 deletions src/core/puppeteer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import { readRegistryKey } from "./windows.ts";
import { safeExistsSync, which } from "./path.ts";
import { error, info } from "../deno_ral/log.ts";
import { debug, error, info } from "../deno_ral/log.ts";
import { existsSync } from "../deno_ral/fs.ts";
import { UnreachableError } from "./lib/error.ts";
import { quartoDataDir } from "./appdirs.ts";
Expand Down Expand Up @@ -201,12 +201,20 @@ export async function withHeadlessBrowser<T>(

async function findChrome(): Promise<string | undefined> {
let path;
// First check env var and use this path if specified
const envPath = Deno.env.get("QUARTO_CHROMIUM");
if (envPath && safeExistsSync(envPath)) {
debug("[CHROMIUM] Using path specified in QUARTO_CHROMIUM");
debug(`[CHROMIUM] Path: ${envPath}`);
return envPath;
}
// Otherwise, try to find the path based on OS.
if (Deno.build.os === "darwin") {
const programs = [
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
"/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge",
];
return programs.find(safeExistsSync);
path = programs.find(safeExistsSync);
} else if (Deno.build.os === "windows") {
// Try the HKLM key
const programs = ["chrome.exe", "msedge.exe"];
Expand All @@ -216,7 +224,7 @@ async function findChrome(): Promise<string | undefined> {
programs[i],
"(Default)",
);
if (path && existsSync(path)) break;
if (path && safeExistsSync(path)) break;
}

// Try the HKCR key
Expand All @@ -240,6 +248,12 @@ async function findChrome(): Promise<string | undefined> {
path = await which("chromium-browser");
}
}
if (path) {
debug("[CHROMIUM] Found Chromium on OS known location");
debug(`[CHROMIUM] Path: ${path}`);
} else {
debug("[CHROMIUM] Chromium not found on OS known location");
}
return path;
}

Expand Down
Loading