chore: bump chromium to 144.0.7527.0 (main) (#48959)

* chore: bump chromium in DEPS to 144.0.7527.0

* 7106405: [video pip] Fix gesture handling issues

https://chromium-review.googlesource.com/c/chromium/src/+/7106405

* 7130938: Reland "Remove some dependencies from the custom_handlers component"

https://chromium-review.googlesource.com/c/chromium/src/+/7130938

* 7139361: Rename PluginService's GetPlugins methods

https://chromium-review.googlesource.com/c/chromium/src/+/7139361

* chore: fixup patch indices

* test: fix macos webgl test | 7128438: Reland "Flip SwiftShader deprecation to launched." | https://chromium-review.googlesource.com/c/chromium/src/+/7128438

* test: update webgl test to skip on fallback adapters

* Fixup spec runner to properly fail on linux when tests fail

* test: fixup dbus tests

* test: convert shared-texture-spec from old done callback to async

Fixes Error: done() called multiple times in test <sharedTexture module import shared texture produced by osr successfully imported and rendered with subtle api> of file /__w/electron/electron/src/electron/spec/api-shared-texture-spec.ts

* test: fixup shared texture spec

* Revert "test: fixup dbus tests"

This reverts commit 3e2e720003.

* test: fixup dbus tests

* test: disable context menu spellcheck tests on linux

https://github.com/electron/electron/pull/48657 broke those tests

* disable sharedTexture tests on platforms other than macOS arm64

They were not working on other platforms previously but now they error out.

Also removed extraneous debugging.

* fix: use github.sha for yarn cache key to avoid hashFiles() composite action bug

* Use --immutable-cache to allow native module builds

* fix: wait for devtools blur event in focus test to avoid race condition

* fix: wait for devtools blur event in focus test to avoid race condition

* fix allow native module builds in spec workspace

* test:rebuild native modules

* Revert "fix allow native module builds in spec workspace"

This reverts commit ffda3be98c.

* Revert "Use --immutable-cache to allow native module builds"

This reverts commit 2e6eea4348.

* Revert "fix: use github.sha for yarn cache key to avoid hashFiles() composite action bug"

This reverts commit 33560ba0de.

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: Keeley Hammond <khammond@slack-corp.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
Co-authored-by: Alice Zhao <alicelovescake@anthropic.com>
This commit is contained in:
electron-roller[bot]
2025-11-24 12:30:57 -05:00
committed by GitHub
parent 05233b4962
commit 66367e9db4
31 changed files with 495 additions and 370 deletions

2
spec/ambient.d.ts vendored
View File

@@ -1,2 +1,4 @@
declare let standardScheme: string;
declare let serviceWorkerScheme: string;
declare module 'dbus-native';

View File

@@ -10,7 +10,7 @@ import { nativeImage } from 'electron/common';
import { app } from 'electron/main';
import { expect } from 'chai';
import * as dbus from 'dbus-ts';
import * as dbus from 'dbus-native';
import * as path from 'node:path';
import { promisify } from 'node:util';
@@ -40,9 +40,10 @@ ifdescribe(!skip)('Notification module (dbus)', () => {
const path = '/org/freedesktop/Notifications';
const iface = 'org.freedesktop.DBus.Mock';
console.log(`session bus: ${process.env.DBUS_SESSION_BUS_ADDRESS}`);
const bus = await dbus.sessionBus();
const bus = dbus.sessionBus();
const service = bus.getService(serviceName);
mock = await service.getInterface(path, iface);
const getInterface = promisify(service.getInterface.bind(service));
mock = await getInterface(path, iface);
getCalls = promisify(mock.GetCalls.bind(mock));
reset = promisify(mock.Reset.bind(mock));
});

View File

@@ -7,7 +7,7 @@
// See https://pypi.python.org/pypi/python-dbusmock for more information about
// python-dbusmock.
import { expect } from 'chai';
import * as dbus from 'dbus-ts';
import * as dbus from 'dbus-native';
import { once } from 'node:events';
import { setTimeout } from 'node:timers/promises';
@@ -20,9 +20,10 @@ describe('powerMonitor', () => {
ifdescribe(process.platform === 'linux' && process.env.DBUS_SYSTEM_BUS_ADDRESS != null)('when powerMonitor module is loaded with dbus mock', () => {
before(async () => {
const systemBus = await dbus.systemBus();
const systemBus = dbus.systemBus();
const loginService = systemBus.getService('org.freedesktop.login1');
logindMock = await loginService.getInterface('/org/freedesktop/login1', 'org.freedesktop.DBus.Mock');
const getInterface = promisify(loginService.getInterface.bind(loginService));
logindMock = await getInterface('/org/freedesktop/login1', 'org.freedesktop.DBus.Mock');
getCalls = promisify(logindMock.GetCalls.bind(logindMock));
emitSignal = promisify(logindMock.EmitSignal.bind(logindMock));
reset = promisify(logindMock.Reset.bind(logindMock));

View File

@@ -5,11 +5,14 @@ import { expect } from 'chai';
import { randomUUID } from 'node:crypto';
import * as path from 'node:path';
import { ifdescribe } from './lib/spec-helpers';
import { closeWindow } from './lib/window-helpers';
const fixtures = path.resolve(__dirname, 'fixtures');
describe('sharedTexture module', () => {
// Tests only run properly on macOS arm64 for now
const skip = process.platform !== 'darwin' || process.arch !== 'arm64';
ifdescribe(!skip)('sharedTexture module', () => {
const {
nativeImage
} = require('electron');
@@ -35,7 +38,8 @@ describe('sharedTexture module', () => {
}
});
it('successfully imported and rendered with subtle api', (done) => {
it('successfully imported and rendered with subtle api', async function () {
this.timeout(debugSpec ? 100000 : 10000);
type CapturedTextureHolder = {
importedSubtle: Electron.SharedTextureImportedSubtle,
texture: Electron.OffscreenSharedTexture
@@ -45,172 +49,67 @@ describe('sharedTexture module', () => {
const preloadPath = path.join(dirPath, 'subtle', 'preload.js');
const htmlPath = path.join(dirPath, 'subtle', 'index.html');
const createWindow = () => {
const win = new BrowserWindow({
width: 256,
height: 256,
show: debugSpec,
webPreferences: {
preload: preloadPath
}
});
const osr = new BrowserWindow({
width: 128,
height: 128,
show: debugSpec,
webPreferences: {
offscreen: {
useSharedTexture: true
return new Promise<void>((resolve, reject) => {
const createWindow = () => {
const win = new BrowserWindow({
width: 256,
height: 256,
show: debugSpec,
webPreferences: {
preload: preloadPath
}
}
});
});
osr.webContents.setFrameRate(1);
osr.webContents.on('paint', (event: any) => {
const osr = new BrowserWindow({
width: 128,
height: 128,
show: debugSpec,
webPreferences: {
offscreen: {
useSharedTexture: true
}
}
});
osr.webContents.setFrameRate(1);
osr.webContents.on('paint', (event: any) => {
// Step 1: Input source of shared texture handle.
const texture = event.texture;
const texture = event.texture;
if (!texture) {
console.error('No texture, GPU may be unavailable, skipping.');
done();
return;
}
if (!texture) {
console.error('No texture, GPU may be unavailable, skipping.');
resolve();
}
// Step 2: Import as SharedTextureImported
console.log(texture.textureInfo);
const importedSubtle = sharedTexture.subtle.importSharedTexture(texture.textureInfo);
// Step 2: Import as SharedTextureImported
const importedSubtle = sharedTexture.subtle.importSharedTexture(texture.textureInfo);
// Step 3: Prepare for transfer to another process (win's renderer)
const transfer = importedSubtle.startTransferSharedTexture();
// Step 3: Prepare for transfer to another process (win's renderer)
const transfer = importedSubtle.startTransferSharedTexture();
const id = randomUUID();
capturedTextures.set(id, { importedSubtle, texture });
const id = randomUUID();
capturedTextures.set(id, { importedSubtle, texture });
// Step 4: Send the shared texture to the renderer process (goto preload.js)
win.webContents.send('shared-texture', id, transfer);
});
// Step 4: Send the shared texture to the renderer process (goto preload.js)
win.webContents.send('shared-texture', id, transfer);
});
ipcMain.on('shared-texture-done', (event: any, id: string) => {
ipcMain.on('shared-texture-done', (event: any, id: string) => {
// Step 12: Release the shared texture resources at main process
const data = capturedTextures.get(id);
if (data) {
capturedTextures.delete(id);
const { importedSubtle, texture } = data;
const data = capturedTextures.get(id);
if (data) {
capturedTextures.delete(id);
const { importedSubtle, texture } = data;
// Step 13: Release the imported shared texture
importedSubtle.release(() => {
// Step 13: Release the imported shared texture
importedSubtle.release(() => {
// Step 14: Release the shared texture once GPU is done
texture.release();
});
// Step 15: Slightly timeout and capture the node screenshot
setTimeout(async () => {
// Step 16: Compare the captured image with the target image
const captured = await win.webContents.capturePage({
x: 16,
y: 16,
width: 128,
height: 128
texture.release();
});
// Step 17: Resize the target image to match the captured image size, in case dpr != 1
const target = targetImage.resize({ ...captured.getSize() });
// Step 18: nativeImage have error comparing pixel data when color space is different,
// send to browser for comparison using canvas.
win.webContents.send('verify-captured-image', {
captured: captured.toDataURL(),
target: target.toDataURL()
});
}, 300);
}
});
ipcMain.on('verify-captured-image-done', (event: any, result: { difference: number, total: number }) => {
// Step 22: Verify the result from renderer process
try {
// macOS may have tiny color difference after the whole rendering process,
// and the color may change slightly when resizing at device pixel ratio != 1.
// Limit error should not be different more than 1% of the whole image.
const ratio = result.difference / result.total;
console.log('image difference: ', ratio);
expect(ratio).to.be.lessThan(0.01);
done();
} catch (e) {
done(e);
}
});
ipcMain.on('webgpu-unavailable', () => {
console.error('WebGPU is not available, skipping.');
done();
});
win.loadFile(htmlPath);
osr.loadFile(osrPath);
};
app.whenReady().then(() => {
createWindow();
});
}).timeout(debugSpec ? 100000 : 10000);
const runSharedTextureManagedTest = (done: Mocha.Done, iframe: boolean) => {
const preloadPath = path.join(dirPath, 'managed', 'preload.js');
const htmlPath = path.join(dirPath, 'managed', iframe ? 'frame.html' : 'index.html');
const createWindow = () => {
const win = new BrowserWindow({
width: 256,
height: 256,
show: debugSpec,
webPreferences: {
preload: preloadPath,
nodeIntegrationInSubFrames: iframe
}
});
const osr = new BrowserWindow({
width: 128,
height: 128,
show: debugSpec,
webPreferences: {
offscreen: {
useSharedTexture: true
}
}
});
osr.webContents.setFrameRate(1);
osr.webContents.on('paint', async (event: any) => {
const targetFrame = iframe ? win.webContents.mainFrame.frames[0] : win.webContents.mainFrame;
if (!targetFrame) {
done(new Error('Target frame not found'));
return;
}
// Step 1: Input source of shared texture handle.
const texture = event.texture;
if (!texture) {
console.error('No texture, GPU may be unavailable, skipping.');
done();
return;
}
// Step 2: Import as SharedTextureImported
console.log(texture.textureInfo);
const imported = sharedTexture.importSharedTexture({
textureInfo: texture.textureInfo,
allReferencesReleased: () => {
// Release the shared texture source once GPU is done.
// Will be called when all processes have finished using the shared texture.
texture.release();
// Slightly timeout and capture the node screenshot
// Step 15: Slightly timeout and capture the node screenshot
setTimeout(async () => {
// Compare the captured image with the target image
// Step 16: Compare the captured image with the target image
const captured = await win.webContents.capturePage({
x: 16,
y: 16,
@@ -218,12 +117,12 @@ describe('sharedTexture module', () => {
height: 128
});
// Resize the target image to match the captured image size, in case dpr != 1
// Step 17: Resize the target image to match the captured image size, in case dpr != 1
const target = targetImage.resize({ ...captured.getSize() });
// nativeImage have error comparing pixel data when color space is different,
// Step 18: nativeImage have error comparing pixel data when color space is different,
// send to browser for comparison using canvas.
targetFrame.send('verify-captured-image', {
win.webContents.send('verify-captured-image', {
captured: captured.toDataURL(),
target: target.toDataURL()
});
@@ -231,51 +130,155 @@ describe('sharedTexture module', () => {
}
});
// Step 3: Transfer to another process (win's renderer)
await sharedTexture.sendSharedTexture({
frame: iframe ? targetFrame : win.webContents.mainFrame,
importedSharedTexture: imported
});
// Step 4: Release the imported and wait for signal to release the source
imported.release();
});
ipcMain.on('verify-captured-image-done', (event: any, result: { difference: number, total: number }) => {
// Verify the result from renderer process
try {
ipcMain.on('verify-captured-image-done', (event: any, result: { difference: number, total: number }) => {
// Step 22: Verify the result from renderer process
try {
// macOS may have tiny color difference after the whole rendering process,
// and the color may change slightly when resizing at device pixel ratio != 1.
// Limit error should not be different more than 1% of the whole image.
const ratio = result.difference / result.total;
console.log('image difference: ', ratio);
expect(ratio).to.be.lessThan(0.01);
done();
} catch (e) {
setTimeout(() => done(e), 1000000);
}
const ratio = result.difference / result.total;
expect(ratio).to.be.lessThan(0.01);
resolve();
} catch (e) {
reject(e);
}
});
ipcMain.on('webgpu-unavailable', () => {
console.error('WebGPU is not available, skipping.');
resolve();
});
win.loadFile(htmlPath);
osr.loadFile(osrPath);
};
app.whenReady().then(() => {
createWindow();
});
});
});
ipcMain.on('webgpu-unavailable', () => {
console.error('WebGPU is not available, skipping.');
done();
const runSharedTextureManagedTest = (iframe: boolean): Promise<void> => {
const preloadPath = path.join(dirPath, 'managed', 'preload.js');
const htmlPath = path.join(dirPath, 'managed', iframe ? 'frame.html' : 'index.html');
return new Promise<void>((resolve, reject) => {
const createWindow = () => {
const win = new BrowserWindow({
width: 256,
height: 256,
show: debugSpec,
webPreferences: {
preload: preloadPath,
nodeIntegrationInSubFrames: iframe
}
});
const osr = new BrowserWindow({
width: 128,
height: 128,
show: debugSpec,
webPreferences: {
offscreen: {
useSharedTexture: true
}
}
});
osr.webContents.setFrameRate(1);
osr.webContents.on('paint', async (event: any) => {
const targetFrame = iframe ? win.webContents.mainFrame.frames[0] : win.webContents.mainFrame;
if (!targetFrame) {
reject(new Error('Target frame not found'));
return;
}
// Step 1: Input source of shared texture handle.
const texture = event.texture;
if (!texture) {
console.error('No texture, GPU may be unavailable, skipping.');
resolve();
return;
}
// Step 2: Import as SharedTextureImported
const imported = sharedTexture.importSharedTexture({
textureInfo: texture.textureInfo,
allReferencesReleased: () => {
// Release the shared texture source once GPU is done.
// Will be called when all processes have finished using the shared texture.
texture.release();
// Slightly timeout and capture the node screenshot
setTimeout(async () => {
// Compare the captured image with the target image
const captured = await win.webContents.capturePage({
x: 16,
y: 16,
width: 128,
height: 128
});
// Resize the target image to match the captured image size, in case dpr != 1
const target = targetImage.resize({ ...captured.getSize() });
// nativeImage have error comparing pixel data when color space is different,
// send to browser for comparison using canvas.
targetFrame.send('verify-captured-image', {
captured: captured.toDataURL(),
target: target.toDataURL()
});
}, 300);
}
});
// Step 3: Transfer to another process (win's renderer)
await sharedTexture.sendSharedTexture({
frame: iframe ? targetFrame : win.webContents.mainFrame,
importedSharedTexture: imported
});
// Step 4: Release the imported and wait for signal to release the source
imported.release();
});
ipcMain.on('verify-captured-image-done', (event: any, result: { difference: number, total: number }) => {
// Verify the result from renderer process
try {
// macOS may have tiny color difference after the whole rendering process,
// and the color may change slightly when resizing at device pixel ratio != 1.
// Limit error should not be different more than 1% of the whole image.
const ratio = result.difference / result.total;
expect(ratio).to.be.lessThan(0.01);
resolve();
} catch (e) {
setTimeout(() => reject(e), 1000000);
}
});
ipcMain.on('webgpu-unavailable', () => {
console.error('WebGPU is not available, skipping.');
resolve();
});
win.loadFile(htmlPath);
osr.loadFile(osrPath);
};
app.whenReady().then(() => {
createWindow();
});
win.loadFile(htmlPath);
osr.loadFile(osrPath);
};
app.whenReady().then(() => {
createWindow();
});
};
it('successfully imported and rendered with managed api, without iframe', (done) => {
runSharedTextureManagedTest(done, false);
it('successfully imported and rendered with managed api, without iframe', async () => {
return runSharedTextureManagedTest(false);
}).timeout(debugSpec ? 100000 : 10000);
it('successfully imported and rendered with managed api, with iframe', (done) => {
runSharedTextureManagedTest(done, true);
it('successfully imported and rendered with managed api, with iframe', async () => {
return runSharedTextureManagedTest(true);
}).timeout(debugSpec ? 100000 : 10000);
});
});

View File

@@ -1067,13 +1067,15 @@ describe('webContents module', () => {
assert(devToolsWebContents !== null);
const windowFocused = once(window, 'focus');
const devToolsBlurred = once(devToolsWebContents, 'blur');
window.focus();
await windowFocused;
await Promise.all([windowFocused, devToolsBlurred]);
expect(devToolsWebContents.isFocused()).to.be.false();
const devToolsWebContentsFocused = once(devToolsWebContents, 'focus');
const windowBlurred = once(window, 'blur');
window.webContents.inspectElement(100, 100);
await devToolsWebContentsFocused;
await Promise.all([devToolsWebContentsFocused, windowBlurred]);
expect(devToolsWebContents.isFocused()).to.be.true();
expect(window.isFocused()).to.be.false();

View File

@@ -2878,16 +2878,26 @@ describe('chromium features', () => {
});
});
// This is intentionally disabled on arm macs: https://chromium-review.googlesource.com/c/chromium/src/+/4143761
ifdescribe(process.platform === 'darwin' && process.arch !== 'arm64')('webgl', () => {
it('can be gotten as context in canvas', async () => {
const w = new BrowserWindow({ show: false });
describe('webgl', () => {
it('can be gotten as context in canvas', async function () {
const w = new BrowserWindow({
show: false
});
w.loadURL('about:blank');
await w.loadURL(`file://${fixturesPath}/pages/blank.html`);
const canWebglContextBeCreated = await w.webContents.executeJavaScript(`
document.createElement('canvas').getContext('webgl') != null;
`);
expect(canWebglContextBeCreated).to.be.true();
const isFallbackAdapter = await w.webContents.executeJavaScript(`
navigator.gpu?.requestAdapter().then(adapter => (adapter?.info?.isFallbackAdapter || !adapter?.info), true)`
);
if (isFallbackAdapter) {
console.log('Skipping webgl test on fallback adapter');
this.skip();
} else {
const canWebglContextBeCreated = await w.webContents.executeJavaScript(`
document.createElement('canvas').getContext('webgl') != null;
`);
expect(canWebglContextBeCreated).to.be.true();
}
});
});

View File

@@ -27,12 +27,13 @@
"@types/uuid": "^3.4.6",
"@types/w3c-web-serial": "^1.0.7",
"@types/ws": "^7.2.0",
"abstract-socket": "github:deepak1556/node-abstractsocket#928cc591decd12aff7dad96449da8afc29832c19",
"basic-auth": "^2.0.1",
"busboy": "^1.6.0",
"chai": "^4.2.0",
"chai-as-promised": "^7.1.1",
"coffeescript": "^2.4.1",
"dbus-ts": "^0.0.7",
"dbus-native": "github:nornagon/dbus-native#master",
"dirty-chai": "^2.0.1",
"express": "^4.20.0",
"graceful-fs": "^4.1.15",

View File

@@ -88,8 +88,8 @@ ifdescribe(features.isBuiltinSpellCheckerEnabled())('spellchecker', function ()
await closeWindow(w);
});
// Context menu test can not run on Windows.
const shouldRun = process.platform !== 'win32';
// Context menu test can not run on Windows or Linux (https://github.com/electron/electron/pull/48657 broke linux).
const shouldRun = process.platform !== 'win32' && process.platform !== 'linux';
ifit(shouldRun)('should detect correctly spelled words as correct', async () => {
await w.webContents.executeJavaScript('document.body.querySelector("textarea").value = "typography"');