From 1571d7b43228a0ed4347f681a16b2b23defccda9 Mon Sep 17 00:00:00 2001
From: Sine Striker <trueful@163.com>
Date: 周三, 27 12月 2023 03:52:03 +0800
Subject: [PATCH] Add doxygen documentations

---
 src/widgets/widgetwindowagent_mac.cpp |    7 +
 src/widgets/widgetwindowagent.cpp     |   58 +++++++++++
 src/widgets/CMakeLists.txt            |    2 
 src/quick/CMakeLists.txt              |    2 
 src/core/windowagentbase.h            |    3 
 src/CMakeLists.txt                    |   37 +++++++
 src/widgets/widgetwindowagent.h       |    3 
 src/core/windowagentbase.cpp          |   55 +++++++++++
 examples/mainwindow/mainwindow.cpp    |    4 
 src/core/style/styleagent.cpp         |   24 ++++
 README.md                             |   61 ++++++------
 src/quick/quickwindowagent.cpp        |   11 ++
 12 files changed, 229 insertions(+), 38 deletions(-)

diff --git a/README.md b/README.md
index d84cc1c..97cf4fa 100644
--- a/README.md
+++ b/README.md
@@ -5,21 +5,11 @@
 This project inherited most of [wangwenx190 FramelessHelper](https://github.com/wangwenx190/framelesshelper)
 implementation, with a complete refactoring and upgrading of the architecture.
 
-Support as many system native features as possible without requiring additional dependencies.
+Feature requests are welcome.
 
-<!-- ## Why using QWindowKit?
+## Join with Us :triangular_flag_on_post:
 
-Here are why `QWindowKit` is better than `FramelessHelper`:
-
-+ Full support of Windows 11 Snap Layout
-+ Most of the redundant codes and architectural flaws are eliminated, and the binary size compiled by MSVC is about 1/9 of `FramelessHelper`
-+ A critical issue that moving window forces the entire window to be repainted on Windows is fixed
-+ Capable to cope with WinId mutation, and `QWebEngineView` is perfectly supported
-+ Better workaround to handle Windows 10 top border issue
-+ Simpler APIs, more detailed documentation and comments
-+ A lot of bugs are fixed
-
-Feature requests are welcome. -->
+You can join our [Discord channel](https://discord.gg/grrM4Tmesy). You can share your findings, thoughts and ideas on improving / implementing FramelessHelper functionalities on more platforms and apps!
 
 ## Supported Platforms
 
@@ -27,12 +17,21 @@
 + Apple macOS (11+)
 + GNU/Linux
 
+## Features
+
++ Full support of Windows 11 Snap Layout
++ Better workaround to handle Windows 10 top border issue
++ Support Mac system buttons geometry customization
++ Simpler APIs, more detailed documentations and comments
+
 ## Gallery
 
 ### Windows 11 (With Snap Layout)
+
 ![image](./docs/images/win11.png)
 
 ### Windows 10 (And 7, Vista)
+
 ![image](./docs/images/win10.png)
 
 ### macOS & Linux
@@ -130,7 +129,8 @@
 }
 ```
 
-If you don't want to derive a new widget class or change the constructor, you can initialize the agent after the window constructs.
+If you don't want to derive a new widget class or change the constructor, you can initialize the agent after the window
+constructs.
 
 ```c++
 auto w = new MyWidget();
@@ -140,9 +140,11 @@
 
 #### Construct Title bar
 
-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.
+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.
+You can use the [`WindowBar`](examples/shared/widgetframe/windowbar.h) provided by `WidgetFrame` in the examples as the
+container of your title bar components.
 
 Let `WidgetWindowAgent` know which widget the title bar is.
 
@@ -150,7 +152,8 @@
 agent->setTitleBar(myTitleBar);
 ```
 
-Next, set system button hints to let `WidgetWindowAgent` know the role of the child widgets, which is important for the Snap Layout to work.
+Next, set system button hints to let `WidgetWindowAgent` know the role of the child widgets, which is important for the
+Snap Layout to work.
 
 ```c++
 agent->setSystemButton(QWK::WindowAgentBase::WindowIcon, myTitleBar->iconButton());
@@ -158,11 +161,14 @@
 agent->setSystemButton(QWK::WindowAgentBase::Maximize, myTitleBar->maxButton());
 agent->setSystemButton(QWK::WindowAgentBase::Close, myTitleBar->closeButton());
 ```
-Doing this does not mean that these buttons' click events are automatically associated with window actions, you still need to manually connect the signals and slots to emulate the native window behaviors.
+
+Doing this does not mean that these buttons' click events are automatically associated with window actions, you still
+need to manually connect the signals and slots to emulate the native window behaviors.
 
 On macOS, this step can be skipped because it is better to use the buttons provided by the system.
 
-Last but not least, set hit-test visible hint to let `WidgetWindowAgent` know other widgets that desire to receive mouse events.
+Last but not least, set hit-test visible hint to let `WidgetWindowAgent` know other widgets that desire to receive mouse
+events.
 
 ```c++
 agent->setHitTestVisible(myTitleBar->menuBar(), true);
@@ -170,8 +176,7 @@
 
 The rest region within the title bar will be regarded as the draggable area for the user to move the window.
 
-
-#### Window Attributes (Experimental)
+<!-- #### Window Attributes (Experimental)
 
 On Windows 11, you can use this API to enable system effects.
 
@@ -179,7 +184,7 @@
 agent->setWindowAttribute("mica", true);
 ```
 
-Available keys: `mica`, `mica-alt`, `acrylic`, `dark-mode`.
+Available keys: `mica`, `mica-alt`, `acrylic`, `dark-mode`. -->
 
 ### Qt Quick Application
 
@@ -224,23 +229,19 @@
 
 You can omit the version number or use "auto" instead of "1.0" for the module URI if you are using Qt6.
 
-#### Window Attributes (Experimental)
-
-TODO
-
 ### Learn More
 
 See [examples](examples) for more demo use cases. The examples have no High DPI support.
 
-## Documentations
-
-+ Examples (TODO)
-+ Notes (TODO)
 + [FramelessHelper Related](docs/framelesshelper-related.md)
 
 ## TODO
 
 + Fix 5.15 window abnormal behavior
++ Support Mac style change notification
++ Support Mac system buttons customization for Quick
++ More documentations
++ When do we support Linux native features?
 
 ## Special Thanks
 
diff --git a/examples/mainwindow/mainwindow.cpp b/examples/mainwindow/mainwindow.cpp
index 983a7a3..b445ce3 100644
--- a/examples/mainwindow/mainwindow.cpp
+++ b/examples/mainwindow/mainwindow.cpp
@@ -292,6 +292,10 @@
 
 void MainWindow::installStyleAgent() {
     styleAgent = new QWK::StyleAgent(this);
+
+    connect(styleAgent, &QWK::StyleAgent::systemThemeChanged, this, [this]() {
+        qDebug() << "System style changed:" << styleAgent->systemTheme(); //
+    });
 }
 
 void MainWindow::loadStyleSheet(Theme theme) {
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 267b05a..d847a76 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -136,6 +136,43 @@
 endif()
 
 # ----------------------------------
+# Documentation
+# ----------------------------------
+if(QWINDOWKIT_BUILD_DOCUMENTATIONS)
+    if(NOT DOXYGEN_EXECUTABLE)
+        find_package(Doxygen REQUIRED)
+    endif()
+
+    set(_install_options)
+
+    if(QWINDOWKIT_INSTALL)
+        set(_install_options INSTALL_DIR share/doc/${QWINDOWKIT_INSTALL_NAME})
+    endif()
+
+    set(_doc_targets ${QWINDOWKIT_ENABLED_TARGETS})
+
+    set(QWINDOWKIT_DOXYGEN_TAGFILE
+        ${CMAKE_BUILD_SHARE_DIR}/doc/${QWINDOWKIT_INSTALL_NAME}/${QWINDOWKIT_INSTALL_NAME}_tagfile.xml
+        CACHE FILEPATH "QWindowKit doxygen tag file path" FORCE
+    )
+
+    qm_import(Doxygen)
+    qm_setup_doxygen(QWindowKit_RunDoxygen
+        NAME "QWindowKit"
+        DESCRIPTION "${QWINDOWKIT_PROJECT_DESCRIPTION}"
+        MDFILE ../README.md
+        OUTPUT_DIR ${CMAKE_BUILD_SHARE_DIR}/doc/${QWINDOWKIT_INSTALL_NAME}
+        INPUT ${QWINDOWKIT_ENABLED_SUBDIRECTORIES}
+        TARGETS ${_doc_targets}
+        DEPENDS ${_doc_targets}
+        NO_EXPAND_MACROS Q_OBJECT Q_GADGET Q_DECLARE_TR_FUNCTIONS
+        COMPILE_DEFINITIONS Q_SIGNALS=Q_SIGNALS Q_SLOTS=Q_SLOTS
+        GENERATE_TAGFILE "${QWINDOWKIT_DOXYGEN_TAGFILE}"
+        ${_install_options}
+    )
+endif()
+
+# ----------------------------------
 # Install
 # ----------------------------------
 if(QWINDOWKIT_INSTALL)
diff --git a/src/core/style/styleagent.cpp b/src/core/style/styleagent.cpp
index 9e6206d..11d1adc 100644
--- a/src/core/style/styleagent.cpp
+++ b/src/core/style/styleagent.cpp
@@ -5,6 +5,11 @@
 
 namespace QWK {
 
+    /*!
+        \class StyleAgent
+        \brief StyleAgent provides some features related to system theme.
+    */
+
     StyleAgentPrivate::StyleAgentPrivate() {
     }
 
@@ -25,21 +30,40 @@
         Q_EMIT q->systemThemeChanged();
     }
 
+    /*!
+        Constructor. Since it is not related to a concrete window instance, it is better to be used
+        as a singleton.
+    */
     StyleAgent::StyleAgent(QObject *parent) : StyleAgent(*new StyleAgentPrivate(), parent) {
     }
 
+    /*!
+        Destructor.
+    */
     StyleAgent::~StyleAgent() {
     }
 
+    /*!
+        Returns the system theme.
+    */
     StyleAgent::SystemTheme StyleAgent::systemTheme() const {
         Q_D(const StyleAgent);
         return d->systemTheme;
     }
 
+    /*!
+        \internal
+    */
     StyleAgent::StyleAgent(StyleAgentPrivate &d, QObject *parent) : QObject(parent), d_ptr(&d) {
         d.q_ptr = this;
 
         d.init();
     }
 
+    /*!
+        \fn void StyleAgent::systemThemeChanged()
+
+        This signal is emitted when the system theme changes.
+    */
+
 }
diff --git a/src/core/windowagentbase.cpp b/src/core/windowagentbase.cpp
index 0131a60..60ade6a 100644
--- a/src/core/windowagentbase.cpp
+++ b/src/core/windowagentbase.cpp
@@ -17,6 +17,20 @@
 
 namespace QWK {
 
+    /*!
+        \namespace QWK
+        \brief QWindowKit namespace
+    */
+
+    /*!
+        \class WindowAgentBase
+        \brief WindowAgentBase is the base class of the specifiy window agent for QtWidgets and
+        QtQuick.
+
+        It processes some system events and the implements of frameless logic, and provides some
+        common methods for derived classes to call.
+    */
+
     WindowAgentBasePrivate::WindowContextFactoryMethod
         WindowAgentBasePrivate::windowContextFactoryMethod = nullptr;
 
@@ -48,33 +62,74 @@
         context.reset(ctx);
     }
 
+    /*!
+        Destructor.
+    */
     WindowAgentBase::~WindowAgentBase() = default;
 
+    /*!
+        Returns the window attribute value.
+
+        \sa setWindowAttribute()
+    */
     QVariant WindowAgentBase::windowAttribute(const QString &key) const {
         Q_D(const WindowAgentBase);
         return d->context->windowAttribute(key);
     }
 
+    /*!
+        Sets the platform-related attribute for the window.
+
+        Available attributes:
+
+        On Windows,
+            \li \c acrylic-material: Specify a boolean value to enable or disable acrylic material,
+                    this attribute is only available on Windows 11.
+            \li \c mica: Specify a boolean value to enable or disable mica material,
+                    this attribute is only available on Windows 11.
+            \li \c mica-alt: Specify a boolean value to enable or disable mica-alt material,
+                    this attribute is only available on Windows 11.
+            \li \c dark-mode: Specify a boolean value to enable or disable the dark mode, it is
+                    enabled by default on Windows 10 if the system borders config is enabled.
+            \li \c extra-margins: Specify a margin value to change the \c dwm extended area
+                    geometry, you shouldn't change this attribute because it may break the
+                    internal state.
+
+        On macOS,
+            \li \c no-system-buttons: Specify a boolean value to set the system buttons' visibility.
+    */
     bool WindowAgentBase::setWindowAttribute(const QString &key, const QVariant &attribute) {
         Q_D(WindowAgentBase);
         return d->context->setWindowAttribute(key, attribute);
     }
 
+    /*!
+        Shows the system menu, it's only implemented on Windows.
+    */
     void WindowAgentBase::showSystemMenu(const QPoint &pos) {
         Q_D(WindowAgentBase);
         d->context->showSystemMenu(pos);
     }
 
+    /*!
+        Makes the window show in center of the current screen.
+    */
     void WindowAgentBase::centralize() {
         Q_D(WindowAgentBase);
         d->context->virtual_hook(AbstractWindowContext::CentralizeHook, nullptr);
     }
 
+    /*!
+        Brings the window to top.
+    */
     void WindowAgentBase::raise() {
         Q_D(WindowAgentBase);
         d->context->virtual_hook(AbstractWindowContext::RaiseWindowHook, nullptr);
     }
 
+    /*!
+        \internal
+    */
     WindowAgentBase::WindowAgentBase(WindowAgentBasePrivate &d, QObject *parent)
         : QObject(parent), d_ptr(&d) {
         d.q_ptr = this;
diff --git a/src/core/windowagentbase.h b/src/core/windowagentbase.h
index c6507c6..6748ebc 100644
--- a/src/core/windowagentbase.h
+++ b/src/core/windowagentbase.h
@@ -30,9 +30,6 @@
         QVariant windowAttribute(const QString &key) const;
         Q_INVOKABLE bool setWindowAttribute(const QString &key, const QVariant &attribute);
 
-    Q_SIGNALS:
-        void systemThemeChanged();
-
     public Q_SLOTS:
         void showSystemMenu(const QPoint &pos); // Only available on Windows now
         void centralize();
diff --git a/src/quick/CMakeLists.txt b/src/quick/CMakeLists.txt
index 9389c8b..5e4978c 100644
--- a/src/quick/CMakeLists.txt
+++ b/src/quick/CMakeLists.txt
@@ -22,7 +22,7 @@
     LINKS QWKCore
     QT_LINKS Core Gui Quick
     QT_INCLUDE_PRIVATE Core Gui Quick
-    INCLUDE_PRIVATE contexts
+    INCLUDE_PRIVATE
     PREFIX QWK_QUICK
 )
 
diff --git a/src/quick/quickwindowagent.cpp b/src/quick/quickwindowagent.cpp
index 0731836..20b48b9 100644
--- a/src/quick/quickwindowagent.cpp
+++ b/src/quick/quickwindowagent.cpp
@@ -8,6 +8,14 @@
 
 namespace QWK {
 
+    /*!
+        \class QuickWindowAgent
+        \brief QuickWindowAgent is the window agent for QtQuick.
+
+        It provides interfaces for QtQuick and processes some Qt events related to the QQuickItem
+        instance. The usage of all APIs is consistent with the \a Widgets module.
+    */
+
     QuickWindowAgentPrivate::QuickWindowAgentPrivate() = default;
 
     QuickWindowAgentPrivate::~QuickWindowAgentPrivate() = default;
@@ -77,6 +85,9 @@
         d->context->setHitTestVisible(item, visible);
     }
 
+    /*!
+        \internal
+    */
     QuickWindowAgent::QuickWindowAgent(QuickWindowAgentPrivate &d, QObject *parent)
         : WindowAgentBase(d, parent) {
         d.init();
diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt
index 3b8db9a..e6ede73 100644
--- a/src/widgets/CMakeLists.txt
+++ b/src/widgets/CMakeLists.txt
@@ -23,7 +23,7 @@
     LINKS QWKCore
     QT_LINKS Core Gui Widgets
     QT_INCLUDE_PRIVATE Core Gui Widgets
-    INCLUDE_PRIVATE contexts
+    INCLUDE_PRIVATE
     PREFIX QWK_WIDGETS
 )
 
diff --git a/src/widgets/widgetwindowagent.cpp b/src/widgets/widgetwindowagent.cpp
index d74c5f6..e2b6db1 100644
--- a/src/widgets/widgetwindowagent.cpp
+++ b/src/widgets/widgetwindowagent.cpp
@@ -9,6 +9,14 @@
 
 namespace QWK {
 
+    /*!
+        \class WidgetWindowAgent
+        \brief WindowAgentBase is the window agent for QtWidgets.
+
+        It provides interfaces for QtWidgets and processes some Qt events related to the QWidget
+        instance.
+    */
+
     WidgetWindowAgentPrivate::WidgetWindowAgentPrivate() = default;
 
     WidgetWindowAgentPrivate::~WidgetWindowAgentPrivate() = default;
@@ -16,12 +24,22 @@
     void WidgetWindowAgentPrivate::init() {
     }
 
+    /*!
+        Constructs a widget agent, it's better to set the widget to setup as \a parent.
+    */
     WidgetWindowAgent::WidgetWindowAgent(QObject *parent)
         : WidgetWindowAgent(*new WidgetWindowAgentPrivate(), parent) {
     }
 
+    /*!
+        Destructor.
+    */
     WidgetWindowAgent::~WidgetWindowAgent() = default;
 
+    /*!
+        Installs the window agent on the widget. The window agent will take over some of the window
+        events, making the window look frameless.
+    */
     bool WidgetWindowAgent::setup(QWidget *w) {
         Q_ASSERT(w);
         if (!w) {
@@ -45,24 +63,38 @@
         return true;
     }
 
+    /*!
+        Returns the title bar widget.
+    */
     QWidget *WidgetWindowAgent::titleBar() const {
         Q_D(const WidgetWindowAgent);
         return static_cast<QWidget *>(d->context->titleBar());
     }
 
+    /*!
+        Sets the title bar widget, all system button and hit-test visible widget references that
+        have been set will be removed.
+    */
     void WidgetWindowAgent::setTitleBar(QWidget *w) {
         Q_D(WidgetWindowAgent);
         if (!d->context->setTitleBar(w)) {
             return;
         }
-        Q_EMIT titleBarWidgetChanged(w);
+        Q_EMIT titleBarChanged(w);
     }
 
+    /*!
+        Returns the system button of the given type.
+    */
     QWidget *WidgetWindowAgent::systemButton(SystemButton button) const {
         Q_D(const WidgetWindowAgent);
         return static_cast<QWidget *>(d->context->systemButton(button));
     }
 
+    /*!
+        Sets the system button of the given type, the system buttons always receive mouse events so
+        you don't need to call \c setHitTestVisible for them.
+    */
     void WidgetWindowAgent::setSystemButton(SystemButton button, QWidget *w) {
         Q_D(WidgetWindowAgent);
         if (!d->context->setSystemButton(button, w)) {
@@ -71,18 +103,42 @@
         Q_EMIT systemButtonChanged(button, w);
     }
 
+    /*!
+        Returns \a true if the widget can receive mouse events on title bar.
+    */
     bool WidgetWindowAgent::isHitTestVisible(const QWidget *w) const {
         Q_D(const WidgetWindowAgent);
         return d->context->isHitTestVisible(w);
     }
 
+    /*!
+        Makes the widget able to receive mouse events on title bar if \a visible is \c true.
+        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) {
         Q_D(WidgetWindowAgent);
         d->context->setHitTestVisible(w, visible);
     }
 
+    /*!
+        \internal
+    */
     WidgetWindowAgent::WidgetWindowAgent(WidgetWindowAgentPrivate &d, QObject *parent)
         : WindowAgentBase(d, parent) {
         d.init();
     }
+
+    /*!
+        \fn void WidgetWindowAgent::titleBarChanged(const QWidget *w)
+
+        This signal is emitted when the title bar widget is replaced.
+    */
+
+    /*!
+        \fn void WidgetWindowAgent::systemButtonChanged(SystemButton button, const QWidget *w)
+
+        This signal is emitted when a system button is replaced.
+    */
+
 }
diff --git a/src/widgets/widgetwindowagent.h b/src/widgets/widgetwindowagent.h
index 1136812..85eb3be 100644
--- a/src/widgets/widgetwindowagent.h
+++ b/src/widgets/widgetwindowagent.h
@@ -26,7 +26,6 @@
         QWidget *systemButton(SystemButton button) const;
         void setSystemButton(SystemButton button, QWidget *w);
 
-        // Not implement, don't use now
 #ifdef Q_OS_MAC
         QWidget *systemButtonArea() const;
         void setSystemButtonArea(QWidget *widget);
@@ -36,7 +35,7 @@
         void setHitTestVisible(const QWidget *w, bool visible = true);
 
     Q_SIGNALS:
-        void titleBarWidgetChanged(const QWidget *w);
+        void titleBarChanged(const QWidget *w);
         void systemButtonChanged(SystemButton button, const QWidget *w);
 
     protected:
diff --git a/src/widgets/widgetwindowagent_mac.cpp b/src/widgets/widgetwindowagent_mac.cpp
index 48679cd..31f45e6 100644
--- a/src/widgets/widgetwindowagent_mac.cpp
+++ b/src/widgets/widgetwindowagent_mac.cpp
@@ -35,11 +35,18 @@
         AbstractWindowContext *ctx;
     };
 
+    /*!
+        Returns the widget that acts as the system button area.
+    */
     QWidget *WidgetWindowAgent::systemButtonArea() const {
         Q_D(const WidgetWindowAgent);
         return d->systemButtonAreaWidget;
     }
 
+    /*!
+        Sets the widget that acts as the system button area. The system button will be centered in
+        its area, it is recommended to place the widget in a layout and set a fixed size policy.
+    */
     void WidgetWindowAgent::setSystemButtonArea(QWidget *widget) {
         Q_D(WidgetWindowAgent);
         auto ctx = d->context.get();

--
Gitblit v1.9.1