diff options
author | Florian Bruhin <me@the-compiler.org> | 2020-01-12 23:42:44 +0100 |
---|---|---|
committer | Florian Bruhin <me@the-compiler.org> | 2020-01-13 08:09:35 +0100 |
commit | fee1b84ae85eaf465507b016acbdd9039f72ad34 (patch) | |
tree | ce7d7d3b257383201bda5bccec7e4390a46c28f7 /qutebrowser/mainwindow/tabbedbrowser.py | |
parent | 515f90ba8adaaef20859e6957a3a046784225ed2 (diff) | |
download | qutebrowser-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.py | 2 |
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') |