Only delete last commands in the undostack if the new command in not obsolete#32
Closed
Only delete last commands in the undostack if the new command in not obsolete#32
Conversation
Author
|
Will need to do it through gerrit someday! |
qtprojectorg
pushed a commit
that referenced
this pull request
Apr 4, 2025
…howAndHide()
The event filter was still active when the QDialogButtonBox in its
destruction process had already been demoted to QWidget. The
ignoreShowAndHide guard came too late, because by the time we check
it, in Private::handleButtonShowAndHide(), we had already cast q_ptr
to QDialogButtonBox.
Says UBSan:
qdialogbuttonbox_p.h:26:5: runtime error: downcast of address 0x7fffefab47e0 which does not point to an object of type 'QDialogButtonBox'
0x7fffefab47e0: note: object is of type 'QWidget'
00 00 00 00 28 c1 5b 6e 6d 7f 00 00 80 22 10 00 90 61 00 00 d8 c2 5b 6e 6d 7f 00 00 00 00 00 00
^~~~~~~~~~~~~~~~~~~~~~~
vptr for 'QWidget'
#0 0x7f6d6b51141d in QDialogButtonBoxPrivate::q_func() qdialogbuttonbox_p.h:26
#1 0x7f6d6b51141d in QDialogButtonBoxPrivate::handleButtonShowAndHide(QAbstractButton*, QEvent*) qdialogbuttonbox.cpp:913
#2 0x7f6d6b51436c in eventFilter qdialogbuttonbox.cpp:127
#3 0x7f6d40c1a8f1 in QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) qcoreapplication.cpp:1248
#4 0x7f6d690b23d5 in QApplicationPrivate::notify_helper(QObject*, QEvent*) qapplication.cpp:3303
#5 0x7f6d69132a3a in QApplication::notify(QObject*, QEvent*) qapplication.cpp:3259
#6 0x7f6d40c1da6a in QCoreApplication::notifyInternal2(QObject*, QEvent*) qcoreapplication.cpp:1111
#7 0x7f6d40c20473 in QCoreApplication::sendEvent(QObject*, QEvent*) qcoreapplication.cpp:1551
#8 0x7f6d690fe76c in QApplicationPrivate::setActiveWindow(QWidget*) qapplication.cpp:1857
#9 0x7f6d695ac796 in QWidgetPrivate::deactivateWidgetCleanup() qwidget.cpp:2326
#10 0x7f6d6976f8ce in QWidgetPrivate::hide_sys() qwidget.cpp:8256
#11 0x7f6d69814579 in QWidgetPrivate::hide_helper() qwidget.cpp:8199
#12 0x7f6d69887c1f in QWidgetPrivate::setVisible(bool) qwidget.cpp:8406
#13 0x7f6d69775d23 in QWidget::setVisible(bool) qwidget.cpp:8314
#14 0x7f6d695fb018 in QWidget::hide() qwidget.cpp:8179
#15 0x7f6d6981a183 in QWidgetPrivate::handleClose(QWidgetPrivate::CloseMode) qwidget.cpp:8580
#16 0x7f6d699e6fc6 in QWidgetWindow::closeEvent(QCloseEvent*) qwidgetwindow.cpp:871
#17 0x7f6d52ef9f5d in QWindow::event(QEvent*) qwindow.cpp:2721
#18 0x7f6d69a575f8 in QWidgetWindow::event(QEvent*) qwidgetwindow.cpp:398
#19 0x7f6d690b2491 in QApplicationPrivate::notify_helper(QObject*, QEvent*) qapplication.cpp:3309
#20 0x7f6d69132a3a in QApplication::notify(QObject*, QEvent*) qapplication.cpp:3259
#21 0x7f6d40c1da6a in QCoreApplication::notifyInternal2(QObject*, QEvent*) qcoreapplication.cpp:1111
#22 0x7f6d40c205b3 in QCoreApplication::sendSpontaneousEvent(QObject*, QEvent*) qcoreapplication.cpp:1565
#23 0x7f6d5287415b in QGuiApplicationPrivate::processCloseEvent(QWindowSystemInterfacePrivate::CloseEvent*) qguiapplication.cpp:2911
#24 0x7f6d528b543f in QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) qguiapplication.cpp:2259
#25 0x7f6d52fb5b02 in QWindowSystemEventHandler::sendEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) qwindowsysteminterface.cpp:190
#26 0x7f6d52fb5b02 in bool QWindowSystemHelper<QWindowSystemInterface::SynchronousDelivery>::handleEvent<QWindowSystemInterfacePrivate::CloseEvent, QWindow*>(QWindow*) qwindowsysteminterface.cpp:102
#27 0x7f6d52fb5b02 in handleWindowSystemEvent<QWindowSystemInterfacePrivate::CloseEvent, QWindowSystemInterface::SynchronousDelivery, QWindow*> qwindowsysteminterface.cpp:138
#28 0x7f6d52fb5b02 in bool QWindowSystemInterface::handleCloseEvent<QWindowSystemInterface::SynchronousDelivery>(QWindow*) qwindowsysteminterface.cpp:351
#29 0x7f6d52cb6f1e in QPlatformWindow::close() qplatformwindow.cpp:348
#30 0x7f6d52e7e158 in QWindow::close() qwindow.cpp:2449
#31 0x7f6d6981b4d2 in QWidgetPrivate::close() qwidget.cpp:8632
#32 0x7f6d698205c6 in QWidget::~QWidget() qwidget.cpp:1508
#33 0x7f6d6b4f6bf0 in QDialogButtonBox::~QDialogButtonBox() qdialogbuttonbox.cpp:496
To fix, don't delay the Q_Q to until after the ignoreShowAndHide
check, since that woould be brittle. Instead, do as we for signal/slot
connections, which we disconnect explicitly in ~QDialogButtonBox(),
and delete the EventFilter explicitly there, too. This way, it's more
natural, and also prevents all those useless event filter invocations
from having to be processed later on.
Amends aff0915. The original code,
using QDialogButtonBox::eventFilter(), was not affected, since by the
time QDialogButtonBox was demoted to QWidget, QWidget::eventFilter(),
not QDialogButtonBox::eventFilter() would been invoked. Which just
goes to show that one needs to be very careful with delegating too
much responsibilites to the Private class, as it lives, fully derived,
until ~QWidget() executes.
Pick-to: 6.9 6.8 6.5
Change-Id: I04f36fd6d7d160932bfe1494fdff464786b85047
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
qtprojectorg
pushed a commit
that referenced
this pull request
Apr 12, 2025
…howAndHide()
The event filter was still active when the QDialogButtonBox in its
destruction process had already been demoted to QWidget. The
ignoreShowAndHide guard came too late, because by the time we check
it, in Private::handleButtonShowAndHide(), we had already cast q_ptr
to QDialogButtonBox.
Says UBSan:
qdialogbuttonbox_p.h:26:5: runtime error: downcast of address 0x7fffefab47e0 which does not point to an object of type 'QDialogButtonBox'
0x7fffefab47e0: note: object is of type 'QWidget'
00 00 00 00 28 c1 5b 6e 6d 7f 00 00 80 22 10 00 90 61 00 00 d8 c2 5b 6e 6d 7f 00 00 00 00 00 00
^~~~~~~~~~~~~~~~~~~~~~~
vptr for 'QWidget'
#0 0x7f6d6b51141d in QDialogButtonBoxPrivate::q_func() qdialogbuttonbox_p.h:26
#1 0x7f6d6b51141d in QDialogButtonBoxPrivate::handleButtonShowAndHide(QAbstractButton*, QEvent*) qdialogbuttonbox.cpp:913
#2 0x7f6d6b51436c in eventFilter qdialogbuttonbox.cpp:127
#3 0x7f6d40c1a8f1 in QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) qcoreapplication.cpp:1248
#4 0x7f6d690b23d5 in QApplicationPrivate::notify_helper(QObject*, QEvent*) qapplication.cpp:3303
#5 0x7f6d69132a3a in QApplication::notify(QObject*, QEvent*) qapplication.cpp:3259
#6 0x7f6d40c1da6a in QCoreApplication::notifyInternal2(QObject*, QEvent*) qcoreapplication.cpp:1111
#7 0x7f6d40c20473 in QCoreApplication::sendEvent(QObject*, QEvent*) qcoreapplication.cpp:1551
#8 0x7f6d690fe76c in QApplicationPrivate::setActiveWindow(QWidget*) qapplication.cpp:1857
#9 0x7f6d695ac796 in QWidgetPrivate::deactivateWidgetCleanup() qwidget.cpp:2326
#10 0x7f6d6976f8ce in QWidgetPrivate::hide_sys() qwidget.cpp:8256
#11 0x7f6d69814579 in QWidgetPrivate::hide_helper() qwidget.cpp:8199
#12 0x7f6d69887c1f in QWidgetPrivate::setVisible(bool) qwidget.cpp:8406
#13 0x7f6d69775d23 in QWidget::setVisible(bool) qwidget.cpp:8314
#14 0x7f6d695fb018 in QWidget::hide() qwidget.cpp:8179
#15 0x7f6d6981a183 in QWidgetPrivate::handleClose(QWidgetPrivate::CloseMode) qwidget.cpp:8580
#16 0x7f6d699e6fc6 in QWidgetWindow::closeEvent(QCloseEvent*) qwidgetwindow.cpp:871
#17 0x7f6d52ef9f5d in QWindow::event(QEvent*) qwindow.cpp:2721
#18 0x7f6d69a575f8 in QWidgetWindow::event(QEvent*) qwidgetwindow.cpp:398
#19 0x7f6d690b2491 in QApplicationPrivate::notify_helper(QObject*, QEvent*) qapplication.cpp:3309
#20 0x7f6d69132a3a in QApplication::notify(QObject*, QEvent*) qapplication.cpp:3259
#21 0x7f6d40c1da6a in QCoreApplication::notifyInternal2(QObject*, QEvent*) qcoreapplication.cpp:1111
#22 0x7f6d40c205b3 in QCoreApplication::sendSpontaneousEvent(QObject*, QEvent*) qcoreapplication.cpp:1565
#23 0x7f6d5287415b in QGuiApplicationPrivate::processCloseEvent(QWindowSystemInterfacePrivate::CloseEvent*) qguiapplication.cpp:2911
#24 0x7f6d528b543f in QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) qguiapplication.cpp:2259
#25 0x7f6d52fb5b02 in QWindowSystemEventHandler::sendEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) qwindowsysteminterface.cpp:190
#26 0x7f6d52fb5b02 in bool QWindowSystemHelper<QWindowSystemInterface::SynchronousDelivery>::handleEvent<QWindowSystemInterfacePrivate::CloseEvent, QWindow*>(QWindow*) qwindowsysteminterface.cpp:102
#27 0x7f6d52fb5b02 in handleWindowSystemEvent<QWindowSystemInterfacePrivate::CloseEvent, QWindowSystemInterface::SynchronousDelivery, QWindow*> qwindowsysteminterface.cpp:138
#28 0x7f6d52fb5b02 in bool QWindowSystemInterface::handleCloseEvent<QWindowSystemInterface::SynchronousDelivery>(QWindow*) qwindowsysteminterface.cpp:351
#29 0x7f6d52cb6f1e in QPlatformWindow::close() qplatformwindow.cpp:348
#30 0x7f6d52e7e158 in QWindow::close() qwindow.cpp:2449
#31 0x7f6d6981b4d2 in QWidgetPrivate::close() qwidget.cpp:8632
#32 0x7f6d698205c6 in QWidget::~QWidget() qwidget.cpp:1508
#33 0x7f6d6b4f6bf0 in QDialogButtonBox::~QDialogButtonBox() qdialogbuttonbox.cpp:496
To fix, don't delay the Q_Q to until after the ignoreShowAndHide
check, since that woould be brittle. Instead, do as we for signal/slot
connections, which we disconnect explicitly in ~QDialogButtonBox(),
and delete the EventFilter explicitly there, too. This way, it's more
natural, and also prevents all those useless event filter invocations
from having to be processed later on.
Amends aff0915. The original code,
using QDialogButtonBox::eventFilter(), was not affected, since by the
time QDialogButtonBox was demoted to QWidget, QWidget::eventFilter(),
not QDialogButtonBox::eventFilter() would been invoked. Which just
goes to show that one needs to be very careful with delegating too
much responsibilites to the Private class, as it lives, fully derived,
until ~QWidget() executes.
Pick-to: 6.8 6.5
Change-Id: I04f36fd6d7d160932bfe1494fdff464786b85047
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
(cherry picked from commit dceff0a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
qtprojectorg
pushed a commit
that referenced
this pull request
Apr 12, 2025
…howAndHide()
The event filter was still active when the QDialogButtonBox in its
destruction process had already been demoted to QWidget. The
ignoreShowAndHide guard came too late, because by the time we check
it, in Private::handleButtonShowAndHide(), we had already cast q_ptr
to QDialogButtonBox.
Says UBSan:
qdialogbuttonbox_p.h:26:5: runtime error: downcast of address 0x7fffefab47e0 which does not point to an object of type 'QDialogButtonBox'
0x7fffefab47e0: note: object is of type 'QWidget'
00 00 00 00 28 c1 5b 6e 6d 7f 00 00 80 22 10 00 90 61 00 00 d8 c2 5b 6e 6d 7f 00 00 00 00 00 00
^~~~~~~~~~~~~~~~~~~~~~~
vptr for 'QWidget'
#0 0x7f6d6b51141d in QDialogButtonBoxPrivate::q_func() qdialogbuttonbox_p.h:26
#1 0x7f6d6b51141d in QDialogButtonBoxPrivate::handleButtonShowAndHide(QAbstractButton*, QEvent*) qdialogbuttonbox.cpp:913
#2 0x7f6d6b51436c in eventFilter qdialogbuttonbox.cpp:127
#3 0x7f6d40c1a8f1 in QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) qcoreapplication.cpp:1248
#4 0x7f6d690b23d5 in QApplicationPrivate::notify_helper(QObject*, QEvent*) qapplication.cpp:3303
#5 0x7f6d69132a3a in QApplication::notify(QObject*, QEvent*) qapplication.cpp:3259
#6 0x7f6d40c1da6a in QCoreApplication::notifyInternal2(QObject*, QEvent*) qcoreapplication.cpp:1111
#7 0x7f6d40c20473 in QCoreApplication::sendEvent(QObject*, QEvent*) qcoreapplication.cpp:1551
#8 0x7f6d690fe76c in QApplicationPrivate::setActiveWindow(QWidget*) qapplication.cpp:1857
#9 0x7f6d695ac796 in QWidgetPrivate::deactivateWidgetCleanup() qwidget.cpp:2326
#10 0x7f6d6976f8ce in QWidgetPrivate::hide_sys() qwidget.cpp:8256
#11 0x7f6d69814579 in QWidgetPrivate::hide_helper() qwidget.cpp:8199
#12 0x7f6d69887c1f in QWidgetPrivate::setVisible(bool) qwidget.cpp:8406
#13 0x7f6d69775d23 in QWidget::setVisible(bool) qwidget.cpp:8314
#14 0x7f6d695fb018 in QWidget::hide() qwidget.cpp:8179
#15 0x7f6d6981a183 in QWidgetPrivate::handleClose(QWidgetPrivate::CloseMode) qwidget.cpp:8580
#16 0x7f6d699e6fc6 in QWidgetWindow::closeEvent(QCloseEvent*) qwidgetwindow.cpp:871
#17 0x7f6d52ef9f5d in QWindow::event(QEvent*) qwindow.cpp:2721
#18 0x7f6d69a575f8 in QWidgetWindow::event(QEvent*) qwidgetwindow.cpp:398
#19 0x7f6d690b2491 in QApplicationPrivate::notify_helper(QObject*, QEvent*) qapplication.cpp:3309
#20 0x7f6d69132a3a in QApplication::notify(QObject*, QEvent*) qapplication.cpp:3259
#21 0x7f6d40c1da6a in QCoreApplication::notifyInternal2(QObject*, QEvent*) qcoreapplication.cpp:1111
#22 0x7f6d40c205b3 in QCoreApplication::sendSpontaneousEvent(QObject*, QEvent*) qcoreapplication.cpp:1565
#23 0x7f6d5287415b in QGuiApplicationPrivate::processCloseEvent(QWindowSystemInterfacePrivate::CloseEvent*) qguiapplication.cpp:2911
#24 0x7f6d528b543f in QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) qguiapplication.cpp:2259
#25 0x7f6d52fb5b02 in QWindowSystemEventHandler::sendEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) qwindowsysteminterface.cpp:190
#26 0x7f6d52fb5b02 in bool QWindowSystemHelper<QWindowSystemInterface::SynchronousDelivery>::handleEvent<QWindowSystemInterfacePrivate::CloseEvent, QWindow*>(QWindow*) qwindowsysteminterface.cpp:102
#27 0x7f6d52fb5b02 in handleWindowSystemEvent<QWindowSystemInterfacePrivate::CloseEvent, QWindowSystemInterface::SynchronousDelivery, QWindow*> qwindowsysteminterface.cpp:138
#28 0x7f6d52fb5b02 in bool QWindowSystemInterface::handleCloseEvent<QWindowSystemInterface::SynchronousDelivery>(QWindow*) qwindowsysteminterface.cpp:351
#29 0x7f6d52cb6f1e in QPlatformWindow::close() qplatformwindow.cpp:348
#30 0x7f6d52e7e158 in QWindow::close() qwindow.cpp:2449
#31 0x7f6d6981b4d2 in QWidgetPrivate::close() qwidget.cpp:8632
#32 0x7f6d698205c6 in QWidget::~QWidget() qwidget.cpp:1508
#33 0x7f6d6b4f6bf0 in QDialogButtonBox::~QDialogButtonBox() qdialogbuttonbox.cpp:496
To fix, don't delay the Q_Q to until after the ignoreShowAndHide
check, since that woould be brittle. Instead, do as we for signal/slot
connections, which we disconnect explicitly in ~QDialogButtonBox(),
and delete the EventFilter explicitly there, too. This way, it's more
natural, and also prevents all those useless event filter invocations
from having to be processed later on.
Amends aff0915. The original code,
using QDialogButtonBox::eventFilter(), was not affected, since by the
time QDialogButtonBox was demoted to QWidget, QWidget::eventFilter(),
not QDialogButtonBox::eventFilter() would been invoked. Which just
goes to show that one needs to be very careful with delegating too
much responsibilites to the Private class, as it lives, fully derived,
until ~QWidget() executes.
Pick-to: 6.5
Change-Id: I04f36fd6d7d160932bfe1494fdff464786b85047
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
(cherry picked from commit dceff0a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 6753ab4)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.