From 2452f5958272d50981ab89ff843d2fa715d33957 Mon Sep 17 00:00:00 2001
From: Zhao Yuhang <2546789017@qq.com>
Date: 摹曛, 14 12月 2023 21:23:25 +0800
Subject: [PATCH] add macos titlebar

---
 src/widgets/widgetwindowagent.cpp       |    3 +
 src/widgets/CMakeLists.txt              |    6 ++
 examples/mainwindow/mainwindow.cpp      |    2 
 src/widgets/widgetwindowagent_p.h       |    4 +
 src/widgets/widgetwindowagent_cocoa.cpp |   92 ++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 104 insertions(+), 3 deletions(-)

diff --git a/examples/mainwindow/mainwindow.cpp b/examples/mainwindow/mainwindow.cpp
index 3566081..80a4c3a 100644
--- a/examples/mainwindow/mainwindow.cpp
+++ b/examples/mainwindow/mainwindow.cpp
@@ -107,7 +107,7 @@
 void MainWindow::installWindowAgent() {
     auto agent = new QWK::WidgetWindowAgent(this);
     if (!agent->setup(this)) {
-        qFatal("Frameless handle failed to initialize.");
+        qFatal("QWK failed to initialize.");
     }
 
     auto menuBar = []() {
diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt
index ba6dd89..dfcedd1 100644
--- a/src/widgets/CMakeLists.txt
+++ b/src/widgets/CMakeLists.txt
@@ -14,6 +14,10 @@
 
 if(WIN32)
     list(APPEND _src widgetwindowagent_win.cpp)
+elseif(APPLE)
+    list(APPEND _src widgetwindowagent_cocoa.cpp)
+else()
+    list(APPEND _src widgetwindowagent_qt.cpp)
 endif()
 
 qwk_add_library(${PROJECT_NAME} AUTOGEN
@@ -31,4 +35,4 @@
 )
 
 set(QWINDOWKIT_ENABLED_TARGETS ${QWINDOWKIT_ENABLED_TARGETS} ${PROJECT_NAME} PARENT_SCOPE)
-set(QWINDOWKIT_ENABLED_SUBDIRECTORIES ${QWINDOWKIT_ENABLED_SUBDIRECTORIES} widgets PARENT_SCOPE)
\ No newline at end of file
+set(QWINDOWKIT_ENABLED_SUBDIRECTORIES ${QWINDOWKIT_ENABLED_SUBDIRECTORIES} widgets PARENT_SCOPE)
diff --git a/src/widgets/widgetwindowagent.cpp b/src/widgets/widgetwindowagent.cpp
index fc21be4..8fa28a7 100644
--- a/src/widgets/widgetwindowagent.cpp
+++ b/src/widgets/widgetwindowagent.cpp
@@ -57,6 +57,9 @@
         if (!d->context->setTitleBar(w)) {
             return;
         }
+#ifdef Q_OS_MACOS
+        d->setupMacOSTitleBar(w);
+#endif
         Q_EMIT titleBarWidgetChanged(w);
     }
 
diff --git a/src/widgets/widgetwindowagent_cocoa.cpp b/src/widgets/widgetwindowagent_cocoa.cpp
new file mode 100644
index 0000000..583f846
--- /dev/null
+++ b/src/widgets/widgetwindowagent_cocoa.cpp
@@ -0,0 +1,92 @@
+#include "widgetwindowagent_p.h"
+
+namespace QWK {
+
+    class TitleBarEventFilter : public QObject {
+        Q_OBJECT
+
+    public:
+        explicit TitleBarEventFilter(AbstractWindowContext *context, QObject *parent = nullptr);
+        ~TitleBarEventFilter() override;
+
+    protected:
+        bool eventFilter(QObject *object, QEvent *event) override;
+
+    private:
+        AbstractWindowContext *m_context;
+        bool m_leftButtonPressed;
+    }
+
+    TitleBarEventFilter::TitleBarEventFilter(QObject *parent) : QObject(parent), m_context(context), m_leftButtonPressed(false) {}
+
+    TitleBarEventFilter::~TitleBarEventFilter() = default;
+
+    bool TitleBarEventFilter::eventFilter(QObject *object, QEvent *event) {
+        const auto type = event->type();
+        if (type < QEvent::MouseButtonPress || type > QEvent::MouseMove) {
+            return false;
+        }
+        const auto me = static_cast<const QMouseEvent *>(event);
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+        const QPoint scenePos = mouseEvent->scenePosition().toPoint();
+        const QPoint globalPos = mouseEvent->globalPosition().toPoint();
+#else
+        const QPoint scenePos = mouseEvent->windowPos().toPoint();
+        const QPoint globalPos = mouseEvent->screenPos().toPoint();
+#endif
+        if (!m_context->isInTitleBarDraggableArea(scenePos)) {
+            return false;
+        }
+        switch (type) {
+            case QEvent::MouseButtonPress: {
+                if (me->button() == Qt::LeftButton) {
+                    m_leftButtonPressed = true;
+                    event->accept();
+                    return true;
+                }
+                break;
+            }
+            case QEvent::MouseButtonRelease: {
+                if (me->button() == Qt::LeftButton) {
+                    m_leftButtonPressed = false;
+                    event->accept();
+                    return true;
+                }
+                break;
+            }
+            case QEvent::MouseMove: {
+                if (m_leftButtonPressed) {
+                    const auto widget = static_cast<QWidget *>(object);
+                    widget->windowHandle()->startSystemMove();
+                    event->accept();
+                    return true;
+                }
+                break;
+            }
+            case QEvent::MouseButtonDblClick: {
+                if (me->button() == Qt::LeftButton) {
+                    if (!widget->isFullScreen()) {
+                        if (widget->isMaximized()) {
+                            widget->showNormal();
+                        } else {
+                            widget->showMaximized();
+                        }
+                        event->accept();
+                        return true;
+                    }
+                }
+                break;
+            }
+            default:
+                break;
+        }
+        return false;
+    }
+
+    void WidgetWindowAgentPrivate::setupMacOSTitleBar(QWidget *titleBar) {
+        titleBar->installEventFilter(new TitleBarEventFilter(context.get(), titleBar));
+    }
+
+}
+
+#include "widgetwindowagent_cocoa.moc"
diff --git a/src/widgets/widgetwindowagent_p.h b/src/widgets/widgetwindowagent_p.h
index 5b60770..36bb202 100644
--- a/src/widgets/widgetwindowagent_p.h
+++ b/src/widgets/widgetwindowagent_p.h
@@ -19,9 +19,11 @@
 
 #ifdef Q_OS_WINDOWS
         void setupWindows10BorderWorkaround();
+#elif defined(Q_OS_MACOS)
+        void setupMacOSTitleBar(QWidget *titleBar);
 #endif
     };
 
 }
 
-#endif // WIDGETWINDOWAGENTPRIVATE_H
\ No newline at end of file
+#endif // WIDGETWINDOWAGENTPRIVATE_H

--
Gitblit v1.9.1