Skip to content

Commit 9159645

Browse files
linesightclaude
andcommitted
fix: force xcb on Linux and warn on handle=0 in Wayland sessions
qt.py: override QT_QPA_PLATFORM=xcb unconditionally on Linux for all Qt bindings (PyQt5/PyQt6/PySide6). Wayland desktops such as KDE Plasma on Kubuntu often pre-set QT_QPA_PLATFORM=wayland in the session environment; setdefault was insufficient to override it, causing CEF to open a detached top-level window instead of embedding into the Qt widget. window_info.pyx: add a warnings.warn() in SetAsChild when parentWindowHandle is 0 and WAYLAND_DISPLAY is set. This catches the same misconfiguration for any toolkit (Qt, GTK, SDL2) and points the developer to the correct per-toolkit env var fix. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 1d8b6b1 commit 9159645

2 files changed

Lines changed: 27 additions & 6 deletions

File tree

examples/qt.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,14 @@
6262
LINUX = (platform.system() == "Linux")
6363
MAC = (platform.system() == "Darwin")
6464

65-
# Qt6 (PyQt6/PySide6) defaults to the Wayland backend when the session is
66-
# Wayland. CEF always uses X11 (ozone-platform=x11), so embedding requires
67-
# both sides to use X11. Force Qt6 onto the xcb (X11) platform.
68-
# This must be set before creating QApplication.
69-
if LINUX and (PYQT6 or PYSIDE6):
70-
os.environ.setdefault("QT_QPA_PLATFORM", "xcb")
65+
# CEF only supports X11 on Linux. Force Qt onto the xcb (X11/XWayland)
66+
# backend for all bindings so that winId() returns a real X11 window ID
67+
# that CEF can embed into. Wayland desktops (e.g. KDE Plasma on Kubuntu)
68+
# often pre-set QT_QPA_PLATFORM=wayland in the session environment, so a
69+
# hard override is needed — setdefault would not override a pre-set value.
70+
# Must be set before creating QApplication.
71+
if LINUX:
72+
os.environ["QT_QPA_PLATFORM"] = "xcb"
7173

7274
# On Linux, query the X11 pointer button mask directly to detect outside-clicks
7375
# on the context menu. XQueryPointer returns real button state even while CEF

src/window_info.pyx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,25 @@ cdef class WindowInfo:
113113
% parentWindowHandle)
114114
self.windowType = "child"
115115
IF UNAME_SYSNAME == "Linux":
116+
if parentWindowHandle == 0:
117+
import os as _os
118+
import warnings
119+
if "WAYLAND_DISPLAY" in _os.environ:
120+
warnings.warn(
121+
"WindowInfo.SetAsChild: parentWindowHandle is 0 on Linux "
122+
"in a Wayland session. The GUI toolkit is likely using the "
123+
"native Wayland backend where winId()/GetHandle() returns 0 "
124+
"instead of an X11 window ID — CEF will open a detached "
125+
"window instead of embedding. Force X11 (XWayland) before "
126+
"initialising the toolkit:\n"
127+
" Qt (PyQt5/PyQt6/PySide2/PySide6): "
128+
"os.environ[\"QT_QPA_PLATFORM\"] = \"xcb\"\n"
129+
" GTK (wxPython/PyGTK): "
130+
"os.environ[\"GDK_BACKEND\"] = \"x11\"\n"
131+
" SDL2 (pysdl2): "
132+
"os.environ[\"SDL_VIDEODRIVER\"] = \"x11\"",
133+
stacklevel=2,
134+
)
116135
if parentWindowHandle != 0:
117136
# Xwayland cross-client restriction: Chrome's internal XCB
118137
# connection cannot create a child window under a window owned

0 commit comments

Comments
 (0)