From 6e5ad39f4f7af02ed9d684f896d318f49e38a2d2 Mon Sep 17 00:00:00 2001 From: Mentalflow <312902918@qq.com> Date: Sun, 21 Apr 2024 02:57:29 +0800 Subject: [PATCH] 3rdparty: Remove framelesshelper and add qwindowkit. --- .gitmodules | 6 ++-- CMakeLists.txt | 3 +- example/about.qml | 1 + lib_source/3rdparty/framelesshelper | 1 - lib_source/3rdparty/qwindowkit | 1 + lib_source/CMakeLists.txt | 31 +++++++++++------ lib_source/platformsupport.h | 33 ++++++++++++++++++ lib_source/platformsupport.mm | 10 ++++++ lib_source/qml/RibbonWindow.qml | 54 +++++++++++++++++++---------- lib_source/ribbonui.cpp | 19 +++++----- lib_source/ribbonui.h | 3 -- 11 files changed, 115 insertions(+), 47 deletions(-) delete mode 160000 lib_source/3rdparty/framelesshelper create mode 160000 lib_source/3rdparty/qwindowkit create mode 100644 lib_source/platformsupport.h create mode 100644 lib_source/platformsupport.mm diff --git a/.gitmodules b/.gitmodules index a5ac807..41d62e4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "lib_source/3rdparty/framelesshelper"] - path = lib_source/3rdparty/framelesshelper - url = git@github.com:mentalfl0w/framelesshelper.git +[submodule "lib_source/3rdparty/qwindowkit"] + path = lib_source/3rdparty/qwindowkit + url = https://github.com/stdware/qwindowkit.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 97ac832..a5f457d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ set(QT_SDK_DIR ${Qt6_DIR}/../../..) cmake_path(SET QT_SDK_DIR NORMALIZE ${QT_SDK_DIR}) option(RIBBONUI_BUILD_EXAMPLES "Build RibbonUI APP." ON) -option(RIBBONUI_BUILD_FRAMELESSHEPLER "Build FramelessHelper." ON) +option(RIBBONUI_BUILD_QWINDOWKIT "Build QWindowKit." ON) option(RIBBONUI_BUILD_STATIC_LIB "Build RibbonUI static library." OFF) if(NOT RIBBONUI_QML_PLUGIN_DIRECTORY) @@ -22,5 +22,6 @@ add_subdirectory(lib_source) message("---------------------------- RibbonUI ----------------------------") message("Build RibbonUI APP: ${RIBBONUI_BUILD_EXAMPLES}") message("Build RibbonUI static library: ${RIBBONUI_BUILD_STATIC_LIB}") +message("Build QWindowKit: ${RIBBONUI_BUILD_QWINDOWKIT}") message("RibbonUI QML Plugin Path: ${RIBBONUI_QML_PLUGIN_DIRECTORY}") message("------------------------------------------------------------------") diff --git a/example/about.qml b/example/about.qml index 2be9827..7fa4d3f 100644 --- a/example/about.qml +++ b/example/about.qml @@ -12,6 +12,7 @@ RibbonWindow { title: qsTr("About") title_bar.show_darkmode_btn: false title_bar.show_style_switch: false + windowStatus: RibbonWindow.Status.SingleInstance ColumnLayout{ id: content diff --git a/lib_source/3rdparty/framelesshelper b/lib_source/3rdparty/framelesshelper deleted file mode 160000 index 206cd79..0000000 --- a/lib_source/3rdparty/framelesshelper +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 206cd7953eb37618bee14f7c3eae73f0bb863cad diff --git a/lib_source/3rdparty/qwindowkit b/lib_source/3rdparty/qwindowkit new file mode 160000 index 0000000..15c5605 --- /dev/null +++ b/lib_source/3rdparty/qwindowkit @@ -0,0 +1 @@ +Subproject commit 15c5605a6a55f9fc08e9b8fa2644b2027e673812 diff --git a/lib_source/CMakeLists.txt b/lib_source/CMakeLists.txt index 64efbbe..c873370 100644 --- a/lib_source/CMakeLists.txt +++ b/lib_source/CMakeLists.txt @@ -5,7 +5,6 @@ project(RibbonUI VERSION ${PROJECT_VERSION} LANGUAGES CXX) set(CMAKE_CXX_STANDARD_REQUIRED ON) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/.cmake/) - include(GNUInstallDirs) if(QT_VERSION VERSION_GREATER_EQUAL "6.3") @@ -21,11 +20,15 @@ if(APPLE) set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE) endif() -set(FRAMELESSHELPER_BUILD_STATIC ON) -set(FRAMELESSHELPER_NO_SUMMARY OFF) -set(FRAMELESSHELPER_NO_DEBUG_OUTPUT ON) -set(FRAMELESSHELPER_BUILD_WIDGETS OFF) -add_subdirectory(3rdparty/framelesshelper) +if (RIBBONUI_BUILD_QWINDOWKIT) + set(QWINDOWKIT_BUILD_STATIC ON) + set(QWINDOWKIT_BUILD_EXAMPLES OFF) + set(QWINDOWKIT_BUILD_QUICK ON) + set(QWINDOWKIT_BUILD_WIDGETS OFF) + set(QWINDOWKIT_ENABLE_STYLE_AGENT ON) + set(QWINDOWKIT_INSTALL OFF) + add_subdirectory(3rdparty/qwindowkit) +endif() find_package(Qt6 COMPONENTS Core Quick Qml REQUIRED) @@ -56,6 +59,15 @@ set( qml/RibbonMessageListView.qml ) +set ( + source_files ribbonui.cpp ribbonui.h definitions.h ribbontheme.h ribbontheme.cpp + platformsupport.h +) + +if(APPLE) + list(APPEND source_files platformsupport.mm) +endif() + foreach(qmlfile ${qml_files}) string(REPLACE "qml/" "" fixedfile ${qmlfile}) set_source_files_properties(${qmlfile} PROPERTIES QT_RESOURCE_ALIAS ${fixedfile}) @@ -68,7 +80,7 @@ qt_add_qml_module(${PROJECT_NAME} URI ${PROJECT_NAME} VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} QML_FILES ${qml_files} - SOURCES ribbonui.cpp ribbonui.h definitions.h ribbontheme.h ribbontheme.cpp + SOURCES ${source_files} RESOURCES resources/FluentSystemIcons-Resizable.ttf resources/imgs/icon.png RESOURCE_PREFIX "/qt/qml/" ) @@ -98,12 +110,11 @@ target_link_libraries(${PROJECT_NAME} PRIVATE Qt::QmlPrivate ) target_link_libraries(${PROJECT_NAME} PUBLIC - FramelessHelper::Core - FramelessHelper::Quick + QWindowKit::Quick ) target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR} - ${PROJECT_SOURCE_DIR}/3rdparty/framelesshelper/include + ${PROJECT_SOURCE_DIR}/3rdparty/qwindowkit/include ) install(DIRECTORY ${RIBBONUI_QML_PLUGIN_DIRECTORY} DESTINATION ${CMAKE_INSTALL_PREFIX}/imports) diff --git a/lib_source/platformsupport.h b/lib_source/platformsupport.h new file mode 100644 index 0000000..aa59c99 --- /dev/null +++ b/lib_source/platformsupport.h @@ -0,0 +1,33 @@ +#ifndef PLATFORMSUPPORT_H +#define PLATFORMSUPPORT_H +#include +#include +#include + +class PlatformSupport : public QObject +{ + Q_OBJECT + QML_ELEMENT + QML_SINGLETON + QML_NAMED_ELEMENT(PlatformSupport) +public: + static PlatformSupport* create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return instance();} + static PlatformSupport* instance(){ + static QMutex mutex; + QMutexLocker locker(&mutex); + + static PlatformSupport *singleton = nullptr; + if (!singleton) { + singleton = new PlatformSupport(); + } + return singleton; + } +#ifdef Q_OS_MACOS + Q_INVOKABLE void showSystemTitleBtns(QWindow *window, bool enable); +#endif +private: + PlatformSupport(QObject *parent = nullptr) : QObject(parent){} + Q_DISABLE_COPY_MOVE(PlatformSupport) +}; + +#endif // PLATFORMSUPPORT_H diff --git a/lib_source/platformsupport.mm b/lib_source/platformsupport.mm new file mode 100644 index 0000000..959833f --- /dev/null +++ b/lib_source/platformsupport.mm @@ -0,0 +1,10 @@ +#include "platformsupport.h" +#include + +void PlatformSupport::showSystemTitleBtns(QWindow *window, bool enable) +{ + NSWindow* nswindow = [reinterpret_cast(window->winId()) window]; + [nswindow standardWindowButton:NSWindowCloseButton].hidden = (enable ? NO : YES); + [nswindow standardWindowButton:NSWindowMiniaturizeButton].hidden = (enable ? NO : YES); + [nswindow standardWindowButton:NSWindowZoomButton].hidden = (enable ? NO : YES); +} diff --git a/lib_source/qml/RibbonWindow.qml b/lib_source/qml/RibbonWindow.qml index 034400c..d026315 100644 --- a/lib_source/qml/RibbonWindow.qml +++ b/lib_source/qml/RibbonWindow.qml @@ -1,6 +1,6 @@ import QtQuick import RibbonUI -import org.wangwenx190.FramelessHelper +import QWindowKit Window { id:window @@ -16,27 +16,42 @@ Window { property alias title_bar: titleBar property alias popup: pop property bool comfirmed_quit: false + property bool blurBehindWindow: true visible: false color: { - if (FramelessHelper.blurBehindWindowEnabled) { + if (blurBehindWindow) { return "transparent"; } - if (FramelessUtils.systemTheme === FramelessHelperConstants.Dark) { - return FramelessUtils.defaultSystemDarkColor; + if (RibbonTheme.dark_mode) { + return '#2C2B29' } - return FramelessUtils.defaultSystemLightColor; + return '#FFFFFF' } - FramelessHelper.onReady: { + onBlurBehindWindowChanged: { + if (Qt.platform.os === 'windows') + windowAgent.setWindowAttribute("acrylic-material", blurBehindWindow) + else if (Qt.platform.os === 'osx') + windowAgent.setWindowAttribute("blur-effect", blurBehindWindow ? RibbonTheme.dark_mode ? "dark" : "light" : "none") + } + + Component.onCompleted: { + windowAgent.setup(window) if (Qt.platform.os === 'windows') { - FramelessHelper.setSystemButton(titleBar.minimizeBtn, FramelessHelperConstants.Minimize); - FramelessHelper.setSystemButton(titleBar.maximizeBtn, FramelessHelperConstants.Maximize); - FramelessHelper.setSystemButton(titleBar.closeBtn, FramelessHelperConstants.Close); + windowAgent.setWindowAttribute("acrylic-material", blurBehindWindow) + windowAgent.setSystemButton(WindowAgent.Minimize, titleBar.minimizeBtn); + windowAgent.setSystemButton(WindowAgent.Maximize, titleBar.maximizeBtn); + windowAgent.setSystemButton(WindowAgent.Close, titleBar.closeBtn); } - FramelessHelper.setHitTestVisible(titleBar.left_container) - FramelessHelper.setHitTestVisible(titleBar.right_container) - FramelessHelper.titleBarItem = titleBar; - FramelessHelper.moveWindowToDesktopCenter(); + if(Qt.platform.os === "osx") + { + windowAgent.setWindowAttribute("blur-effect", blurBehindWindow ? RibbonTheme.dark_mode ? "dark" : "light" : "none") + PlatformSupport.showSystemTitleBtns(window, true) + } + windowAgent.setHitTestVisible(titleBar.left_container) + windowAgent.setHitTestVisible(titleBar.right_container) + windowAgent.setTitleBar(titleBar); + windowAgent.centralize() window.visible = true; } Item{ @@ -65,10 +80,9 @@ Window { Connections{ target: RibbonTheme function onTheme_modeChanged() { - if (RibbonTheme.dark_mode) - FramelessUtils.systemTheme = FramelessHelperConstants.Dark - else - FramelessUtils.systemTheme = FramelessHelperConstants.Light + windowAgent.setWindowAttribute("dark-mode", RibbonTheme.dark_mode) + if (Qt.platform.os === 'osx') + windowAgent.setWindowAttribute("blur-effect", blurBehindWindow ? RibbonTheme.dark_mode ? "dark" : "light" : "none") } } Rectangle{ @@ -82,7 +96,7 @@ Window { anchors.fill: parent color: 'transparent' border.color: RibbonTheme.dark_mode ? "#7A7A7A" : "#2C59B7" - border.width: RibbonTheme.modern_style ? Qt.platform.os === 'windows' ? 2 : 1 : 0 + border.width: RibbonTheme.modern_style ? 1 : 0 radius: Qt.platform.os === 'windows' ? 8 : 10 visible: RibbonTheme.modern_style } @@ -111,6 +125,10 @@ Window { } } + WindowAgent { + id: windowAgent + } + onClosing:function(event){ window.raise() event.accepted = !comfirmed_quit diff --git a/lib_source/ribbonui.cpp b/lib_source/ribbonui.cpp index bed4ad4..c5c011d 100644 --- a/lib_source/ribbonui.cpp +++ b/lib_source/ribbonui.cpp @@ -1,6 +1,8 @@ #include "ribbonui.h" #include #include +#include +#include #define STR(x) #x #define JOIN(a,b,c) STR(a.b.c) #define VER_JOIN(x) JOIN x @@ -26,20 +28,15 @@ RibbonUI* RibbonUI::instance(){ void RibbonUI::init() { - qputenv("QT_QUICK_CONTROLS_STYLE","Basic"); - FramelessHelper::Quick::initialize(); -#ifdef Q_OS_WINDOWS - FramelessConfig::instance()->set(Global::Option::ForceNonNativeBackgroundBlur); - FramelessConfig::instance()->set(Global::Option::DisableLazyInitializationForMicaMaterial); - if(QOperatingSystemVersion::current() < QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 22000)) - FramelessConfig::instance()->set(Global::Option::WindowUseRoundCorners); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + qputenv("QT_QUICK_CONTROLS_STYLE", "Basic"); +#else + qputenv("QT_QUICK_CONTROLS_STYLE", "Default"); #endif - FramelessConfig::instance()->set(Global::Option::ForceHideWindowFrameBorder); - FramelessConfig::instance()->set(Global::Option::CenterWindowBeforeShow); - FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow); + QQuickWindow::setDefaultAlphaBuffer(true); } void RibbonUI::registerTypes(QQmlEngine *qmlEngine) { - FramelessHelper::Quick::registerTypes(qmlEngine); + QWK::registerTypes(qmlEngine); } diff --git a/lib_source/ribbonui.h b/lib_source/ribbonui.h index c786aa3..732f104 100644 --- a/lib_source/ribbonui.h +++ b/lib_source/ribbonui.h @@ -3,10 +3,7 @@ #include #include "definitions.h" -#include -#include -FRAMELESSHELPER_USE_NAMESPACE class RibbonUI : public QQuickItem { Q_OBJECT