diff --git a/src/DockRegistry.cpp b/src/DockRegistry.cpp index 3f226614..fdeb9a65 100644 --- a/src/DockRegistry.cpp +++ b/src/DockRegistry.cpp @@ -120,11 +120,6 @@ void DockRegistry::checkSanityAll(bool dumpLayout) } } -bool DockRegistry::isProcessingAppQuitEvent() const -{ - return m_isProcessingAppQuitEvent; -} - bool DockRegistry::affinitiesMatch(const QStringList &affinities1, const QStringList &affinities2) const { if (affinities1.isEmpty() && affinities2.isEmpty()) @@ -666,12 +661,7 @@ bool DockRegistry::eventFilter(QObject *watched, QEvent *event) if (!view) return false; - if (event->type() == QEvent::Quit && !m_isProcessingAppQuitEvent) { - m_isProcessingAppQuitEvent = true; - qGuiApp->sendEvent(qApp, event); - m_isProcessingAppQuitEvent = false; - return true; - } else if (event->type() == QEvent::Expose) { + if (event->type() == QEvent::Expose) { if (auto window = Platform::instance()->qobjectAsWindow(watched)) { if (Controllers::FloatingWindow *fw = floatingWindowForHandle(window)) { // This floating window was exposed diff --git a/src/DockRegistry.h b/src/DockRegistry.h index 655edb5d..1f824f76 100644 --- a/src/DockRegistry.h +++ b/src/DockRegistry.h @@ -184,13 +184,6 @@ public: */ void checkSanityAll(bool dumpDebug = false); - /** - * @brief Returns whether we're processing a QEvent::Quit - * - * Used internally to know if we should let Qt close a NonClosable dock widget at shutdown time. - */ - bool isProcessingAppQuitEvent() const; - /** * @brief Returns all main windows which match at least one of the @p affinities */ @@ -256,7 +249,6 @@ private: class Private; Private *const d; - bool m_isProcessingAppQuitEvent = false; QVector m_dockWidgets; QVector m_mainWindows; QList m_groups; diff --git a/src/Platform.h b/src/Platform.h index d80ecac0..c682dbea 100644 --- a/src/Platform.h +++ b/src/Platform.h @@ -100,6 +100,13 @@ public: /// @brief Releases the mouse grab, if any virtual void ungrabMouse() = 0; + /** + * @brief Returns whether we're processing a QEvent::Quit + * + * Used internally to know if we should let Qt close a NonClosable dock widget at shutdown time. + */ + virtual bool isProcessingAppQuitEvent() const = 0; + #ifdef DOCKS_DEVELOPER_MODE struct CreateViewOptions diff --git a/src/controllers/Group.cpp b/src/controllers/Group.cpp index ebbd3106..a70d61da 100644 --- a/src/controllers/Group.cpp +++ b/src/controllers/Group.cpp @@ -618,7 +618,7 @@ int Group::currentTabIndex() const bool Group::anyNonClosable() const { for (auto dw : dockWidgets()) { - if ((dw->options() & DockWidgetOption_NotClosable) && !DockRegistry::self()->isProcessingAppQuitEvent()) + if ((dw->options() & DockWidgetOption_NotClosable) && !Platform::instance()->isProcessingAppQuitEvent()) return true; } diff --git a/src/qtcommon/Platform_qt.cpp b/src/qtcommon/Platform_qt.cpp index c61d5412..be043682 100644 --- a/src/qtcommon/Platform_qt.cpp +++ b/src/qtcommon/Platform_qt.cpp @@ -98,7 +98,39 @@ EventFilter::~EventFilter() = default; } #endif +class Platform_qt::GlobalEventFilter : public QObject +{ +public: + GlobalEventFilter() + { + if (qGuiApp) + qGuiApp->installEventFilter(this); + } + + bool eventFilter(QObject *o, QEvent *ev) override + { + auto view = Platform::instance()->qobjectAsView(o); + if (!view) + return false; + + if (ev->type() == QEvent::Quit && !m_isProcessingAppQuitEvent) { + m_isProcessingAppQuitEvent = true; + qGuiApp->sendEvent(qApp, ev); + m_isProcessingAppQuitEvent = false; + return true; + } + + return false; + } + + ~GlobalEventFilter() override; + bool m_isProcessingAppQuitEvent = false; +}; + +Platform_qt::GlobalEventFilter::~GlobalEventFilter() = default; + Platform_qt::Platform_qt() + : m_globalEventFilter(new GlobalEventFilter()) { if (!qGuiApp) qWarning() << "Please call KDDockWidgets::initPlatform() after QGuiApplication"; @@ -106,6 +138,7 @@ Platform_qt::Platform_qt() Platform_qt::~Platform_qt() { + delete m_globalEventFilter; } std::shared_ptr Platform_qt::focusedView() const @@ -275,6 +308,7 @@ bool Platform_qt::isGammaray() } Platform_qt::Platform_qt(int &argc, char **argv) + : m_globalEventFilter(new GlobalEventFilter()) { // This CTOR is called before we have a QApplication @@ -298,3 +332,8 @@ void Platform_qt::tests_wait(int ms) } #endif + +bool Platform_qt::isProcessingAppQuitEvent() const +{ + return m_globalEventFilter->m_isProcessingAppQuitEvent; +} diff --git a/src/qtcommon/Platform_qt.h b/src/qtcommon/Platform_qt.h index c36a7dbf..4897adf5 100644 --- a/src/qtcommon/Platform_qt.h +++ b/src/qtcommon/Platform_qt.h @@ -34,6 +34,8 @@ public: void sendEvent(View *, QEvent *) const override; + bool isProcessingAppQuitEvent() const override; + #ifdef DOCKS_DEVELOPER_MODE static bool isGammaray(); explicit Platform_qt(int &argc, char **argv); @@ -55,6 +57,10 @@ public: #endif protected: int screenNumberForQWindow(QWindow *) const; + +private: + class GlobalEventFilter; + GlobalEventFilter *const m_globalEventFilter; }; }