From 3e942c3dc8955be577079fbc028ce216e1c594b2 Mon Sep 17 00:00:00 2001
From: SineStriker <55847490+SineStriker@users.noreply.github.com>
Date: 周二, 11 2月 2025 19:07:53 +0800
Subject: [PATCH] Fix numerous bugs (#162)

---
 examples/shared/widgetframe/windowbar_p.h         |    5 
 examples/qml/main.qml                             |   12 -
 src/core/contexts/abstractwindowcontext_p.h       |   14 +
 src/quick/quickwindowagent_win.cpp                |   83 ++++++++--
 examples/mainwindow/light-style.qss               |   20 +
 examples/shared/resources/shared.qrc              |    2 
 src/core/contexts/win32windowcontext.cpp          |   90 ++++++++---
 src/core/qwindowkit_windows.h                     |    6 
 src/core/qwindowkit_windows.cpp                   |    8 
 examples/shared/resources/window-bar/pin-fill.svg |    9 +
 LICENSE                                           |    2 
 examples/mainwindow/mainwindow.cpp                |   54 ++++--
 src/quick/quickwindowagent.cpp                    |    9 
 examples/shared/widgetframe/windowbar.cpp         |   38 ++++
 src/core/contexts/abstractwindowcontext.cpp       |   33 ++-
 examples/mainwindow/CMakeLists.txt                |    4 
 examples/shared/widgetframe/windowbar.h           |    4 
 src/core/shared/qwkwindowsextra_p.h               |    1 
 src/core/shared/windows10borderhandler_p.h        |   16 +
 examples/shared/resources/window-bar/pin.svg      |    9 +
 README.md                                         |    2 
 examples/qml/CMakeLists.txt                       |    4 
 src/core/kernel/sharedeventfilter_p.h             |    2 
 src/widgets/widgetwindowagent.cpp                 |   13 
 examples/qml/QWKButton.qml                        |    2 
 src/core/kernel/nativeeventfilter_p.h             |    2 
 src/CMakeLists.txt                                |    4 
 examples/mainwindow/dark-style.qss                |   12 +
 28 files changed, 323 insertions(+), 137 deletions(-)

diff --git a/LICENSE b/LICENSE
index 36395aa..d6629a9 100644
--- a/LICENSE
+++ b/LICENSE
@@ -186,7 +186,7 @@
       same "printed page" as the copyright notice for easier
       identification within third-party archives.
 
-   Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware)
+   Copyright (C) 2023-2025 Stdware Collections (https://www.github.com/stdware)
    Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao)
 
    Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/README.md b/README.md
index c2e1f9d..6c51124 100644
--- a/README.md
+++ b/README.md
@@ -12,9 +12,7 @@
 You can share your findings, thoughts and ideas on improving / implementing QWindowKit functionalities on more platforms and apps!
 
 - Chat with us on [Discord](https://discord.gg/grrM4Tmesy)
-  - Please inform us if your product uses QWK, we would like to show it on this README!
 - 涓枃鐢ㄦ埛鍙姞鍏� QQ 缇� 876419693
-  - 濡傛灉鎮ㄧ殑浜у搧浣跨敤浜哘WK锛岃鍛婄煡鎴戜滑銆傛垜浠笇鏈涘湪杩欎釜鑷堪鏂囦欢涓婂睍绀哄畠锛�
 
 ## Supported Platforms
 
diff --git a/examples/mainwindow/CMakeLists.txt b/examples/mainwindow/CMakeLists.txt
index 6196bec..24d2eab 100644
--- a/examples/mainwindow/CMakeLists.txt
+++ b/examples/mainwindow/CMakeLists.txt
@@ -11,6 +11,4 @@
 set_target_properties(${PROJECT_NAME} PROPERTIES
     CXX_STANDARD 17
     CXX_STANDARD_REQUIRED TRUE
-    WIN32_EXECUTABLE TRUE
-    MACOSX_BUNDLE TRUE
-)
+)
\ No newline at end of file
diff --git a/examples/mainwindow/dark-style.qss b/examples/mainwindow/dark-style.qss
index 09f32ab..33ac251 100644
--- a/examples/mainwindow/dark-style.qss
+++ b/examples/mainwindow/dark-style.qss
@@ -32,9 +32,19 @@
     background-color: transparent;
 }
 
+QWK--WindowBar>QAbstractButton#pin-button {
+    qproperty-iconNormal: url(":/window-bar/pin.svg");
+    qproperty-iconChecked: url(":/window-bar/pin-fill.svg");
+    qproperty-iconSize: 15px 15px;
+}
+
+QWK--WindowBar>QAbstractButton#pin-button:hover,
+QWK--WindowBar>QAbstractButton#pin-button:pressed {
+    background-color: rgba(255, 255, 255, 15%);
+}
+
 QWK--WindowBar>QAbstractButton#min-button {
     qproperty-iconNormal: url(":/window-bar/minimize.svg");
-    qproperty-iconSize: 12px 12px;
 }
 
 QWK--WindowBar>QAbstractButton#min-button:hover,
diff --git a/examples/mainwindow/light-style.qss b/examples/mainwindow/light-style.qss
index 9180001..1f7b4c9 100644
--- a/examples/mainwindow/light-style.qss
+++ b/examples/mainwindow/light-style.qss
@@ -1,13 +1,13 @@
 /* Window bar */
 
 QWK--WindowBar[bar-active=true] {
-    /*background-color: #195ABE;*/
-    background-color: transparent;
+    background-color: #195ABE;
+    /* background-color: transparent; */
 }
 
 QWK--WindowBar[bar-active=false] {
-    /*background-color: #195ABE;*/
-    background-color: transparent;
+    background-color: #195ABE;
+    /* background-color: transparent; */
 }
 
 
@@ -32,9 +32,19 @@
     background-color: transparent;
 }
 
+QWK--WindowBar>QAbstractButton#pin-button {
+    qproperty-iconNormal: url(":/window-bar/pin.svg");
+    qproperty-iconChecked: url(":/window-bar/pin-fill.svg");
+    qproperty-iconSize: 15px 15px;
+}
+
+QWK--WindowBar>QAbstractButton#pin-button:hover,
+QWK--WindowBar>QAbstractButton#pin-button:pressed {
+    background-color: rgba(0, 0, 0, 15%);
+}
+
 QWK--WindowBar>QAbstractButton#min-button {
     qproperty-iconNormal: url(":/window-bar/minimize.svg");
-    qproperty-iconSize: 12px 12px;
 }
 
 QWK--WindowBar>QAbstractButton#min-button:hover,
