diff --git a/qmsetup b/qmsetup index ba85e3a..f17220c 160000 --- a/qmsetup +++ b/qmsetup @@ -1 +1 @@ -Subproject commit ba85e3a940c1698987ce0faecb5af9bdca83c599 +Subproject commit f17220c8b491d85942329abacfc3ed7abf440535 diff --git a/src/core/contexts/abstractwindowcontext.cpp b/src/core/contexts/abstractwindowcontext.cpp index 71818c2..f08964d 100644 --- a/src/core/contexts/abstractwindowcontext.cpp +++ b/src/core/contexts/abstractwindowcontext.cpp @@ -26,16 +26,27 @@ namespace QWK { notifyWinIdChange(); } - bool AbstractWindowContext::setHitTestVisible(const QObject *obj, bool visible) { + bool AbstractWindowContext::setHitTestVisible(QObject *obj, bool visible) { Q_ASSERT(obj); if (!obj) { return false; } + auto it = m_hitTestVisibleItems.find(obj); if (visible) { + if (it != m_hitTestVisibleItems.end()) { + return true; + } + connect(obj, &QObject::destroyed, this, + &AbstractWindowContext::_q_hitTestVisibleItemDestroyed); m_hitTestVisibleItems.insert(obj); } else { - m_hitTestVisibleItems.remove(obj); + if (it == m_hitTestVisibleItems.end()) { + return false; + } + disconnect(obj, &QObject::destroyed, this, + &AbstractWindowContext::_q_hitTestVisibleItemDestroyed); + m_hitTestVisibleItems.erase(it); } return true; } @@ -47,8 +58,18 @@ namespace QWK { return false; } - if (m_systemButtons[button] == obj) { - return false; + auto org = m_systemButtons[button]; + if (org == obj) { + return true; + } + + if (org) { + disconnect(org, &QObject::destroyed, this, + &AbstractWindowContext::_q_systemButtonDestroyed); + } + if (obj) { + connect(obj, &QObject::destroyed, this, + &AbstractWindowContext::_q_systemButtonDestroyed); } m_systemButtons[button] = obj; return true; @@ -56,18 +77,20 @@ namespace QWK { bool AbstractWindowContext::setTitleBar(QObject *item) { Q_ASSERT(item); - if (m_titleBar == item) { + auto org = m_titleBar; + if (org == item) { return false; } - if (m_titleBar) { + if (org) { // Since the title bar is changed, all items inside it should be dereferenced right away - for (auto &button : m_systemButtons) { - button = nullptr; - } - m_hitTestVisibleItems.clear(); + removeSystemButtonsAndHitTestItems(); + disconnect(org, &QObject::destroyed, this, + &AbstractWindowContext::_q_titleBarDistroyed); + } + if (item) { + connect(item, &QObject::destroyed, this, &AbstractWindowContext::_q_titleBarDistroyed); } - m_titleBar = item; return true; } @@ -278,4 +301,35 @@ namespace QWK { return false; } + void AbstractWindowContext::removeSystemButtonsAndHitTestItems() { + for (auto &button : m_systemButtons) { + disconnect(button, &QObject::destroyed, this, + &AbstractWindowContext::_q_systemButtonDestroyed); + button = nullptr; + } + for (auto &item : m_hitTestVisibleItems) { + disconnect(item, &QObject::destroyed, this, + &AbstractWindowContext::_q_hitTestVisibleItemDestroyed); + } + m_hitTestVisibleItems.clear(); + } + + void AbstractWindowContext::_q_titleBarDistroyed(QObject *obj) { + Q_UNUSED(obj) + removeSystemButtonsAndHitTestItems(); + m_titleBar = nullptr; + } + + void AbstractWindowContext::_q_hitTestVisibleItemDestroyed(QObject *obj) { + m_hitTestVisibleItems.remove(obj); + } + + void AbstractWindowContext::_q_systemButtonDestroyed(QObject *obj) { + for (auto &item : m_systemButtons) { + if (item == obj) { + item = nullptr; + } + } + } + } diff --git a/src/core/contexts/abstractwindowcontext_p.h b/src/core/contexts/abstractwindowcontext_p.h index e2b8f4b..062494d 100644 --- a/src/core/contexts/abstractwindowcontext_p.h +++ b/src/core/contexts/abstractwindowcontext_p.h @@ -47,7 +47,7 @@ namespace QWK { inline WindowItemDelegate *delegate() const; inline bool isHitTestVisible(const QObject *obj) const; - bool setHitTestVisible(const QObject *obj, bool visible); + bool setHitTestVisible(QObject *obj, bool visible); inline QObject *systemButton(WindowAgentBase::SystemButton button) const; bool setSystemButton(WindowAgentBase::SystemButton button, QObject *obj); @@ -124,6 +124,13 @@ namespace QWK { QVariantHash m_windowAttributes; std::unique_ptr m_winIdChangeEventFilter; + + void removeSystemButtonsAndHitTestItems(); + + private: + void _q_titleBarDistroyed(QObject *obj); + void _q_hitTestVisibleItemDestroyed(QObject *obj); + void _q_systemButtonDestroyed(QObject *obj); }; inline QObject *AbstractWindowContext::host() const { diff --git a/src/quick/quickwindowagent.cpp b/src/quick/quickwindowagent.cpp index a9bfd84..5225a09 100644 --- a/src/quick/quickwindowagent.cpp +++ b/src/quick/quickwindowagent.cpp @@ -90,11 +90,8 @@ namespace QWK { Q_D(const QuickWindowAgent); return d->context->isHitTestVisible(item); } -#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) + void QuickWindowAgent::setHitTestVisible(QQuickItem *item, bool visible) { -#else - void QuickWindowAgent::setHitTestVisible(const QQuickItem *item, bool visible) { -#endif Q_D(QuickWindowAgent); d->context->setHitTestVisible(item, visible); } diff --git a/src/quick/quickwindowagent.h b/src/quick/quickwindowagent.h index de52d49..e4290e6 100644 --- a/src/quick/quickwindowagent.h +++ b/src/quick/quickwindowagent.h @@ -33,11 +33,10 @@ namespace QWK { #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) Q_INVOKABLE bool isHitTestVisible(QQuickItem *item) const; - Q_INVOKABLE void setHitTestVisible(QQuickItem *item, bool visible = true); #else Q_INVOKABLE bool isHitTestVisible(const QQuickItem *item) const; - Q_INVOKABLE void setHitTestVisible(const QQuickItem *item, bool visible = true); #endif + Q_INVOKABLE void setHitTestVisible(QQuickItem *item, bool visible = true); #ifdef Q_OS_MAC // The system button area APIs are experimental, very likely to change in the future. diff --git a/src/widgets/widgetwindowagent.cpp b/src/widgets/widgetwindowagent.cpp index 991c28f..aa48f79 100644 --- a/src/widgets/widgetwindowagent.cpp +++ b/src/widgets/widgetwindowagent.cpp @@ -123,7 +123,7 @@ namespace QWK { You're supposed to make sure that the specified widget \a w is a child or descendant of the title bar widget. */ - void WidgetWindowAgent::setHitTestVisible(const QWidget *w, bool visible) { + void WidgetWindowAgent::setHitTestVisible(QWidget *w, bool visible) { Q_D(WidgetWindowAgent); d->context->setHitTestVisible(w, visible); } diff --git a/src/widgets/widgetwindowagent.h b/src/widgets/widgetwindowagent.h index 0b1c0e9..4a0f9c8 100644 --- a/src/widgets/widgetwindowagent.h +++ b/src/widgets/widgetwindowagent.h @@ -40,7 +40,7 @@ namespace QWK { #endif bool isHitTestVisible(const QWidget *w) const; - void setHitTestVisible(const QWidget *w, bool visible = true); + void setHitTestVisible(QWidget *w, bool visible = true); Q_SIGNALS: void titleBarChanged(QWidget *w);