From ed5f9693b3cd7ddcdc746c4bb65dcd9cf7a8268b Mon Sep 17 00:00:00 2001
From: Sine Striker <trueful@163.com>
Date: 周二, 19 12月 2023 15:09:49 +0800
Subject: [PATCH] Add window attributes

---
 src/core/contexts/abstractwindowcontext.cpp |   15 +++++++
 src/core/contexts/abstractwindowcontext_p.h |   11 +++++
 src/core/windowagentbase.h                  |    5 +-
 src/core/windowagentbase.cpp                |   36 +++++++-----------
 README.md                                   |    7 ++-
 src/core/contexts/win32windowcontext.cpp    |   21 +++++++++-
 6 files changed, 66 insertions(+), 29 deletions(-)

diff --git a/README.md b/README.md
index 5b0f685..c8f6c14 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,6 @@
 + Fix window 10 top border color in dark background
 + Fix `isFixedSize` code
 + Support customized system button area on Mac
-+ Make Linux system move/resize more robust
 
 ## Supported Platforms
 
@@ -95,7 +94,7 @@
 
 MyWidget::MyWidget(QWidget *parent) {
     // ...
-    auto agent = new WidgetWindowAgent(w);
+    auto agent = new QWK::WidgetWindowAgent(w);
     agent->setup(w);
     // ...
 }
@@ -104,10 +103,12 @@
 You can also initialize the agent after the window constructs.
 ```c++
 auto w = new MyWidget();
-auto agent = new WidgetWindowAgent(w);
+auto agent = new QWK::WidgetWindowAgent(w);
 agent->setup(w);
 ```
 
+
+
 Then, construct your title bar widget, without which the window lacks the basic interaction feature, and it's better to put it into the window's layout.
 
 You can use the [`WindowBar`](examples/shared/widgetframe/windowbar.h) provided by `WidgetFrame` in the examples as the container of your title bar components.
diff --git a/src/core/contexts/abstractwindowcontext.cpp b/src/core/contexts/abstractwindowcontext.cpp
index d34a1f9..a62d037 100644
--- a/src/core/contexts/abstractwindowcontext.cpp
+++ b/src/core/contexts/abstractwindowcontext.cpp
@@ -23,6 +23,21 @@
         }
     }
 
