Review Request 125208: Workaround bug 350758
Xuetian Weng
wengxt at gmail.com
Sat Sep 12 21:40:42 UTC 2015
-----------------------------------------------------------
This is an automatically generated e-mail. To reply, visit:
https://git.reviewboard.kde.org/r/125208/
-----------------------------------------------------------
Review request for KDE Frameworks, David Faure and Jean-Baptiste Mardelle.
Repository: frameworkintegration
Description
-------
1. The reason of 350758: https://bugreports.qt.io/browse/QTBUG-48248 , I just tried to reproduce it with pure Qt code. If a dialog called against show, hide, and exec one immediately after another, the dialog may not show up.
2. Why hide() is needed in the first place?
If one runs dialog.show() and dialog.exec(), it usually works. So there is something happened in between KDEPlatformFileDialogHelper::show() and KDEPlatformFileDialogHelper::exec().
The real reason is the platform dialog helper doesn't expect that user may use "Qt" dialog to implement it.
https://github.com/qtproject/qtbase/blob/5bfac9d653357c906946563b9494d7ae69cdad92/src/widgets/dialogs/qfiledialog.cpp#L845
here it sets Qt::WA_DontShowOnScreen on the actual dialog.
https://github.com/qtproject/qtbase/blob/5bfac9d653357c906946563b9494d7ae69cdad92/src/widgets/dialogs/qfiledialog.cpp#L868
and call QDialog::setVisible() here
https://github.com/qtproject/qtbase/blob/17d6b2d1f02e5f679008d97036befd713025a0f2/src/widgets/dialogs/qdialog.cpp#L713
Thus it will by pass the first check, and QDialog will actually show an invisible qdialog with it. I assume https://git.reviewboard.kde.org/r/123335/ tries to solve this issue by "steal" the focus from that invisible dialog by hide it first.
It makes some sense for Qt with "real" native dialog, because this invisble dialog helps Qt to aware that there's a modal dialog, but doesn't work for our case.
3. To avoid calling hide() in exec()
I'd rather to see that KDEPlatformFileDialogHelper::show() is not called in QDialog::exec(), but that's not gonna happen. So here I used a trick with QTimer to delegate the show to next event when calling to KDEPlatformFileDialogHelper::show().
I uses QTimer instead of QMetaObject::invoke here, because we can discard the "m_dialog->show()" if hide() or exec() is called immediately. (Actually we don't need to discard the one in exec(), but we can save a call to m_dialog->show() if we discard it.)
Before this change, the calling sequence on m_dialog is
m_dialog->show();
The dummy dialog setVisible(true);
m_dialog->hide();
m_dialog->exec();
After this change, it becomes
The dummy dialog setVisible(true);
m_dialog->exec();
4. Required changes to autotest
QTest::qWaitForWindowExposed(fw->window()) is added to some necessary places.
Diffs
-----
autotests/kfiledialog_unittest.cpp 0d4c816
autotests/kfiledialogqml_unittest.cpp f805ef2
src/platformtheme/kdeplatformfiledialogbase.cpp 8e696bd
src/platformtheme/kdeplatformfiledialogbase_p.h 5936dfb
src/platformtheme/kdeplatformfiledialoghelper.h dfbbed1
src/platformtheme/kdeplatformfiledialoghelper.cpp 94f2059
Diff: https://git.reviewboard.kde.org/r/125208/diff/
Testing
-------
not able to reproduce the bug.
Thanks,
Xuetian Weng
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.kde.org/pipermail/kde-frameworks-devel/attachments/20150912/b49389a7/attachment-0001.html>
More information about the Kde-frameworks-devel
mailing list