diff --git a/examples/mainwindow/mainwindow.cpp b/examples/mainwindow/mainwindow.cpp
index 7492b43..a8d2c61 100644
--- a/examples/mainwindow/mainwindow.cpp
+++ b/examples/mainwindow/mainwindow.cpp
@@ -188,24 +188,26 @@
         winStyleGroup->addAction(acrylicAction);
         winStyleGroup->addAction(micaAction);
         winStyleGroup->addAction(micaAltAction);
-        connect(winStyleGroup, &QActionGroup::triggered, this, [this, winStyleGroup](QAction *action) {
-            // Unset all custom style attributes first, otherwise the style will not display correctly
-            for (const QAction* _act : winStyleGroup->actions()) {
-                const QString data = _act->data().toString();
-                if (data.isEmpty() || data == QStringLiteral("none")) {
-                    continue;
-                }
-                windowAgent->setWindowAttribute(data, false);
-            }
-            const QString data = action->data().toString();
-            if (data == QStringLiteral("none")) {
-                setProperty("custom-style", false);
-            } else if (!data.isEmpty()) {
-                windowAgent->setWindowAttribute(data, true);
-                setProperty("custom-style", true);
-            }
-            style()->polish(this);
-        });
+        connect(winStyleGroup, &QActionGroup::triggered, this,
+                [this, winStyleGroup](QAction *action) {
+                    // Unset all custom style attributes first, otherwise the style will not display
+                    // correctly
+                    for (const QAction *_act : winStyleGroup->actions()) {
+                        const QString data = _act->data().toString();
+                        if (data.isEmpty() || data == QStringLiteral("none")) {
+                            continue;
+                        }
+                        windowAgent->setWindowAttribute(data, false);
+                    }
+                    const QString data = action->data().toString();
+                    if (data == QStringLiteral("none")) {
+                        setProperty("custom-style", false);
+                    } else if (!data.isEmpty()) {
+                        windowAgent->setWindowAttribute(data, true);
+                        setProperty("custom-style", true);
+                    }
+                    style()->polish(this);
+                });
 
 #elif defined(Q_OS_MAC)
         auto darkBlurAction = new QAction(tr("Dark blur"), menuBar);
@@ -283,6 +285,12 @@
     iconButton->setObjectName(QStringLiteral("icon-button"));
     iconButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
 
+    auto pinButton = new QWK::WindowButton();
+    pinButton->setCheckable(true);
+    pinButton->setObjectName(QStringLiteral("pin-button"));
+    pinButton->setProperty("system-button", true);
+    pinButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+
     auto minButton = new QWK::WindowButton();
     minButton->setObjectName(QStringLiteral("min-button"));
     minButton->setProperty("system-button", true);
@@ -303,6 +311,7 @@
     auto windowBar = new QWK::WindowBar();
 #ifndef Q_OS_MAC
     windowBar->setIconButton(iconButton);
+    windowBar->setPinButton(pinButton);
     windowBar->setMinButton(minButton);
     windowBar->setMaxButton(maxButton);
     windowBar->setCloseButton(closeButton);
@@ -313,6 +322,7 @@
 
     windowAgent->setTitleBar(windowBar);
 #ifndef Q_OS_MAC
+    windowAgent->setHitTestVisible(pinButton, true);
     windowAgent->setSystemButton(QWK::WindowAgentBase::WindowIcon, iconButton);
     windowAgent->setSystemButton(QWK::WindowAgentBase::Minimize, minButton);
     windowAgent->setSystemButton(QWK::WindowAgentBase::Maximize, maxButton);
@@ -331,6 +341,14 @@
 
 
 #ifndef Q_OS_MAC
