setZoomLevel() / setZoomFactor() is silently ignored before the first navigation in the isolated and manual zoom modes
- Dominant language
- C++
- Stars
- 123k
- Forks
- 17.5k
- Avg merge
- 14h 31m
- Merged PRs (30d)
- 858
Description
### Preflight Checklist
- [x] I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/main/CONTRIBUTING.md) for this project.
- [x] I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/main/CODE_OF_CONDUCT.md) that this project adheres to.
- [x] I have searched the [issue tracker](https://www.github.com/electron/electron/issues) for a bug report that matches the one I want to file, without success.
### Electron Version
45.0.0-nightly.20260826 (current `main`, local build)
### What operating system(s) are you using?
macOS
### Operating System Version
macOS 26.5
### What arch are you using?
arm64
### Last Known Working Electron version
None known
### Does the issue also appear in Chromium / Google Chrome?
No
### Expected Behavior
A zoom level set before the first navigation commits is applied once the page loads, in the zoom
modes that are meant to persist (`isolated` and `manual`) – the same way
`webPreferences: { zoomMode: 'isolated', zoomFactor: 1.5 }` already behaves.
### Actual Behavior
The call is silently dropped – no error, no return value, and `getZoomFactor()` stays at `1`:
```js
const w = new BrowserWindow({ webPreferences: { zoomMode: 'isolated' } })
w.webContents.setZoomFactor(1.5) // silently dropped
await w.loadURL('https://example.com')
w.webContents.getZoomFactor() // 1 (expected 1.5)
```
`WebContentsZoomController::SetZoomLevel()` bails out on `!IsRenderFrameLive()` (no frame is live
before the first navigation commits), and the JS binding discards its `bool` result, so nothing
surfaces to the app. Expressing the same intent through web preferences does work, so the two
spellings of one intent disagree.
### Testcase Gist URL
_No response_
### Additional Information
The snippet above is the complete reproduction. The affected API surface is Electron-specific
(`webContents.setZoomLevel()` / `setZoomFactor()` and the `zoomMode` web preference), so there is
no Chromium equivalent to compare against. Workaround: pass the initial factor via
`webPreferences: { zoomFactor }` instead of calling the setter before load.
Fix with regression specs: #53226.
Contributor guide
Research direction
Start with WebContentsZoomController::SetZoomLevel() and the JavaScript binding that exposes webContents.setZoomLevel() and setZoomFactor(). Use the regression specs planned in #53226 to verify that pre-navigation setters persist in isolated and manual zoom modes and that getZoomFactor() reports the requested value after loading.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, electron, javascript
- Domain
- api, desktop
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100