From d0461eece367d975d29a8da6c988db0dfb792c1d Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 13 Apr 2017 15:48:46 +0200 Subject: [PATCH 1/3] Reorganize earlyinit checks We first do all checks we can without knowing the backend, before getting that. This is because we need to do some more stuff in get_backend now. --- qutebrowser/misc/earlyinit.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/qutebrowser/misc/earlyinit.py b/qutebrowser/misc/earlyinit.py index 1a0c361fc..c6a21a008 100644 --- a/qutebrowser/misc/earlyinit.py +++ b/qutebrowser/misc/earlyinit.py @@ -322,8 +322,7 @@ def check_libraries(backend): if backend == 'webengine': modules['PyQt5.QtWebEngineWidgets'] = _missing_str("QtWebEngine", webengine=True) - else: - assert backend == 'webkit' + elif backend == 'webkit': modules['PyQt5.QtWebKit'] = _missing_str("PyQt5.QtWebKit") modules['PyQt5.QtWebKitWidgets'] = _missing_str( "PyQt5.QtWebKitWidgets") @@ -407,10 +406,15 @@ def earlyinit(args): fix_harfbuzz(args) # Now we can be sure QtCore is available, so we can print dialogs on # errors, so people only using the GUI notice them as well. - backend = get_backend(args) - check_qt_version(backend) + # + # First do some early version checks, without knowing the backend. + check_qt_version(None) remove_inputhook() - check_libraries(backend) + check_libraries(None) check_ssl_support() check_optimize_flag() + # Now find out the backend to use, and do the rest of the checks + backend = get_backend(args) + check_qt_version(backend) + check_libraries(backend) set_backend(backend) From 048aec1aa657f8a403169ac1632d4e8c6ea76d20 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 13 Apr 2017 16:23:50 +0200 Subject: [PATCH 2/3] Revert "Reorganize earlyinit checks" This reverts commit 6f3f9ede01a6b30b105d5110a48cfea592e8db52. --- qutebrowser/misc/earlyinit.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/qutebrowser/misc/earlyinit.py b/qutebrowser/misc/earlyinit.py index c6a21a008..1a0c361fc 100644 --- a/qutebrowser/misc/earlyinit.py +++ b/qutebrowser/misc/earlyinit.py @@ -322,7 +322,8 @@ def check_libraries(backend): if backend == 'webengine': modules['PyQt5.QtWebEngineWidgets'] = _missing_str("QtWebEngine", webengine=True) - elif backend == 'webkit': + else: + assert backend == 'webkit' modules['PyQt5.QtWebKit'] = _missing_str("PyQt5.QtWebKit") modules['PyQt5.QtWebKitWidgets'] = _missing_str( "PyQt5.QtWebKitWidgets") @@ -406,15 +407,10 @@ def earlyinit(args): fix_harfbuzz(args) # Now we can be sure QtCore is available, so we can print dialogs on # errors, so people only using the GUI notice them as well. - # - # First do some early version checks, without knowing the backend. - check_qt_version(None) - remove_inputhook() - check_libraries(None) - check_ssl_support() - check_optimize_flag() - # Now find out the backend to use, and do the rest of the checks backend = get_backend(args) check_qt_version(backend) + remove_inputhook() check_libraries(backend) + check_ssl_support() + check_optimize_flag() set_backend(backend) From 67755e6f6caee61bd4611bb3fb9d01a4f84d9ea2 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 30 May 2017 16:47:39 +0200 Subject: [PATCH 3/3] Add error message for QtWebEngine and Nouveau See #2368 --- qutebrowser/app.py | 2 +- qutebrowser/browser/webengine/webenginetab.py | 10 ++++++- qutebrowser/utils/version.py | 30 +++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/qutebrowser/app.py b/qutebrowser/app.py index 19a278ceb..a3a855f9a 100644 --- a/qutebrowser/app.py +++ b/qutebrowser/app.py @@ -136,7 +136,7 @@ def init(args, crash_handler): try: _init_modules(args, crash_handler) - except (OSError, UnicodeDecodeError) as e: + except (OSError, UnicodeDecodeError, browsertab.WebTabError) as e: error.handle_fatal_exc(e, args, "Error while initializing!", pre_text="Error while initializing") sys.exit(usertypes.Exit.err_init) diff --git a/qutebrowser/browser/webengine/webenginetab.py b/qutebrowser/browser/webengine/webenginetab.py index 97bd9b181..773404be9 100644 --- a/qutebrowser/browser/webengine/webenginetab.py +++ b/qutebrowser/browser/webengine/webenginetab.py @@ -19,6 +19,7 @@ """Wrapper over a QWebEngineView.""" +import os import functools import sip @@ -35,7 +36,7 @@ from qutebrowser.browser.webengine import (webview, webengineelem, tabhistory, webenginesettings) from qutebrowser.misc import miscwidgets from qutebrowser.utils import (usertypes, qtutils, log, javascript, utils, - objreg, jinja, debug) + objreg, jinja, debug, version) _qute_scheme_handler = None @@ -49,6 +50,13 @@ def init(): global _qute_scheme_handler app = QApplication.instance() + software_rendering = os.environ.get('LIBGL_ALWAYS_SOFTWARE') == '1' + if version.opengl_vendor() == 'nouveau' and not software_rendering: + # FIXME:qtwebengine display something more sophisticated here + raise browsertab.WebTabError( + "QtWebEngine is not supported with Nouveau graphics (unless " + "LIBGL_ALWAYS_SOFTWARE is set as environment variable).") + log.init.debug("Initializing qute://* handler...") _qute_scheme_handler = webenginequtescheme.QuteSchemeHandler(parent=app) _qute_scheme_handler.install(webenginesettings.default_profile) diff --git a/qutebrowser/utils/version.py b/qutebrowser/utils/version.py index 4d0fd5146..490f72784 100644 --- a/qutebrowser/utils/version.py +++ b/qutebrowser/utils/version.py @@ -377,3 +377,33 @@ def version(): lines += ['{}: {}'.format(name, path)] return '\n'.join(lines) + + +def opengl_vendor(): # pragma: no cover + """Get the OpenGL vendor used.""" + # We're doing those imports here because this is only available with Qt 5.4 + # or newer. + from PyQt5.QtWidgets import QOpenGLWidget + from PyQt5.QtOpenGL import QGLWidget + from PyQt5.QtGui import QOpenGLContext, QSurfaceFormat, QOpenGLVersionProfile, QOffscreenSurface + assert QApplication.instance() + assert QOpenGLContext.currentContext() is None + + surface = QOffscreenSurface() + surface.create() + + ctx = QOpenGLContext() + ok = ctx.create() + assert ok + + ok = ctx.makeCurrent(surface) + assert ok + + vp = QOpenGLVersionProfile() + vp.setVersion(2, 0) + + vf = ctx.versionFunctions(vp) + vendor = vf.glGetString(vf.GL_VENDOR) + ctx.doneCurrent() + + return vendor