Make QWidgetPrivate::setVisible virtual

Initially the function was used as a helper function for QWidget,
implemented in da55a1b04121abd44d9c72e0c7cba7d72f16d4f2. But with
e0bb9e81ab1a9d71f2893844ea82430467422e21 we started overriding it
e.g. QDialog. This "worked" because QDialog itself would call the
private helper, but left a footgun when called via a plain QWidget
pointer, as we did in 5ba0982b2879a1a4c13bf97467b8e5ad296e57a2.

That specific instance of the problem was solved by the change in
fc4c6fb5f6bd6bd63b13f1f8b5b7a7289a5fd230, but the trap still exists.

To ensure we can use the function in a polymorphic context in the
future we make it virtual.

Task-number: QTBUG-127806
Pick-to: 6.8
Change-Id: Ic0810c5439b1e696cfbf199e701f41217acc5742
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Tor Arne Vestbø 2024-08-12 12:38:11 +02:00
parent 6548156e75
commit 1a0f056f31
5 changed files with 31 additions and 4 deletions

View File

@ -772,7 +772,7 @@ void QDialogPrivate::setVisible(bool visible)
}
if (visible) {
q->QWidget::setVisible(visible);
QWidgetPrivate::setVisible(visible);
// Window activation might be prevented. We can't test isActiveWindow here,
// as the window will be activated asynchronously by the window manager.
@ -831,7 +831,7 @@ void QDialogPrivate::setVisible(bool visible)
#endif
// Reimplemented to exit a modal event loop when the dialog is hidden.
q->QWidget::setVisible(visible);
QWidgetPrivate::setVisible(visible);
if (eventLoop)
eventLoop->exit();
}

View File

@ -51,7 +51,7 @@ public:
{}
~QDialogPrivate();
virtual void setVisible(bool visible);
void setVisible(bool visible) override;
QWindow *transientParentWindow() const;
bool setNativeDialogVisible(bool visible);

View File

@ -387,7 +387,7 @@ public:
void hide_helper();
bool isExplicitlyHidden() const;
void _q_showIfNotHidden();
void setVisible(bool);
virtual void setVisible(bool);
void setEnabled_helper(bool);
static void adjustFlags(Qt::WindowFlags &flags, QWidget *w = nullptr);

View File

@ -236,6 +236,7 @@ public:
bool restoreFocus();
void storeFocusWidget();
void setWindowFlags(Qt::WindowFlags windowFlags) override;
using QWidgetPrivate::setVisible;
void setVisible(WindowStateAction, bool visible = true);
#ifndef QT_NO_ACTION
void setEnabled(WindowStateAction, bool enable = true);

View File

@ -468,6 +468,7 @@ private slots:
#endif
void setVisibleDuringDestruction();
void setVisibleOverrideIsCalled();
void explicitShowHide();
@ -13616,6 +13617,31 @@ void tst_QWidget::setVisibleDuringDestruction()
QTRY_COMPARE(signalSpy.count(), 4);
}
void tst_QWidget::setVisibleOverrideIsCalled()
{
struct WidgetPrivate : public QWidgetPrivate
{
void setVisible(bool visible) override
{
wasCalled = true;
}
bool wasCalled = false;
};
class Widget : public QWidget {
public:
explicit Widget(QWidget *p = nullptr)
: QWidget(*new WidgetPrivate, p, {})
{
}
};
Widget widget;
widget.setVisible(true);
auto *widgetPrivate = static_cast<WidgetPrivate*>(QWidgetPrivate::get(&widget));
QCOMPARE(widgetPrivate->wasCalled, true);
}
void tst_QWidget::explicitShowHide()
{
{