Skip to content

Commit ad61434

Browse files
committed
Sync cefpython147-qt with cefpython147 (2026-05-09)
Squash-merge of 10 commits from cefpython147 to refresh PR cztomczak#691 with the latest fixes and enhancements developed since the last sync. Features: * Add native Wayland support — explicit opt-in via WindowInfo; X11/XWayland remains the default (9c2ae77) * Implement RenderHandler.GetScreenInfo with HiDPI support so high-DPI displays report accurate device scale factors (9969797) * examples/pysdl2: support multiple popup windows with clean shutdown (bb24151) Fixes: * Sync render_handler with current CEF API (c6f2a56) * Guard X11 error-handler install at compile time in cefpython.pyx (7a65e6b) * examples/pysdl2: window resize, HiDPI rendering, mouse drag, Wayland DPI handling (2aff2c9) * examples/pysdl2: scale mouse wheel by deviceScaleFactor for HiDPI (3e45abd) Refactor / docs: * Audit cef.Initialize defaults on Linux; drop dead switches and stale workarounds (db13d7d) * Correct version-tagged comments to match actual upstream history (bd924c4) * Drop defensive parenthetical from sandbox History comment in window_utils_linux.pyx (7ae0553)
1 parent ec3acf4 commit ad61434

19 files changed

Lines changed: 980 additions & 347 deletions