+    connect(windowBar, &QWK::WindowBar::pinRequested, this, [this, pinButton](bool pin){
+        if (isHidden() || isMinimized() || isMaximized() || isFullScreen()) {
+            return;
+        }
+        setWindowFlag(Qt::WindowStaysOnTopHint, pin);
+        show();
+        pinButton->setChecked(pin);
+    });
     connect(windowBar, &QWK::WindowBar::minimizeRequested, this, &QWidget::showMinimized);
     connect(windowBar, &QWK::WindowBar::maximizeRequested, this, [this, maxButton](bool max) {
         if (max) {
diff --git a/examples/qml/CMakeLists.txt b/examples/qml/CMakeLists.txt
index fe1cbbf..1755395 100644
--- a/examples/qml/CMakeLists.txt
+++ b/examples/qml/CMakeLists.txt
@@ -11,6 +11,4 @@
 set_target_properties(${PROJECT_NAME} PROPERTIES
     CXX_STANDARD 17
     CXX_STANDARD_REQUIRED TRUE
-    WIN32_EXECUTABLE TRUE
-    MACOSX_BUNDLE TRUE
-)
+)
\ No newline at end of file
diff --git a/examples/qml/QWKButton.qml b/examples/qml/QWKButton.qml
index 8bf58a2..e781d69 100644
--- a/examples/qml/QWKButton.qml
+++ b/examples/qml/QWKButton.qml
@@ -1,5 +1,5 @@
 import QtQuick 2.15
-import QtQuick.Controls.Basic 2.15
+import QtQuick.Controls 2.15
 
 Button {
     id: root
diff --git a/examples/qml/main.qml b/examples/qml/main.qml
index edb563e..dd4f284 100644
--- a/examples/qml/main.qml
+++ b/examples/qml/main.qml
@@ -1,6 +1,6 @@
 import QtQuick 2.15
 import QtQuick.Window 2.15
-import QtQuick.Controls.Basic 2.15
+import QtQuick.Controls 2.15
 import Qt.labs.platform 1.1
 import QWindowKit 1.0
 
@@ -12,8 +12,8 @@
     title: qsTr("Hello, world!")
     Component.onCompleted: {
         windowAgent.setup(window)
+        windowAgent.setWindowAttribute("dark-mode", true)
         window.visible = true
-        delayInitTimer.start()
     }
 
     QtObject {
@@ -30,14 +30,6 @@
         running: true
         repeat: true
         onTriggered: timeLabel.text = Qt.formatTime(new Date(), "hh:mm:ss")
-    }
-
-    Timer {
-        id: delayInitTimer
-        interval: 100
-        running: false
-        repeat: false
-        onTriggered: windowAgent.setWindowAttribute("dark-mode", true)
     }
 
     WindowAgent {
diff --git a/examples/shared/resources/shared.qrc b/examples/shared/resources/shared.qrc
index 5aec715..46efc75 100644
--- a/examples/shared/resources/shared.qrc
+++ b/examples/shared/resources/shared.qrc
@@ -6,6 +6,8 @@
         <file>window-bar/minimize.svg</file>
         <file>window-bar/restore.svg</file>
         <file>window-bar/more-line.svg</file>
+        <file>window-bar/pin.svg</file>
+        <file>window-bar/pin-fill.svg</file>
         <file>app/example.png</file>
     </qresource>
 </RCC>
diff --git a/examples/shared/resources/window-bar/pin-fill.svg b/examples/shared/resources/window-bar/pin-fill.svg
new file mode 100644
index 0000000..6be8c4d
--- /dev/null
+++ b/examples/shared/resources/window-bar/pin-fill.svg
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg t="1735286082742" class="icon" viewBox="0 0 1024 1024" version="1.1"
+    xmlns="http://www.w3.org/2000/svg" p-id="2501" width="512" height="512"
+    xmlns:xlink="http://www.w3.org/1999/xlink">
+    <path
+        d="M648.728381 130.779429a73.142857 73.142857 0 0 1 22.674286 15.433142l191.561143 191.756191a73.142857 73.142857 0 0 1-22.137905 118.564571l-67.876572 30.061715-127.341714 127.488-10.093714 140.239238a73.142857 73.142857 0 0 1-124.684191 46.445714l-123.66019-123.782095-210.724572 211.699809-51.833904-51.614476 210.846476-211.821714-127.926857-128.024381a73.142857 73.142857 0 0 1 46.299428-124.635429l144.237715-10.776381 125.074285-125.220571 29.379048-67.779048a73.142857 73.142857 0 0 1 96.207238-38.034285z"
+        p-id="2502" fill="white"></path>
+</svg>
\ No newline at end of file
diff --git a/examples/shared/resources/window-bar/pin.svg b/examples/shared/resources/window-bar/pin.svg
new file mode 100644
index 0000000..3c5d0bf
--- /dev/null
+++ b/examples/shared/resources/window-bar/pin.svg
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg t="1735285955420" class="icon" viewBox="0 0 1024 1024" version="1.1"
+    xmlns="http://www.w3.org/2000/svg" p-id="2053" width="512" height="512"
+    xmlns:xlink="http://www.w3.org/1999/xlink">
+    <path
+        d="M648.728381 130.779429a73.142857 73.142857 0 0 1 22.674286 15.433142l191.561143 191.756191a73.142857 73.142857 0 0 1-22.137905 118.564571l-67.876572 30.061715-127.341714 127.488-10.093714 140.239238a73.142857 73.142857 0 0 1-124.684191 46.445714l-123.66019-123.782095-210.724572 211.699809-51.833904-51.614476 210.846476-211.821714-127.926857-128.024381a73.142857 73.142857 0 0 1 46.299428-124.635429l144.237715-10.776381 125.074285-125.220571 29.379048-67.779048a73.142857 73.142857 0 0 1 96.207238-38.034285z m-29.086476 67.120761l-34.913524 80.530286-154.087619 154.331429-171.398095 12.751238 303.323428 303.542857 12.044191-167.399619 156.233143-156.428191 80.384-35.59619-191.585524-191.73181z"
+        p-id="2054" fill="white"></path>
+</svg>
\ No newline at end of file
diff --git a/examples/shared/widgetframe/windowbar.cpp b/examples/shared/widgetframe/windowbar.cpp
index 362383f..38a398e 100644
--- a/examples/shared/widgetframe/windowbar.cpp
+++ b/examples/shared/widgetframe/windowbar.cpp
@@ -79,14 +79,19 @@
         return static_cast<QAbstractButton *>(d->widgetAt(WindowBarPrivate::IconButton));
     }
 
+    QAbstractButton *WindowBar::pinButton() const {
+        Q_D(const WindowBar);
+        return static_cast<QAbstractButton *>(d->widgetAt(WindowBarPrivate::PinButton));
+    }
+
     QAbstractButton *WindowBar::minButton() const {
         Q_D(const WindowBar);
-        return static_cast<QAbstractButton *>(d->widgetAt(WindowBarPrivate::MinimumButton));
+        return static_cast<QAbstractButton *>(d->widgetAt(WindowBarPrivate::MinimizeButton));
     }
 
     QAbstractButton *WindowBar::maxButton() const {
         Q_D(const WindowBar);
-        return static_cast<QAbstractButton *>(d->widgetAt(WindowBarPrivate::MaximumButton));
+        return static_cast<QAbstractButton *>(d->widgetAt(WindowBarPrivate::MaximizeButton));
     }
 
     QAbstractButton *WindowBar::closeButton() const {
@@ -131,6 +136,17 @@
         btn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
     }
 
+    void WindowBar::setPinButton(QAbstractButton *btn) {
+        Q_D(WindowBar);
+        auto org = takePinButton();
+        if (org)
+            org->deleteLater();
+        if (!btn)
+            return;
+        d->setWidgetAt(WindowBarPrivate::PinButton, btn);
+        connect(btn, &QAbstractButton::clicked, this, &WindowBar::pinRequested);
+    }
+
     void WindowBar::setMinButton(QAbstractButton *btn) {
         Q_D(WindowBar);
         auto org = takeMinButton();
@@ -138,7 +154,7 @@
             org->deleteLater();
         if (!btn)
             return;
-        d->setWidgetAt(WindowBarPrivate::MinimumButton, btn);
+        d->setWidgetAt(WindowBarPrivate::MinimizeButton, btn);
         connect(btn, &QAbstractButton::clicked, this, &WindowBar::minimizeRequested);
     }
 
@@ -149,7 +165,7 @@
             org->deleteLater();
         if (!btn)
             return;
-        d->setWidgetAt(WindowBarPrivate::MaximumButton, btn);
+        d->setWidgetAt(WindowBarPrivate::MaximizeButton, btn);
         connect(btn, &QAbstractButton::clicked, this, &WindowBar::maximizeRequested);
     }
 
@@ -179,9 +195,19 @@
         return static_cast<QAbstractButton *>(d->takeWidgetAt(WindowBarPrivate::IconButton));
     }
 
+    QAbstractButton *WindowBar::takePinButton() {
+        Q_D(WindowBar);
+        auto btn = static_cast<QAbstractButton *>(d->takeWidgetAt(WindowBarPrivate::PinButton));
+        if (!btn) {
+            return nullptr;
+        }
+        disconnect(btn, &QAbstractButton::clicked, this, &WindowBar::pinRequested);
+        return btn;
+    }
+
     QAbstractButton *WindowBar::takeMinButton() {
         Q_D(WindowBar);
-        auto btn = static_cast<QAbstractButton *>(d->takeWidgetAt(WindowBarPrivate::MinimumButton));
+        auto btn = static_cast<QAbstractButton *>(d->takeWidgetAt(WindowBarPrivate::MinimizeButton));
         if (!btn) {
             return nullptr;
         }
@@ -191,7 +217,7 @@
 
     QAbstractButton *WindowBar::takeMaxButton() {
         Q_D(WindowBar);
-        auto btn = static_cast<QAbstractButton *>(d->takeWidgetAt(WindowBarPrivate::MaximumButton));
+        auto btn = static_cast<QAbstractButton *>(d->takeWidgetAt(WindowBarPrivate::MaximizeButton));
         if (!btn) {
             return nullptr;
         }
diff --git a/examples/shared/widgetframe/windowbar.h b/examples/shared/widgetframe/windowbar.h
index 2e802f2..e9cf04c 100644
--- a/examples/shared/widgetframe/windowbar.h
+++ b/examples/shared/widgetframe/windowbar.h
@@ -25,6 +25,7 @@
         QMenuBar *menuBar() const;
         QLabel *titleLabel() const;
         QAbstractButton *iconButton() const;
+        QAbstractButton *pinButton() const;
         QAbstractButton *minButton() const;
         QAbstractButton *maxButton() const;
         QAbstractButton *closeButton() const;
@@ -32,6 +33,7 @@
         void setMenuBar(QMenuBar *menuBar);
         void setTitleLabel(QLabel *label);
         void setIconButton(QAbstractButton *btn);
+        void setPinButton(QAbstractButton *btn);
         void setMinButton(QAbstractButton *btn);
         void setMaxButton(QAbstractButton *btn);
         void setCloseButton(QAbstractButton *btn);
@@ -39,6 +41,7 @@
         QMenuBar *takeMenuBar();
         QLabel *takeTitleLabel();
         QAbstractButton *takeIconButton();
+        QAbstractButton *takePinButton();
         QAbstractButton *takeMinButton();
         QAbstractButton *takeMaxButton();
         QAbstractButton *takeCloseButton();
@@ -53,6 +56,7 @@
         void setIconFollowWindow(bool value);
 
     Q_SIGNALS:
+        void pinRequested(bool pin = false);
         void minimizeRequested();
         void maximizeRequested(bool max = false);
         void closeRequested();
diff --git a/examples/shared/widgetframe/windowbar_p.h b/examples/shared/widgetframe/windowbar_p.h
index 36ceb17..35422ae 100644
--- a/examples/shared/widgetframe/windowbar_p.h
+++ b/examples/shared/widgetframe/windowbar_p.h
@@ -29,8 +29,9 @@
             IconButton,
             MenuWidget,
             TitleLabel,
-            MinimumButton,
-            MaximumButton,
+            PinButton,
+            MinimizeButton,
+            MaximizeButton,
             CloseButton,
         };
 
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6279fb5..510c161 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,7 +1,9 @@
 qm_import(Preprocess)
 
+string(TIMESTAMP _current_year "%Y")
+
 set(QWINDOWKIT_PROJECT_DESCRIPTION "Cross-platform window customization framework")
-set(QWINDOWKIT_PROJECT_COPYRIGHT "Copyright 2023 Stdware Collections")
+set(QWINDOWKIT_PROJECT_COPYRIGHT "Copyright 2023-${_current_year} Stdware Collections")
 set(QWINDOWKIT_GENERATED_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/../include)
 set(QWINDOWKIT_BUILD_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/../etc/include)
 
diff --git a/src/core/contexts/abstractwindowcontext.cpp b/src/core/contexts/abstractwindowcontext.cpp
index f838064..f3a9c7f 100644
--- a/src/core/contexts/abstractwindowcontext.cpp
+++ b/src/core/contexts/abstractwindowcontext.cpp
@@ -240,13 +240,13 @@
             m_windowHandle->installEventFilter(this);
 
             // Refresh window attributes
-            auto attributes = m_windowAttributes;
-            m_windowAttributes.clear();
-            for (auto it = attributes.begin(); it != attributes.end(); ++it) {
-                if (!windowAttributeChanged(it.key(), it.value(), {})) {
+            for (auto it = m_windowAttributesOrder.begin(); it != m_windowAttributesOrder.end();) {
+                if (!windowAttributeChanged(it->first, it->second, {})) {
+                    m_windowAttributes.remove(it->first);
+                    it = m_windowAttributesOrder.erase(it);
                     continue;
                 }
-                m_windowAttributes.insert(it.key(), it.value());
+                ++it;
             }
         }
 
@@ -258,7 +258,11 @@
     }
 
     QVariant AbstractWindowContext::windowAttribute(const QString &key) const {
-        return m_windowAttributes.value(key);
+        auto it = m_windowAttributes.find(key);
+        if (it == m_windowAttributes.end()) {
+            return {};
+        }
+        return it.value()->second;
     }
 
     bool AbstractWindowContext::setWindowAttribute(const QString &key, const QVariant &attribute) {
@@ -267,22 +271,27 @@
             if (!attribute.isValid()) {
                 return true;
             }
-            if (!m_windowHandle || !windowAttributeChanged(key, attribute, {})) {
+            if (m_windowHandle && !windowAttributeChanged(key, attribute, {})) {
                 return false;
             }
-            m_windowAttributes.insert(key, attribute);
+            m_windowAttributes.insert(key,
+                                      m_windowAttributesOrder.insert(m_windowAttributesOrder.end(),
+                                      std::make_pair(key, attribute)));
             return true;
         }
 
-        if (it.value() == attribute)
-            return true;
-        if (!m_windowHandle || !windowAttributeChanged(key, attribute, it.value())) {
+        auto &listIter = it.value();
+        auto &oldAttr = listIter->second;
+        if (m_windowHandle && !windowAttributeChanged(key, attribute, oldAttr)) {
             return false;
         }
 
         if (attribute.isValid()) {
-            it.value() = attribute;
+            oldAttr = attribute;
+            m_windowAttributesOrder.splice(m_windowAttributesOrder.end(), m_windowAttributesOrder,
+                                           listIter);
         } else {
+            m_windowAttributesOrder.erase(listIter);
             m_windowAttributes.erase(it);
         }
         return true;
diff --git a/src/core/contexts/abstractwindowcontext_p.h b/src/core/contexts/abstractwindowcontext_p.h
index 062494d..e978cb4 100644
--- a/src/core/contexts/abstractwindowcontext_p.h
+++ b/src/core/contexts/abstractwindowcontext_p.h
@@ -15,7 +15,9 @@
 //
 
 #include <array>
+#include <list>
 #include <memory>
+#include <utility>
 
 #include <QtCore/QSet>
 #include <QtCore/QPointer>
@@ -88,9 +90,9 @@
             RaiseWindowHook,
             ShowSystemMenuHook,
             DefaultColorsHook,
-            DrawWindows10BorderHook,     // Only works on Windows 10, emulated workaround
-            DrawWindows10BorderHook2,    // Only works on Windows 10, native workaround
-            SystemButtonAreaChangedHook, // Only works on Mac
+            DrawWindows10BorderHook_Emulated, // Only works on Windows 10, emulated workaround
+            DrawWindows10BorderHook_Native,   // Only works on Windows 10, native workaround
+            SystemButtonAreaChangedHook,      // Only works on Mac
         };
         virtual void virtual_hook(int id, void *data);
 
@@ -122,9 +124,11 @@
         QObject *m_titleBar{};
         std::array<QObject *, WindowAgentBase::Close + 1> m_systemButtons{};
 
-        QVariantHash m_windowAttributes;
+        std::list<std::pair<QString, QVariant>> m_windowAttributesOrder;
+        QHash<QString, decltype(m_windowAttributesOrder)::iterator> m_windowAttributes;
+
         std::unique_ptr<WinIdChangeEventFilter> m_winIdChangeEventFilter;
-        
+
         void removeSystemButtonsAndHitTestItems();
 
     private:
diff --git a/src/core/contexts/win32windowcontext.cpp b/src/core/contexts/win32windowcontext.cpp
index 775f2ca..3360b9d 100644
--- a/src/core/contexts/win32windowcontext.cpp
+++ b/src/core/contexts/win32windowcontext.cpp
@@ -86,7 +86,10 @@
     static void setInternalWindowFrameMargins(QWindow *window, const QMargins &margins) {
         const QVariant marginsVar = QVariant::fromValue(margins);
 
-        // TODO: Add comments
+        // We need to tell Qt we have set a custom margin, because we are hiding
+        // the title bar by pretending the whole window is filled by client area,
+        // this however confuses Qt's internal logic. We need to do the following
+        // hack to let Qt consider the extra margin when changing window geometry.
         window->setProperty("_q_windowsCustomMargins", marginsVar);
 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
         if (QPlatformWindow *platformWindow = window->handle()) {
@@ -197,8 +200,8 @@
 
         [[maybe_unused]] const auto &cleaner =
             qScopeGuard([windowThreadProcessId, currentThreadId]() {
-                ::AttachThreadInput(windowThreadProcessId, currentThreadId, FALSE); //
-            }); // TODO: Remove it
+                ::AttachThreadInput(windowThreadProcessId, currentThreadId, FALSE);
+            });
 
         ::BringWindowToTop(hwnd);
         // Activate the window too. This will force us to the virtual desktop this
@@ -219,12 +222,20 @@
             return true;
         }
 
+        const auto windowStyles = ::GetWindowLongPtrW(hWnd, GWL_STYLE);
+        const bool allowMaximize = windowStyles & WS_MAXIMIZEBOX;
+        const bool allowMinimize = windowStyles & WS_MINIMIZEBOX;
+
         const bool maxOrFull = isMaximized(hWnd) || isFullScreen(hWnd);
         ::EnableMenuItem(hMenu, SC_CLOSE, (MF_BYCOMMAND | MFS_ENABLED));
-        ::EnableMenuItem(hMenu, SC_MAXIMIZE,
-                         (MF_BYCOMMAND | ((maxOrFull || fixedSize) ? MFS_DISABLED : MFS_ENABLED)));
-        ::EnableMenuItem(hMenu, SC_RESTORE,
-                         (MF_BYCOMMAND | ((maxOrFull && !fixedSize) ? MFS_ENABLED : MFS_DISABLED)));
+        ::EnableMenuItem(
+            hMenu, SC_MAXIMIZE,
+            (MF_BYCOMMAND |
+             ((maxOrFull || fixedSize || !allowMaximize) ? MFS_DISABLED : MFS_ENABLED)));
+        ::EnableMenuItem(
+            hMenu, SC_RESTORE,
+            (MF_BYCOMMAND |
+             ((maxOrFull && !fixedSize && allowMaximize) ? MFS_ENABLED : MFS_DISABLED)));
         // The first menu item should be selected by default if the menu is brought
         // up by keyboard. I don't know how to pre-select a menu item but it seems
         // highlight can do the job. However, there's an annoying issue if we do
@@ -236,7 +247,8 @@
         // the menu look kind of weird. Currently I don't know how to fix this issue.
         ::HiliteMenuItem(hWnd, hMenu, SC_RESTORE,
                          (MF_BYCOMMAND | (selectFirstEntry ? MFS_HILITE : MFS_UNHILITE)));
-        ::EnableMenuItem(hMenu, SC_MINIMIZE, (MF_BYCOMMAND | MFS_ENABLED));
+        ::EnableMenuItem(hMenu, SC_MINIMIZE,
+                         (MF_BYCOMMAND | (allowMinimize ? MFS_ENABLED : MFS_DISABLED)));
         ::EnableMenuItem(hMenu, SC_SIZE,
                          (MF_BYCOMMAND | ((maxOrFull || fixedSize) ? MFS_DISABLED : MFS_ENABLED)));
         ::EnableMenuItem(hMenu, SC_MOVE, (MF_BYCOMMAND | (maxOrFull ? MFS_DISABLED : MFS_ENABLED)));
@@ -355,8 +367,8 @@
 
     static MSG createMessageBlock(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
         MSG msg;
-        msg.hwnd = hWnd;       // re-create MSG structure
-        msg.message = message; // time and pt fields ignored
+        msg.hwnd = hWnd;
+        msg.message = message;
         msg.wParam = wParam;
         msg.lParam = lParam;
 
@@ -366,6 +378,8 @@
         if (!isNonClientMessage(message)) {
             ::ScreenToClient(hWnd, &msg.pt);
         }
+
+        msg.time = ::GetMessageTime();
         return msg;
     }
 
@@ -400,7 +414,7 @@
     }
 
     // Send to QAbstractEventDispatcher
-    bool filterNativeEvent(MSG *msg, LRESULT *result) {
+    static bool filterNativeEvent(MSG *msg, LRESULT *result) {
         auto dispatcher = QAbstractEventDispatcher::instance();
         QT_NATIVE_EVENT_RESULT_TYPE filterResult = *result;
         if (dispatcher && dispatcher->filterNativeEvent(nativeEventType(), msg, &filterResult)) {
@@ -411,7 +425,7 @@
     }
 
     // Send to QWindowSystemInterface
-    bool filterNativeEvent(QWindow *window, MSG *msg, LRESULT *result) {
+    static bool filterNativeEvent(QWindow *window, MSG *msg, LRESULT *result) {
         QT_NATIVE_EVENT_RESULT_TYPE filterResult = *result;
         if (QWindowSystemInterface::handleNativeEvent(window, nativeEventType(), msg,
                                                       &filterResult)) {
@@ -624,6 +638,11 @@
 
         // Save window handle mapping
         g_wndProcHash->insert(hWnd, ctx);
+
+        // Force a WM_NCCALCSIZE message manually to avoid the title bar become visible
+        // while Qt is re-creating the window (such as setWindowFlag(s) calls). It has
+        // been observed by our users.
+        triggerFrameChange(hWnd);
     }
 
     static inline void removeManagedWindow(HWND hWnd) {
@@ -688,7 +707,7 @@
             }
 
 #if QWINDOWKIT_CONFIG(ENABLE_WINDOWS_SYSTEM_BORDERS)
-            case DrawWindows10BorderHook: {
+            case DrawWindows10BorderHook_Emulated: {
                 if (!m_windowId)
                     return;
 
@@ -731,7 +750,7 @@
                 return;
             }
 
-            case DrawWindows10BorderHook2: {
+            case DrawWindows10BorderHook_Native: {
                 if (!m_windowId)
                     return;
 
@@ -897,7 +916,6 @@
         Q_UNUSED(oldAttribute)
 
         const auto hwnd = reinterpret_cast<HWND>(m_windowId);
-        Q_ASSERT(hwnd);
         if (!hwnd) {
             return false;
         }
@@ -933,8 +951,26 @@
         };
         const auto &restoreMargins = [this, &apis, hwnd]() {
             auto margins = qmargins2margins(
-                m_windowAttributes.value(QStringLiteral("extra-margins")).value<QMargins>());
+                windowAttribute(QStringLiteral("extra-margins")).value<QMargins>());
             apis.pDwmExtendFrameIntoClientArea(hwnd, &margins);
+        };
+
+        const auto &effectBugWorkaround = [this, hwnd]() {
+            // We don't need the following *HACK* for QWidget windows.
+            if (m_host->isWidgetType()) {
+                return;
+            }
+            static QSet<WId> bugWindowSet{};
+            if (bugWindowSet.contains(m_windowId)) {
+                return;
+            }
+            bugWindowSet.insert(m_windowId);
+            RECT rect{};
+            ::GetWindowRect(hwnd, &rect);
+            ::MoveWindow(hwnd, rect.left, rect.top, 1, 1, FALSE);
+            ::MoveWindow(hwnd, rect.right - 1, rect.bottom - 1, 1, 1, FALSE);
+            ::MoveWindow(hwnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
+                         FALSE);
         };
 
         if (key == QStringLiteral("extra-margins")) {
@@ -953,7 +989,8 @@
             } else {
                 apis.pAllowDarkModeForApp(enable);
             }
-            const auto attr = isWin1020H1OrGreater() ? _DWMWA_USE_IMMERSIVE_DARK_MODE : _DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1;
+            const auto attr = isWin1020H1OrGreater() ? _DWMWA_USE_IMMERSIVE_DARK_MODE
+                                                     : _DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1;
             apis.pDwmSetWindowAttribute(hwnd, attr, &enable, sizeof(enable));
 
             apis.pFlushMenuThemes();
@@ -990,6 +1027,7 @@
                 }
                 restoreMargins();
             }
+            effectBugWorkaround();
             return true;
         }
 
@@ -1010,6 +1048,7 @@
                                             sizeof(backdropType));
                 restoreMargins();
             }
+            effectBugWorkaround();
             return true;
         }
 
