summaryrefslogtreecommitdiff
path: root/qutebrowser/mainwindow/tabbedbrowser.py
diff options
context:
space:
mode:
authorFlorian Bruhin <me@the-compiler.org>2020-01-12 23:42:44 +0100
committerFlorian Bruhin <me@the-compiler.org>2020-01-13 08:09:35 +0100
commitfee1b84ae85eaf465507b016acbdd9039f72ad34 (patch)
treece7d7d3b257383201bda5bccec7e4390a46c28f7 /qutebrowser/mainwindow/tabbedbrowser.py
parent515f90ba8adaaef20859e6957a3a046784225ed2 (diff)
downloadqutebrowser-fee1b84ae85eaf465507b016acbdd9039f72ad34.tar.gz
qutebrowser-fee1b84ae85eaf465507b016acbdd9039f72ad34.zip
Use quitter to shut down tabbed browser
Before this change, we did shut down TabbedBrowser (and thus all the tabs) from the closeEvent of MainWindow. However, this has (at least) two problems: 1) When starting with --nowindow, we never get a window close event when shutting down. Since Qt 5.14 (or probably since the new PyQt exit scheme), this leads to various segfaults around QStyleSheetStyle: [...] QStyleSheetStyle::event(QEvent*) (this=0x5640dfe08940, e=0x7ffe8b8f5eb0) at styles/qstylesheetstyle.cpp:6040 [...] QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x5640dfe08940, event=0x7ffe8b8f5eb0) at ../../include/QtCore/../../src/corelib/kernel/qobject.h:153 QApplicationPrivate::setFocusWidget(QWidget*, Qt::FocusReason) (reason=Qt::OtherFocusReason, focus=<optimized out>) at /usr/include/c++/9.2.0/bits/atomic_base.h:413 QApplicationPrivate::setFocusWidget(QWidget*, Qt::FocusReason) (focus=focus@entry=0x0, reason=reason@entry=Qt::OtherFocusReason) at kernel/qapplication.cpp:1691 QWidget::clearFocus() (this=this@entry=0x5640dff74640) at kernel/qwidget.cpp:6514 QWidget::~QWidget() (this=0x5640dff74640, __in_chrg=<optimized out>) at kernel/qwidget.cpp:1467 sipQWidget::~sipQWidget() (this=0x5640dff74640, __in_chrg=<optimized out>) at sipQtWidgetsQWidget.cpp:355 sipQWidget::~sipQWidget() (this=0x5640dff74640, __in_chrg=<optimized out>) at sipQtWidgetsQWidget.cpp:358 QObjectPrivate::deleteChildren() (this=this@entry=0x5640dfee2ed0) at kernel/qobject.cpp:2123 QWidget::~QWidget() (this=0x5640dff57f10, __in_chrg=<optimized out>) at kernel/qwidget.cpp:1530 QStackedWidget::~QStackedWidget() (this=0x5640dff57f10, __in_chrg=<optimized out>) at widgets/qstackedwidget.cpp:145 QObjectPrivate::deleteChildren() (this=this@entry=0x5640e006f7d0) at kernel/qobject.cpp:2123 QWidget::~QWidget() (this=0x7fb6a0005b50, __in_chrg=<optimized out>) at kernel/qwidget.cpp:1530 sipQTabWidget::~sipQTabWidget() (this=0x7fb6a0005b50, __in_chrg=<optimized out>) at sipQtWidgetsQTabWidget.cpp:326 sipQTabWidget::~sipQTabWidget() (this=0x7fb6a0005b50, __in_chrg=<optimized out>) at sipQtWidgetsQTabWidget.cpp:329 QObjectPrivate::deleteChildren() (this=this@entry=0x5640df3d3030) at kernel/qobject.cpp:2123 QWidget::~QWidget() (this=0x5640df86e200, __in_chrg=<optimized out>) at kernel/qwidget.cpp:1530 sipQWidget::~sipQWidget() (this=0x5640df86e200, __in_chrg=<optimized out>) at sipQtWidgetsQWidget.cpp:355 sipQWidget::~sipQWidget() (this=0x5640df86e200, __in_chrg=<optimized out>) at sipQtWidgetsQWidget.cpp:358 cleanup_qobject(sipSimpleWrapper*, void*) (sw=0x7fb694fb38b0, closure=0x5640df761b80) at ../../qpy/QtCore/qpycore_public_api.cpp:66 sip_api_visit_wrappers (visitor=0x7fb6bdae33ab <cleanup_qobject(sipSimpleWrapper*, void*)>, closure=0x5640df761b80) at siplib.c:13227 pyqt5_cleanup_qobjects() () at ../../qpy/QtCore/qpycore_public_api.cpp:78 cleanup_on_exit(PyObject*, PyObject*) () at ../../qpy/QtCore/qpycore_init.cpp:37 [...] [...] QObject::inherits(char const*) const (classname=0x7ffff30723cb "QMacStyle", this=<optimized out>) at ../../include/QtCore/../../src/corelib/kernel/qobject.h:428 QStyleSheetStyle::getDefaultStyleSheet() const (this=this@entry=0x5555564b8b70) at styles/qstylesheetstyle_default.cpp:157 QStyleSheetStyle::styleRules(QObject const*) const (this=0x5555564b8b70, obj=<optimized out>) at styles/qstylesheetstyle.cpp:1607 QStyleSheetStyle::renderRule(QObject const*, int, unsigned long long) const (this=this@entry=0x5555564b8b70, obj=<optimized out>, obj@entry=0x555556637bb0, element=element@entry=0, state=<optimized out>) at styles/qstylesheetstyle.cpp:1803 QStyleSheetStyle::setGeometry(QWidget*) (this=this@entry=0x5555564b8b70, w=w@entry=0x555556637bb0) at styles/qstylesheetstyle.cpp:2518 QStyleSheetStyle::unpolish(QWidget*) (w=0x555556637bb0, this=0x5555564b8b70) at styles/qstylesheetstyle.cpp:2948 QStyleSheetStyle::unpolish(QWidget*) (this=0x5555564b8b70, w=0x555556637bb0) at styles/qstylesheetstyle.cpp:2936 QWidgetPrivate::setStyle_helper(QStyle*, bool) (this=this@entry=0x5555565ae550, newStyle=newStyle@entry=0x0, propagate=propagate@entry=true) at kernel/qwidget.cpp:2639 QWidgetPrivate::inheritStyle() (this=this@entry=0x5555565ae550) at kernel/qwidget.cpp:2714 QWidget::setParent(QWidget*, QFlags<Qt::WindowType>) (this=this@entry=0x555556637bb0, parent=<optimized out>, parent@entry=0x0, f=...) at kernel/qwidget.cpp:10457 QWidget::setParent(QWidget*) (parent=0x0, this=0x555556637bb0) at ../../include/QtCore/../../src/corelib/global/qflags.h:140 QWidget::setParent(QWidget*) (this=this@entry=0x555556637bb0, parent=parent@entry=0x0) at kernel/qwidget.cpp:10322 QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget::removeParentBeforeParentDelete() (this=0x555556637bb0) at /tmp/makepkg/qt5-webengine-debug/src/qtwebengine-everywhere-src-5.14.0/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp:192 QtPrivate::QSlotObjectBase::call(QObject*, void**) (a=0x7fffffffd570, r=0x555556637bb0, this=0x5555566326a0) at ../../include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:394 doActivate<false>(QObject*, int, void**) (sender=0x555556644a00, signal_index=0, argv=0x7fffffffd570) at kernel/qobject.cpp:3870 QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (sender=sender@entry=0x555556644a00, m=m@entry=0x7ffff62fe320 <QObject::staticMetaObject>, local_signal_index=local_signal_index@entry=0, argv=argv@entry=0x7fffffffd570) at kernel/qobject.cpp:3930 QObject::destroyed(QObject*) (this=this@entry=0x555556644a00, _t1=<optimized out>, _t1@entry=0x555556644a00) at .moc/moc_qobject.cpp:219 QWidget::~QWidget() (this=0x555556644a00, __in_chrg=<optimized out>) at kernel/qwidget.cpp:1505 sipQWebEngineView::~sipQWebEngineView() () at /usr/lib/python3.8/site-packages/PyQt5/QtWebEngineWidgets.abi3.so QObjectPrivate::deleteChildren() (this=this@entry=0x555556671b40) at kernel/qobject.cpp:2123 QWidget::~QWidget() (this=0x55555663cd90, __in_chrg=<optimized out>) at kernel/qwidget.cpp:1530 sipQWidget::~sipQWidget() (this=0x55555663cd90, __in_chrg=<optimized out>) at sipQtWidgetsQWidget.cpp:355 sipQWidget::~sipQWidget() (this=0x55555663cd90, __in_chrg=<optimized out>) at sipQtWidgetsQWidget.cpp:358 QObjectPrivate::deleteChildren() (this=this@entry=0x5555565fbab0) at kernel/qobject.cpp:2123 QWidget::~QWidget() (this=0x5555565bbb80, __in_chrg=<optimized out>) at kernel/qwidget.cpp:1530 QStackedWidget::~QStackedWidget() (this=0x5555565bbb80, __in_chrg=<optimized out>) at widgets/qstackedwidget.cpp:145 QObjectPrivate::deleteChildren() (this=this@entry=0x55555669aa80) at kernel/qobject.cpp:2123 QWidget::~QWidget() (this=0x7fffd8005a90, __in_chrg=<optimized out>) at kernel/qwidget.cpp:1530 sipQTabWidget::~sipQTabWidget() (this=0x7fffd8005a90, __in_chrg=<optimized out>) at sipQtWidgetsQTabWidget.cpp:326 sipQTabWidget::~sipQTabWidget() (this=0x7fffd8005a90, __in_chrg=<optimized out>) at sipQtWidgetsQTabWidget.cpp:329 QObjectPrivate::deleteChildren() (this=this@entry=0x555555b5f8b0) at kernel/qobject.cpp:2123 QWidget::~QWidget() (this=0x5555565fc9f0, __in_chrg=<optimized out>) at kernel/qwidget.cpp:1530 sipQWidget::~sipQWidget() (this=0x5555565fc9f0, __in_chrg=<optimized out>) at sipQtWidgetsQWidget.cpp:355 sipQWidget::~sipQWidget() (this=0x5555565fc9f0, __in_chrg=<optimized out>) at sipQtWidgetsQWidget.cpp:358 cleanup_qobject(sipSimpleWrapper*, void*) (sw=0x7fffc42bb8b0, closure=0x555555e45d20) at ../../qpy/QtCore/qpycore_public_api.cpp:66 sip_api_visit_wrappers (visitor=0x7ffff65e83ab <cleanup_qobject(sipSimpleWrapper*, void*)>, closure=0x555555e45d20) at siplib.c:13227 pyqt5_cleanup_qobjects() () at ../../qpy/QtCore/qpycore_public_api.cpp:78 cleanup_on_exit(PyObject*, PyObject*) () at ../../qpy/QtCore/qpycore_init.cpp:37 [...] 2) We sometimes get a "RuntimeError: wrapped C/C++ object of type QCommonStyle has been deleted" on exit, with this C++ stacktrace: pyqt5_err_print() () at ../../qpy/QtCore/qpycore_public_api.cpp:116 sipVEH_QtCore_PyQt5(_sipSimpleWrapper*, PyGILState_STATE) () at /tmp/makepkg/pyqt5-debug/src/PyQt5-5.14.0/sip/QtCore/qpycore_virtual_error_handler.sip:22 sip_api_call_error_handler (sipGILState=PyGILState_UNLOCKED, py_self=0x7f1c94711820, error_handler=0x7f1cb9044f4c <sipVEH_QtCore_PyQt5(_sipSimpleWrapper*, PyGILState_STATE)>) at siplib.c:12416 sip_api_call_procedure_method (gil_state=PyGILState_UNLOCKED, error_handler=0x7f1cb9044f4c <sipVEH_QtCore_PyQt5(_sipSimpleWrapper*, PyGILState_STATE)>, py_self=0x7f1c94711820, method=0x7f1ca116e220, fmt=<optimized out>) at siplib.c:2303 sipVH_QtWidgets_47(PyGILState_STATE, void (*)(_sipSimpleWrapper*, PyGILState_STATE), _sipSimpleWrapper*, _object*, QWidget*) (sipGILState=PyGILState_UNLOCKED, sipErrorHandler=0x7f1cb9044f4c <sipVEH_QtCore_PyQt5(_sipSimpleWrapper*, PyGILState_STATE)>, sipPySelf=0x7f1c94711820, sipMethod=0x7f1ca116e220, a0=0x55fd39c06df0) at sipQtWidgetscmodule.cpp:6200 sipQCommonStyle::unpolish(QWidget*) (this=0x55fd39b4bbd0, a0=0x55fd39c06df0) at sipQtWidgetsQCommonStyle.cpp:380 QStyleSheetStyle::unpolish(QWidget*) (this=0x55fd39baacc0, w=0x55fd39c06df0) at styles/qstylesheetstyle.cpp:2960 QWidgetPrivate::setStyle_helper(QStyle*, bool) (this=this@entry=0x55fd398b5380, newStyle=newStyle@entry=0x0, propagate=propagate@entry=true) at kernel/qwidget.cpp:2639 QWidgetPrivate::inheritStyle() (this=this@entry=0x55fd398b5380) at kernel/qwidget.cpp:2714 QWidget::setParent(QWidget*, QFlags<Qt::WindowType>) (this=this@entry=0x55fd39c06df0, parent=<optimized out>, parent@entry=0x0, f=...) at kernel/qwidget.cpp:10457 QWidget::setParent(QWidget*) (parent=0x0, this=0x55fd39c06df0) at ../../include/QtCore/../../src/corelib/global/qflags.h:140 QWidget::setParent(QWidget*) (this=this@entry=0x55fd39c06df0, parent=parent@entry=0x0) at kernel/qwidget.cpp:10322 QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget::removeParentBeforeParentDelete() (this=0x55fd39c06df0) at /tmp/makepkg/qt5-webengine-debug/src/qtwebengine-everywhere-src-5.14.0/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp:192 QtPrivate::QSlotObjectBase::call(QObject*, void**) (a=0x7ffff40c2340, r=0x55fd39c06df0, this=0x55fd39c022c0) at ../../include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:394 doActivate<false>(QObject*, int, void**) (sender=0x55fd39c1e700, signal_index=0, argv=0x7ffff40c2340) at kernel/qobject.cpp:3870 QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (sender=sender@entry=0x55fd39c1e700, m=m@entry=0x7f1cb8f22320 <QObject::staticMetaObject>, local_signal_index=local_signal_index@entry=0, argv=argv@entry=0x7ffff40c2340) at kernel/qobject.cpp:3930 QObject::destroyed(QObject*) (this=this@entry=0x55fd39c1e700, _t1=<optimized out>, _t1@entry=0x55fd39c1e700) at .moc/moc_qobject.cpp:219 QWidget::~QWidget() (this=0x55fd39c1e700, __in_chrg=<optimized out>) at kernel/qwidget.cpp:1505 sipQWebEngineView::~sipQWebEngineView() () at /usr/lib/python3.8/site-packages/PyQt5/QtWebEngineWidgets.abi3.so QObjectPrivate::deleteChildren() (this=this@entry=0x55fd39c1e4a0) at kernel/qobject.cpp:2123 QWidget::~QWidget() (this=0x55fd39bc1430, __in_chrg=<optimized out>) at kernel/qwidget.cpp:1530 sipQWidget::~sipQWidget() (this=0x55fd39bc1430, __in_chrg=<optimized out>) at sipQtWidgetsQWidget.cpp:355 sipQWidget::~sipQWidget() (this=0x55fd39bc1430, __in_chrg=<optimized out>) at sipQtWidgetsQWidget.cpp:358 QObjectPrivate::deleteChildren() (this=this@entry=0x55fd39b7aa60) at kernel/qobject.cpp:2123 QWidget::~QWidget() (this=0x55fd39b9e3c0, __in_chrg=<optimized out>) at kernel/qwidget.cpp:1530 QStackedWidget::~QStackedWidget() (this=0x55fd39b9e3c0, __in_chrg=<optimized out>) at widgets/qstackedwidget.cpp:145 QObjectPrivate::deleteChildren() (this=this@entry=0x55fd39c68ba0) at kernel/qobject.cpp:2123 QWidget::~QWidget() (this=0x7f1c98005a70, __in_chrg=<optimized out>) at kernel/qwidget.cpp:1530 sipQTabWidget::~sipQTabWidget() (this=0x7f1c98005a70, __in_chrg=<optimized out>) at sipQtWidgetsQTabWidget.cpp:326 sipQTabWidget::~sipQTabWidget() (this=0x7f1c98005a70, __in_chrg=<optimized out>) at sipQtWidgetsQTabWidget.cpp:329 QObjectPrivate::deleteChildren() (this=this@entry=0x55fd39481760) at kernel/qobject.cpp:2123 QWidget::~QWidget() (this=0x55fd394c90d0, __in_chrg=<optimized out>) at kernel/qwidget.cpp:1530 sipQWidget::~sipQWidget() (this=0x55fd394c90d0, __in_chrg=<optimized out>) at sipQtWidgetsQWidget.cpp:355 sipQWidget::~sipQWidget() (this=0x55fd394c90d0, __in_chrg=<optimized out>) at sipQtWidgetsQWidget.cpp:358 cleanup_qobject(sipSimpleWrapper*, void*) (sw=0x7f1c946dc940, closure=0x55fd3939f9a0) at ../../qpy/QtCore/qpycore_public_api.cpp:66 sip_api_visit_wrappers (visitor=0x7f1cb920c3ab <cleanup_qobject(sipSimpleWrapper*, void*)>, closure=0x55fd3939f9a0) at siplib.c:13227 pyqt5_cleanup_qobjects() () at ../../qpy/QtCore/qpycore_public_api.cpp:78 cleanup_on_exit(PyObject*, PyObject*) () at ../../qpy/QtCore/qpycore_init.cpp:37 [...] Instead, let's use the shutting_down signal we have already to shut down all the TabbedBrowsers (and their children). I'm not exactly sure why, but this results in a clean exit. Fixes #5124 Fixes #5187
Diffstat (limited to 'qutebrowser/mainwindow/tabbedbrowser.py')
-rw-r--r--qutebrowser/mainwindow/tabbedbrowser.py2
1 files changed, 2 insertions, 0 deletions
diff --git a/qutebrowser/mainwindow/tabbedbrowser.py b/qutebrowser/mainwindow/tabbedbrowser.py
index 8c9d1ba9d..f5dc3277b 100644
--- a/qutebrowser/mainwindow/tabbedbrowser.py
+++ b/qutebrowser/mainwindow/tabbedbrowser.py
@@ -35,6 +35,7 @@ from qutebrowser.mainwindow import tabwidget, mainwindow
from qutebrowser.browser import signalfilter, browsertab, history
from qutebrowser.utils import (log, usertypes, utils, qtutils, objreg,
urlutils, message, jinja)
+from qutebrowser.misc import quitter
@attr.s
@@ -235,6 +236,7 @@ class TabbedBrowser(QWidget):
self.is_private = private
self.tab_deque = TabDeque()
config.instance.changed.connect(self._on_config_changed)
+ quitter.instance.shutting_down.connect(self.shutdown)
def _update_stack_size(self):
newsize = config.instance.get('tabs.undo_stack_size')