From c50dd144b085afe2d63f1b344f55fb99c0caa8ab5913e5e0171151c48ff10668 Mon Sep 17 00:00:00 2001 From: Dominique Leuenberger Date: Wed, 24 Feb 2016 17:52:25 +0000 Subject: [PATCH] Accepting request 360928 from KDE:Qt5 - Added QMimeDatabase-follow-symlinks-when-checking-for-FIFO.patch to fix dolphin freeze when opening a folder containing symlinks to special files (boo#957006, qtbug#48529) - Update Add-option-to-disable-session-management-by-closing-windows.patch to version actually commited upstream OBS-URL: https://build.opensuse.org/request/show/360928 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/libqt5-qtbase?expand=0&rev=51 --- ...ession-management-by-closing-windows.patch | 285 ++++++++++-------- ...llow-symlinks-when-checking-for-FIFO.patch | 94 ++++++ libqt5-qtbase.changes | 13 + libqt5-qtbase.spec | 2 + 4 files changed, 265 insertions(+), 129 deletions(-) create mode 100644 QMimeDatabase-follow-symlinks-when-checking-for-FIFO.patch diff --git a/Add-option-to-disable-session-management-by-closing-windows.patch b/Add-option-to-disable-session-management-by-closing-windows.patch index 331eb78..caa87dc 100644 --- a/Add-option-to-disable-session-management-by-closing-windows.patch +++ b/Add-option-to-disable-session-management-by-closing-windows.patch @@ -1,180 +1,207 @@ -From 2722dd7bb544949ff8ca9fe2cfb7b41ceaaddc56 Mon Sep 17 00:00:00 2001 +From e7bf0edfd49de9a4d8285fbe8d878f8fda910e6d Mon Sep 17 00:00:00 2001 From: Andreas Hartmetz Date: Tue, 19 Jan 2016 14:30:18 +0100 -Subject: [PATCH 1/1] Add option to disable "session management by closing - windows". +Subject: Add option to disable "session management by closing windows". That feature is a poor man's session management for applications that do not implement any specific session management features. It badly interferes with proper session management support, so applications must be able to disable it. -This fixes some KDE applications dying too early, before they are -enumerated for the list of applications to restart on session -restore, thus preventing them from being restored. See +This enables fixing applications with +QGuiApplication::quitOnLastWindowClosed() true - the default - +dying too early, before they are enumerated for the list of +applications to restart on session restore, thus preventing them +from being restored. See https://bugs.kde.org/show_bug.cgi?id=354724 +[ChangeLog][QtGui] Qt asking to close windows on session exit as +a fallback session management mechanism has been made optional. +Disabling it fixes session management for applications that +implement full session management. See +QGuiApplication::isFallbackSessionManagementEnabled(). + Task-number: QTBUG-49667 Change-Id: Ib22e58c9c64351dea8b7e2a74db91d26dd7ab7aa +Reviewed-by: Oswald Buddenhagen +Reviewed-by: David Faure --- + .../widgets/mainwindows/application/mainwindow.cpp | 16 ++++++ + .../widgets/mainwindows/application/mainwindow.h | 2 + .../code/src_gui_kernel_qguiapplication.cpp | 1 + - src/gui/kernel/qguiapplication.cpp | 14 +++++- - src/gui/kernel/qsessionmanager.cpp | 55 +++++++++++++++++++++- - src/gui/kernel/qsessionmanager.h | 3 ++ - src/gui/kernel/qsessionmanager_p.h | 1 + - 5 files changed, 71 insertions(+), 3 deletions(-) + src/gui/kernel/qguiapplication.cpp | 60 +++++++++++++++++++++- + src/gui/kernel/qguiapplication.h | 3 ++ + src/gui/kernel/qguiapplication_p.h | 1 + + src/gui/kernel/qsessionmanager.cpp | 19 ++++--- + 7 files changed, 90 insertions(+), 12 deletions(-) diff --git a/src/gui/doc/snippets/code/src_gui_kernel_qguiapplication.cpp b/src/gui/doc/snippets/code/src_gui_kernel_qguiapplication.cpp -index 4ddf8c8..3006d19 100644 +index 4ddf8c8..63fdb3b 100644 --- a/src/gui/doc/snippets/code/src_gui_kernel_qguiapplication.cpp +++ b/src/gui/doc/snippets/code/src_gui_kernel_qguiapplication.cpp -@@ -58,6 +58,7 @@ MyMainWidget::MyMainWidget(QWidget *parent) - - void MyMainWidget::commitData(QSessionManager& manager) +@@ -53,6 +53,7 @@ int main(int argc, char *argv[]) + MyMainWidget::MyMainWidget(QWidget *parent) + :QWidget(parent) { -+ manager.setAutoCloseWindowsEnabled(false); - if (manager.allowsInteraction()) { - int ret = QMessageBox::warning( - mainWindow, ++ QGuiApplication::setFallbackSessionManagementEnabled(false); + connect(qApp, SIGNAL(commitDataRequest(QSessionManager)), SLOT(commitData(QSessionManager))); + } + diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp -index 770f847..40f2d5f 100644 +index 65d679c..8f1c62f 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp -@@ -3087,6 +3087,12 @@ void QGuiApplicationPrivate::setApplicationState(Qt::ApplicationState state, boo - the session manager may or may not do this afterwards, depending on the - context. +@@ -138,6 +138,8 @@ QPlatformTheme *QGuiApplicationPrivate::platform_theme = 0; -+ When you connect to this signal to ask the user for permission to close -+ the application and / or commit application data, you should also call -+ QSessionManager::setAutoCloseWindowsEnabled(false) on \a manager to disable -+ a feature that helps applications that do not support full session -+ management, but hurts applications that do. + QList QGuiApplicationPrivate::generic_plugin_list; + ++bool QGuiApplicationPrivate::is_fallback_session_management_enabled = true; + - \warning Within this signal, no user interaction is possible, \e - unless you ask the \a manager for explicit permission. See - QSessionManager::allowsInteraction() and -@@ -3095,7 +3101,8 @@ void QGuiApplicationPrivate::setApplicationState(Qt::ApplicationState state, boo + enum ApplicationResourceFlags + { + ApplicationPaletteExplicitlySet = 0x1, +@@ -3082,6 +3084,55 @@ void QGuiApplicationPrivate::setApplicationState(Qt::ApplicationState state, boo + emit qApp->applicationStateChanged(applicationState); + } + ++// ### Qt6: consider removing the feature or making it less intrusive ++/*! ++ \since 5.6 ++ ++ Returns whether QGuiApplication will use fallback session management. ++ ++ The default is \c true. ++ ++ If this is \c true and the session manager allows user interaction, ++ QGuiApplication will try to close toplevel windows after ++ commitDataRequest() has been emitted. If a window cannot be closed, session ++ shutdown will be canceled and the application will keep running. ++ ++ Fallback session management only benefits applications that have an ++ "are you sure you want to close this window?" feature or other logic that ++ prevents closing a toplevel window depending on certain conditions, and ++ that do nothing to explicitly implement session management. In applications ++ that \e do implement session management using the proper session management ++ API, fallback session management interferes and may break session ++ management logic. ++ ++ \warning If all windows \e are closed due to fallback session management ++ and quitOnLastWindowClosed() is \c true, the application will quit before ++ it is explicitly instructed to quit through the platform's session ++ management protocol. That violation of protocol may prevent the platform ++ session manager from saving application state. ++ ++ \sa setFallbackSessionManagementEnabled(), ++ QSessionManager::allowsInteraction(), saveStateRequest(), ++ commitDataRequest(), {Session Management} ++*/ ++bool QGuiApplication::isFallbackSessionManagementEnabled() ++{ ++ return QGuiApplicationPrivate::is_fallback_session_management_enabled; ++} ++ ++/*! ++ \since 5.6 ++ ++ Sets whether QGuiApplication will use fallback session management to ++ \a enabled. ++ ++ \sa isFallbackSessionManagementEnabled() ++*/ ++void QGuiApplication::setFallbackSessionManagementEnabled(bool enabled) ++{ ++ QGuiApplicationPrivate::is_fallback_session_management_enabled = enabled; ++} ++ + /*! + \since 4.2 + \fn void QGuiApplication::commitDataRequest(QSessionManager &manager) +@@ -3106,7 +3157,8 @@ void QGuiApplicationPrivate::setApplicationState(Qt::ApplicationState state, boo \note You should use Qt::DirectConnection when connecting to this signal. - \sa isSessionRestored(), sessionId(), saveStateRequest(), {Session Management} -+ \sa QSessionManager::setAutoCloseWindowsEnabled(), isSessionRestored(), ++ \sa setFallbackSessionManagementEnabled(), isSessionRestored(), + sessionId(), saveStateRequest(), {Session Management} */ /*! -@@ -3225,9 +3232,12 @@ void QGuiApplicationPrivate::commitData() +@@ -3236,9 +3288,13 @@ void QGuiApplicationPrivate::commitData() { Q_Q(QGuiApplication); is_saving_session = true; + emit q->commitDataRequest(*session_manager); - if (session_manager->allowsInteraction() && !tryCloseAllWindows()) -+ if (session_manager->autoCloseWindowsEnabled() && session_manager->allowsInteraction() -+ && !tryCloseAllWindows()) ++ if (is_fallback_session_management_enabled && session_manager->allowsInteraction() ++ && !tryCloseAllWindows()) { session_manager->cancel(); ++ } + is_saving_session = false; } +diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h +index d995387..3f233d4 100644 +--- a/src/gui/kernel/qguiapplication.h ++++ b/src/gui/kernel/qguiapplication.h +@@ -152,6 +152,9 @@ public: + QString sessionId() const; + QString sessionKey() const; + bool isSavingSession() const; ++ ++ static bool isFallbackSessionManagementEnabled(); ++ static void setFallbackSessionManagementEnabled(bool); + #endif + + static void sync(); +diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h +index 7c7da97..4f0f6fd 100644 +--- a/src/gui/kernel/qguiapplication_p.h ++++ b/src/gui/kernel/qguiapplication_p.h +@@ -234,6 +234,7 @@ public: + #endif + + #ifndef QT_NO_SESSIONMANAGER ++ static bool is_fallback_session_management_enabled; + QSessionManager *session_manager; + bool is_session_restored; + bool is_saving_session; diff --git a/src/gui/kernel/qsessionmanager.cpp b/src/gui/kernel/qsessionmanager.cpp -index f4b56fd..4d140f9 100644 +index f4b56fd..c6d23f1 100644 --- a/src/gui/kernel/qsessionmanager.cpp +++ b/src/gui/kernel/qsessionmanager.cpp -@@ -116,7 +116,8 @@ QT_BEGIN_NAMESPACE +@@ -64,22 +64,21 @@ QT_BEGIN_NAMESPACE + settings. - QSessionManagerPrivate::QSessionManagerPrivate(const QString &id, - const QString &key) -- : QObjectPrivate() -+ : QObjectPrivate(), -+ autoCloseWindowsEnabled(true) - { - platformSessionManager = QGuiApplicationPrivate::platformIntegration()->createPlatformSessionManager(id, key); - Q_ASSERT_X(platformSessionManager, "Platform session management", -@@ -350,6 +351,58 @@ QStringList QSessionManager::discardCommand() const - } + QSessionManager provides an interface between the application and the +- session manager so that the program can work well with the session manager. +- In Qt, session management requests for action are handled by the two +- signals QGuiApplication::commitDataRequest() and +- QGuiApplication::saveStateRequest(). Both provide a reference to a session +- manager object as argument, to allow the application to communicate with +- the session manager. The session manager can only be accessed through these +- functions. ++ platform's session manager. In Qt, session management requests for action ++ are handled by the two signals QGuiApplication::commitDataRequest() and ++ QGuiApplication::saveStateRequest(). Both provide a reference to a ++ QSessionManager object as argument. The session manager can only be ++ accessed in slots invoked by these signals. ++ ++ \warning If you use QSessionManager, you should disable fallback session ++ management: QGuiApplication::setFallbackSessionManagementEnabled(). - /*! -+ \since 5.6 -+ -+ Sets whether the session manager will try to close application windows during -+ session exit to \a enabled. -+ -+ \sa autoCloseWindowsEnabled() -+*/ -+void QSessionManager::setAutoCloseWindowsEnabled(bool enabled) -+{ -+ Q_D(QSessionManager); -+ d->autoCloseWindowsEnabled = enabled; -+} -+ -+/*! -+ \since 5.6 -+ -+ Returns whether the session manager will try to close application windows during -+ session exit. -+ -+ If this is true immediately after QGuiApplication::commitDataRequest() has been -+ emitted, and allowsInteraction() is true, Qt will send CloseEvent to all -+ windows of the application. If that fails to close all windows, session exit is -+ canceled and the application keeps running. -+ -+ The purpose of that is to give applications without explicit session management -+ support a chance to cancel session exit through the common -+ "are you sure you want to close this window?" feature. -+ -+ \warning If all windows \e are closed due to this feature, -+ that may quit the application before it is explicitly instructed to quit through -+ the platform's session management protocol - see -+ QGuiApplication::quitOnLastWindowClosed(). That may in turn prevent the platform -+ session manager from saving the application's state correctly because the -+ application broke the protocol. -+ -+ If your application implements full session management, you should disable this. -+ -+ It is sufficient to set this property once on any instance of QSessionManager -+ to set its value for the lifetime of the application - it acts like a class -+ static variable. -+ -+ The default is true. -+ -+ \sa setAutoCloseWindowsEnabled() -+*/ -+bool QSessionManager::autoCloseWindowsEnabled() const -+{ -+ Q_D(const QSessionManager); -+ return d->autoCloseWindowsEnabled; -+} -+ -+/*! - \overload + No user interaction is possible \e unless the application gets explicit + permission from the session manager. You ask for permission by calling + allowsInteraction() or, if it is really urgent, allowsErrorInteraction(). + Qt does not enforce this, but the session manager may. - Low-level write access to the application's identification and state -diff --git a/src/gui/kernel/qsessionmanager.h b/src/gui/kernel/qsessionmanager.h -index 36aa391..696d9d8 100644 ---- a/src/gui/kernel/qsessionmanager.h -+++ b/src/gui/kernel/qsessionmanager.h -@@ -78,6 +78,9 @@ public: - void setDiscardCommand(const QStringList&); - QStringList discardCommand() const; +- You can try to abort the shutdown process by calling cancel(). The default +- commitData() function does this if some top-level window rejected its +- closeEvent(). ++ You can try to abort the shutdown process by calling cancel(). -+ void setAutoCloseWindowsEnabled(bool); -+ bool autoCloseWindowsEnabled() const; -+ - void setManagerProperty(const QString& name, const QString& value); - void setManagerProperty(const QString& name, const QStringList& value); - -diff --git a/src/gui/kernel/qsessionmanager_p.h b/src/gui/kernel/qsessionmanager_p.h -index 8949962..0acf865 100644 ---- a/src/gui/kernel/qsessionmanager_p.h -+++ b/src/gui/kernel/qsessionmanager_p.h -@@ -65,6 +65,7 @@ public: - virtual ~QSessionManagerPrivate(); - - QPlatformSessionManager *platformSessionManager; -+ bool autoCloseWindowsEnabled; - }; - - QT_END_NAMESPACE + For sophisticated session managers provided on Unix/X11, QSessionManager + offers further possibilities to fine-tune an application's session -- -2.6.2.2.g1b5ffa3 +cgit v0.11.0 diff --git a/QMimeDatabase-follow-symlinks-when-checking-for-FIFO.patch b/QMimeDatabase-follow-symlinks-when-checking-for-FIFO.patch new file mode 100644 index 0000000..4c32eb3 --- /dev/null +++ b/QMimeDatabase-follow-symlinks-when-checking-for-FIFO.patch @@ -0,0 +1,94 @@ +From 72b4f0d4743826ee14ec06bf0ada26418f4a69be Mon Sep 17 00:00:00 2001 +From: David Faure +Date: Mon, 30 Nov 2015 12:03:18 +0100 +Subject: [PATCH 1/1] QMimeDatabase: follow symlinks when checking for FIFO + etc. + +This was documented, but not what the code did. + +Task-number: QTBUG-48529 +Change-Id: I4849778c61dcae13be27c62b24717693c0c07d78 +Reviewed-by: Edward Welbourne +Reviewed-by: Thiago Macieira +--- + src/corelib/mimetypes/qmimedatabase.cpp | 3 ++- + .../mimetypes/qmimedatabase/tst_qmimedatabase.cpp | 27 ++++++++++++++++++++++ + .../mimetypes/qmimedatabase/tst_qmimedatabase.h | 1 + + 3 files changed, 30 insertions(+), 1 deletion(-) + +diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp +index c1e17b9..fd11dbc 100644 +--- a/src/corelib/mimetypes/qmimedatabase.cpp ++++ b/src/corelib/mimetypes/qmimedatabase.cpp +@@ -354,9 +354,10 @@ QMimeType QMimeDatabase::mimeTypeForFile(const QFileInfo &fileInfo, MatchMode mo + + #ifdef Q_OS_UNIX + // Cannot access statBuf.st_mode from the filesystem engine, so we have to stat again. ++ // In addition we want to follow symlinks. + const QByteArray nativeFilePath = QFile::encodeName(file.fileName()); + QT_STATBUF statBuffer; +- if (QT_LSTAT(nativeFilePath.constData(), &statBuffer) == 0) { ++ if (QT_STAT(nativeFilePath.constData(), &statBuffer) == 0) { + if (S_ISCHR(statBuffer.st_mode)) + return d->mimeTypeForName(QLatin1String("inode/chardevice")); + if (S_ISBLK(statBuffer.st_mode)) +diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp +index 0171c4a..1b4dc02 100644 +--- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp ++++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp +@@ -35,6 +35,11 @@ + + #include "qstandardpaths.h" + ++#ifdef Q_OS_UNIX ++#include ++#include ++#endif ++ + #include + #include + #include +@@ -646,6 +651,28 @@ void tst_QMimeDatabase::knownSuffix() + QCOMPARE(db.suffixForFileName(QString::fromLatin1("foo.tar.bz2")), QString::fromLatin1("tar.bz2")); + } + ++void tst_QMimeDatabase::symlinkToFifo() // QTBUG-48529 ++{ ++#ifdef Q_OS_UNIX ++ QTemporaryDir tempDir; ++ QVERIFY(tempDir.isValid()); ++ const QString dir = tempDir.path(); ++ const QString fifo = dir + "/fifo"; ++ QCOMPARE(mkfifo(QFile::encodeName(fifo), 0006), 0); ++ ++ QMimeDatabase db; ++ QCOMPARE(db.mimeTypeForFile(fifo).name(), QString::fromLatin1("inode/fifo")); ++ ++ // Now make a symlink to the fifo ++ const QString link = dir + "/link"; ++ QVERIFY(QFile::link(fifo, link)); ++ QCOMPARE(db.mimeTypeForFile(link).name(), QString::fromLatin1("inode/fifo")); ++ ++#else ++ QSKIP("This test requires pipes and symlinks"); ++#endif ++} ++ + void tst_QMimeDatabase::findByFileName_data() + { + QTest::addColumn("filePath"); +diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h +index 2827bd2..4b703f1 100644 +--- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h ++++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h +@@ -70,6 +70,7 @@ private slots: + void suffixes_data(); + void suffixes(); + void knownSuffix(); ++ void symlinkToFifo(); + void fromThreads(); + + // shared-mime-info test suite +-- +2.6.2.2.g1b5ffa3 + diff --git a/libqt5-qtbase.changes b/libqt5-qtbase.changes index 38f345e..f0c3ed6 100644 --- a/libqt5-qtbase.changes +++ b/libqt5-qtbase.changes @@ -1,3 +1,16 @@ +------------------------------------------------------------------- +Sun Feb 21 00:52:42 UTC 2016 - wbauer@tmo.at + +- Added QMimeDatabase-follow-symlinks-when-checking-for-FIFO.patch + to fix dolphin freeze when opening a folder containing symlinks + to special files (boo#957006, qtbug#48529) + +------------------------------------------------------------------- +Sat Feb 20 16:08:45 UTC 2016 - hrvoje.senjan@gmail.com + +- Update Add-option-to-disable-session-management-by-closing-windows.patch + to version actually commited upstream + ------------------------------------------------------------------- Wed Feb 10 12:28:49 UTC 2016 - alarrosa@suse.com diff --git a/libqt5-qtbase.spec b/libqt5-qtbase.spec index b530c4d..4afd7c3 100644 --- a/libqt5-qtbase.spec +++ b/libqt5-qtbase.spec @@ -68,6 +68,7 @@ Patch3005: xcb-fix-yet-another-crash-when-screens-are-disconnected.patch Patch3006: xcb-dont-crash-in-mapToNativemapFromNative-if-the-screen-is-null.patch Patch3007: qtwidgets_do_not-hide_show_via_WA_OutsideWSRange_for_native_widgets.patch Patch3008: Add-option-to-disable-session-management-by-closing-windows.patch +Patch3009: QMimeDatabase-follow-symlinks-when-checking-for-FIFO.patch BuildRequires: alsa-devel BuildRequires: cups-devel BuildRequires: gcc-c++ @@ -163,6 +164,7 @@ handling. %patch3006 -p1 %patch3007 -p1 %patch3008 -p1 +%patch3009 -p1 # be sure not to use them rm -r src/3rdparty/{libjpeg,freetype,libpng,zlib}