@@ -1055,6 +1094,7 @@
 
                 restoreMargins();
             }
+            effectBugWorkaround();
             return true;
         }
 
@@ -1094,6 +1134,7 @@
                     apis.pDwmEnableBlurBehindWindow(hwnd, &bb);
                 }
             }
+            effectBugWorkaround();
             return true;
         }
         return false;
@@ -1571,7 +1612,7 @@
                 bool isInTitleBar = isInTitleBarDraggableArea(qtScenePos);
                 WindowAgentBase::SystemButton sysButtonType = WindowAgentBase::Unknown;
                 bool isInCaptionButtons = isInSystemButtons(qtScenePos, &sysButtonType);
-                bool dontOverrideCursor = false; // ### TODO
+                static constexpr bool dontOverrideCursor = false; // ### TODO
 
                 if (isInCaptionButtons) {
                     // Firstly, we set the hit test result to a default value to be able to detect
@@ -2019,20 +2060,21 @@
         // implement an elaborate client-area preservation technique, and
         // simply return 0, which means "preserve the entire old client area
         // and align it with the upper-left corner of our new client area".
+
         const auto clientRect = wParam ? &(reinterpret_cast<LPNCCALCSIZE_PARAMS>(lParam))->rgrc[0]
                                        : reinterpret_cast<LPRECT>(lParam);
-        [[maybe_unused]] const auto& flickerReducer = qScopeGuard([this]() {
+        [[maybe_unused]] const auto &flickerReducer = qScopeGuard([this]() {
             // When we receive this message, it means the window size has changed
             // already, and it seems this message always come before any client
             // area size notifications (eg. WM_WINDOWPOSCHANGED and WM_SIZE). Let
             // D3D/VK paint immediately to let user see the latest result as soon
             // as possible.
-            const auto& isTargetSurface = [](const QSurface::SurfaceType st){
-                return st != QSurface::RasterSurface && st != QSurface::OpenGLSurface
-                       && st != QSurface::RasterGLSurface && st != QSurface::OpenVGSurface;
+            const auto &isTargetSurface = [](const QSurface::SurfaceType st) {
+                return st != QSurface::RasterSurface && st != QSurface::OpenGLSurface &&
+                       st != QSurface::RasterGLSurface && st != QSurface::OpenVGSurface;
             };
-            if (m_windowHandle && isTargetSurface(m_windowHandle->surfaceType())
-                && isDwmCompositionEnabled() && DynamicApis::instance().pDwmFlush) {
+            if (m_windowHandle && isTargetSurface(m_windowHandle->surfaceType()) &&
+                isDwmCompositionEnabled() && DynamicApis::instance().pDwmFlush) {
                 DynamicApis::instance().pDwmFlush();
             }
         });
diff --git a/src/core/kernel/nativeeventfilter_p.h b/src/core/kernel/nativeeventfilter_p.h
index cef78b7..d7d3e3f 100644
--- a/src/core/kernel/nativeeventfilter_p.h
+++ b/src/core/kernel/nativeeventfilter_p.h
@@ -34,7 +34,7 @@
         void removeNativeEventFilter(NativeEventFilter *filter);
 
     protected:
-        QVector<NativeEventFilter *> m_nativeEventFilters;
+        QList<NativeEventFilter *> m_nativeEventFilters;
 
         friend class NativeEventFilter;
 
diff --git a/src/core/kernel/sharedeventfilter_p.h b/src/core/kernel/sharedeventfilter_p.h
index eeaf38f..5c1935b 100644
--- a/src/core/kernel/sharedeventfilter_p.h
+++ b/src/core/kernel/sharedeventfilter_p.h
@@ -33,7 +33,7 @@
         void removeSharedEventFilter(SharedEventFilter *filter);
 
     protected:
-        QVector<SharedEventFilter *> m_sharedEventFilters;
+        QList<SharedEventFilter *> m_sharedEventFilters;
 
         friend class SharedEventFilter;
 
diff --git a/src/core/qwindowkit_windows.cpp b/src/core/qwindowkit_windows.cpp
index 58c3d0f..640528c 100644
--- a/src/core/qwindowkit_windows.cpp
+++ b/src/core/qwindowkit_windows.cpp
@@ -71,21 +71,21 @@
         return result;
     }
 
-    QPair<DWORD, bool> WindowsRegistryKey::dwordValue(QStringView subKey) const {
+    std::pair<DWORD, bool> WindowsRegistryKey::dwordValue(QStringView subKey) const {
         if (!isValid())
-            return qMakePair(0, false);
+            return std::make_pair(0, false);
         DWORD type;
         auto subKeyC = reinterpret_cast<const wchar_t *>(subKey.utf16());
         if (::RegQueryValueExW(m_key, subKeyC, nullptr, &type, nullptr, nullptr) != ERROR_SUCCESS ||
             type != REG_DWORD) {
-            return qMakePair(0, false);
+            return std::make_pair(0, false);
         }
         DWORD value = 0;
         DWORD size = sizeof(value);
         const bool ok =
             ::RegQueryValueExW(m_key, subKeyC, nullptr, nullptr,
                                reinterpret_cast<unsigned char *>(&value), &size) == ERROR_SUCCESS;
-        return qMakePair(value, ok);
+        return std::make_pair(value, ok);
     }
 #endif
 }
\ No newline at end of file
diff --git a/src/core/qwindowkit_windows.h b/src/core/qwindowkit_windows.h
index d6c0afe..7e9b8a7 100644
--- a/src/core/qwindowkit_windows.h
+++ b/src/core/qwindowkit_windows.h
@@ -145,7 +145,7 @@
 
         void close();
         QString stringValue(QStringView subKey) const;
-        QPair<DWORD, bool> dwordValue(QStringView subKey) const;
+        std::pair<DWORD, bool> dwordValue(QStringView subKey) const;
 
     private:
         HKEY m_key;
@@ -166,10 +166,10 @@
             : QWinRegistryKey(parentHandle, subKey, permissions, access) {
         }
 
-        inline QPair<DWORD, bool> dwordValue(QStringView subKey) const;
+        inline std::pair<DWORD, bool> dwordValue(QStringView subKey) const;
     };
 
-    inline QPair<DWORD, bool> WindowsRegistryKey::dwordValue(QStringView subKey) const {
+    inline std::pair<DWORD, bool> WindowsRegistryKey::dwordValue(QStringView subKey) const {
         const auto val = value<DWORD>(subKey);
         if (!val) {
             return {0, false};
diff --git a/src/core/shared/qwkwindowsextra_p.h b/src/core/shared/qwkwindowsextra_p.h
index 65c1faa..8fdc86e 100644
--- a/src/core/shared/qwkwindowsextra_p.h
+++ b/src/core/shared/qwkwindowsextra_p.h
@@ -21,7 +21,6 @@
 #include <QWKCore/qwindowkit_windows.h>
 
 #include <QtCore/QtMath>
-#include <QtCore/QPair>
 #include <QtGui/QGuiApplication>
 #include <QtGui/QStyleHints>
 #include <QtGui/QPalette>
diff --git a/src/core/shared/windows10borderhandler_p.h b/src/core/shared/windows10borderhandler_p.h
index cf530e8..8099fe0 100644
--- a/src/core/shared/windows10borderhandler_p.h
+++ b/src/core/shared/windows10borderhandler_p.h
@@ -46,7 +46,7 @@
         }
 
         inline void drawBorder() {
-            ctx->virtual_hook(AbstractWindowContext::DrawWindows10BorderHook2, nullptr);
+            ctx->virtual_hook(AbstractWindowContext::DrawWindows10BorderHook_Native, nullptr);
         }
 
         inline int borderThickness() const {
@@ -94,6 +94,20 @@
                     break;
                 }
 
+                case WM_THEMECHANGED:
+                case WM_SYSCOLORCHANGE:
+                case WM_DWMCOLORIZATIONCOLORCHANGED: {
+                    // If we do not refresh this property, the native border will turn white
+                    // permanently (like the dark mode is turned off) after the user changes
+                    // the accent color in system personalization settings.
+                    // So we need this ugly hack to re-apply dark mode to get rid of this
+                    // strange Windows bug.
+                    if (ctx->windowAttribute(QStringLiteral("dark-mode")).toBool()) {
+                        ctx->setWindowAttribute(QStringLiteral("dark-mode"), true);
+                    }
+                    break;
+                }
+
                 default:
                     break;
             }
diff --git a/src/quick/quickwindowagent.cpp b/src/quick/quickwindowagent.cpp
index 9270311..aaa321c 100644
--- a/src/quick/quickwindowagent.cpp
+++ b/src/quick/quickwindowagent.cpp
@@ -44,17 +44,14 @@
             return false;
         }
 
+        // Make sure the native window handle is actually created before we apply
+        // various hooks. But we don't need the actual window handle so just ignore it.
+        std::ignore = window->winId();
         d->setup(window, new QuickItemDelegate());
         d->hostWindow = window;
 
 #if defined(Q_OS_WINDOWS) && QWINDOWKIT_CONFIG(ENABLE_WINDOWS_SYSTEM_BORDERS)
         d->setupWindows10BorderWorkaround();
-#endif
-
-#ifdef Q_OS_WINDOWS
-        if (!windowAttribute(QStringLiteral("windows-system-border-enabled")).toBool()) {
-            window->setFlag(Qt::FramelessWindowHint);
-        }
 #endif
         return true;
     }
diff --git a/src/quick/quickwindowagent_win.cpp b/src/quick/quickwindowagent_win.cpp
index a47f4c0..acfdd42 100644
--- a/src/quick/quickwindowagent_win.cpp
+++ b/src/quick/quickwindowagent_win.cpp
@@ -12,6 +12,13 @@
 
 namespace QWK {
 
+    static inline bool isWindows1022H2OrGreater() {
+        RTL_OSVERSIONINFOW rovi = Private::GetRealOSVersion();
+        return (rovi.dwMajorVersion > 10) ||
+               (rovi.dwMajorVersion == 10 &&
+                (rovi.dwMinorVersion > 0 || rovi.dwBuildNumber >= 19045));
+    }
+
 #if QWINDOWKIT_CONFIG(ENABLE_WINDOWS_SYSTEM_BORDERS)
 
     class BorderItem : public QQuickPaintedItem, public Windows10BorderHandler {
@@ -19,6 +26,7 @@
         explicit BorderItem(QQuickItem *parent, AbstractWindowContext *context);
         ~BorderItem() override;
 
+        bool shouldEnableEmulatedPainter() const;
         void updateGeometry() override;
 
     public:
@@ -27,14 +35,34 @@
 
     protected:
         bool sharedEventFilter(QObject *obj, QEvent *event) override;
-
-#  if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
-        volatile bool needPaint = false;
+        bool nativeEventFilter(const QByteArray &eventType, void *message,
+                               QT_NATIVE_EVENT_RESULT_TYPE *result) override;
 
     private:
+        volatile bool needPaint = false;
+
         void _q_afterSynchronizing();
-#  endif
+        void _q_windowActivityChanged();
     };
+
+    bool BorderItem::shouldEnableEmulatedPainter() const {
+#  if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+        auto api = window()->rendererInterface()->graphicsApi();
+        switch (api) {
+            case QSGRendererInterface::OpenGL:
+                // FIXME: experimental, try to find the exact fixed version.
+                return !isWindows1022H2OrGreater();
+            case QSGRendererInterface::Direct3D11:
+#    if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
+            case QSGRendererInterface::Direct3D12:
+#    endif
+                return false;
+            default:
+                break;
+        }
+#  endif
+        return true;
+    }
 
     BorderItem::BorderItem(QQuickItem *parent, AbstractWindowContext *context)
         : QQuickPaintedItem(parent), Windows10BorderHandler(context) {
@@ -56,6 +84,8 @@
         connect(window(), &QQuickWindow::afterSynchronizing, this,
                 &BorderItem::_q_afterSynchronizing, Qt::DirectConnection);
 #  endif
+        connect(window(), &QQuickWindow::activeChanged, this,
+                &BorderItem::_q_windowActivityChanged);
 
         // First update
         if (context->windowId()) {
@@ -73,16 +103,7 @@
 
     void BorderItem::paint(QPainter *painter) {
         Q_UNUSED(painter)
-
-#  if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
-        if (auto api = window()->rendererInterface()->graphicsApi();
-            !(api == QSGRendererInterface::Direct3D11
-
-#    if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
-              || api == QSGRendererInterface::Direct3D12
-#    endif
-              )) {
-#  endif
+        if (shouldEnableEmulatedPainter()) {
             QRect rect(QPoint(0, 0), size().toSize());
             QRegion region(rect);
             void *args[] = {
@@ -90,12 +111,10 @@
                 &rect,
                 &region,
             };
-            ctx->virtual_hook(AbstractWindowContext::DrawWindows10BorderHook, args);
-#  if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+            ctx->virtual_hook(AbstractWindowContext::DrawWindows10BorderHook_Emulated, args);
         } else {
             needPaint = true;
         }
-#  endif
     }
 
     void BorderItem::itemChange(ItemChange change, const ItemChangeData &data) {
@@ -124,14 +143,40 @@
         return Windows10BorderHandler::sharedEventFilter(obj, event);
     }
 
-#  if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+    bool BorderItem::nativeEventFilter(const QByteArray &eventType, void *message,
+                                       QT_NATIVE_EVENT_RESULT_TYPE *result) {
+        const auto msg = static_cast<const MSG *>(message);
+        switch (msg->message) {
+            case WM_THEMECHANGED:
+            case WM_SYSCOLORCHANGE:
+            case WM_DWMCOLORIZATIONCOLORCHANGED: {
+                update();
+                break;
+            }
+
+            case WM_SETTINGCHANGE: {
+                if (isImmersiveColorSetChange(msg->wParam, msg->lParam)) {
+                    update();
+                }
+                break;
+            }
+
+            default:
+                break;
+        }
+        return Windows10BorderHandler::nativeEventFilter(eventType, message, result);
+    }
+
     void BorderItem::_q_afterSynchronizing() {
         if (needPaint) {
             needPaint = false;
             drawBorder();
         }
     }
-#  endif
+
+    void BorderItem::_q_windowActivityChanged() {
+        update();
+    }
 
     void QuickWindowAgentPrivate::setupWindows10BorderWorkaround() {
         // Install painting hook
diff --git a/src/widgets/widgetwindowagent.cpp b/src/widgets/widgetwindowagent.cpp
index ea6b22c..e2a36d1 100644
--- a/src/widgets/widgetwindowagent.cpp
+++ b/src/widgets/widgetwindowagent.cpp
@@ -55,20 +55,19 @@
             return false;
         }
 
+        // Qt will create invisible native window container for native QWidget
+        // without this attribute, and this behavior will break QWK functionality.
+        // So far enabling this attribute is a must for QWK users.
         w->setAttribute(Qt::WA_DontCreateNativeAncestors);
-        w->setAttribute(Qt::WA_NativeWindow); // Create new window id
+        // Make sure the native window handle is actually created before we apply
+        // various hooks.
+        w->setAttribute(Qt::WA_NativeWindow);
 
         d->setup(w, new WidgetItemDelegate());
         d->hostWidget = w;
 
 #if defined(Q_OS_WINDOWS) && QWINDOWKIT_CONFIG(ENABLE_WINDOWS_SYSTEM_BORDERS)
         d->setupWindows10BorderWorkaround();
-#endif
-
-#ifdef Q_OS_WINDOWS
-        if (!windowAttribute(QStringLiteral("windows-system-border-enabled")).toBool()) {
-            w->setWindowFlag(Qt::FramelessWindowHint);
-        }
 #endif
         return true;
     }

--
Gitblit v1.9.1