Hrvoje Senjan 2015-10-02 19:19:48 +00:00 committed by Git OBS Bridge
parent cc4a47ddcf
commit 59faba5a49
3 changed files with 254 additions and 0 deletions

View File

@ -0,0 +1,245 @@
From 6ae74671ca68e9444db618207d662ad5d1c16f31 Mon Sep 17 00:00:00 2001
From: Weng Xuetian <wengxt@gmail.com>
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 <QDialog>
#include <QUrl>
+#include <QTimer>
class KFileWidget;
class QDialogButtonBox;
@@ -40,6 +41,9 @@ public:
virtual QString selectedNameFilter() = 0;
virtual QList<QUrl> 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 <QWindow>
#include <QTextStream>
-#include <QEventLoop>
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

View File

@ -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

View File

@ -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