Add EventFilterInterface and port DockRegistry to it

Some classes wont have any Qt in it, so they need another way
to install global event filters. Added API to Platform.h for this
purpose. Implemented as regular event filter in Platform_qt.
This commit is contained in:
Sergio Martins
2022-07-01 15:25:48 +01:00
parent a690477b73
commit c72fdf3586
8 changed files with 120 additions and 13 deletions

View File

@@ -48,11 +48,14 @@ DockRegistry::DockRegistry(QObject *parent)
, d(new Private())
{
qGuiApp->installEventFilter(this);
Platform::instance()->installGlobalEventFilter(this);
d->m_connection = Platform::instance()->d->focusedViewChanged.connect(&DockRegistry::onFocusedViewChanged, this);
}
DockRegistry::~DockRegistry()
{
Platform::instance()->removeGlobalEventFilter(this);
d->m_connection.disconnect();
delete d;
}
@@ -661,15 +664,7 @@ bool DockRegistry::eventFilter(QObject *watched, QEvent *event)
if (!view)
return false;
if (event->type() == QEvent::Expose) {
if (auto window = Platform::instance()->qobjectAsWindow(watched)) {
if (Controllers::FloatingWindow *fw = floatingWindowForHandle(window)) {
// This floating window was exposed
m_floatingWindows.removeOne(fw);
m_floatingWindows.append(fw);
}
}
} else if (event->type() == QEvent::MouseButtonPress) {
if (event->type() == QEvent::MouseButtonPress) {
// When clicking on a MDI Frame we raise the window
if (Controller *c = View::firstParentOfType(watched, Type::Frame)) {
auto group = static_cast<Group *>(c);
@@ -737,3 +732,14 @@ bool DockRegistry::onDockWidgetPressed(Controllers::DockWidget *dw, QMouseEvent
return false;
}
bool DockRegistry::onExposeEvent(Window::Ptr window)
{
if (Controllers::FloatingWindow *fw = floatingWindowForHandle(window)) {
// This floating window was exposed
m_floatingWindows.removeOne(fw);
m_floatingWindows.append(fw);
}
return false;
}

View File

@@ -14,6 +14,7 @@
#include "kddockwidgets/KDDockWidgets.h"
#include "kddockwidgets/View.h"
#include "kddockwidgets/EventFilterInterface.h"
#include <QVector>
#include <QObject>
@@ -45,7 +46,7 @@ class MainWindowViewInterface;
class MainWindowMDI;
struct WindowBeingDragged;
class DOCKS_EXPORT DockRegistry : public QObject
class DOCKS_EXPORT DockRegistry : public QObject, public EventFilterInterface
{
Q_OBJECT
@@ -246,6 +247,8 @@ private:
void maybeDelete();
void setFocusedDockWidget(Controllers::DockWidget *);
bool onExposeEvent(std::shared_ptr<Window>) override;
class Private;
Private *const d;

View File

@@ -0,0 +1,33 @@
/*
This file is part of KDDockWidgets.
SPDX-FileCopyrightText: 2020-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
Author: Sérgio Martins <sergio.martins@kdab.com>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
Contact KDAB at <info@kdab.com> for commercial licensing options.
*/
#pragma once
#include <memory>
namespace KDDockWidgets {
class Window;
class View;
class EventFilterInterface
{
public:
virtual ~EventFilterInterface();
/// @brief Override to handle expose events for a certain window
virtual bool onExposeEvent(std::shared_ptr<Window>)
{
return false;
}
};
}

View File

@@ -11,6 +11,7 @@
#include "Platform.h"
#include "private/Platform_p.h"
#include "EventFilterInterface.h"
#ifdef KDDW_FRONTEND_QTWIDGETS
#include "qtwidgets/Platform_qtwidgets.h"
@@ -31,6 +32,8 @@ using namespace KDDockWidgets;
static Platform *s_platform = nullptr;
EventFilterInterface::~EventFilterInterface() = default;
#ifdef DOCKS_DEVELOPER_MODE
QString Platform::s_expectedWarning = {};
Platform::WarningObserver *Platform::s_warningObserver = nullptr;
@@ -153,3 +156,15 @@ std::vector<KDDockWidgets::FrontendType> Platform::frontendTypes()
}
#endif
void Platform::installGlobalEventFilter(EventFilterInterface *filter)
{
d->m_globalEventFilters.push_back(filter);
}
void Platform::removeGlobalEventFilter(EventFilterInterface *filter)
{
d->m_globalEventFilters.erase(std::remove(d->m_globalEventFilters.begin(),
d->m_globalEventFilters.end(), filter),
d->m_globalEventFilters.end());
}

View File

@@ -27,6 +27,7 @@ class ClassicIndicators;
class SegmentedIndicators;
}
class EventFilterInterface;
class ViewFactory;
class Window;
@@ -184,6 +185,13 @@ public:
virtual void installMessageHandler() = 0;
virtual void uninstallMessageHandler() = 0;
/// @brief Installs a global event filter
/// Events will be forwarded to the specified EventFilterInterface
void installGlobalEventFilter(EventFilterInterface *);
/// @brief Removes a global event filter
void removeGlobalEventFilter(EventFilterInterface *);
/// @brief Creates a main window. This is not API that the user will use, but used
/// internally by some tools that need a main window
virtual Controllers::MainWindow *createMainWindow(const QString &uniqueName, CreateViewOptions,

View File

@@ -0,0 +1,12 @@
/*
This file is part of KDDockWidgets.
SPDX-FileCopyrightText: 2020-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
Author: Sergio Martins <sergio.martins@kdab.com>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
Contact KDAB at <info@kdab.com> for commercial licensing options.
*/
#include "../../EventFilterInterface.h"

View File

@@ -15,8 +15,12 @@
#include "kdbindings/signal.h"
#include <memory>
#include <vector>
namespace KDDockWidgets {
class EventFilterInterface;
class Platform::Private
{
public:
@@ -35,5 +39,8 @@ public:
}
bool m_inDestruction = false;
std::vector<EventFilterInterface *> m_globalEventFilters;
};
}

View File

@@ -12,6 +12,7 @@
#include "Platform_qt.h"
#include "kddockwidgets/KDDockWidgets.h"
#include "kddockwidgets/Window_qt.h"
#include "kddockwidgets/EventFilterInterface.h"
#include "private/Platform_p.h"
#include <QWindow>
@@ -101,7 +102,8 @@ EventFilter::~EventFilter() = default;
class Platform_qt::GlobalEventFilter : public QObject
{
public:
GlobalEventFilter()
GlobalEventFilter(Platform_qt *qq)
: q(qq)
{
if (qGuiApp)
qGuiApp->installEventFilter(this);
@@ -109,6 +111,9 @@ public:
bool eventFilter(QObject *o, QEvent *ev) override
{
if (ev->type() == QEvent::Expose)
return handleExpose(o);
auto view = Platform::instance()->qobjectAsView(o);
if (!view)
return false;
@@ -123,14 +128,32 @@ public:
return false;
}
bool handleExpose(QObject *o)
{
if (q->d->m_globalEventFilters.empty())
return false;
auto window = Platform::instance()->qobjectAsWindow(o);
if (!window)
return false;
for (EventFilterInterface *filter : qAsConst(q->d->m_globalEventFilters)) {
if (filter->onExposeEvent(window))
return true;
}
return false;
}
~GlobalEventFilter() override;
bool m_isProcessingAppQuitEvent = false;
Platform_qt *const q;
};
Platform_qt::GlobalEventFilter::~GlobalEventFilter() = default;
Platform_qt::Platform_qt()
: m_globalEventFilter(new GlobalEventFilter())
: m_globalEventFilter(new GlobalEventFilter(this))
{
if (!qGuiApp)
qWarning() << "Please call KDDockWidgets::initPlatform() after QGuiApplication";
@@ -308,7 +331,7 @@ bool Platform_qt::isGammaray()
}
Platform_qt::Platform_qt(int &argc, char **argv)
: m_globalEventFilter(new GlobalEventFilter())
: m_globalEventFilter(new GlobalEventFilter(this))
{
// This CTOR is called before we have a QApplication