+    void AbstractWindowContext::setWindowAttribute(const QString &key, const QVariant &var) {
+        auto it = m_windowAttributes.find(key);
+        if (it.value() == var)
+            return;
+
+        auto newVar = var;
+        auto oldVar = it.value();
+        void *a[] = {
+            &const_cast<QString &>(key),
+            &newVar,
+            &oldVar,
+        };
+        virtual_hook(WindowAttributeChangedHook, a);
+    }
+
     bool AbstractWindowContext::setHitTestVisible(const QObject *obj, bool visible) {
         Q_ASSERT(obj);
         if (!obj) {
diff --git a/src/core/contexts/abstractwindowcontext_p.h b/src/core/contexts/abstractwindowcontext_p.h
index 3938d75..3115141 100644
--- a/src/core/contexts/abstractwindowcontext_p.h
+++ b/src/core/contexts/abstractwindowcontext_p.h
@@ -28,6 +28,9 @@
         inline QWindow *window() const;
         inline WindowItemDelegate *delegate() const;
 
+        inline QVariant windowAttribute(const QString &key) const;
+        void setWindowAttribute(const QString &key, const QVariant &var);
+
         inline bool isHitTestVisible(const QObject *obj) const;
         bool setHitTestVisible(const QObject *obj, bool visible);
 
@@ -49,8 +52,10 @@
 
         enum WindowContextHook {
             CentralizeHook = 1,
+            RaiseWindowHook,
             ShowSystemMenuHook,
             DefaultColorsHook,
+            WindowAttributeChangedHook,
             DrawWindows10BorderHook,     // Only works on Windows 10
             SystemButtonAreaChangedHook, // Only works on Mac
         };
@@ -74,6 +79,8 @@
 
         QObject *m_titleBar{};
         std::array<QObject *, WindowAgentBase::NumSystemButton> m_systemButtons{};
+
+        QVariantHash m_windowAttributes;
     };
 
     inline QObject *AbstractWindowContext::host() const {
@@ -88,6 +95,10 @@
         return m_delegate.get();
     }
 
+    inline QVariant AbstractWindowContext::windowAttribute(const QString &key) const {
+        return m_windowAttributes.value(key);
+    }
+
     inline bool AbstractWindowContext::isHitTestVisible(const QObject *obj) const {
         return m_hitTestVisibleItems.contains(obj);
     }
diff --git a/src/core/contexts/win32windowcontext.cpp b/src/core/contexts/win32windowcontext.cpp
index 2a6ee76..8af6a3f 100644
--- a/src/core/contexts/win32windowcontext.cpp
+++ b/src/core/contexts/win32windowcontext.cpp
@@ -117,7 +117,7 @@
     private:
         DynamicApis() {
 #define DYNAMIC_API_RESOLVE(DLL, NAME)                                                             \
-  p##NAME = reinterpret_cast<decltype(p##NAME)>(DLL.resolve(#NAME))
+    p##NAME = reinterpret_cast<decltype(p##NAME)>(DLL.resolve(#NAME))
 
             QSystemLibrary user32(QStringLiteral("user32"));
             DYNAMIC_API_RESOLVE(user32, GetDpiForWindow);
@@ -332,7 +332,7 @@
 
     static inline quint32 getDpiForWindow(HWND hwnd) {
         const DynamicApis &apis = DynamicApis::instance();
-        if (apis.pGetDpiForWindow) { // Win10
+        if (apis.pGetDpiForWindow) {         // Win10
             return apis.pGetDpiForWindow(hwnd);
         } else if (apis.pGetDpiForMonitor) { // Win8.1
             HMONITOR monitor = ::MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
@@ -826,6 +826,23 @@
                 return;
             }
 
+            case WindowAttributeChangedHook: {
+                auto args = static_cast<void **>(data);
+                const auto &key = *static_cast<const QString *>(args[0]);
+                const auto &newVar = *static_cast<const QVariant *>(args[1]);
+                const auto &oldVar = *static_cast<const QVariant *>(args[2]);
+
+                if (key == QStringLiteral("no-frame-shadow")) {
+                    if (newVar.toBool()) {
+                        // TODO: set off
+                    } else {
+                        // TODO: set on
+                    }
+                }
+
+                break;
+            }
+
             case DefaultColorsHook: {
                 auto &map = *static_cast<QMap<QString, QColor> *>(data);
                 map.clear();
diff --git a/src/core/windowagentbase.cpp b/src/core/windowagentbase.cpp
index d2b9e1e..c043838 100644
--- a/src/core/windowagentbase.cpp
+++ b/src/core/windowagentbase.cpp
@@ -50,37 +50,29 @@
 
     WindowAgentBase::~WindowAgentBase() = default;
 
+    QVariant WindowAgentBase::windowAttribute(const QString &key) const {
+        Q_D(const WindowAgentBase);
+        return d->context->windowAttribute(key);
+    }
+
+    void WindowAgentBase::setWindowAttribute(const QString &key, const QVariant &var) {
+        Q_D(WindowAgentBase);
+        d->context->setWindowAttribute(key, var);
+    }
+
     void WindowAgentBase::showSystemMenu(const QPoint &pos) {
         Q_D(WindowAgentBase);
         d->context->showSystemMenu(pos);
     }
 
-    void WindowAgentBase::startSystemMove(const QPoint &pos) {
-        Q_D(WindowAgentBase);
-        auto win = d->context->window();
-        if (!win) {
-            return;
-        }
-
-        Q_UNUSED(pos)
-        win->startSystemMove();
-    }
-
-    void WindowAgentBase::startSystemResize(Qt::Edges edges, const QPoint &pos) {
-        Q_D(WindowAgentBase);
-        auto win = d->context->window();
-        if (!win) {
-            return;
-        }
-
-        Q_UNUSED(pos)
-        win->startSystemResize(edges);
-    }
-
     void WindowAgentBase::centralize() {
+        Q_D(WindowAgentBase);
+        d->context->virtual_hook(AbstractWindowContext::CentralizeHook, nullptr);
     }
 
     void WindowAgentBase::raise() {
+        Q_D(WindowAgentBase);
+        d->context->virtual_hook(AbstractWindowContext::RaiseWindowHook, nullptr);
     }
 
     WindowAgentBase::WindowAgentBase(WindowAgentBasePrivate &d, QObject *parent)
diff --git a/src/core/windowagentbase.h b/src/core/windowagentbase.h
index b0b884b..d5b02fa 100644
--- a/src/core/windowagentbase.h
+++ b/src/core/windowagentbase.h
@@ -28,10 +28,11 @@
         };
         Q_ENUM(SystemButton)
 
+        QVariant windowAttribute(const QString &key) const;
+        void setWindowAttribute(const QString &key, const QVariant &var);
+
     public Q_SLOTS:
         void showSystemMenu(const QPoint &pos);
-        void startSystemMove(const QPoint &pos);
-        void startSystemResize(Qt::Edges edges, const QPoint &pos);
         void centralize();
         void raise();
 

--
Gitblit v1.9.1