diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc index 3ef3f8439..1c67fa6da 100644 --- a/doc/help/settings.asciidoc +++ b/doc/help/settings.asciidoc @@ -211,6 +211,7 @@ |<>|Show a filebrowser in upload/download prompts. |<>|The rounding radius for the edges of prompts. |<>|Additional arguments to pass to Qt, without leading `--`. +|<>|Force a Qt platform to use. |<>|Force software rendering for QtWebEngine. |<>|Show a scrollbar. |<>|Enable smooth scrolling for web pages. @@ -2443,6 +2444,15 @@ Type: <> Default: empty +[[qt.force_platform]] +=== qt.force_platform +Force a Qt platform to use. +This sets the `QT_QPA_PLATFORM` environment variable and is useful to force using the XCB plugin when running QtWebEngine on Wayland. + +Type: <> + +Default: empty + [[qt.force_software_rendering]] === qt.force_software_rendering Force software rendering for QtWebEngine. diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml index 881e5595e..54fefe29e 100644 --- a/qutebrowser/config/configdata.yml +++ b/qutebrowser/config/configdata.yml @@ -145,6 +145,17 @@ qt.force_software_rendering: This is needed for QtWebEngine to work with Nouveau drivers. This setting requires a restart. +qt.force_platform: + type: + name: String + none_ok: true + default: null + desc: >- + Force a Qt platform to use. + + This sets the `QT_QPA_PLATFORM` environment variable and is useful to force + using the XCB plugin when running QtWebEngine on Wayland. + ## auto_save diff --git a/qutebrowser/config/configinit.py b/qutebrowser/config/configinit.py index bd2d46a12..6c049439e 100644 --- a/qutebrowser/config/configinit.py +++ b/qutebrowser/config/configinit.py @@ -85,6 +85,9 @@ def _init_envvars(): config.val.qt.force_software_rendering): os.environ['QT_XCB_FORCE_SOFTWARE_OPENGL'] = '1' + if config.val.qt.force_platform is not None: + os.environ['QT_QPA_PLATFORM'] = config.val.qt.force_platform + if config.val.window.hide_wayland_decoration: os.environ['QT_WAYLAND_DISABLE_WINDOWDECORATION'] = '1' else: diff --git a/qutebrowser/misc/backendproblem.py b/qutebrowser/misc/backendproblem.py index f6438ce25..5b3f3f7d7 100644 --- a/qutebrowser/misc/backendproblem.py +++ b/qutebrowser/misc/backendproblem.py @@ -197,14 +197,31 @@ def _handle_wayland(): if platform not in ['wayland', 'wayland-egl']: return - _show_dialog( - backend=usertypes.Backend.QtWebEngine, - because="you're using Wayland", - text="

There are two ways to fix this:

" - "

Set up XWayland

" - "

This allows you to use the newer QtWebEngine backend (based " - "on Chromium). " - ) + if 'DISPLAY' in os.environ: + # XWayland is available, but QT_QPA_PLATFORM=wayland is set + button = _Button("Force XWayland", 'qt.force_platform', 'xcb') + _show_dialog( + backend=usertypes.Backend.QtWebEngine, + because="you're using Wayland", + text="

There are two ways to fix this:

" + "

Force Qt to use XWayland

" + "

This allows you to use the newer QtWebEngine backend " + "(based on Chromium). " + "This sets the qt.force_platform = 'xcb' option " + "(if you have a config.py file, you'll need to set " + "this manually).

", + buttons=[button], + ) + else: + # XWayland is unavailable + _show_dialog( + backend=usertypes.Backend.QtWebEngine, + because="you're using Wayland without XWayland", + text="

There are two ways to fix this:

" + "

Set up XWayland

" + "

This allows you to use the newer QtWebEngine backend " + "(based on Chromium). " + ) # Should never be reached assert False diff --git a/tests/unit/config/test_configinit.py b/tests/unit/config/test_configinit.py index cf77d415e..7836c063a 100644 --- a/tests/unit/config/test_configinit.py +++ b/tests/unit/config/test_configinit.py @@ -213,6 +213,15 @@ class TestEarlyInit: assert os.environ[envvar] == '1' + def test_force_platform(self, monkeypatch, config_stub): + envvar = 'QT_QPA_PLATFORM' + monkeypatch.delenv(envvar, raising=False) + + config_stub.val.qt.force_platform = 'toaster' + + configinit._init_envvars() + assert os.environ[envvar] == 'toaster' + @pytest.mark.parametrize('old', ['1', '0', None]) @pytest.mark.parametrize('configval', [True, False]) def test_hide_wayland_decoration(self, monkeypatch, config_stub,