mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
fix: paintWhenInitiallyHidden on Windows/Linux
This commit is contained in:
@@ -49,6 +49,7 @@ BrowserWindow::BrowserWindow(gin::Arguments* args,
|
||||
// when initially hidden
|
||||
bool paint_when_initially_hidden = true;
|
||||
options.Get(options::kPaintWhenInitiallyHidden, &paint_when_initially_hidden);
|
||||
paint_when_initially_hidden_ = paint_when_initially_hidden;
|
||||
if (!paint_when_initially_hidden) {
|
||||
bool show = true;
|
||||
options.Get(options::kShow, &show);
|
||||
@@ -288,6 +289,17 @@ void BrowserWindow::OnWindowHide() {
|
||||
BaseWindow::OnWindowHide();
|
||||
}
|
||||
|
||||
void BrowserWindow::RenderViewReady() {
|
||||
// When paintWhenInitiallyHidden is true and the native window has not been
|
||||
// shown yet, tell the WebContents it is visible so the renderer's compositor
|
||||
// starts producing frames. Without this the renderer's LayerTreeHost stays
|
||||
// hidden and no CompositorFrames (and therefore no presentation callbacks)
|
||||
// are ever produced, which means PerformanceObserver paint-timing entries
|
||||
// (first-paint / first-contentful-paint) never fire.
|
||||
if (paint_when_initially_hidden_ && !window()->IsVisible())
|
||||
web_contents()->WasShown();
|
||||
}
|
||||
|
||||
void BrowserWindow::Show() {
|
||||
web_contents()->WasShown();
|
||||
BaseWindow::Show();
|
||||
|
||||
@@ -42,6 +42,7 @@ class BrowserWindow : public BaseWindow,
|
||||
|
||||
// content::WebContentsObserver:
|
||||
void BeforeUnloadDialogCancelled() override;
|
||||
void RenderViewReady() override;
|
||||
void WebContentsDestroyed() override;
|
||||
|
||||
// ExtendedWebContentsObserver:
|
||||
@@ -79,6 +80,12 @@ class BrowserWindow : public BaseWindow,
|
||||
private:
|
||||
// Helpers.
|
||||
|
||||
// When true and the window is created with show: false, the renderer is
|
||||
// told it is visible as soon as it is ready so that PerformanceObserver
|
||||
// paint‐timing entries (first-paint / first-contentful-paint) are
|
||||
// produced even before the native window is shown.
|
||||
bool paint_when_initially_hidden_ = false;
|
||||
|
||||
v8::Global<v8::Value> web_contents_;
|
||||
v8::Global<v8::Value> web_contents_view_;
|
||||
base::WeakPtr<api::WebContents> api_web_contents_;
|
||||
|
||||
@@ -6721,28 +6721,35 @@ describe('BrowserWindow module', () => {
|
||||
w.loadFile(path.join(fixtures, 'pages', 'send-after-node.html'));
|
||||
});
|
||||
|
||||
// TODO(codebytere): fix on Windows and Linux too
|
||||
ifdescribe(process.platform === 'darwin')('window.webContents initial paint', () => {
|
||||
describe('window.webContents initial paint', () => {
|
||||
afterEach(closeAllWindows);
|
||||
it('paints when a window is initially hidden', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
it('paints when a window is initially hidden with paintWhenInitiallyHidden', async () => {
|
||||
const w = new BrowserWindow({
|
||||
show: false,
|
||||
paintWhenInitiallyHidden: true
|
||||
});
|
||||
await w.loadFile(path.join(fixtures, 'pages', 'a.html'));
|
||||
|
||||
const entries = await w.webContents.executeJavaScript(`
|
||||
new Promise((resolve) => {
|
||||
const observer = new PerformanceObserver((performance) => {
|
||||
observer.disconnect();
|
||||
resolve(performance.getEntries());
|
||||
const observer = new PerformanceObserver((list) => {
|
||||
const paintEntries = list.getEntries().filter(
|
||||
e => e.name === 'first-paint' || e.name === 'first-contentful-paint'
|
||||
);
|
||||
if (paintEntries.length > 0) {
|
||||
observer.disconnect();
|
||||
resolve(paintEntries.map(e => e.name));
|
||||
}
|
||||
});
|
||||
observer.observe({ entryTypes: ['paint'] });
|
||||
});
|
||||
|
||||
const header = document.createElement('h1');
|
||||
header.innerText = 'Paint me!!';
|
||||
document.getElementById('div').appendChild(header);
|
||||
const header = document.createElement('h1');
|
||||
header.innerText = 'Paint me!!';
|
||||
document.getElementById('div').appendChild(header);
|
||||
});
|
||||
`);
|
||||
|
||||
expect(JSON.stringify(entries)).to.eq('{}');
|
||||
expect(entries).to.be.an('array').that.includes('first-contentful-paint');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user