README.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -587,9 +587,6 @@ at this moment.
587587
* [SetUrl](api/Request.md#seturl)
588588
* [GetMethod](api/Request.md#getmethod)
589589
* [SetMethod](api/Request.md#setmethod)
590-
* [SetReferrer](api/Request.md#setreferrer)
591-
* [GetReferrerURL](api/Request.md#getreferrerurl)
592-
* [GetReferrerPolicy](api/Request.md#getreferrerpolicy)
593590
* [GetPostData](api/Request.md#getpostdata)
594591
* [SetPostData](api/Request.md#setpostdata)
595592
* [GetHeaderMap](api/Request.md#getheadermap)

api/API-index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,8 +347,8 @@
347347
* [RenderHandler (interface)](RenderHandler.md#renderhandler-interface)
348348
* [GetRootScreenRect](RenderHandler.md#getrootscreenrect)
349349
* [GetViewRect](RenderHandler.md#getviewrect)
350-
* [GetScreenRect](RenderHandler.md#getscreenrect)
351350
* [GetScreenPoint](RenderHandler.md#getscreenpoint)
351+
* [GetScreenInfo](RenderHandler.md#getscreeninfo)
352352
* [OnPopupShow](RenderHandler.md#onpopupshow)
353353
* [OnPopupSize](RenderHandler.md#onpopupsize)
354354
* [OnPaint](RenderHandler.md#onpaint)

api/RenderHandler.md

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ Table of contents:
1515
* [Callbacks](#callbacks)
1616
* [GetRootScreenRect](#getrootscreenrect)
1717
* [GetViewRect](#getviewrect)
18-
* [GetScreenRect](#getscreenrect)
1918
* [GetScreenPoint](#getscreenpoint)
19+
* [GetScreenInfo](#getscreeninfo)
2020
* [OnPopupShow](#onpopupshow)
2121
* [OnPopupSize](#onpopupsize)
2222
* [OnPaint](#onpaint)
@@ -43,7 +43,6 @@ Off-screen rendering examples:
4343

4444
Callbacks available in upstream CEF, but not yet exposed in CEF Python
4545
(see src/include/cef_render_handler.h):
46-
* GetScreenInfo
4746
* OnImeCompositionRangeChanged
4847

4948

@@ -74,30 +73,58 @@ Called to retrieve the view rectangle which is relative to screen
7473
coordinates. Return true if the rectangle was provided.
7574

7675

77-
### GetScreenRect
76+
### GetScreenPoint
7877

7978
| Parameter | Type |
8079
| --- | --- |
8180
| browser | [Browser](Browser.md) |
82-
| rect_out | list[x,y,width,height] |
81+
| view_x | int |
82+
| view_y | int |
83+
| screen_coordinates_out | list[x,y] |
8384
| __Return__ | bool |
8485

85-
Called to retrieve the simulated screen rectangle. Return true
86-
if the rectangle was provided.
86+
Called to retrieve the translation from view coordinates to actual
87+
screen coordinates. Return true if the screen coordinates were provided.
8788

8889

89-
### GetScreenPoint
90+
### GetScreenInfo
9091

9192
| Parameter | Type |
9293
| --- | --- |
9394
| browser | [Browser](Browser.md) |
94-
| view_x | int |
95-
| view_y | int |
96-
| screen_coordinates_out | list[x,y] |
95+
| screen_info_out | dict |
9796
| __Return__ | bool |
9897

99-
Called to retrieve the translation from view coordinates to actual
100-
screen coordinates. Return true if the screen coordinates were provided.
98+
Called to allow the client to fill in the screen info with appropriate
99+
values. Return true if `screen_info_out` was modified, false to let CEF
100+
use defaults.
101+
102+
Fill `screen_info_out` with any of the following keys (all optional):
103+
104+
| Key | Type | Default | Notes |
105+
| --- | --- | --- | --- |
106+
| `device_scale_factor` | float | `1.0` | Ratio between physical and logical pixels. **Must be > 0.** |
107+
| `depth` | int | `24` | Screen depth in bits per pixel. |
108+
| `depth_per_component` | int | `8` | Bits per color component. |
109+
| `is_monochrome` | bool | `False` | True for black-and-white printers. |
110+
| `rect` | list[x,y,width,height] | unset | Display monitor rectangle in DIP. |
111+
| `available_rect` | list[x,y,width,height] | unset | Work-area rectangle in DIP (excludes taskbars). If only `rect` is supplied it is mirrored into `available_rect`. |
112+
113+
If neither `rect` nor `available_rect` is supplied, CEF falls back to
114+
the rectangle returned by `GetViewRect` (popups may be misplaced if
115+
the rectangle ends up empty).
116+
117+
**HiDPI handling:** set `device_scale_factor` to match the host
118+
display (e.g. `2.0` on a Retina/4K screen, `1.5` for 150% fractional
119+
scaling). The factor is applied to the OnPaint buffer: with a view
120+
rect of 800x600 and `device_scale_factor=2.0`, OnPaint receives a
121+
1600x1200 BGRA buffer while `width`/`height` arguments equal the
122+
buffer's pixel dimensions. Always upload the buffer at its actual
123+
pixel size and lay it out at the view's logical size to avoid
124+
blurry output. Call
125+
[Browser.NotifyScreenInfoChanged](Browser.md#notifyscreeninfochanged)
126+
when the device scale factor or display geometry changes (e.g. the
127+
window moved to a different monitor) so CEF re-queries this callback.
101128

102129

103130
### OnPopupShow
@@ -173,6 +200,8 @@ Called when the browser's cursor has changed. If |type| is CT_CUSTOM then
173200
| Parameter | Type |
174201
| --- | --- |
175202
| browser | [Browser](Browser.md) |
203+
| x | float |
204+
| y | float |
176205
| __Return__ | void |
177206

178207
Called when the scroll offset has changed.

api/Request.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ Set the request referrer.
102102
* **REFERRER_POLICY_CLEAR_REFERRER_ON_TRANSITION_CROSS_ORIGIN**
103103
* **REFERRER_POLICY_ORIGIN_CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE**
104104
* **REFERRER_POLICY_NO_REFERRER**
105-
* **REFERRER_POLICY_LAST_VALUE**
105+
* **REFERRER_POLICY_NUM_VALUES**
106106

107107

108108
### GetReferrerURL

docs/Knowledge-Base.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@ Table of contents:
1313
* [How to capture Audio and Video in HTML5?](#how-to-capture-audio-and-video-in-html5)
1414
* [Touch and multi-touch support](#touch-and-multi-touch-support)
1515
* [Black or white browser screen](#black-or-white-browser-screen)
16+
* ["kTransientFailure: Failed to send GpuControl.CreateCommandBuffer" on Linux](#ktransientfailure-failed-to-send-gpucontrolcreatecommandbuffer-on-linux)
1617
* [Python crashes with "Segmentation fault" - how to debug?](#python-crashes-with-segmentation-fault---how-to-debug)
1718
* [Windows XP support](#windows-xp-support)
1819
* [Mac 32-bit support](#mac-32-bit-support)
1920
* [Security](#security)
21+
* [Linux: enabling the Chromium sandbox (advanced)](#linux-enabling-the-chromium-sandbox-advanced)
2022

2123

2224
## Notifications about new releases / commits
@@ -264,6 +266,33 @@ appear even after disabling GPU hardware acceleration. This is normal
264266
because GPU was disabled so WebGL cannot work.
265267

266268

269+
## "kTransientFailure: Failed to send GpuControl.CreateCommandBuffer" on Linux
270+
271+
You may see a log line like this during startup, especially on Linux
272+
VMs and other systems without a working GPU. On VMs the line appears in
273+
nearly every run; on bare metal with a real GPU it is rarer:
274+
275+
```
276+
ERROR:gpu/ipc/client/command_buffer_proxy_impl.cc:285] ContextResult::kTransientFailure: Failed to send GpuControl.CreateCommandBuffer.
277+
```
278+
279+
**This is a Chromium-recoverable transient and can be ignored.** It is
280+
emitted by the renderer process when it tries to create a GPU command
281+
buffer before the GPU process has finished binding its IPC endpoint —
282+
typically a millisecond-scale race during startup, more likely on slow
283+
disks or when Chromium falls back from real-GL to SwiftShader. The
284+
compositor retries automatically; pages still render and
285+
`OnContextInitialized` still fires. The `kTransientFailure` label is
286+
Chromium's own classification — Chromium expects callers to retry, and
287+
they do.
288+
289+
If a clean log is more important than hardware acceleration in your
290+
deployment, you can opt in to disabling the GPU process by passing
291+
`switches={"disable-gpu": ""}` to `cef.Initialize()`. Do not enable
292+
`in-process-gpu` to silence this line — it is not stable across
293+
multiple browser windows.
294+
295+
267296
## Python crashes with "Segmentation fault" - how to debug?
268297

269298
Install gdb:
@@ -347,3 +376,59 @@ A quote by Marshall Greenblatt:
347376
Reference: [Question on browser security](http://magpcss.org/ceforum/viewtopic.php?f=10&t=10222)
348377
on the CEF Forum.
349378

379+
380+
### Linux: enabling the Chromium sandbox (advanced)
381+
382+
cefpython on Linux passes `--no-sandbox` by default
383+
(`_linux_apply_initialize_defaults` in `src/window_utils_linux.pyx`).
384+
385+
Reasons for the default:
386+
1. cefpython does not bundle the SUID-root `chrome-sandbox` helper that
387+
Chromium's namespace sandbox needs to bypass AppArmor's
388+
`apparmor_restrict_unprivileged_userns=1` (the default on Ubuntu
389+
23.10+, Debian 12+, and other modern distros).
390+
2. Without the helper, Chromium aborts at startup with
391+
`FATAL: No usable sandbox!` — every cefpython app would fail to
392+
launch out of the box.
393+
3. The most common cefpython use case is rendering the application's
394+
own trusted HTML/JS as a UI surface, where the sandbox provides
395+
defense-in-depth rather than primary security.
396+
397+
If your app loads untrusted web content and you want the Chromium
398+
sandbox enabled, three steps are required:
399+
400+
**1. Install the SUID-root `chrome-sandbox` helper.**
401+
The binary ships in the CEF binary distribution under
402+
`Release/chrome-sandbox`. Copy it to a stable path and set it up:
403+
404+
```bash
405+
sudo cp /path/to/cef_binary_<ver>_linux64/Release/chrome-sandbox \
406+
/opt/cef/chrome-sandbox
407+
sudo chown root:root /opt/cef/chrome-sandbox
408+
sudo chmod 4755 /opt/cef/chrome-sandbox
409+
```
410+
411+
**2. Tell Chromium where the helper lives.** Set the
412+
`CHROME_DEVEL_SANDBOX` environment variable before `cef.Initialize()`:
413+
414+
```python
415+
import os
416+
os.environ["CHROME_DEVEL_SANDBOX"] = "/opt/cef/chrome-sandbox"
417+
```
418+
419+
**3. Remove cefpython's `--no-sandbox` default.** Because
420+
`_linux_apply_initialize_defaults` sets it via `setdefault`, passing
421+
`switches={"no-sandbox": ""}` to `cef.Initialize()` does not override
422+
it. The default has to be deleted at the source (or pop the key from
423+
your switches dict after init detection). The simplest path is a small
424+
local patch in `src/window_utils_linux.pyx` that drops the
425+
`cmd_switches.setdefault("no-sandbox", "")` line.
426+
427+
After all three steps, Chromium subprocesses should launch under the
428+
namespace sandbox (no `--no-sandbox` in their argv, no FATAL at
429+
startup). Verify via the GPU process command line:
430+
431+
```bash
432+
ps -Af | grep "type=gpu" | grep -v "no-sandbox"
433+
```
434+

0 commit comments

Comments
 (0)