diff --git a/0001-Fix-random-file-dialog-not-showing-up-problem.patch b/0001-Fix-random-file-dialog-not-showing-up-problem.patch new file mode 100644 index 0000000..6aad56a --- /dev/null +++ b/0001-Fix-random-file-dialog-not-showing-up-problem.patch @@ -0,0 +1,245 @@ +From 6ae74671ca68e9444db618207d662ad5d1c16f31 Mon Sep 17 00:00:00 2001 +From: Weng Xuetian +Date: Wed, 30 Sep 2015 10:40:35 -0700 +Subject: [PATCH 1/1] Fix random file dialog not showing up problem. + +When using QDialog to implement QPlatformDialog there will be a issue, +that QDialog will use a dummy invisible to make Qt aware that a modal +dialog exists. But for our usecase, this invisible dialog will show up +after our own qdialog and cause our dialog not accept any input. + +The original workaround is to hide our dialog and show it again, but +this will hit QTBUG-48248 and our dialog will not show up at all +randomly. To avoid this, we delegate the call to show() on our +QDialog with a timer. + +BUG: 350758 +REVIEW: 125208 +--- + autotests/kfiledialog_unittest.cpp | 10 +++++++ + autotests/kfiledialogqml_unittest.cpp | 4 +++ + src/platformtheme/kdeplatformfiledialogbase.cpp | 16 ++++++++++- + src/platformtheme/kdeplatformfiledialogbase_p.h | 5 ++++ + src/platformtheme/kdeplatformfiledialoghelper.cpp | 35 +++++++++++++++-------- + src/platformtheme/kdeplatformfiledialoghelper.h | 1 + + 6 files changed, 58 insertions(+), 13 deletions(-) + +diff --git a/autotests/kfiledialog_unittest.cpp b/autotests/kfiledialog_unittest.cpp +index 0d4c8165d58a82789ace3190403d563fc0b37368..6abd98a4a542fad6834026291ad33acef6f2bb7e 100644 +--- a/autotests/kfiledialog_unittest.cpp ++++ b/autotests/kfiledialog_unittest.cpp +@@ -92,6 +92,8 @@ private Q_SLOTS: + + KFileWidget *fw = findFileWidget(); + QVERIFY(fw); ++ // real show() is delayed to next event. ++ QTest::qWaitForWindowExposed(fw->window()); + KDirOperator *op = fw->dirOperator(); + QCOMPARE(fileViewToString(op->viewMode()), fileViewToString(KFile::Tree)); + fw->setViewMode(KFile::Simple); +@@ -120,6 +122,8 @@ private Q_SLOTS: + + KFileWidget *fw = findFileWidget(); + QVERIFY(fw); ++ // real show() is delayed to next event. ++ QTest::qWaitForWindowExposed(fw->window()); + QCOMPARE(fw->isVisible(), true); + fw->slotCancel(); + } +@@ -133,6 +137,8 @@ private Q_SLOTS: + + KFileWidget *fw = findFileWidget(); + QVERIFY(fw); ++ // real show() is delayed to next event. ++ QTest::qWaitForWindowExposed(fw->window()); + QCOMPARE(fw->isVisible(), true); + fw->slotCancel(); + } +@@ -147,6 +153,8 @@ private Q_SLOTS: + + KFileWidget *fw = findFileWidget(); + QVERIFY(fw); ++ // real show() is delayed to next event. ++ QTest::qWaitForWindowExposed(fw->window()); + QCOMPARE(fw->isVisible(), true); + fw->slotCancel(); + } +@@ -160,6 +168,8 @@ private Q_SLOTS: + + KFileWidget *fw = findFileWidget(); + QVERIFY(fw); ++ // real show() is delayed to next event. ++ QTest::qWaitForWindowExposed(fw->window()); + QCOMPARE(fw->isVisible(), true); + fw->slotCancel(); + } +diff --git a/autotests/kfiledialogqml_unittest.cpp b/autotests/kfiledialogqml_unittest.cpp +index f805ef27cc1007c7e667ebf95e044b2ca895ecb1..eb7dfc5adc4a6921637aafddce2bf511f23d6b44 100644 +--- a/autotests/kfiledialogqml_unittest.cpp ++++ b/autotests/kfiledialogqml_unittest.cpp +@@ -48,6 +48,8 @@ private Q_SLOTS: + + fw = findFileWidget(); + QVERIFY(fw); ++ // real show() is delayed to next event. ++ QTest::qWaitForWindowExposed(fw->window()); + QCOMPARE(fw->isVisible(), true); + fw->slotCancel(); + } +@@ -65,6 +67,8 @@ private Q_SLOTS: + + fw = findFileWidget(); + QVERIFY(fw); ++ // real show() is delayed to next event. ++ QTest::qWaitForWindowExposed(fw->window()); + QCOMPARE(fw->isVisible(), true); + fw->slotCancel(); + } +diff --git a/src/platformtheme/kdeplatformfiledialogbase.cpp b/src/platformtheme/kdeplatformfiledialogbase.cpp +index 8e696bd5e0343fe6894cb0fea77cd8c8cdd0e4b3..856c052dffd2436399ed02dd9a8a4467c2fd18f2 100644 +--- a/src/platformtheme/kdeplatformfiledialogbase.cpp ++++ b/src/platformtheme/kdeplatformfiledialogbase.cpp +@@ -22,6 +22,20 @@ + + KDEPlatformFileDialogBase::KDEPlatformFileDialogBase() + { ++ m_timer.setInterval(0); ++ m_timer.setSingleShot(true); ++ connect(&m_timer, &QTimer::timeout, this, &KDEPlatformFileDialogBase::show); ++} ++ ++void KDEPlatformFileDialogBase::delayedShow() ++{ ++ m_timer.start(); ++} ++ ++void KDEPlatformFileDialogBase::discardDelayedShow() ++{ ++ // this is used when hide() is called before timer triggers. ++ m_timer.stop(); + } + + void KDEPlatformFileDialogBase::closeEvent(QCloseEvent *e) +@@ -30,4 +44,4 @@ void KDEPlatformFileDialogBase::closeEvent(QCloseEvent *e) + QDialog::closeEvent(e); + } + +-#include "moc_kdeplatformfiledialogbase_p.cpp" +\ No newline at end of file ++#include "moc_kdeplatformfiledialogbase_p.cpp" +diff --git a/src/platformtheme/kdeplatformfiledialogbase_p.h b/src/platformtheme/kdeplatformfiledialogbase_p.h +index 5936dfb3a5ae79b066d14235559cc921993d7aad..3191027bb1d10a70c2a01ef36007e0780ccb633a 100644 +--- a/src/platformtheme/kdeplatformfiledialogbase_p.h ++++ b/src/platformtheme/kdeplatformfiledialogbase_p.h +@@ -23,6 +23,7 @@ + + #include + #include ++#include + + class KFileWidget; + class QDialogButtonBox; +@@ -40,6 +41,9 @@ public: + virtual QString selectedNameFilter() = 0; + virtual QList selectedFiles() = 0; + ++ void delayedShow(); ++ void discardDelayedShow(); ++ + Q_SIGNALS: + void closed(); + void fileSelected(const QUrl &file); +@@ -51,6 +55,7 @@ Q_SIGNALS: + protected: + void closeEvent(QCloseEvent *e) Q_DECL_OVERRIDE; + QDialogButtonBox *m_buttons; ++ QTimer m_timer; + }; + + #endif +diff --git a/src/platformtheme/kdeplatformfiledialoghelper.cpp b/src/platformtheme/kdeplatformfiledialoghelper.cpp +index 94f2059284450ff378b6526233faa582f09e2d48..11e7efbb66948da40bf19f430f8020f95d0233f8 100644 +--- a/src/platformtheme/kdeplatformfiledialoghelper.cpp ++++ b/src/platformtheme/kdeplatformfiledialoghelper.cpp +@@ -37,7 +37,6 @@ + #include + + #include +-#include + + namespace + { +@@ -281,19 +280,17 @@ void KDEPlatformFileDialogHelper::initializeDialog() + + void KDEPlatformFileDialogHelper::exec() + { +- m_dialog->hide(); // ensure dialog is not shown (exec would block input) +- m_dialog->winId(); // ensure there's a window created +- KSharedConfig::Ptr conf = KSharedConfig::openConfig(); +- KWindowConfig::restoreWindowSize(m_dialog->windowHandle(), conf->group("FileDialogSize")); +- // NOTICE: QWindow::setGeometry() does NOT impact the backing QWidget geometry even if the platform +- // window was created -> QTBUG-40584. We therefore copy the size here. +- // TODO: remove once this was resolved in QWidget QPA +- m_dialog->resize(m_dialog->windowHandle()->size()); ++ restoreSize(); ++ // KDEPlatformFileDialog::show() will always be called during QFileDialog::exec() ++ // discard the delayed show() it and use exec() and it will call show() for us. ++ // We can't hide and show it here because of https://bugreports.qt.io/browse/QTBUG-48248 ++ m_dialog->discardDelayedShow(); + m_dialog->exec(); + } + + void KDEPlatformFileDialogHelper::hide() + { ++ m_dialog->discardDelayedShow(); + m_dialog->hide(); + } + +@@ -304,15 +301,29 @@ void KDEPlatformFileDialogHelper::saveSize() + KWindowConfig::saveWindowSize(m_dialog->windowHandle(), group); + } + ++void KDEPlatformFileDialogHelper::restoreSize() ++{ ++ m_dialog->winId(); // ensure there's a window created ++ KSharedConfig::Ptr conf = KSharedConfig::openConfig(); ++ KWindowConfig::restoreWindowSize(m_dialog->windowHandle(), conf->group("FileDialogSize")); ++ // NOTICE: QWindow::setGeometry() does NOT impact the backing QWidget geometry even if the platform ++ // window was created -> QTBUG-40584. We therefore copy the size here. ++ // TODO: remove once this was resolved in QWidget QPA ++ m_dialog->resize(m_dialog->windowHandle()->size()); ++} ++ + bool KDEPlatformFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) + { + Q_UNUSED(parent) + initializeDialog(); + m_dialog->setWindowFlags(windowFlags); + m_dialog->setWindowModality(windowModality); +- m_dialog->show(); +- KSharedConfig::Ptr conf = KSharedConfig::openConfig(); +- KWindowConfig::restoreWindowSize(m_dialog->windowHandle(), conf->group("FileDialogSize")); ++ restoreSize(); ++ // Use a delayed show here to delay show() after the internal Qt invisible QDialog. ++ // The delayed call shouldn't matter, because for other "real" native QPlatformDialog ++ // implementation like Mac and Windows, the native dialog is not necessarily ++ // show up immediately. ++ m_dialog->delayedShow(); + return true; + } + +diff --git a/src/platformtheme/kdeplatformfiledialoghelper.h b/src/platformtheme/kdeplatformfiledialoghelper.h +index dfbbed1ddcd56d668e879f7e29f6499ee9c258f2..f80b8c78e455312acff23b0461a6f1131b360431 100644 +--- a/src/platformtheme/kdeplatformfiledialoghelper.h ++++ b/src/platformtheme/kdeplatformfiledialoghelper.h +@@ -74,6 +74,7 @@ private Q_SLOTS: + void saveSize(); + + private: ++ void restoreSize(); + KDEPlatformFileDialogBase *m_dialog; + }; + +-- +2.5.2 + diff --git a/frameworkintegration.changes b/frameworkintegration.changes index 205ef57..2097c69 100644 --- a/frameworkintegration.changes +++ b/frameworkintegration.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Fri Oct 2 19:22:20 UTC 2015 - hrvoje.senjan@gmail.com + +- Added 0001-Fix-random-file-dialog-not-showing-up-problem.patch + (kde#350758) + ------------------------------------------------------------------- Tue Sep 8 17:12:29 UTC 2015 - hrvoje.senjan@gmail.com diff --git a/frameworkintegration.spec b/frameworkintegration.spec index 49161a4..58f611e 100644 --- a/frameworkintegration.spec +++ b/frameworkintegration.spec @@ -47,6 +47,8 @@ Group: System/GUI/KDE Url: http://www.kde.org Source: http://download.kde.org/stable/frameworks/%{_tar_path}/%{name}-%{version}.tar.xz Source1: baselibs.conf +# PATCH-FIX-UPSTREAM 0001-Fix-random-file-dialog-not-showing-up-problem.patch +Patch0: 0001-Fix-random-file-dialog-not-showing-up-problem.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build %description @@ -103,6 +105,7 @@ Applications do not need to link to this directly. Development files %lang_package -n %lname %prep %setup -q +%patch0 -p1 %build %cmake_kf5 -d build