Merge pull request #6026 from electron/ready-to-show

Add "ready-to-show" event and docs on showing window gracefully
This commit is contained in:
Cheng Zhao 2016-06-13 23:24:14 +00:00 committed by GitHub
commit fcc7dc774a
6 changed files with 84 additions and 9 deletions

View file

@ -156,6 +156,10 @@ void Window::OnWindowHide() {
Emit("hide");
}
void Window::OnReadyToShow() {
Emit("ready-to-show");
}
void Window::OnWindowMaximize() {
Emit("maximize");
}

View file

@ -61,6 +61,7 @@ class Window : public mate::TrackableObject<Window>,
void OnWindowFocus() override;
void OnWindowShow() override;
void OnWindowHide() override;
void OnReadyToShow() override;
void OnWindowMaximize() override;
void OnWindowUnmaximize() override;
void OnWindowMinimize() override;

View file

@ -560,6 +560,22 @@ void NativeWindow::BeforeUnloadDialogCancelled() {
window_unresposive_closure_.Cancel();
}
void NativeWindow::DidFirstVisuallyNonEmptyPaint() {
if (IsVisible())
return;
// When there is a non-empty first paint, resize the RenderWidget to force
// Chromium to draw.
const auto view = web_contents()->GetRenderWidgetHostView();
view->Show();
view->SetSize(GetContentSize());
// Emit the ReadyToShow event in next tick in case of pending drawing work.
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&NativeWindow::NotifyReadyToShow, GetWeakPtr()));
}
bool NativeWindow::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(NativeWindow, message)
@ -601,6 +617,10 @@ void NativeWindow::NotifyWindowUnresponsive() {
OnRendererUnresponsive());
}
void NativeWindow::NotifyReadyToShow() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnReadyToShow());
}
void NativeWindow::OnCapturePageDone(const CapturePageCallback& callback,
const SkBitmap& bitmap,
content::ReadbackResponse response) {

View file

@ -275,6 +275,7 @@ class NativeWindow : public base::SupportsUserData,
// content::WebContentsObserver:
void RenderViewCreated(content::RenderViewHost* render_view_host) override;
void BeforeUnloadDialogCancelled() override;
void DidFirstVisuallyNonEmptyPaint() override;
bool OnMessageReceived(const IPC::Message& message) override;
private:
@ -284,6 +285,9 @@ class NativeWindow : public base::SupportsUserData,
// Dispatch unresponsive event to observers.
void NotifyWindowUnresponsive();
// Dispatch ReadyToShow event to observers.
void NotifyReadyToShow();
// Called when CapturePage has done.
void OnCapturePageDone(const CapturePageCallback& callback,
const SkBitmap& bitmap,

View file

@ -48,6 +48,9 @@ class NativeWindowObserver {
// Called when window is hidden.
virtual void OnWindowHide() {}
// Called when window is ready to show.
virtual void OnReadyToShow() {}
// Called when window state changed.
virtual void OnWindowMaximize() {}
virtual void OnWindowUnmaximize() {}

View file

@ -4,22 +4,60 @@
```javascript
// In the main process.
const {BrowserWindow} = require('electron');
const {BrowserWindow} = require('electron')
// Or in the renderer process.
const {BrowserWindow} = require('electron').remote;
const {BrowserWindow} = require('electron').remote
let win = new BrowserWindow({width: 800, height: 600, show: false});
let win = new BrowserWindow({width: 800, height: 600})
win.on('closed', () => {
win = null;
});
win = null
})
win.loadURL('https://github.com');
win.show();
win.loadURL('https://github.com')
```
You can also create a window without chrome by using
[Frameless Window](frameless-window.md) API.
## Frameless window
To create a window without chrome, or a transparent window in arbitrary shape,
you can use the [Frameless Window](frameless-window.md) API.
## Showing window gracefully
When loading a page in window directly, users will see the progress of loading
page, which is not good experience for native app. To make the window display
without visual flash, there are two solutions for different situations.
### Using `ready-to-show` event
While loading the page, the `ready-to-show` event will be emitted when renderer
process has done drawing for the first time, showing window after this event
will have no visual flash:
```javascript
let win = new BrowserWindow({show: false})
win.once('ready-to-show', () => {
win.show()
})
```
This is event is usually emitted after the `did-finish-load` event, but for
pages with many remote resources, it may be emitted before the `did-finish-load`
event.
### Setting `backgroundColor`
For a complex app, the `ready-to-show` event could be emitted too late, making
the app feel slow. In this case, it is recommended to show the window
immediately, and use a `backgroundColor` close to your app's background:
```javascript
let win = new BrowserWindow({backgroundColor: '#2e2c29'})
win.loadURL('https://github.com')
```
Note that even for apps that use `ready-to-show` event, it is still recommended
to set `backgroundColor` to make app feel more native.
## Class: BrowserWindow
@ -271,6 +309,11 @@ Emitted when the window is shown.
Emitted when the window is hidden.
### Event: 'ready-to-show'
Emitted when the web page has been rendered and window can be displayed without
visual flash.
### Event: 'maximize'
Emitted when window is maximized.