Skip to content

Instantly share code, notes, and snippets.

@johnlindquist
Created December 11, 2024 20:57
Show Gist options
  • Save johnlindquist/892635da6969d48777edd7caac05a21b to your computer and use it in GitHub Desktop.
Save johnlindquist/892635da6969d48777edd7caac05a21b to your computer and use it in GitHub Desktop.
Let me break down how `showInactive()` works on Windows and explain the rendering behavior:
1. For Windows, `showInactive()` is implemented in `native_window_views.cc`:
```478:487:shell/browser/native_window_views.cc
void NativeWindowViews::ShowInactive() {
widget()->ShowInactive();
NotifyWindowShow();
#if defined(USE_X11)
if (global_menu_bar_)
global_menu_bar_->OnWindowMapped();
#endif
}
```
The key is that it calls `widget()->ShowInactive()` which maps to the Win32 API call `ShowWindow(hwnd, SW_SHOWNOACTIVATE)`. This shows the window without giving it focus or bringing it to the foreground.
2. As for why rendering happens after calling `show()`, this is due to a chain of events:
When `show()` is called:
```460:476:shell/browser/native_window_views.cc
void NativeWindowViews::Show() {
if (is_modal() && NativeWindow::parent() &&
!widget()->native_widget_private()->IsVisible())
static_cast<NativeWindowViews*>(parent())->IncrementChildModals();
widget()->native_widget_private()->Show(GetRestoredState(), gfx::Rect());
// explicitly focus the window
widget()->Activate();
NotifyWindowShow();
#if defined(USE_X11)
if (global_menu_bar_)
global_menu_bar_->OnWindowMapped();
#endif
}
```
This triggers three important things:
1. `widget()->native_widget_private()->Show()` - Makes the window visible
2. `widget()->Activate()` - Gives the window focus
3. `NotifyWindowShow()` - Sends notifications about visibility change
The key to rendering is in `BrowserWindow::OnWindowShow()`:
```485:488:shell/browser/api/electron_api_browser_window.cc
void BrowserWindow::OnWindowShow() {
web_contents()->WasShown();
BaseWindow::OnWindowShow();
}
```
The critical line is `web_contents()->WasShown()` which tells Chromium's content layer that the window is now visible. This triggers Chromium to:
1. Start the compositor
2. Allocate GPU resources
3. Begin actual rendering of web content
Before `show()` is called, Chromium keeps the renderer in a suspended state to conserve resources. This is why you don't see any rendering until after `show()`.
To implement similar behavior in another library, you would need to:
```cpp
// For showing without activation
void ShowWindowInactive(HWND hwnd) {
ShowWindow(hwnd, SW_SHOWNOACTIVATE);
}
// For normal show with rendering
void ShowWindow(HWND hwnd) {
ShowWindow(hwnd, SW_SHOW);
SetForegroundWindow(hwnd);
// Signal your rendering system to start
StartRendering();
}
```
The key difference between `show()` and `showInactive()` on Windows is:
- `show()`: Uses `SW_SHOW` + `SetForegroundWindow()`
- `showInactive()`: Uses `SW_SHOWNOACTIVATE` only
This is why `showInactive()` makes the window visible but doesn't steal focus or trigger the taskbar to flash.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment