| | |
| | | #include <QtGui/QPen> |
| | | #include <QtGui/QPainter> |
| | | #include <QtGui/QScreen> |
| | | #include <memory> |
| | | |
| | | #include "qwkglobal_p.h" |
| | | |
| | |
| | | |
| | | namespace { |
| | | |
| | | class WinIdChangeEventFilter : public QObject { |
| | | public: |
| | | explicit WinIdChangeEventFilter(QObject *widget, AbstractWindowContext *ctx, |
| | | QObject *parent = nullptr) |
| | | : QObject(parent), ctx(ctx) { |
| | | widget->installEventFilter(this); |
| | | } |
| | | |
| | | protected: |
| | | bool eventFilter(QObject *obj, QEvent *event) override { |
| | | Q_UNUSED(obj) |
| | | if (event->type() == QEvent::WinIdChange) { |
| | | ctx->notifyWinIdChange(); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | protected: |
| | | AbstractWindowContext *ctx; |
| | | }; |
| | | |
| | | class WindowEventFilter : public QObject { |
| | | public: |
| | | explicit WindowEventFilter(QWindow *window, AbstractWindowContext *ctx, |
| | | QObject *parent = nullptr) |
| | | : QObject(parent), ctx(ctx), window(window) { |
| | | window->installEventFilter(this); |
| | | if (window) |
| | | window->installEventFilter(this); |
| | | } |
| | | |
| | | inline void setWindow(QWindow *win) { |
| | | if (auto oldWin = window.data(); oldWin) { |
| | | oldWin->removeEventFilter(this); |
| | | } |
| | | window = win; |
| | | if (win) { |
| | | win->installEventFilter(this); |
| | | } |
| | | } |
| | | |
| | | protected: |
| | |
| | | |
| | | protected: |
| | | AbstractWindowContext *ctx; |
| | | QWindow *window; |
| | | QPointer<QWindow> window; |
| | | }; |
| | | |
| | | } |
| | |
| | | } |
| | | m_host = host; |
| | | m_delegate.reset(delegate); |
| | | m_winIdChangeEventFilter = std::make_unique<WinIdChangeEventFilter>(host, this); |
| | | |
| | | m_windowHandle = m_delegate->hostWindow(m_host); |
| | | if (m_windowHandle) { |
| | | winIdChanged(); |
| | | m_windowEventFilter = std::make_unique<WindowEventFilter>(m_windowHandle, this); |
| | | } |
| | | m_winIdChangeEventFilter.reset(delegate->createWinIdEventFilter(host, this)); |
| | | m_windowEventFilter = std::make_unique<WindowEventFilter>(m_windowHandle, this); |
| | | notifyWinIdChange(); |
| | | } |
| | | |
| | | |
| | | |
| | | bool AbstractWindowContext::setHitTestVisible(const QObject *obj, bool visible) { |
| | | Q_ASSERT(obj); |
| | |
| | | int y = (screenGeometry.height() - windowGeometry.height()) / 2; |
| | | QPoint pos(x, y); |
| | | pos += screenGeometry.topLeft(); |
| | | m_windowHandle->setPosition(pos); |
| | | m_delegate->setGeometry(m_host, QRect(pos, windowGeometry.size())); |
| | | return; |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | void AbstractWindowContext::notifyWinIdChange() { |
| | | auto oldWindow = m_windowHandle; |
| | | auto oldWinId = m_windowId; |
| | | m_windowId = m_winIdChangeEventFilter->winId(); |
| | | |
| | | // In Qt6, after QWidget::close() is called, the related QWindow's all surfaces and the |
| | | // platform window will be removed, and the WinId will be set to 0. After that, when the |
| | | // QWidget is shown again, the whole things will be recreated again. |
| | | // As a result, we must update our WindowContext each time the WinId changes. |
| | | m_windowHandle = m_delegate->hostWindow(m_host); |
| | | if (oldWindow == m_windowHandle) |
| | | return; |
| | | m_windowEventFilter.reset(); |
| | | winIdChanged(); |
| | | |
| | | auto windowEventFilter = static_cast<WindowEventFilter *>(m_windowEventFilter.get()); |
| | | windowEventFilter->setWindow(nullptr); |
| | | |
| | | if (oldWinId != m_windowId) { |
| | | winIdChanged(m_windowId, oldWinId); |
| | | } |
| | | |
| | | if (m_windowHandle) { |
| | | m_windowEventFilter = std::make_unique<WindowEventFilter>(m_windowHandle, this); |
| | | windowEventFilter->setWindow(m_windowHandle); |
| | | |
| | | // Refresh window attributes |
| | | auto attributes = m_windowAttributes; |