From f62f429158ff584ba3a13116f8e6c53dd36f67cb Mon Sep 17 00:00:00 2001 From: hoenking Date: Tue, 11 Nov 2025 20:12:39 +0800 Subject: [PATCH 1/5] Add cross-platform power monitor and macOS Vulkan --- CMakeLists.txt | 16 ++++- run_mac.sh | 14 +++++ src/powermonitor.cpp | 88 +++++++++++++------------- src/powermonitor.h | 55 ++++++++-------- src/powermonitor_base.cpp | 27 ++++++++ src/powermonitor_base.h | 61 ++++++++++++++++++ src/powermonitor_linux.cpp | 79 +++++++++++++++++++++++ src/powermonitor_linux.h | 51 +++++++++++++++ src/powermonitor_macos.h | 58 +++++++++++++++++ src/powermonitor_macos.mm | 125 +++++++++++++++++++++++++++++++++++++ src/vulkanwidget.cpp | 48 +++++++++++++- src/vulkanwidget.h | 1 + src/vulkanwidget_macos.h | 29 +++++++++ src/vulkanwidget_macos.mm | 62 ++++++++++++++++++ 14 files changed, 637 insertions(+), 77 deletions(-) create mode 100644 src/powermonitor_base.cpp create mode 100644 src/powermonitor_base.h create mode 100644 src/powermonitor_linux.cpp create mode 100644 src/powermonitor_linux.h create mode 100644 src/powermonitor_macos.h create mode 100644 src/powermonitor_macos.mm create mode 100644 src/vulkanwidget_macos.h create mode 100644 src/vulkanwidget_macos.mm diff --git a/CMakeLists.txt b/CMakeLists.txt index c344219..61ed4ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,7 +75,11 @@ set(VULKAN_FOUND FALSE) if(ENABLE_VULKAN) # Set Vulkan headers path - set(VULKAN_HEADERS_DIR "$ENV{HOME}/sdk/Vulkan-Headers-1.3.302/include") + if(APPLE) + set(VULKAN_HEADERS_DIR "$ENV{HOME}/VulkanSDK/1.4.328.1/macOS/include") + elseif(LINUX) + set(VULKAN_HEADERS_DIR "$ENV{HOME}/sdk/Vulkan-Headers-1.3.302/include") + endif() # Check if Vulkan headers exist if(EXISTS "${VULKAN_HEADERS_DIR}/vulkan/vulkan.h") @@ -145,6 +149,7 @@ set(SOURCES src/screenlockdetector.cpp src/screenlockdetector_base.cpp src/powermonitor.cpp + src/powermonitor_base.cpp ) set(HEADERS @@ -154,6 +159,7 @@ set(HEADERS src/screenlockdetector.h src/screenlockdetector_base.h src/powermonitor.h + src/powermonitor_base.h ) # Add Vulkan widget if Vulkan is available @@ -174,14 +180,20 @@ if(APPLE) # macOS specific files list(APPEND SOURCES src/screenlockdetector_macos.mm + src/powermonitor_macos.mm + src/vulkanwidget_macos.mm ) list(APPEND HEADERS src/screenlockdetector_macos.h + src/powermonitor_macos.h + src/vulkanwidget_macos.h ) # Enable Objective-C++ for .mm files set_source_files_properties( src/screenlockdetector_macos.mm + src/powermonitor_macos.mm + src/vulkanwidget_macos.mm PROPERTIES COMPILE_FLAGS "-x objective-c++" ) @@ -189,9 +201,11 @@ elseif(UNIX) # Linux specific files list(APPEND SOURCES src/screenlockdetector_linux.cpp + src/powermonitor_linux.cpp ) list(APPEND HEADERS src/screenlockdetector_linux.h + src/powermonitor_linux.h ) endif() diff --git a/run_mac.sh b/run_mac.sh index 04a7edd..a35a20d 100755 --- a/run_mac.sh +++ b/run_mac.sh @@ -21,6 +21,20 @@ if [[ "$OSTYPE" != "darwin"* ]]; then exit 1 fi +# Set up Vulkan SDK environment for MoltenVK +VULKAN_SDK="$HOME/VulkanSDK/1.4.328.1/macOS" +if [ -d "$VULKAN_SDK" ]; then + echo -e "${GREEN}Found Vulkan SDK at: $VULKAN_SDK${NC}" + export VULKAN_SDK + export DYLD_LIBRARY_PATH="$VULKAN_SDK/lib:$DYLD_LIBRARY_PATH" + export VK_ICD_FILENAMES="$VULKAN_SDK/share/vulkan/icd.d/MoltenVK_icd.json" + export VK_ADD_LAYER_PATH="$VULKAN_SDK/share/vulkan/explicit_layer.d" +else + echo -e "${YELLOW}Warning: Vulkan SDK not found at $VULKAN_SDK${NC}" + echo "Vulkan rendering may not work. Install from: https://vulkan.lunarg.com/sdk/home" + echo "" +fi + # Check if executable exists EXECUTABLE="build/bin/ScreenLockDetector" diff --git a/src/powermonitor.cpp b/src/powermonitor.cpp index a3958ff..55c17be 100644 --- a/src/powermonitor.cpp +++ b/src/powermonitor.cpp @@ -1,54 +1,50 @@ #include "powermonitor.h" -void PowerMonitor::initLogin1Dbus() { - // 连接 org.freedesktop.login1 服务(系统总线) - m_login1Interface = new QDBusInterface( - "org.freedesktop.login1", // DBus 服务名 - "/org/freedesktop/login1", // 对象路径 - "org.freedesktop.login1.Manager", // 接口名 - QDBusConnection::systemBus(), // 系统总线(关键!不是会话总线) - this - ); +#ifdef Q_OS_LINUX +#include "powermonitor_linux.h" +#elif defined(Q_OS_MAC) +#include "powermonitor_macos.h" +#endif - // 检查接口是否有效 - if (m_login1Interface->isValid()) { - // 监听 PrepareForSleep 信号(签名:b = bool) - bool connectOk = QDBusConnection::systemBus().connect( - "org.freedesktop.login1", // 服务名 - "/org/freedesktop/login1", // 对象路径 - "org.freedesktop.login1.Manager", // 接口名 - "PrepareForSleep", // 信号名 - this, - SLOT(onPrepareForSleep(bool)) // 接收信号的槽函数 - ); +#include - if (connectOk) { - qDebug() << "================================================="; - qDebug() << "✅ 成功连接 login1 电源管理接口"; - qDebug() << "================================================="; - } else { - qDebug() << "================================================="; - qDebug() << "❌ 连接 login1 信号失败:" << QDBusConnection::systemBus().lastError().message(); - qDebug() << "================================================="; - } - } else { - qDebug() << "================================================="; - qDebug() << "❌ 无法创建 login1 接口:" << m_login1Interface->lastError().message(); - qDebug() << "================================================="; +PowerMonitor::PowerMonitor(QObject *parent) + : PowerMonitorBase(parent) + , m_impl(nullptr) +{ +#ifdef Q_OS_LINUX + m_impl = new PowerMonitorLinux(this); + qDebug() << "创建 Linux 电源监视器实例"; +#elif defined(Q_OS_MAC) + m_impl = new PowerMonitorMacOS(this); + qDebug() << "创建 macOS 电源监视器实例"; +#else + qWarning() << "警告:当前平台不支持电源监视功能"; +#endif + + if (m_impl) { + // 转发平台实现的信号到工厂类 + connect(m_impl, &PowerMonitorBase::aboutToSleep, + this, &PowerMonitor::aboutToSleep); + connect(m_impl, &PowerMonitorBase::aboutToWakeUp, + this, &PowerMonitor::aboutToWakeUp); + connect(m_impl, &PowerMonitorBase::powerStateChanged, + this, &PowerMonitor::powerStateChanged); + + // 自动初始化 + m_impl->initialize(); } } -// 槽函数:处理睡眠/唤醒事件 -void PowerMonitor::onPrepareForSleep(bool enteringSleep) { - if (enteringSleep) { - // 系统即将进入 休眠/待机 状态 - qDebug() << "================================================="; - qDebug() << "\n📥 系统即将进入睡眠(休眠/待机)"; - emit aboutToSleep(); - } else { - // 系统从睡眠中唤醒 - qDebug() << "📤 系统已从睡眠中唤醒\n"; - qDebug() << "================================================="; - emit aboutToWakeUp(); - } +PowerMonitor::~PowerMonitor() +{ + // m_impl 会被 Qt 的父对象机制自动删除 } + +bool PowerMonitor::initialize() +{ + if (m_impl) { + return m_impl->initialize(); + } + return false; +} \ No newline at end of file diff --git a/src/powermonitor.h b/src/powermonitor.h index 8770a62..b6afad5 100644 --- a/src/powermonitor.h +++ b/src/powermonitor.h @@ -1,39 +1,38 @@ -#pragma once -#include -#include -#include -#include +#ifndef POWERMONITOR_H +#define POWERMONITOR_H -class PowerMonitor : public QObject +#include "powermonitor_base.h" + +/** + * @brief 跨平台电源监视器工厂类 + * + * 根据编译平台自动选择合适的电源监视器实现 + * 提供统一的接口用于监听系统睡眠/唤醒事件 + */ +class PowerMonitor : public PowerMonitorBase { Q_OBJECT public: - explicit PowerMonitor(QObject *parent = nullptr) : QObject(parent) { initLogin1Dbus(); } - -signals: - /* - * @brief 发送即将唤醒的信号 + /** + * @brief 创建平台特定的电源监视器实例 + * @param parent 父对象 + * + * 根据编译时的平台宏自动创建对应的实现: + * - Linux: PowerMonitorLinux (使用 DBus login1) + * - macOS: PowerMonitorMacOS (使用 NSWorkspace 通知) */ - void aboutToWakeUp(); + explicit PowerMonitor(QObject *parent = nullptr); + ~PowerMonitor() override; - /* - * @brief 发送即将进入睡眠的信号 + /** + * @brief 初始化电源监视器 + * @return true 如果初始化成功,否则返回 false */ - void aboutToSleep(); - -private slots: - /* - * @brief 处理睡眠/唤醒信号的槽函数 - * @param enteringSleep 是否进入睡眠状态 - */ - void onPrepareForSleep(bool enteringSleep); + bool initialize() override; private: - /* - * @brief 初始化Login1 DBus接口 - */ - void initLogin1Dbus(); - - QDBusInterface *m_login1Interface = nullptr; + PowerMonitorBase *m_impl; // 平台特定的实现 }; + +#endif // POWERMONITOR_H \ No newline at end of file diff --git a/src/powermonitor_base.cpp b/src/powermonitor_base.cpp new file mode 100644 index 0000000..640ec01 --- /dev/null +++ b/src/powermonitor_base.cpp @@ -0,0 +1,27 @@ +#include "powermonitor_base.h" +#include + +PowerMonitorBase::PowerMonitorBase(QObject *parent) + : QObject(parent) +{ +} + +PowerMonitorBase::~PowerMonitorBase() +{ +} + +void PowerMonitorBase::emitAboutToSleep() +{ + qDebug() << "================================================="; + qDebug() << "\n📥 系统即将进入睡眠(休眠/待机)"; + emit aboutToSleep(); + emit powerStateChanged(true); +} + +void PowerMonitorBase::emitAboutToWakeUp() +{ + qDebug() << "📤 系统已从睡眠中唤醒\n"; + qDebug() << "================================================="; + emit aboutToWakeUp(); + emit powerStateChanged(false); +} \ No newline at end of file diff --git a/src/powermonitor_base.h b/src/powermonitor_base.h new file mode 100644 index 0000000..7a0bd1d --- /dev/null +++ b/src/powermonitor_base.h @@ -0,0 +1,61 @@ +#ifndef POWERMONITOR_BASE_H +#define POWERMONITOR_BASE_H + +#include + +/** + * @brief 电源监视器抽象基类 + * + * 定义跨平台电源监视的公共接口 + * 各平台的具体实现需要继承此类并实现纯虚函数 + */ +class PowerMonitorBase : public QObject +{ + Q_OBJECT + +public: + explicit PowerMonitorBase(QObject *parent = nullptr); + virtual ~PowerMonitorBase(); + + /** + * @brief 初始化平台特定的电源监视 + * @return true 如果初始化成功,否则返回 false + * + * 纯虚函数,由子类实现平台特定的初始化逻辑 + */ + virtual bool initialize() = 0; + +signals: + /** + * @brief 发送即将唤醒的信号 + * 当系统从睡眠/休眠状态唤醒时发出 + */ + void aboutToWakeUp(); + + /** + * @brief 发送即将进入睡眠的信号 + * 当系统即将进入睡眠/休眠状态时发出 + */ + void aboutToSleep(); + + /** + * @brief 电源状态改变信号 + * @param sleeping true表示进入睡眠,false表示从睡眠唤醒 + */ + void powerStateChanged(bool sleeping); + +protected: + /** + * @brief 触发睡眠事件 + * 由子类调用以发出即将进入睡眠的信号 + */ + void emitAboutToSleep(); + + /** + * @brief 触发唤醒事件 + * 由子类调用以发出即将唤醒的信号 + */ + void emitAboutToWakeUp(); +}; + +#endif // POWERMONITOR_BASE_H \ No newline at end of file diff --git a/src/powermonitor_linux.cpp b/src/powermonitor_linux.cpp new file mode 100644 index 0000000..5814160 --- /dev/null +++ b/src/powermonitor_linux.cpp @@ -0,0 +1,79 @@ +#include "powermonitor_linux.h" + +#ifdef Q_OS_LINUX + +#include + +PowerMonitorLinux::PowerMonitorLinux(QObject *parent) + : PowerMonitorBase(parent) + , m_login1Interface(nullptr) +{ +} + +PowerMonitorLinux::~PowerMonitorLinux() +{ + if (m_login1Interface) { + delete m_login1Interface; + m_login1Interface = nullptr; + } +} + +bool PowerMonitorLinux::initialize() +{ + return initLogin1Dbus(); +} + +bool PowerMonitorLinux::initLogin1Dbus() +{ + // 连接 org.freedesktop.login1 服务(系统总线) + m_login1Interface = new QDBusInterface( + "org.freedesktop.login1", // DBus 服务名 + "/org/freedesktop/login1", // 对象路径 + "org.freedesktop.login1.Manager", // 接口名 + QDBusConnection::systemBus(), // 系统总线(关键!不是会话总线) + this + ); + + // 检查接口是否有效 + if (!m_login1Interface->isValid()) { + qDebug() << "================================================="; + qDebug() << "❌ 无法创建 login1 接口:" << m_login1Interface->lastError().message(); + qDebug() << "================================================="; + return false; + } + + // 监听 PrepareForSleep 信号(签名:b = bool) + bool connectOk = QDBusConnection::systemBus().connect( + "org.freedesktop.login1", // 服务名 + "/org/freedesktop/login1", // 对象路径 + "org.freedesktop.login1.Manager", // 接口名 + "PrepareForSleep", // 信号名 + this, + SLOT(onPrepareForSleep(bool)) // 接收信号的槽函数 + ); + + if (connectOk) { + qDebug() << "================================================="; + qDebug() << "✅ 成功连接 login1 电源管理接口(Linux)"; + qDebug() << "================================================="; + return true; + } else { + qDebug() << "================================================="; + qDebug() << "❌ 连接 login1 信号失败:" << QDBusConnection::systemBus().lastError().message(); + qDebug() << "================================================="; + return false; + } +} + +void PowerMonitorLinux::onPrepareForSleep(bool enteringSleep) +{ + if (enteringSleep) { + // 系统即将进入 休眠/待机 状态 + emitAboutToSleep(); + } else { + // 系统从睡眠中唤醒 + emitAboutToWakeUp(); + } +} + +#endif // Q_OS_LINUX \ No newline at end of file diff --git a/src/powermonitor_linux.h b/src/powermonitor_linux.h new file mode 100644 index 0000000..ef5f476 --- /dev/null +++ b/src/powermonitor_linux.h @@ -0,0 +1,51 @@ +#ifndef POWERMONITOR_LINUX_H +#define POWERMONITOR_LINUX_H + +#include "powermonitor_base.h" + +#ifdef Q_OS_LINUX + +#include +#include + +/** + * @brief Linux 电源监视器类 + * + * 通过监听 DBus 的 login1 服务来检测系统睡眠/唤醒状态 + * 使用 org.freedesktop.login1.Manager 的 PrepareForSleep 信号 + */ +class PowerMonitorLinux : public PowerMonitorBase +{ + Q_OBJECT + +public: + explicit PowerMonitorLinux(QObject *parent = nullptr); + ~PowerMonitorLinux() override; + + /** + * @brief 初始化 Linux 平台的电源监视 + * @return true 如果初始化成功,否则返回 false + */ + bool initialize() override; + +private slots: + /** + * @brief 处理睡眠/唤醒信号的槽函数 + * @param enteringSleep 是否进入睡眠状态 + */ + void onPrepareForSleep(bool enteringSleep); + +private: + /** + * @brief 初始化Login1 DBus接口 + * @return true 如果初始化成功 + */ + bool initLogin1Dbus(); + +private: + QDBusInterface *m_login1Interface; // Login1 DBus 接口 +}; + +#endif // Q_OS_LINUX + +#endif // POWERMONITOR_LINUX_H \ No newline at end of file diff --git a/src/powermonitor_macos.h b/src/powermonitor_macos.h new file mode 100644 index 0000000..c188183 --- /dev/null +++ b/src/powermonitor_macos.h @@ -0,0 +1,58 @@ +#ifndef POWERMONITOR_MACOS_H +#define POWERMONITOR_MACOS_H + +#include "powermonitor_base.h" + +#ifdef Q_OS_MAC + +/** + * @brief macOS 电源监视器类 + * + * 通过监听 macOS 的 IOKit 电源管理通知来检测系统睡眠/唤醒状态 + * 使用 NSWorkspace 的分布式通知中心监听系统睡眠和唤醒事件 + */ +class PowerMonitorMacOS : public PowerMonitorBase +{ + Q_OBJECT + +public: + explicit PowerMonitorMacOS(QObject *parent = nullptr); + ~PowerMonitorMacOS() override; + + /** + * @brief 初始化 macOS 平台的电源监视 + * @return true 如果初始化成功,否则返回 false + */ + bool initialize() override; + +public: + /** + * @brief 处理系统将要睡眠通知的回调 + */ + void handleWillSleep(); + + /** + * @brief 处理系统已经唤醒通知的回调 + */ + void handleDidWake(); + +private: + /** + * @brief 注册电源管理通知观察者 + * @return true 如果注册成功 + */ + bool registerPowerNotifications(); + + /** + * @brief 注销电源管理通知观察者 + */ + void unregisterPowerNotifications(); + +private: + void *m_workspaceObserver; // NSWorkspace 通知观察者(不透明指针) + bool m_initialized; // 是否已初始化 +}; + +#endif // Q_OS_MAC + +#endif // POWERMONITOR_MACOS_H \ No newline at end of file diff --git a/src/powermonitor_macos.mm b/src/powermonitor_macos.mm new file mode 100644 index 0000000..4e5f925 --- /dev/null +++ b/src/powermonitor_macos.mm @@ -0,0 +1,125 @@ +#include "powermonitor_macos.h" + +#ifdef Q_OS_MAC + +#import +#import +#include + +PowerMonitorMacOS::PowerMonitorMacOS(QObject *parent) + : PowerMonitorBase(parent) + , m_workspaceObserver(nullptr) + , m_initialized(false) +{ +} + +PowerMonitorMacOS::~PowerMonitorMacOS() +{ + unregisterPowerNotifications(); +} + +bool PowerMonitorMacOS::initialize() +{ + return registerPowerNotifications(); +} + +bool PowerMonitorMacOS::registerPowerNotifications() +{ + if (m_initialized) { + return true; + } + + @autoreleasepool { + NSWorkspace *workspace = [NSWorkspace sharedWorkspace]; + NSNotificationCenter *center = [workspace notificationCenter]; + + if (!center) { + qDebug() << "================================================="; + qDebug() << "❌ 无法获取 NSWorkspace 通知中心"; + qDebug() << "================================================="; + return false; + } + + // 获取 PowerMonitorMacOS 实例指针 + PowerMonitorMacOS *monitor = this; + + // 注册系统将要睡眠通知 + id sleepObserver = [center addObserverForName:NSWorkspaceWillSleepNotification + object:workspace + queue:nil + usingBlock:^(NSNotification *notification) { + Q_UNUSED(notification); + monitor->handleWillSleep(); + }]; + + // 注册系统已经唤醒通知 + id wakeObserver = [center addObserverForName:NSWorkspaceDidWakeNotification + object:workspace + queue:nil + usingBlock:^(NSNotification *notification) { + Q_UNUSED(notification); + monitor->handleDidWake(); + }]; + + if (sleepObserver && wakeObserver) { + // 将观察者保存到数组中 + NSMutableArray *observers = [NSMutableArray arrayWithCapacity:2]; + [observers addObject:sleepObserver]; + [observers addObject:wakeObserver]; + + // 保持观察者数组的引用 (手动 retain) + m_workspaceObserver = (void *)CFBridgingRetain(observers); + + m_initialized = true; + + qDebug() << "================================================="; + qDebug() << "✅ 成功注册 macOS 电源管理通知"; + qDebug() << "================================================="; + return true; + } else { + qDebug() << "================================================="; + qDebug() << "❌ 注册 macOS 电源管理通知失败"; + qDebug() << "================================================="; + return false; + } + } +} + +void PowerMonitorMacOS::unregisterPowerNotifications() +{ + if (!m_initialized || !m_workspaceObserver) { + return; + } + + @autoreleasepool { + NSWorkspace *workspace = [NSWorkspace sharedWorkspace]; + NSNotificationCenter *center = [workspace notificationCenter]; + + // 转换回 NSArray (手动 release) + NSArray *observers = (NSArray *)CFBridgingRelease(m_workspaceObserver); + + // 移除所有观察者 + for (id observer in observers) { + [center removeObserver:observer]; + } + + m_workspaceObserver = nullptr; + m_initialized = false; + + qDebug() << "================================================="; + qDebug() << "✅ 已注销 macOS 电源管理通知观察者"; + qDebug() << "================================================="; + } +} + +void PowerMonitorMacOS::handleWillSleep() +{ + emitAboutToSleep(); +} + +void PowerMonitorMacOS::handleDidWake() +{ + emitAboutToWakeUp(); +} + +#endif // Q_OS_MAC diff --git a/src/vulkanwidget.cpp b/src/vulkanwidget.cpp index bfa38f0..1bff465 100644 --- a/src/vulkanwidget.cpp +++ b/src/vulkanwidget.cpp @@ -15,7 +15,11 @@ // Include volk for Vulkan function loading #define VK_NO_PROTOTYPES -#include "../../third_party/volk/volk.h" +#include "third_party/volk/volk.h" + +#ifdef __APPLE__ +#include "vulkanwidget_macos.h" +#endif #ifndef M_PI #define M_PI 3.14159265358979323846 @@ -38,6 +42,7 @@ VulkanWidget::VulkanWidget(QWidget *parent) , m_swapchain(VK_NULL_HANDLE) , m_commandPool(VK_NULL_HANDLE) , m_x11Display(nullptr) + , m_metalLayer(nullptr) , m_initialized(false) , m_renderingEnabled(false) , m_needsResize(false) @@ -306,9 +311,19 @@ bool VulkanWidget::createInstance() createInfo.ppEnabledExtensionNames = extensions.data(); createInfo.enabledLayerCount = 0; +#ifdef __APPLE__ + // macOS (MoltenVK) requires portability enumeration flag + createInfo.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; + qDebug() << "macOS: Enabling portability enumeration for MoltenVK"; +#endif + VkResult result = vkCreateInstance(&createInfo, nullptr, &m_instance); if (result != VK_SUCCESS) { qDebug() << "Failed to create Vulkan instance, error code:" << result; +#ifdef __APPLE__ + qDebug() << "macOS Hint: Make sure MoltenVK is installed and DYLD_LIBRARY_PATH is set"; + qDebug() << "Expected path: $VULKAN_SDK/lib (e.g., ~/VulkanSDK/1.4.328.1/macOS/lib)"; +#endif return false; } @@ -367,9 +382,19 @@ bool VulkanWidget::createSurface() #elif defined(__APPLE__) // macOS requires MoltenVK and Metal + // Get the native view handle + void* nativeView = reinterpret_cast(window->winId()); + + // Setup CAMetalLayer using helper function + m_metalLayer = createMetalLayer(nativeView); + if (!m_metalLayer) { + qDebug() << "Failed to create CAMetalLayer"; + return false; + } + VkMetalSurfaceCreateInfoEXT createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT; - createInfo.pLayer = nullptr; // This needs proper Metal layer setup + createInfo.pLayer = m_metalLayer; VkResult result = vkCreateMetalSurfaceEXT(m_instance, &createInfo, nullptr, &m_surface); #else @@ -1094,6 +1119,14 @@ void VulkanWidget::cleanupVulkan() } #endif + // Release CAMetalLayer if it was created (macOS only) +#ifdef __APPLE__ + if (m_metalLayer) { + releaseMetalLayer(m_metalLayer); + m_metalLayer = nullptr; + } +#endif + // Cleanup instance if (m_instance != VK_NULL_HANDLE) { vkDestroyInstance(m_instance, nullptr); @@ -1214,6 +1247,10 @@ std::vector VulkanWidget::getRequiredInstanceExtensions() extensions.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); #elif defined(__APPLE__) extensions.push_back(VK_EXT_METAL_SURFACE_EXTENSION_NAME); + // MoltenVK requires portability enumeration extension + extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); + extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); + qDebug() << "macOS: Adding MoltenVK required extensions"; #endif return extensions; @@ -1223,6 +1260,13 @@ std::vector VulkanWidget::getRequiredDeviceExtensions() { std::vector extensions; extensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); + +#ifdef __APPLE__ + // MoltenVK requires portability subset extension for device + extensions.push_back("VK_KHR_portability_subset"); + qDebug() << "macOS: Adding portability_subset device extension for MoltenVK"; +#endif + return extensions; } diff --git a/src/vulkanwidget.h b/src/vulkanwidget.h index 8e46475..cfd8a0e 100644 --- a/src/vulkanwidget.h +++ b/src/vulkanwidget.h @@ -215,6 +215,7 @@ private: VkSwapchainKHR m_swapchain; VkCommandPool m_commandPool; void* m_x11Display; // X11 Display pointer (Linux only), stored as void* to avoid X11 header dependency + void* m_metalLayer; // CAMetalLayer pointer (macOS only), stored as void* to avoid Objective-C header dependency std::vector m_commandBuffers; std::vector m_imageAvailableSemaphores; std::vector m_renderFinishedSemaphores; diff --git a/src/vulkanwidget_macos.h b/src/vulkanwidget_macos.h new file mode 100644 index 0000000..f64f3da --- /dev/null +++ b/src/vulkanwidget_macos.h @@ -0,0 +1,29 @@ +#ifndef VULKANWIDGET_MACOS_H +#define VULKANWIDGET_MACOS_H + +#ifdef __APPLE__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Create a CAMetalLayer for the given native view + * @param nativeViewPtr Pointer to NSView (cast to void*) + * @return Retained pointer to CAMetalLayer (must be released with releaseMetalLayer) + */ +void* createMetalLayer(void* nativeViewPtr); + +/** + * @brief Release the CAMetalLayer + * @param metalLayerPtr Pointer to CAMetalLayer (cast to void*) + */ +void releaseMetalLayer(void* metalLayerPtr); + +#ifdef __cplusplus +} +#endif + +#endif // __APPLE__ + +#endif // VULKANWIDGET_MACOS_H \ No newline at end of file diff --git a/src/vulkanwidget_macos.mm b/src/vulkanwidget_macos.mm new file mode 100644 index 0000000..9f9d472 --- /dev/null +++ b/src/vulkanwidget_macos.mm @@ -0,0 +1,62 @@ +#include "vulkanwidget_macos.h" + +#ifdef __APPLE__ + +#import +#import +#import +#include + +void* createMetalLayer(void* nativeViewPtr) +{ + @autoreleasepool { + NSView* view = (__bridge NSView*)nativeViewPtr; + if (!view) { + qDebug() << "createMetalLayer: Invalid NSView"; + return nullptr; + } + + // Create CAMetalLayer + CAMetalLayer* metalLayer = [CAMetalLayer layer]; + if (!metalLayer) { + qDebug() << "createMetalLayer: Failed to create CAMetalLayer"; + return nullptr; + } + + // Configure the metal layer + metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm; + metalLayer.framebufferOnly = YES; + + // Get the content scale factor for retina displays + NSWindow* window = [view window]; + CGFloat scaleFactor = window ? [window backingScaleFactor] : 1.0; + metalLayer.contentsScale = scaleFactor; + + // Set the layer's drawable size to match the view + CGSize drawableSize = view.bounds.size; + drawableSize.width *= scaleFactor; + drawableSize.height *= scaleFactor; + metalLayer.drawableSize = drawableSize; + + // Set view properties + [view setWantsLayer:YES]; + [view setLayer:metalLayer]; + + qDebug() << "createMetalLayer: Successfully created CAMetalLayer" + << "size:" << drawableSize.width << "x" << drawableSize.height + << "scale:" << scaleFactor; + + // Return retained pointer (caller must release) + return (void*)CFBridgingRetain(metalLayer); + } +} + +void releaseMetalLayer(void* metalLayerPtr) +{ + if (metalLayerPtr) { + CFRelease(metalLayerPtr); + qDebug() << "releaseMetalLayer: CAMetalLayer released"; + } +} + +#endif // __APPLE__ From 1eff46e52362179b8ad5c4ca9af3cc14dbf797af Mon Sep 17 00:00:00 2001 From: hoenking Date: Tue, 11 Nov 2025 20:39:04 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E8=B0=83=E6=95=B4=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 34 ++-- compile_shaders_mac.sh | 174 ++++++++++++++++++ src/{ => platform}/powermonitor_base.cpp | 0 src/{ => platform}/powermonitor_base.h | 0 src/{ => platform}/powermonitor_linux.cpp | 0 src/{ => platform}/powermonitor_linux.h | 0 src/{ => platform}/powermonitor_macos.h | 0 src/{ => platform}/powermonitor_macos.mm | 0 .../screenlockdetector_base.cpp | 0 src/{ => platform}/screenlockdetector_base.h | 0 .../screenlockdetector_linux.cpp | 0 src/{ => platform}/screenlockdetector_linux.h | 0 src/{ => platform}/screenlockdetector_macos.h | 0 .../screenlockdetector_macos.mm | 0 src/{ => platform}/vulkanwidget_macos.h | 0 src/{ => platform}/vulkanwidget_macos.mm | 0 src/powermonitor.cpp | 4 +- src/powermonitor.h | 2 +- src/screenlockdetector.cpp | 4 +- src/screenlockdetector.h | 2 +- src/shaders_spirv/background.frag.spv | Bin 2812 -> 2812 bytes src/shaders_spirv/background.vert.spv | Bin 1672 -> 1672 bytes src/shaders_spirv/background_frag.inc | 14 +- src/shaders_spirv/background_vert.inc | 22 +-- src/shaders_spirv/geometry.frag.spv | Bin 920 -> 920 bytes src/shaders_spirv/geometry.vert.spv | Bin 2160 -> 2160 bytes src/shaders_spirv/geometry_frag.inc | 14 +- src/shaders_spirv/geometry_vert.inc | 18 +- src/shaders_spirv/text.frag.spv | Bin 1456 -> 1456 bytes src/shaders_spirv/text.vert.spv | Bin 2080 -> 2080 bytes src/shaders_spirv/text_frag.inc | 16 +- src/shaders_spirv/text_vert.inc | 20 +- src/vulkanwidget.cpp | 2 +- 33 files changed, 250 insertions(+), 76 deletions(-) create mode 100755 compile_shaders_mac.sh rename src/{ => platform}/powermonitor_base.cpp (100%) rename src/{ => platform}/powermonitor_base.h (100%) rename src/{ => platform}/powermonitor_linux.cpp (100%) rename src/{ => platform}/powermonitor_linux.h (100%) rename src/{ => platform}/powermonitor_macos.h (100%) rename src/{ => platform}/powermonitor_macos.mm (100%) rename src/{ => platform}/screenlockdetector_base.cpp (100%) rename src/{ => platform}/screenlockdetector_base.h (100%) rename src/{ => platform}/screenlockdetector_linux.cpp (100%) rename src/{ => platform}/screenlockdetector_linux.h (100%) rename src/{ => platform}/screenlockdetector_macos.h (100%) rename src/{ => platform}/screenlockdetector_macos.mm (100%) rename src/{ => platform}/vulkanwidget_macos.h (100%) rename src/{ => platform}/vulkanwidget_macos.mm (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 61ed4ac..8613a85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -147,9 +147,9 @@ set(SOURCES src/mainwindow.cpp src/customwidget.cpp src/screenlockdetector.cpp - src/screenlockdetector_base.cpp + src/platform/screenlockdetector_base.cpp src/powermonitor.cpp - src/powermonitor_base.cpp + src/platform/powermonitor_base.cpp ) set(HEADERS @@ -157,9 +157,9 @@ set(HEADERS src/renderwidgetbase.h src/customwidget.h src/screenlockdetector.h - src/screenlockdetector_base.h + src/platform/screenlockdetector_base.h src/powermonitor.h - src/powermonitor_base.h + src/platform/powermonitor_base.h ) # Add Vulkan widget if Vulkan is available @@ -179,33 +179,33 @@ endif() if(APPLE) # macOS specific files list(APPEND SOURCES - src/screenlockdetector_macos.mm - src/powermonitor_macos.mm - src/vulkanwidget_macos.mm + src/platform/screenlockdetector_macos.mm + src/platform/powermonitor_macos.mm + src/platform/vulkanwidget_macos.mm ) list(APPEND HEADERS - src/screenlockdetector_macos.h - src/powermonitor_macos.h - src/vulkanwidget_macos.h + src/platform/screenlockdetector_macos.h + src/platform/powermonitor_macos.h + src/platform/vulkanwidget_macos.h ) # Enable Objective-C++ for .mm files set_source_files_properties( - src/screenlockdetector_macos.mm - src/powermonitor_macos.mm - src/vulkanwidget_macos.mm + src/platform/screenlockdetector_macos.mm + src/platform/powermonitor_macos.mm + src/platform/vulkanwidget_macos.mm PROPERTIES COMPILE_FLAGS "-x objective-c++" ) elseif(UNIX) # Linux specific files list(APPEND SOURCES - src/screenlockdetector_linux.cpp - src/powermonitor_linux.cpp + src/platform/screenlockdetector_linux.cpp + src/platform/powermonitor_linux.cpp ) list(APPEND HEADERS - src/screenlockdetector_linux.h - src/powermonitor_linux.h + src/platform/screenlockdetector_linux.h + src/platform/powermonitor_linux.h ) endif() diff --git a/compile_shaders_mac.sh b/compile_shaders_mac.sh new file mode 100755 index 0000000..cd6ffd4 --- /dev/null +++ b/compile_shaders_mac.sh @@ -0,0 +1,174 @@ +#!/bin/bash + +# Shader compilation script for Vulkan +# Sets up environment and compiles GLSL shaders to SPIR-V + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +SHADERS_DIR="$SCRIPT_DIR/shaders" +OUTPUT_DIR="$SCRIPT_DIR/src/shaders_spirv" + +# Find glslang compiler +GLSLANG="" + +# Check custom paths first +if [ -x "$HOME/VulkanSDK/1.4.328.1/macOS/bin/glslang" ]; then + GLSLANG="$HOME/VulkanSDK/1.4.328.1/macOS/bin/glslang" + echo "Found glslang at: $GLSLANG" +elif [ -x "$HOME/VulkanSDK/1.4.328.1/macOS/bin/glslangValidator" ]; then + GLSLANG="$HOME/VulkanSDK/1.4.328.1/macOS/bin/glslangValidator" + echo "Found glslangValidator at: $GLSLANG" +elif command -v glslc &> /dev/null; then + GLSLANG="glslc" + echo "Using system glslc" +elif command -v glslangValidator &> /dev/null; then + GLSLANG="glslangValidator" + echo "Using system glslangValidator" +elif command -v glslang &> /dev/null; then + GLSLANG="glslang" + echo "Using system glslang" +else + echo "ERROR: No GLSL compiler found!" + echo "Please install:" + echo " - Vulkan SDK (provides glslc)" + echo " - or glslang to ~/VulkanSDK/1.4.328.1/macOS/bin/" + exit 1 +fi + +# Create output directory +mkdir -p "$OUTPUT_DIR" + +# Compilation function +compile_shader() { + local shader_file="$1" + local output_name="$2" + local spirv_file="$OUTPUT_DIR/${shader_file}.spv" + local inc_file="$OUTPUT_DIR/${output_name}" + + echo "Compiling $shader_file..." + + # Determine compiler command + if [[ "$GLSLANG" == *"glslc"* ]]; then + "$GLSLANG" "$SHADERS_DIR/$shader_file" -o "$spirv_file" + else + "$GLSLANG" -V "$SHADERS_DIR/$shader_file" -o "$spirv_file" + fi + + if [ $? -ne 0 ]; then + echo " FAILED to compile $shader_file" + return 1 + fi + + echo " SUCCESS - Generated $spirv_file" + + # Generate C++ include file + echo " Generating $inc_file..." + generate_include "$spirv_file" "$inc_file" + + return 0 +} + +# Generate C++ include file from SPIR-V +generate_include() { + local spirv_file="$1" + local inc_file="$2" + + # Use Python if available for better formatting + if command -v python3 &> /dev/null; then + python3 -c " +import struct +import sys + +with open('$spirv_file', 'rb') as f: + data = f.read() + +num_words = len(data) // 4 +words = struct.unpack('<{}I'.format(num_words), data[:num_words*4]) + +print('// Auto-generated from $(basename $spirv_file)') +print('// Size: {} bytes ({} words)'.format(len(data), num_words)) + +for i in range(0, num_words, 8): + chunk = words[i:i+8] + if i == 0: + sys.stdout.write(' ') + else: + sys.stdout.write(',\n ') + sys.stdout.write(', '.join('0x{:08x}u'.format(w) for w in chunk)) +print() +" > "$inc_file" + else + # Fallback: simple hexdump + echo "// Auto-generated from $(basename $spirv_file)" > "$inc_file" + xxd -i < "$spirv_file" | sed 's/unsigned char/uint32_t/' >> "$inc_file" + fi + + echo " Generated $inc_file" +} + +echo "========================================" +echo "Compiling Vulkan Shaders" +echo "========================================" +echo "Shaders directory: $SHADERS_DIR" +echo "Output directory: $OUTPUT_DIR" +echo "Compiler: $GLSLANG" +echo "========================================" +echo "" + +# Compile all shaders +SUCCESS=0 +FAILED=0 + +# Background shaders +if compile_shader "background.vert" "background_vert.inc"; then + ((SUCCESS++)) +else + ((FAILED++)) +fi + +if compile_shader "background.frag" "background_frag.inc"; then + ((SUCCESS++)) +else + ((FAILED++)) +fi + +# Geometry shaders +if compile_shader "geometry.vert" "geometry_vert.inc"; then + ((SUCCESS++)) +else + ((FAILED++)) +fi + +if compile_shader "geometry.frag" "geometry_frag.inc"; then + ((SUCCESS++)) +else + ((FAILED++)) +fi + +# Text shaders +if compile_shader "text.vert" "text_vert.inc"; then + ((SUCCESS++)) +else + ((FAILED++)) +fi + +if compile_shader "text.frag" "text_frag.inc"; then + ((SUCCESS++)) +else + ((FAILED++)) +fi + +echo "" +echo "========================================" +echo "Compilation Summary" +echo "========================================" +echo "Success: $SUCCESS" +echo "Failed: $FAILED" +echo "========================================" + +if [ $FAILED -gt 0 ]; then + exit 1 +fi + +echo "" +echo "All shaders compiled successfully!" +exit 0 diff --git a/src/powermonitor_base.cpp b/src/platform/powermonitor_base.cpp similarity index 100% rename from src/powermonitor_base.cpp rename to src/platform/powermonitor_base.cpp diff --git a/src/powermonitor_base.h b/src/platform/powermonitor_base.h similarity index 100% rename from src/powermonitor_base.h rename to src/platform/powermonitor_base.h diff --git a/src/powermonitor_linux.cpp b/src/platform/powermonitor_linux.cpp similarity index 100% rename from src/powermonitor_linux.cpp rename to src/platform/powermonitor_linux.cpp diff --git a/src/powermonitor_linux.h b/src/platform/powermonitor_linux.h similarity index 100% rename from src/powermonitor_linux.h rename to src/platform/powermonitor_linux.h diff --git a/src/powermonitor_macos.h b/src/platform/powermonitor_macos.h similarity index 100% rename from src/powermonitor_macos.h rename to src/platform/powermonitor_macos.h diff --git a/src/powermonitor_macos.mm b/src/platform/powermonitor_macos.mm similarity index 100% rename from src/powermonitor_macos.mm rename to src/platform/powermonitor_macos.mm diff --git a/src/screenlockdetector_base.cpp b/src/platform/screenlockdetector_base.cpp similarity index 100% rename from src/screenlockdetector_base.cpp rename to src/platform/screenlockdetector_base.cpp diff --git a/src/screenlockdetector_base.h b/src/platform/screenlockdetector_base.h similarity index 100% rename from src/screenlockdetector_base.h rename to src/platform/screenlockdetector_base.h diff --git a/src/screenlockdetector_linux.cpp b/src/platform/screenlockdetector_linux.cpp similarity index 100% rename from src/screenlockdetector_linux.cpp rename to src/platform/screenlockdetector_linux.cpp diff --git a/src/screenlockdetector_linux.h b/src/platform/screenlockdetector_linux.h similarity index 100% rename from src/screenlockdetector_linux.h rename to src/platform/screenlockdetector_linux.h diff --git a/src/screenlockdetector_macos.h b/src/platform/screenlockdetector_macos.h similarity index 100% rename from src/screenlockdetector_macos.h rename to src/platform/screenlockdetector_macos.h diff --git a/src/screenlockdetector_macos.mm b/src/platform/screenlockdetector_macos.mm similarity index 100% rename from src/screenlockdetector_macos.mm rename to src/platform/screenlockdetector_macos.mm diff --git a/src/vulkanwidget_macos.h b/src/platform/vulkanwidget_macos.h similarity index 100% rename from src/vulkanwidget_macos.h rename to src/platform/vulkanwidget_macos.h diff --git a/src/vulkanwidget_macos.mm b/src/platform/vulkanwidget_macos.mm similarity index 100% rename from src/vulkanwidget_macos.mm rename to src/platform/vulkanwidget_macos.mm diff --git a/src/powermonitor.cpp b/src/powermonitor.cpp index 55c17be..44f62a5 100644 --- a/src/powermonitor.cpp +++ b/src/powermonitor.cpp @@ -1,9 +1,9 @@ #include "powermonitor.h" #ifdef Q_OS_LINUX -#include "powermonitor_linux.h" +#include "platform/powermonitor_linux.h" #elif defined(Q_OS_MAC) -#include "powermonitor_macos.h" +#include "platform/powermonitor_macos.h" #endif #include diff --git a/src/powermonitor.h b/src/powermonitor.h index b6afad5..79f414a 100644 --- a/src/powermonitor.h +++ b/src/powermonitor.h @@ -1,7 +1,7 @@ #ifndef POWERMONITOR_H #define POWERMONITOR_H -#include "powermonitor_base.h" +#include "platform/powermonitor_base.h" /** * @brief 跨平台电源监视器工厂类 diff --git a/src/screenlockdetector.cpp b/src/screenlockdetector.cpp index 3aa8eff..6ca4dc6 100644 --- a/src/screenlockdetector.cpp +++ b/src/screenlockdetector.cpp @@ -1,11 +1,11 @@ #include "screenlockdetector.h" #ifdef Q_OS_LINUX -#include "screenlockdetector_linux.h" +#include "platform/screenlockdetector_linux.h" #endif #ifdef Q_OS_MAC -#include "screenlockdetector_macos.h" +#include "platform/screenlockdetector_macos.h" #endif #include diff --git a/src/screenlockdetector.h b/src/screenlockdetector.h index 9328020..1076a80 100644 --- a/src/screenlockdetector.h +++ b/src/screenlockdetector.h @@ -1,7 +1,7 @@ #ifndef SCREENLOCKDETECTOR_H #define SCREENLOCKDETECTOR_H -#include "screenlockdetector_base.h" +#include "platform/screenlockdetector_base.h" /** * @brief 跨平台屏幕锁定检测器工厂类 diff --git a/src/shaders_spirv/background.frag.spv b/src/shaders_spirv/background.frag.spv index a5ad5d487a694afbabd2402460fc4d68d2557c15..dd500963e3148d360a9893044266d2e08a599ffc 100644 GIT binary patch delta 50 wcmew(`bTtw0TZV?12Y3V0|NuoWL>6-;w%iDK(-&Qh82i|n83Y&@7?>s}G6_!(VG`I}!lc3o0GHti0ssI2 diff --git a/src/shaders_spirv/geometry.vert.spv b/src/shaders_spirv/geometry.vert.spv index 99fb57f1f99438e5055673ba8d38d6aa979fefd8..53bba0b060058c8817da39d2783c68dbe666e7a4 100644 GIT binary patch delta 70 zcmew$@Ihe10wzv(24)6P1_lPE$#a<|sfx97rnxF$lo;iXhJ9MCMR-W(GYVlWFrt H=KU-Hmo5q# diff --git a/src/shaders_spirv/geometry_frag.inc b/src/shaders_spirv/geometry_frag.inc index ee5898c..1b05693 100644 --- a/src/shaders_spirv/geometry_frag.inc +++ b/src/shaders_spirv/geometry_frag.inc @@ -13,13 +13,13 @@ 0x00000004u, 0x65766177u, 0x73616850u, 0x00000065u, 0x00060006u, 0x00000010u, 0x00000005u, 0x64646170u, 0x31676e69u, 0x00000000u, 0x00060006u, 0x00000010u, 0x00000006u, 0x64646170u, 0x32676e69u, 0x00000000u, 0x00030005u, 0x00000012u, 0x006f6275u, 0x00040047u, 0x00000009u, 0x0000001eu, 0x00000000u, 0x00040047u, - 0x0000000bu, 0x0000001eu, 0x00000000u, 0x00040047u, 0x0000000fu, 0x0000001eu, 0x00000001u, 0x00050048u, - 0x00000010u, 0x00000000u, 0x00000023u, 0x00000000u, 0x00050048u, 0x00000010u, 0x00000001u, 0x00000023u, - 0x00000004u, 0x00050048u, 0x00000010u, 0x00000002u, 0x00000023u, 0x00000008u, 0x00050048u, 0x00000010u, - 0x00000003u, 0x00000023u, 0x0000000cu, 0x00050048u, 0x00000010u, 0x00000004u, 0x00000023u, 0x00000010u, - 0x00050048u, 0x00000010u, 0x00000005u, 0x00000023u, 0x00000014u, 0x00050048u, 0x00000010u, 0x00000006u, - 0x00000023u, 0x00000018u, 0x00030047u, 0x00000010u, 0x00000002u, 0x00040047u, 0x00000012u, 0x00000022u, - 0x00000000u, 0x00040047u, 0x00000012u, 0x00000021u, 0x00000000u, 0x00020013u, 0x00000002u, 0x00030021u, + 0x0000000bu, 0x0000001eu, 0x00000000u, 0x00040047u, 0x0000000fu, 0x0000001eu, 0x00000001u, 0x00030047u, + 0x00000010u, 0x00000002u, 0x00050048u, 0x00000010u, 0x00000000u, 0x00000023u, 0x00000000u, 0x00050048u, + 0x00000010u, 0x00000001u, 0x00000023u, 0x00000004u, 0x00050048u, 0x00000010u, 0x00000002u, 0x00000023u, + 0x00000008u, 0x00050048u, 0x00000010u, 0x00000003u, 0x00000023u, 0x0000000cu, 0x00050048u, 0x00000010u, + 0x00000004u, 0x00000023u, 0x00000010u, 0x00050048u, 0x00000010u, 0x00000005u, 0x00000023u, 0x00000014u, + 0x00050048u, 0x00000010u, 0x00000006u, 0x00000023u, 0x00000018u, 0x00040047u, 0x00000012u, 0x00000021u, + 0x00000000u, 0x00040047u, 0x00000012u, 0x00000022u, 0x00000000u, 0x00020013u, 0x00000002u, 0x00030021u, 0x00000003u, 0x00000002u, 0x00030016u, 0x00000006u, 0x00000020u, 0x00040017u, 0x00000007u, 0x00000006u, 0x00000004u, 0x00040020u, 0x00000008u, 0x00000003u, 0x00000007u, 0x0004003bu, 0x00000008u, 0x00000009u, 0x00000003u, 0x00040020u, 0x0000000au, 0x00000001u, 0x00000007u, 0x0004003bu, 0x0000000au, 0x0000000bu, diff --git a/src/shaders_spirv/geometry_vert.inc b/src/shaders_spirv/geometry_vert.inc index d92ed87..9ccc366 100644 --- a/src/shaders_spirv/geometry_vert.inc +++ b/src/shaders_spirv/geometry_vert.inc @@ -21,15 +21,15 @@ 0x00050005u, 0x00000038u, 0x67617266u, 0x6f6c6f43u, 0x00000072u, 0x00040005u, 0x0000003au, 0x6f436e69u, 0x00726f6cu, 0x00060005u, 0x0000003du, 0x67617266u, 0x43786554u, 0x64726f6fu, 0x00000000u, 0x00050005u, 0x0000003eu, 0x65546e69u, 0x6f6f4378u, 0x00006472u, 0x00040047u, 0x0000000fu, 0x0000001eu, 0x00000000u, - 0x00050048u, 0x00000015u, 0x00000000u, 0x00000023u, 0x00000000u, 0x00050048u, 0x00000015u, 0x00000001u, - 0x00000023u, 0x00000004u, 0x00050048u, 0x00000015u, 0x00000002u, 0x00000023u, 0x00000008u, 0x00050048u, - 0x00000015u, 0x00000003u, 0x00000023u, 0x0000000cu, 0x00050048u, 0x00000015u, 0x00000004u, 0x00000023u, - 0x00000010u, 0x00050048u, 0x00000015u, 0x00000005u, 0x00000023u, 0x00000014u, 0x00050048u, 0x00000015u, - 0x00000006u, 0x00000023u, 0x00000018u, 0x00030047u, 0x00000015u, 0x00000002u, 0x00040047u, 0x00000017u, - 0x00000022u, 0x00000000u, 0x00040047u, 0x00000017u, 0x00000021u, 0x00000000u, 0x00050048u, 0x0000002eu, - 0x00000000u, 0x0000000bu, 0x00000000u, 0x00050048u, 0x0000002eu, 0x00000001u, 0x0000000bu, 0x00000001u, - 0x00050048u, 0x0000002eu, 0x00000002u, 0x0000000bu, 0x00000003u, 0x00050048u, 0x0000002eu, 0x00000003u, - 0x0000000bu, 0x00000004u, 0x00030047u, 0x0000002eu, 0x00000002u, 0x00040047u, 0x00000038u, 0x0000001eu, + 0x00030047u, 0x00000015u, 0x00000002u, 0x00050048u, 0x00000015u, 0x00000000u, 0x00000023u, 0x00000000u, + 0x00050048u, 0x00000015u, 0x00000001u, 0x00000023u, 0x00000004u, 0x00050048u, 0x00000015u, 0x00000002u, + 0x00000023u, 0x00000008u, 0x00050048u, 0x00000015u, 0x00000003u, 0x00000023u, 0x0000000cu, 0x00050048u, + 0x00000015u, 0x00000004u, 0x00000023u, 0x00000010u, 0x00050048u, 0x00000015u, 0x00000005u, 0x00000023u, + 0x00000014u, 0x00050048u, 0x00000015u, 0x00000006u, 0x00000023u, 0x00000018u, 0x00040047u, 0x00000017u, + 0x00000021u, 0x00000000u, 0x00040047u, 0x00000017u, 0x00000022u, 0x00000000u, 0x00030047u, 0x0000002eu, + 0x00000002u, 0x00050048u, 0x0000002eu, 0x00000000u, 0x0000000bu, 0x00000000u, 0x00050048u, 0x0000002eu, + 0x00000001u, 0x0000000bu, 0x00000001u, 0x00050048u, 0x0000002eu, 0x00000002u, 0x0000000bu, 0x00000003u, + 0x00050048u, 0x0000002eu, 0x00000003u, 0x0000000bu, 0x00000004u, 0x00040047u, 0x00000038u, 0x0000001eu, 0x00000000u, 0x00040047u, 0x0000003au, 0x0000001eu, 0x00000001u, 0x00040047u, 0x0000003du, 0x0000001eu, 0x00000001u, 0x00040047u, 0x0000003eu, 0x0000001eu, 0x00000002u, 0x00020013u, 0x00000002u, 0x00030021u, 0x00000003u, 0x00000002u, 0x00030016u, 0x00000006u, 0x00000020u, 0x00040020u, 0x00000007u, 0x00000007u, diff --git a/src/shaders_spirv/text.frag.spv b/src/shaders_spirv/text.frag.spv index 063e9645d24ee3c8336fedb95a72cb0a6e43e8cf..106e5e27ecdd5f5f0e8a7a44cb20badadc39e300 100644 GIT binary patch delta 62 zcmdnMy@7kf4#vqR7L0|OHfyECvbXaQ*@AO-;#UvcwB HrvFR;@G=ZX diff --git a/src/shaders_spirv/text.vert.spv b/src/shaders_spirv/text.vert.spv index e96a8af37919c94588390d8fcdad2fe57a7f1491..4eaf40d754926a52f06d8f5539ccb5919b758909 100644 GIT binary patch delta 46 zcmZ1=us~o#4HKt312cm#0|Nuo Date: Tue, 11 Nov 2025 20:49:12 +0800 Subject: [PATCH 3/5] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ac918e5..898a653 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ ## 功能特性 -- ✅ **自动检测锁屏状态**: +- ✅ **自动检测锁屏/休眠/睡眠状态**: - Linux: 通过 DBus 监听系统的锁屏/解锁事件 - macOS: 通过 NSDistributedNotificationCenter 监听系统通知 - ✅ **自动停止绘制**:屏幕锁定时自动停止所有 Paint 事件,节省系统资源 @@ -250,7 +250,7 @@ export LD_LIBRARY_PATH=$HOME/sdk/qt-5.15.2/lib:$LD_LIBRARY_PATH 3. **屏幕保护程序通知**(辅助检测) ``` - Notifications: + Notifications: - com.apple.screensaver.didstart - com.apple.screensaver.didstop ``` From c5de82f0fb10e0b99c1980321b3670426a2af8cd Mon Sep 17 00:00:00 2001 From: hoenking Date: Tue, 11 Nov 2025 20:52:14 +0800 Subject: [PATCH 4/5] Update README --- README.md | 560 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 356 insertions(+), 204 deletions(-) diff --git a/README.md b/README.md index 898a653..78c59f0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Qt Screen Lock Detection Demo -一个基于 Qt5 + CMake 的跨平台应用程序,用于检测系统的锁屏状态,并在锁屏时自动停止所有 Paint 事件。 +一个基于 Qt5 + CMake 的跨平台应用程序,用于检测系统的锁屏状态和电源状态(睡眠/唤醒),并在锁屏时自动停止所有渲染。 **支持平台:** - ✅ **Linux** (Ubuntu, Deepin, Fedora 等) @@ -8,35 +8,76 @@ ## 功能特性 -- ✅ **自动检测锁屏/休眠/睡眠状态**: +### 核心功能 + +- ✅ **自动检测锁屏状态**: - Linux: 通过 DBus 监听系统的锁屏/解锁事件 - macOS: 通过 NSDistributedNotificationCenter 监听系统通知 -- ✅ **自动停止绘制**:屏幕锁定时自动停止所有 Paint 事件,节省系统资源 -- ✅ **实时动画演示**:持续的动画效果,直观展示绘制的启用/禁用状态 -- ✅ **手动控制**:提供手动启用/禁用绘制的按钮 -- ✅ **状态监控**:实时显示锁屏状态、绘制状态和帧数统计 + +- ✅ **电源状态监控**: + - Linux: 通过 DBus login1 服务监听系统睡眠/唤醒事件 + - macOS: 通过 NSWorkspace 监听系统电源状态变化 + +- ✅ **双渲染引擎支持**: + - **Vulkan 渲染器**:高性能 GPU 加速渲染(需要 Vulkan SDK) + - Linux: 支持 Vulkan 1.0+ + - macOS: 支持 MoltenVK(Vulkan over Metal) + - 特性:MSAA 抗锯齿、动态几何、文字渲染(FreeType) + - **QPainter 渲染器**:传统 Qt 绘制(兼容性备选) + +- ✅ **自动停止渲染**:屏幕锁定或系统睡眠时自动停止所有渲染,节省系统资源 + +- ✅ **实时动画演示**: + - 动态旋转圆圈 + - 波浪效果 + - 渐变背景 + - 实时文字显示 + +- ✅ **手动控制**:提供手动启用/禁用渲染的按钮 + +- ✅ **状态监控**:实时显示锁屏状态、电源状态、渲染状态和帧数统计 + - ✅ **多平台支持**: - - Linux: 支持 GNOME、KDE、XFCE、Deepin DDE 等主流桌面环境 - - macOS: 原生系统通知支持 + - Linux: 支持 GNOME、KDE、XFCE、Deepin DDE、UKUI 等主流桌面环境 + - macOS: 原生系统通知支持,MoltenVK 集成 ## 技术架构 ### 核心组件 1. **ScreenLockDetector** - 跨平台锁屏检测器 - - **Linux**: 通过 Qt DBus 监听系统锁屏信号 + - **基础架构**: `ScreenLockDetectorBase` 抽象基类 + - **Linux**: `ScreenLockDetectorLinux` - 通过 Qt DBus 监听系统锁屏信号 - 支持 GNOME ScreenSaver、systemd-logind 和 Deepin DDE 接口 - - **macOS**: 通过 NSDistributedNotificationCenter 监听系统通知 + - **macOS**: `ScreenLockDetectorMacOS` - 通过 NSDistributedNotificationCenter 监听系统通知 - 监听 com.apple.screenIsLocked/Unlocked 通知 - 发出锁屏/解锁信号供其他组件订阅 -2. **CustomWidget** - 自定义绘制组件 - - 实现了动态动画效果(旋转圆圈、波浪效果等) - - 60 FPS 刷新率 - - 可控制的绘制启用/禁用状态 - - 帧数统计功能 +2. **PowerMonitor** - 跨平台电源监视器 + - **基础架构**: `PowerMonitorBase` 抽象基类 + - **Linux**: `PowerMonitorLinux` - 通过 DBus login1 服务监听 + - 监听 org.freedesktop.login1.Manager 的 PrepareForSleep 信号 + - **macOS**: `PowerMonitorMacOS` - 通过 NSWorkspace 监听 + - 监听 NSWorkspaceWillSleepNotification 和 NSWorkspaceDidWakeNotification + - 发出睡眠/唤醒信号 -3. **MainWindow** - 主窗口 +3. **RenderWidgetBase** - 渲染组件抽象接口 + - 定义统一的渲染器接口 + - 支持动态切换不同渲染后端 + +4. **VulkanWidget** - Vulkan 渲染组件 + - 使用 volk 动态加载 Vulkan 函数 + - 支持 MSAA 多重采样抗锯齿 + - 集成 FreeType 字体渲染 + - **macOS**: 专门的 CAMetalLayer 支持(MoltenVK) + - 自动处理窗口大小调整和设备丢失恢复 + +5. **CustomWidget** - QPainter 渲染组件 + - 传统 Qt 绘制实现 + - 作为 Vulkan 不可用时的备选方案 + - 实现了相同的动画效果 + +6. **MainWindow** - 主窗口 - 整合各个组件 - 提供用户界面和控制面板 - 实时状态显示 @@ -46,10 +87,49 @@ - **语言**:C++11 / Objective-C++ (macOS) - **GUI 框架**:Qt 5.15.2 (或更高版本) - **构建系统**:CMake 3.10+ +- **图形 API**: + - Vulkan 1.0+ (通过 volk 动态加载) + - MoltenVK (macOS) + - QPainter (备选方案) +- **字体渲染**:FreeType 2.x - **系统接口**: - - Linux: Qt DBus - - macOS: Foundation Framework (NSDistributedNotificationCenter) -- **平台**:Linux Ubuntu / macOS 10.12+ + - Linux: Qt DBus, X11 + - macOS: Foundation Framework, AppKit, QuartzCore (CAMetalLayer) +- **平台**:Linux / macOS 10.12+ + +### 项目结构 + +``` +ScreenLockDetector/ +├── CMakeLists.txt # CMake 构建配置(跨平台) +├── README.md # 项目文档 +├── build.sh # Linux 编译脚本 +├── run.sh # Linux 运行脚本 +├── build_mac.sh # macOS 编译脚本 +├── run_mac.sh # macOS 运行脚本 +├── docs/ # 文档目录 +├── third_party/ # 第三方库 +│ └── volk/ # Vulkan 函数加载器 +├── shaders/ # GLSL 着色器源码 +└── src/ + ├── main.cpp # 程序入口 + ├── mainwindow.h/cpp # 主窗口 + ├── screenlockdetector.h/cpp # 锁屏检测器工厂类 + ├── powermonitor.h/cpp # 电源监视器工厂类 + ├── renderwidgetbase.h # 渲染组件抽象接口 + ├── vulkanwidget.h/cpp # Vulkan 渲染组件 + ├── vulkanrenderer.h/cpp # Vulkan 渲染器核心 + ├── customwidget.h/cpp # QPainter 渲染组件 + └── platform/ # 平台特定代码 + ├── README.md # 平台代码组织说明 + ├── screenlockdetector_base.h/cpp # 锁屏检测基类 + ├── screenlockdetector_linux.h/cpp # Linux 实现 + ├── screenlockdetector_macos.h/mm # macOS 实现 + ├── powermonitor_base.h/cpp # 电源监视基类 + ├── powermonitor_linux.h/cpp # Linux 实现 + ├── powermonitor_macos.h/mm # macOS 实现 + └── vulkanwidget_macos.h/mm # macOS Vulkan 辅助 +``` ## 系统要求 @@ -59,13 +139,18 @@ - CMake 3.10 或更高版本 - GCC/G++ 编译器(支持 C++11) - DBus 系统服务 +- X11 开发库 +- **可选**:Vulkan SDK 1.0+ (用于 Vulkan 渲染) +- **可选**:FreeType 开发库 (用于 Vulkan 文字渲染) ### macOS - macOS 10.12 (Sierra) 或更高版本 -- Qt 5.15.2 或更高版本(可通过 Homebrew 安装) +- Qt 5.15.2 或更高版本(可通过 Homebrew 或 MacPorts 安装) - CMake 3.10 或更高版本 - Xcode Command Line Tools - Foundation 和 Cocoa 框架(系统自带) +- **可选**:Vulkan SDK 1.4+ (包含 MoltenVK,用于 Vulkan 渲染) +- **可选**:FreeType 库 (用于 Vulkan 文字渲染) ## 安装与编译 @@ -73,8 +158,9 @@ #### 1. 安装依赖 -使用 Homebrew 安装 Qt5: +使用 Homebrew 或 MacPorts 安装 Qt5: +**Homebrew:** ```bash # 安装 Homebrew(如果尚未安装) /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" @@ -84,9 +170,29 @@ brew install qt@5 # 安装 CMake(如果尚未安装) brew install cmake + +# 可选:安装 FreeType(用于文字渲染) +brew install freetype ``` -或者从 Qt 官网下载安装器:https://www.qt.io/download +**MacPorts:** +```bash +sudo port install qt5 +sudo port install cmake +sudo port install freetype +``` + +**Vulkan SDK(可选,用于 Vulkan 渲染):** +```bash +# 从 LunarG 下载并安装 +# https://vulkan.lunarg.com/sdk/home + +# 或者下载到 ~/VulkanSDK/ +# 安装后设置环境变量 +export VULKAN_SDK=~/VulkanSDK/1.4.328.1/macOS +export DYLD_LIBRARY_PATH=$VULKAN_SDK/lib:$DYLD_LIBRARY_PATH +export VK_ICD_FILENAMES=$VULKAN_SDK/share/vulkan/icd.d/MoltenVK_icd.json +``` #### 2. 编译项目 @@ -98,39 +204,39 @@ chmod +x build_mac.sh run_mac.sh ./build_mac.sh ``` -脚本会自动搜索 Qt 安装路径。如果需要手动指定,可以设置环境变量: - -```bash -export Qt5_DIR=/path/to/qt/lib/cmake/Qt5 -./build_mac.sh -``` +脚本会自动搜索 Qt 和 Vulkan SDK 安装路径。 ### Linux 平台 -#### 1. 确保 Qt5 已安装 +#### 1. 安装依赖 ```bash # Ubuntu/Debian -sudo apt-get install qt5-default qtbase5-dev libqt5dbus5 +sudo apt-get update +sudo apt-get install qt5-default qtbase5-dev libqt5dbus5 \ + libx11-dev cmake g++ + +# 可选:Vulkan 开发库 +sudo apt-get install vulkan-tools libvulkan-dev + +# 可选:FreeType 开发库 +sudo apt-get install libfreetype6-dev # Fedora -sudo dnf install qt5-qtbase-devel qt5-qtbase-gui +sudo dnf install qt5-qtbase-devel qt5-qtbase-gui \ + libX11-devel cmake gcc-c++ -# 或使用自定义安装的 Qt -ls $HOME/sdk/qt-5.15.2 +# 可选:Vulkan 和 FreeType +sudo dnf install vulkan-tools vulkan-headers freetype-devel ``` -如果 Qt5 安装在其他位置,请修改 `CMakeLists.txt` 中的 Qt5_DIR 路径或设置环境变量。 - -#### 2. 赋予脚本执行权限 +#### 2. 编译项目 ```bash +# 赋予脚本执行权限 chmod +x build.sh run.sh -``` -#### 3. 编译项目 - -```bash +# 编译 ./build.sh ``` @@ -140,71 +246,63 @@ chmod +x build.sh run.sh ### macOS 平台 -#### 方法 1:使用运行脚本(推荐) - ```bash +# 使用运行脚本(推荐,自动设置环境变量) ./run_mac.sh -``` -#### 方法 2:直接运行可执行文件 - -```bash -./build/bin/ScreenLockDetector -``` - -#### 方法 3:手动设置环境变量并运行 - -```bash -export DYLD_LIBRARY_PATH=/path/to/qt/lib:$DYLD_LIBRARY_PATH +# 或直接运行 ./build/bin/ScreenLockDetector ``` ### Linux 平台 -#### 方法 1:使用运行脚本(推荐) - ```bash +# 使用运行脚本(推荐) ./run.sh -``` -#### 方法 2:直接运行可执行文件 - -```bash -cd build/bin -./ScreenLockDetector -``` - -#### 方法 3:手动设置环境变量并运行 - -```bash -export LD_LIBRARY_PATH=$HOME/sdk/qt-5.15.2/lib:$LD_LIBRARY_PATH +# 或直接运行 ./build/bin/ScreenLockDetector ``` ## 使用说明 1. **启动应用**:运行应用后,会看到一个带有动态动画的窗口 + - 如果 Vulkan 可用,默认使用 Vulkan 渲染器 + - 否则回退到 QPainter 渲染器 -2. **测试锁屏检测**: +2. **查看渲染器类型**: + - 窗口标题显示当前使用的渲染器(Vulkan 或 QPainter) + - Vulkan 渲染器提供更好的性能和效果 + +3. **测试锁屏检测**: - **macOS**: 使用快捷键 `Ctrl + Cmd + Q` 或从菜单栏选择"锁定屏幕" - **Linux**: 使用快捷键 `Ctrl + Alt + L` 或 `Super + L` - 观察动画是否停止 - 解锁后动画应自动恢复 -3. **查看状态信息**: - - **Detector Status**:检测器是否正常工作 - - **Screen Lock Status**:当前屏幕锁定状态(🔒 LOCKED / 🔓 UNLOCKED) - - **Painting Status**:绘制是否启用(✓ ENABLED / ✗ DISABLED) - - **Frame Count**:已绘制的总帧数 +4. **测试电源监控**: + - 合上笔记本屏幕或选择"睡眠" + - 观察控制台输出睡眠/唤醒消息 + - 唤醒后渲染会自动恢复 -4. **手动控制**(可选): - - **Enable Painting**:手动启用绘制 - - **Disable Painting**:手动禁用绘制 +5. **查看状态信息**: + - **Renderer Type**:当前使用的渲染器类型 + - **Detector Status**:锁屏检测器是否正常工作 + - **Screen Lock Status**:当前屏幕锁定状态(🔒 LOCKED / 🔓 UNLOCKED) + - **Rendering Status**:渲染是否启用(✓ ENABLED / ✗ DISABLED) + - **Frame Count**:已渲染的总帧数 + - **FPS**:当前帧率(仅 Vulkan) + +6. **手动控制**(可选): + - **Enable Rendering**:手动启用渲染 + - **Disable Rendering**:手动禁用渲染 - **Reset Frame Count**:重置帧数计数器 ## 工作原理 -### Linux: DBus 监听机制 +### 锁屏检测机制 + +#### Linux: DBus 监听 应用程序通过 Qt DBus 连接到 Linux 系统的锁屏服务: @@ -224,7 +322,7 @@ export LD_LIBRARY_PATH=$HOME/sdk/qt-5.15.2/lib:$LD_LIBRARY_PATH Signal: ActiveChanged(bool) ``` -3. **KylinOS UKUI接口** +3. **KylinOS UKUI 接口** ``` Service: org.ukui.ScreenSaver Path: / @@ -232,7 +330,7 @@ export LD_LIBRARY_PATH=$HOME/sdk/qt-5.15.2/lib:$LD_LIBRARY_PATH Signals: lock(), unlock() ``` -### macOS: 分布式通知中心 +#### macOS: 分布式通知中心 应用程序通过 NSDistributedNotificationCenter 监听 macOS 系统通知: @@ -255,94 +353,141 @@ export LD_LIBRARY_PATH=$HOME/sdk/qt-5.15.2/lib:$LD_LIBRARY_PATH - com.apple.screensaver.didstop ``` -### Paint 事件控制 +### 电源监控机制 -当检测到锁屏时: -1. `ScreenLockDetector` 发出 `screenLocked()` 信号 -2. `MainWindow` 接收信号并调用 `CustomWidget::setPaintingEnabled(false)` -3. `CustomWidget` 停止动画定时器 -4. `paintEvent()` 检查启用状态,不再绘制动画内容 - -当检测到解锁时: -1. `ScreenLockDetector` 发出 `screenUnlocked()` 信号 -2. `MainWindow` 调用 `CustomWidget::setPaintingEnabled(true)` -3. `CustomWidget` 重启动画定时器 -4. 动画恢复正常绘制 - -## 项目结构 +#### Linux: DBus login1 服务 ``` -ScreenLockDetector/ -├── CMakeLists.txt # CMake 构建配置(跨平台) -├── README.md # 项目文档 -├── build.sh # Linux 编译脚本 -├── run.sh # Linux 运行脚本 -├── build_mac.sh # macOS 编译脚本 -├── run_mac.sh # macOS 运行脚本 -└── src/ - ├── main.cpp # 程序入口 - ├── mainwindow.h # 主窗口头文件 - ├── mainwindow.cpp # 主窗口实现 - ├── screenlockdetector.h # 跨平台锁屏检测器头文件 - ├── screenlockdetector.cpp # 跨平台锁屏检测器实现 - ├── screenlockdetector_mac.h # macOS 特定实现头文件 - ├── screenlockdetector_mac.mm # macOS 特定实现(Objective-C++) - ├── customwidget.h # 自定义组件头文件 - └── customwidget.cpp # 自定义组件实现 +Service: org.freedesktop.login1 +Path: /org/freedesktop/login1 +Interface: org.freedesktop.login1.Manager +Signal: PrepareForSleep(bool entering_sleep) ``` +#### macOS: NSWorkspace 通知 + +``` +NSWorkspaceWillSleepNotification - 系统即将睡眠 +NSWorkspaceDidWakeNotification - 系统已经唤醒 +``` + +### Vulkan 渲染流程 + +1. **初始化**: + - 使用 volk 动态加载 Vulkan 函数 + - 创建 Vulkan 实例(macOS 需要 portability 扩展) + - 选择物理设备(GPU) + - 创建逻辑设备和队列 + - **macOS**: 创建 CAMetalLayer 用于 MoltenVK 渲染 + +2. **渲染管线**: + - 创建 swap chain(交换链) + - 创建 render pass(渲染通道) + - 加载 SPIR-V 着色器 + - 创建图形管线(背景、几何、线条、文字) + - 设置 MSAA 多重采样 + +3. **每帧渲染**: + - 获取 swap chain 图像 + - 记录命令缓冲 + - 绘制背景、几何和文字 + - 提交到 GPU 队列 + - 呈现到屏幕 + +### 渲染控制 + +当检测到锁屏或睡眠时: +1. 相应的检测器发出信号 +2. `MainWindow` 接收信号并调用渲染器的 `setRenderingEnabled(false)` +3. 渲染器停止渲染定时器 +4. GPU 进入空闲状态,节省资源 + +当检测到解锁或唤醒时: +1. 相应的检测器发出信号 +2. `MainWindow` 调用 `setRenderingEnabled(true)` +3. 渲染器重启渲染定时器 +4. 动画恢复正常渲染 + +## 平台特定架构 + +### 设计模式 + +项目采用 **工厂模式 + 策略模式** 实现跨平台支持: + +1. **抽象基类** (`*_base.h/cpp`) + - 定义统一接口 + - 实现公共功能 + +2. **平台实现** (`*_linux.h/cpp`, `*_macos.h/mm`) + - 继承基类 + - 实现平台特定 API + +3. **工厂类** (`screenlockdetector.h/cpp`, `powermonitor.h/cpp`) + - 根据编译平台自动选择实现 + - 提供统一的公共 API + +详见:`src/platform/README.md` + ## 故障排除 ### macOS 平台 -#### 问题 1:应用无法检测到锁屏 +#### 问题 1:Vulkan 实例创建失败 -**可能原因**: -- 权限问题 -- 系统通知未正常工作 +**错误信息**:`Failed to create Vulkan instance, error code: -9` + +**原因**:MoltenVK 未正确安装或配置 + +**解决方案**: +```bash +# 确保 Vulkan SDK 已安装 +ls ~/VulkanSDK/1.4.328.1/macOS/lib/libMoltenVK.dylib + +# 设置环境变量 +export VULKAN_SDK=~/VulkanSDK/1.4.328.1/macOS +export DYLD_LIBRARY_PATH=$VULKAN_SDK/lib:$DYLD_LIBRARY_PATH +export VK_ICD_FILENAMES=$VULKAN_SDK/share/vulkan/icd.d/MoltenVK_icd.json + +# 使用 run_mac.sh 脚本运行(已包含配置) +./run_mac.sh +``` + +#### 问题 2:CAMetalLayer 错误 + +**错误信息**:`VK_ERROR_SURFACE_LOST_KHR: On-screen rendering requires a layer of type CAMetalLayer` + +**原因**:已在新版本中修复,确保使用最新代码 + +**解决方案**:重新编译项目 + +#### 问题 3:应用无法检测到锁屏 **解决方案**: ```bash # 查看应用日志 ./run_mac.sh 2>&1 | grep "ScreenLock" -# 检查系统完整性保护(SIP)状态 -csrutil status - # 确保应用有必要的权限 -``` - -#### 问题 2:编译错误 - Qt5 not found - -**解决方案**: -```bash -# 使用 Homebrew 安装 Qt5 -brew install qt@5 - -# 设置 Qt5_DIR 环境变量 -export Qt5_DIR=$(brew --prefix qt@5)/lib/cmake/Qt5 -./build_mac.sh -``` - -#### 问题 3:运行时找不到 Qt 库 - -**解决方案**: -```bash -# 设置 DYLD_LIBRARY_PATH -export DYLD_LIBRARY_PATH=$(brew --prefix qt@5)/lib:$DYLD_LIBRARY_PATH - -# 或使用 run_mac.sh 脚本(已包含此配置) -./run_mac.sh +# 系统偏好设置 > 安全性与隐私 > 隐私 ``` ### Linux 平台 -#### 问题 1:锁屏检测不工作 +#### 问题 1:Vulkan 不可用 -**可能原因**: -- DBus 服务未运行 -- 桌面环境不支持标准 DBus 接口 -- 权限不足 +**错误信息**:`Vulkan headers not found` + +**解决方案**: +```bash +# 安装 Vulkan 开发库 +sudo apt-get install vulkan-tools libvulkan-dev + +# 或手动下载 Vulkan Headers +git clone https://github.com/KhronosGroup/Vulkan-Headers.git +# 更新 CMakeLists.txt 中的 VULKAN_HEADERS_DIR +``` + +#### 问题 2:锁屏检测不工作 **解决方案**: ```bash @@ -352,87 +497,82 @@ ps aux | grep dbus # 检查 GNOME ScreenSaver 是否可用 qdbus org.gnome.ScreenSaver -# 查看应用日志输出,确认连接状态 -``` - -### 问题 2:编译错误 - Qt5 not found - -**解决方案**: -1. 确认 Qt5 安装路径:`ls $HOME/sdk/qt-5.15.2` -2. 修改 `CMakeLists.txt` 中的 Qt5_DIR 路径 -3. 或设置环境变量:`export Qt5_DIR=$HOME/sdk/qt-5.15.2/lib/cmake/Qt5` - -### 问题 3:运行时找不到 Qt 库 - -**解决方案**: -```bash -# 设置 LD_LIBRARY_PATH -export LD_LIBRARY_PATH=$HOME/sdk/qt-5.15.2/lib:$LD_LIBRARY_PATH - -# 或使用 run.sh 脚本(已包含此配置) -./run.sh -``` - -### 问题 4:警告 - Failed to connect to screen lock detection service - -**说明**:这是正常的,表示某些 DBus 接口在当前桌面环境中不可用。只要至少有一个接口连接成功,应用就能正常工作。 - -## 调试模式 - -应用程序会在控制台输出详细的调试信息: - -```bash -# 运行并查看详细日志 -./run.sh 2>&1 | tee app.log - -# 查看特定类别的日志 +# 查看应用日志输出 ./run.sh 2>&1 | grep "ScreenLockDetector" ``` -## 扩展与定制 +### 通用问题 -### 添加更多动画效果 +#### 问题:编译错误 - Qt5 not found -在 `customwidget.cpp` 中的 `drawBackground()`, `drawRotatingCircles()`, `drawWaveEffect()` 等方法中添加自定义绘制代码。 +**解决方案**: +```bash +# 设置 Qt5_DIR 环境变量 +export Qt5_DIR=/path/to/qt/lib/cmake/Qt5 -### 支持其他桌面环境 - -在 `screenlockdetector.cpp` 中添加更多 DBus 接口连接: - -```cpp -bool ScreenLockDetector::connectToKDEScreenSaver() -{ - // 添加 KDE Plasma 锁屏检测支持 - // Service: org.kde.screensaver - // ... -} +# 或修改 CMakeLists.txt 中的 Qt5_DIR 路径 ``` -### 性能优化 +## 性能优化 -调整动画刷新率(当前为 60 FPS): +### Vulkan 渲染器 -```cpp -// 在 customwidget.cpp 构造函数中 -m_animationTimer->start(33); // 30 FPS (1000/30 ≈ 33ms) +- **MSAA**:自动选择最佳采样数(最高 8x) +- **三缓冲**:使用 3 个并行帧减少延迟 +- **动态加载**:使用 volk 避免链接 Vulkan 库 +- **命令缓冲复用**:减少 CPU 开销 + +### 资源节省 + +- 锁屏时自动停止渲染(节省 GPU 资源) +- 睡眠时自动停止所有活动(节省电池) +- 最小化时暂停渲染(可选) + +## 扩展开发 + +### 添加新的平台特性 + +详见:`src/platform/README.md` + +### 自定义着色器 + +编辑 `shaders/` 目录中的 GLSL 文件,然后重新编译: + +```bash +./compile_shaders.sh +./build_mac.sh # 或 ./build.sh ``` +### 添加新的渲染效果 + +在 `VulkanRenderer` 或 `CustomWidget` 中添加自定义绘制代码。 + ## 许可证 本项目仅用于学习和演示目的。 ## 作者 -Qt Screen Lock Detection Demo +Qt Screen Lock Detection Demo Team ## 更新日志 +### v3.0.0 (2024-11-11) +- ✅ **重大更新**: 新增 Vulkan 渲染支持 +- ✅ **重大更新**: 新增电源监控功能(睡眠/唤醒检测) +- ✅ macOS: 完整的 MoltenVK 支持(包含 CAMetalLayer) +- ✅ 双渲染引擎:Vulkan + QPainter +- ✅ MSAA 抗锯齿支持 +- ✅ FreeType 字体渲染集成 +- ✅ 重构项目结构:创建 `platform/` 目录统一管理平台代码 +- ✅ 改进的跨平台架构(Factory + Strategy 模式) +- ✅ 完善的文档和故障排除指南 + ### v2.0.0 (2024) -- ✅ **重大更新**: 新增 macOS 平台支持 +- ✅ 新增 macOS 平台支持 - ✅ 实现跨平台架构(Linux + macOS) - ✅ macOS: 使用 NSDistributedNotificationCenter 监听系统通知 - ✅ 创建平台特定的构建和运行脚本 -- ✅ 更新文档,包含 macOS 使用说明 ### v1.1.0 (2024) - ✅ 新增 Deepin OS (DDE) 锁屏检测支持 @@ -441,10 +581,22 @@ Qt Screen Lock Detection Demo ### v1.0.0 (2024) - ✅ 初始版本发布 - ✅ 支持 GNOME 和 systemd-logind 锁屏检测 -- ✅ 实现自动 Paint 事件控制 +- ✅ 实现自动渲染控制 - ✅ 提供丰富的动画演示效果 -- ✅ 完整的状态监控和手动控制界面 -## 反馈与贡献 +## 技术支持 如有问题或建议,欢迎提出! + +### 相关文档 + +- [平台代码组织说明](src/platform/README.md) +- [Vulkan 渲染架构](docs/) +- [CMake 构建配置](CMakeLists.txt) + +### 相关链接 + +- [Qt Documentation](https://doc.qt.io/qt-5/) +- [Vulkan SDK](https://vulkan.lunarg.com/sdk/home) +- [MoltenVK (macOS)](https://github.com/KhronosGroup/MoltenVK) +- [volk - Vulkan Meta-Loader](https://github.com/zeux/volk) \ No newline at end of file From ce796c1c5c17d7dc4501596fc02954531b40551c Mon Sep 17 00:00:00 2001 From: hoenking Date: Tue, 11 Nov 2025 21:14:12 +0800 Subject: [PATCH 5/5] Bump project version to 3.0.0 --- CMakeLists.txt | 2 +- README.md | 18 ++-- docs/DELIVERY.md | 48 +++++----- docs/FINAL_SOLUTION.md | 2 +- docs/INDEX.md | 12 +-- docs/LIBRARY_PATH_NOTE.md | 4 +- docs/PROJECT_OVERVIEW.md | 6 +- docs/REFACTORING.md | 8 +- shaders/geometry.vert | 7 -- src/main.cpp | 19 ++-- src/shaders_spirv/geometry.vert.spv | Bin 2160 -> 2024 bytes src/shaders_spirv/geometry_vert.inc | 132 ++++++++++++++-------------- version.sh | 6 +- 13 files changed, 127 insertions(+), 137 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8613a85..698494a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.10) -project(ScreenLockDetector VERSION 1.3.0 LANGUAGES C CXX) +project(ScreenLockDetector VERSION 3.0.0 LANGUAGES C CXX) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) diff --git a/README.md b/README.md index 78c59f0..aab6fd0 100644 --- a/README.md +++ b/README.md @@ -13,18 +13,18 @@ - ✅ **自动检测锁屏状态**: - Linux: 通过 DBus 监听系统的锁屏/解锁事件 - macOS: 通过 NSDistributedNotificationCenter 监听系统通知 - + - ✅ **电源状态监控**: - Linux: 通过 DBus login1 服务监听系统睡眠/唤醒事件 - macOS: 通过 NSWorkspace 监听系统电源状态变化 - + - ✅ **双渲染引擎支持**: - **Vulkan 渲染器**:高性能 GPU 加速渲染(需要 Vulkan SDK) - Linux: 支持 Vulkan 1.0+ - macOS: 支持 MoltenVK(Vulkan over Metal) - 特性:MSAA 抗锯齿、动态几何、文字渲染(FreeType) - **QPainter 渲染器**:传统 Qt 绘制(兼容性备选) - + - ✅ **自动停止渲染**:屏幕锁定或系统睡眠时自动停止所有渲染,节省系统资源 - ✅ **实时动画演示**: @@ -32,7 +32,7 @@ - 波浪效果 - 渐变背景 - 实时文字显示 - + - ✅ **手动控制**:提供手动启用/禁用渲染的按钮 - ✅ **状态监控**:实时显示锁屏状态、电源状态、渲染状态和帧数统计 @@ -557,7 +557,7 @@ Qt Screen Lock Detection Demo Team ## 更新日志 -### v3.0.0 (2024-11-11) +### v3.0.0 (2025-11-11) - ✅ **重大更新**: 新增 Vulkan 渲染支持 - ✅ **重大更新**: 新增电源监控功能(睡眠/唤醒检测) - ✅ macOS: 完整的 MoltenVK 支持(包含 CAMetalLayer) @@ -568,17 +568,17 @@ Qt Screen Lock Detection Demo Team - ✅ 改进的跨平台架构(Factory + Strategy 模式) - ✅ 完善的文档和故障排除指南 -### v2.0.0 (2024) +### v2.0.0 (2025) - ✅ 新增 macOS 平台支持 - ✅ 实现跨平台架构(Linux + macOS) - ✅ macOS: 使用 NSDistributedNotificationCenter 监听系统通知 - ✅ 创建平台特定的构建和运行脚本 -### v1.1.0 (2024) +### v1.1.0 (2025) - ✅ 新增 Deepin OS (DDE) 锁屏检测支持 - ✅ 优化多桌面环境兼容性 -### v1.0.0 (2024) +### v1.0.0 (2025) - ✅ 初始版本发布 - ✅ 支持 GNOME 和 systemd-logind 锁屏检测 - ✅ 实现自动渲染控制 @@ -599,4 +599,4 @@ Qt Screen Lock Detection Demo Team - [Qt Documentation](https://doc.qt.io/qt-5/) - [Vulkan SDK](https://vulkan.lunarg.com/sdk/home) - [MoltenVK (macOS)](https://github.com/KhronosGroup/MoltenVK) -- [volk - Vulkan Meta-Loader](https://github.com/zeux/volk) \ No newline at end of file +- [volk - Vulkan Meta-Loader](https://github.com/zeux/volk) diff --git a/docs/DELIVERY.md b/docs/DELIVERY.md index a771734..c4a6c1e 100644 --- a/docs/DELIVERY.md +++ b/docs/DELIVERY.md @@ -2,10 +2,10 @@ ## 📦 交付信息 -**项目名称**: Qt Screen Lock Detection Demo -**交付版本**: v1.0.0 -**交付日期**: 2024 -**项目状态**: ✅ 完成并通过验证 +**项目名称**: Qt Screen Lock Detection Demo +**交付版本**: v1.0.0 +**交付日期**: 2025 +**项目状态**: ✅ 完成并通过验证 --- @@ -81,23 +81,23 @@ ## 🎯 核心功能实现 ### ✅ 功能1: 锁屏检测 -**实现状态**: 完成 -**技术方案**: Qt DBus 系统集成 -**支持环境**: +**实现状态**: 完成 +**技术方案**: Qt DBus 系统集成 +**支持环境**: - GNOME 桌面环境 (org.gnome.ScreenSaver) - KDE/XFCE/其他 (systemd-logind) **测试方法**: 按 Ctrl+Alt+L 锁屏,检查应用是否检测到 ### ✅ 功能2: 自动停止 Paint 事件 -**实现状态**: 完成 -**技术方案**: 信号槽机制 + 条件绘制 +**实现状态**: 完成 +**技术方案**: 信号槽机制 + 条件绘制 **性能提升**: 锁屏时 CPU 使用率从 2-5% 降至 <1% **测试方法**: 锁屏后观察动画停止,解锁后自动恢复 ### ✅ 功能3: 实时动画演示 -**实现状态**: 完成 +**实现状态**: 完成 **动画效果**: - 渐变背景 (颜色随时间变化) - 旋转圆圈 (8个彩色圆圈) @@ -107,7 +107,7 @@ **性能指标**: 稳定 60 FPS ### ✅ 功能4: 状态监控界面 -**实现状态**: 完成 +**实现状态**: 完成 **监控内容**: - 检测器状态 (Active/Inactive) - 锁屏状态 (🔒 Locked / 🔓 Unlocked) @@ -115,7 +115,7 @@ - 帧数统计 (实时更新) ### ✅ 功能5: 手动控制 -**实现状态**: 完成 +**实现状态**: 完成 **控制功能**: - 手动启用绘制 - 手动禁用绘制 @@ -245,9 +245,9 @@ qt_screan_lock/ ## ✅ 验证结果 -**验证日期**: 2024-11-07 -**验证工具**: `verify_project.sh` -**验证结果**: +**验证日期**: 2025-11-07 +**验证工具**: `verify_project.sh` +**验证结果**: ``` Total Checks: 18 @@ -354,11 +354,11 @@ Failed: 0 本项目已完成所有预定目标,并提供了完整的: -✅ **功能实现** - 锁屏检测、自动停止 Paint 事件、实时动画、状态监控 -✅ **代码质量** - 1,096 行高质量 C++ 代码,完整注释 -✅ **文档完善** - 1,266+ 行中文文档,多层次覆盖 -✅ **工具齐全** - 自动化编译、运行、验证脚本 -✅ **开箱即用** - 3 步即可运行,用户体验优秀 +✅ **功能实现** - 锁屏检测、自动停止 Paint 事件、实时动画、状态监控 +✅ **代码质量** - 1,096 行高质量 C++ 代码,完整注释 +✅ **文档完善** - 1,266+ 行中文文档,多层次覆盖 +✅ **工具齐全** - 自动化编译、运行、验证脚本 +✅ **开箱即用** - 3 步即可运行,用户体验优秀 **项目状态**: ✅ **生产就绪 (Production Ready)** @@ -374,12 +374,12 @@ Failed: 0 --- -**交付日期**: 2024-11-07 -**项目版本**: v1.0.0 -**交付状态**: ✅ 完成 +**交付日期**: 2025-11-07 +**项目版本**: v1.0.0 +**交付状态**: ✅ 完成 --- _感谢使用 Qt Screen Lock Detection Demo!_ -Happy Coding! 🚀 \ No newline at end of file +Happy Coding! 🚀 diff --git a/docs/FINAL_SOLUTION.md b/docs/FINAL_SOLUTION.md index 9a7d166..258d627 100644 --- a/docs/FINAL_SOLUTION.md +++ b/docs/FINAL_SOLUTION.md @@ -310,7 +310,7 @@ Position 4: screen(378, 212.5) -> NDC(0, 0) // 中心 --- -**修复完成日期**: 2024 +**修复完成日期**: 2025 **问题持续时间**: 多次迭代 **关键突破**: 使用硬编码值测试发现 UBO 传输问题 **最终原因**: GLSL vec2 对齐问题 diff --git a/docs/INDEX.md b/docs/INDEX.md index 0e82015..826d9f4 100644 --- a/docs/INDEX.md +++ b/docs/INDEX.md @@ -123,13 +123,13 @@ QUICKSTART.md → PROJECT_OVERVIEW.md → README.md → 运行测试 → 完成 ### 路径 3: 开发学习(3小时) ``` -PROJECT_OVERVIEW.md → ARCHITECTURE.md → 阅读源代码 → +PROJECT_OVERVIEW.md → ARCHITECTURE.md → 阅读源代码 → 修改代码 → 重新编译 → 测试 → 完成 ``` ### 路径 4: 完整掌握(1天) ``` -所有文档按顺序阅读 → 理解架构 → 阅读所有源代码 → +所有文档按顺序阅读 → 理解架构 → 阅读所有源代码 → 扩展新功能 → 编写测试 → 优化性能 → 完成 ``` @@ -270,10 +270,10 @@ MainWindow (主窗口) --- -**最后更新**: 2024-11-07 -**项目版本**: v1.0.0 -**索引版本**: v1.0 +**最后更新**: 2025-11-07 +**项目版本**: v1.0.0 +**索引版本**: v1.0 --- -_祝您使用愉快!Happy Coding! 🚀_ \ No newline at end of file +_祝您使用愉快!Happy Coding! 🚀_ diff --git a/docs/LIBRARY_PATH_NOTE.md b/docs/LIBRARY_PATH_NOTE.md index f5c267e..726b435 100644 --- a/docs/LIBRARY_PATH_NOTE.md +++ b/docs/LIBRARY_PATH_NOTE.md @@ -214,8 +214,8 @@ readelf -d /opt/screenlockdemo/bin/ScreenLockDemo | grep -i path ## 更新历史 -- 2024-01-01: 初始版本,添加 /usr/local/lib 和 /usr/local/lib64 支持 +- 2025-01-01: 初始版本,添加 /usr/local/lib 和 /usr/local/lib64 支持 --- -如有问题或需要进一步的库路径配置,请参考此文档或咨询系统管理员。 \ No newline at end of file +如有问题或需要进一步的库路径配置,请参考此文档或咨询系统管理员。 diff --git a/docs/PROJECT_OVERVIEW.md b/docs/PROJECT_OVERVIEW.md index 2c2ba35..02e04b3 100644 --- a/docs/PROJECT_OVERVIEW.md +++ b/docs/PROJECT_OVERVIEW.md @@ -387,8 +387,8 @@ qdbus org.gnome.ScreenSaver --- -**项目创建时间**: 2024 -**最后更新**: 2024 +**项目创建时间**: 2025 +**最后更新**: 2025 **状态**: ✅ 生产就绪 -Happy Coding! 🚀 \ No newline at end of file +Happy Coding! 🚀 diff --git a/docs/REFACTORING.md b/docs/REFACTORING.md index bc5abca..174611b 100644 --- a/docs/REFACTORING.md +++ b/docs/REFACTORING.md @@ -126,9 +126,9 @@ ScreenLockDetectorBase* ScreenLockDetector::createPlatformDetector() ScreenLockDetector *detector = new ScreenLockDetector(this); // 连接信号 -connect(detector, &ScreenLockDetector::screenLocked, +connect(detector, &ScreenLockDetector::screenLocked, this, &YourClass::onScreenLocked); -connect(detector, &ScreenLockDetector::screenUnlocked, +connect(detector, &ScreenLockDetector::screenUnlocked, this, &YourClass::onScreenUnlocked); // 初始化 @@ -230,5 +230,5 @@ ScreenLockDetector 开发团队 ## 版本历史 -- **v2.0.0** (2024): 面向对象重构 -- **v1.0.0** (2024): 初始版本 \ No newline at end of file +- **v2.0.0** (2025): 面向对象重构 +- **v1.0.0** (2025): 初始版本 diff --git a/shaders/geometry.vert b/shaders/geometry.vert index c563756..416837e 100644 --- a/shaders/geometry.vert +++ b/shaders/geometry.vert @@ -18,13 +18,6 @@ layout(binding = 0, std140) uniform UniformBufferObject { } ubo; void main() { - // ULTIMATE TEST: Use hardcoded resolution value instead of UBO - // This will prove whether the problem is in UBO binding or somewhere else - - // Hardcode the resolution we know is correct from debug output - float hardcodedWidth = 756.0; - float hardcodedHeight = 425.0; - // Now use UBO values - they should match the C++ struct exactly float ndcX = (inPosition.x / ubo.resX) * 2.0 - 1.0; float ndcY = (inPosition.y / ubo.resY) * 2.0 - 1.0; diff --git a/src/main.cpp b/src/main.cpp index 036fd1b..0bf8f59 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,36 +1,37 @@ #include #include +#include "version.h" #include "mainwindow.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); - + // 设置应用程序信息 app.setApplicationName("Screen Lock Detection Demo"); - app.setApplicationVersion("1.0.0"); + app.setApplicationVersion(APP_VERSION_STRING); app.setOrganizationName("Qt Demo"); - + qDebug() << "=============================================="; qDebug() << "Qt Screen Lock Detection Demo Starting..."; qDebug() << "Application:" << app.applicationName(); qDebug() << "Version:" << app.applicationVersion(); qDebug() << "=============================================="; - + // 创建并显示主窗口 MainWindow window; window.show(); - + qDebug() << "Main window displayed"; qDebug() << "Tip: Lock your screen (Ctrl+Alt+L or Super+L) to test the screen lock detection!"; qDebug() << ""; - + // 运行应用程序事件循环 int result = app.exec(); - + qDebug() << "=============================================="; qDebug() << "Application exiting with code:" << result; qDebug() << "=============================================="; - + return result; -} \ No newline at end of file +} diff --git a/src/shaders_spirv/geometry.vert.spv b/src/shaders_spirv/geometry.vert.spv index 53bba0b060058c8817da39d2783c68dbe666e7a4..e8e8dfbbccdc78903261b62e42e2b4380bc2a247 100644 GIT binary patch literal 2024 zcmZ{lTTc{05QRr}XTd8X0$vao@Q$J=Ac}WP@PWilP@_*~U}tg6GDBtuB|e!L6MvV# z$`=#Q*F6REVw2jgI(6x)KD|q=Z@NDS4h2Vpf#6Z#*HF+WBoNkc`|8^I+H9|A&(1I0 zA>u?(bAiMRDvDK?Y)46o4sug6FIkj4kUW&s^w+2Tw-Q5TRCBNg6%cFb-Vedck`)isPhgnjUF z4VTMQc~(UJH1a)8pI@UdaqCmmqp;zj^qr{PPSUM8srz{20KW?!YVKj}yBnGGdN3hf zbGoxbW!;dy)&1Ct^LKGx#CtMbEpQe-yM%`B0Gyc|o}|Tk@~xcL`m2R^0GU*jj zx*4mU_c0^B-EMc^M}P3e;@;t{lSf-CSvSiaR(CumsYmD;PKkLF@2zB6-j?Zd;WvL1nQ!XN@KpJle*XsoPdp~-eK+N#5QFg(au@m%cX5|jL7DGn-bPcX&?8d z%ReEVd}>ap3cRBKPdM|G{G3lLXJW$v7-zy&Q$k(N#2zVa@<*i;%Nh9D&q=hNnLX~z z?@z7gi?XZrresrtJGrKv8gMeM&+Da4&V)R0X)*W^`k2wqz2j#NY`#xm*7q&xEbGht zkjf^X9|>ZqO+Gg70Sy0wc6v5HHovQ2_?NU3YusV;Ucih?-V5=IdXvn{j4WdQ2;uud zEbnAM!frP24EwpF;CWEO+kpSa%HhuVu7MK+FJlt8gfENXdj|eXG31<;kO%&=#LkyE zJpL%L3(~>i@`*a8KQQa3DV=`c$!K?jT zl?`tFa6e#HcUC$*ntfY3F)iI99L`CI0p}f1hd$x`o`koCZ`+|mf literal 2160 zcmZ{lTTj$b5XUQf0To3=zzbpl#S4lzKoq&?lE4Fro8a}ylx=snW@$;cDDjEJnE1K; z41O42O#J^&d!RA#nBmO)=Xz$QYpG|d*Ktlbr=31$&B@N7(<8(YRyFs=*7nwHH}z-d z<{w~j)+rf7YzAb-DT{W!FoGWtVYn!ICR!G)h)Vj`qx+{EEAlA%RFtbvy0(}2jo1(T zccGuQv8y_#iuh&_w%V!j?-w5VjrY1FS4`e8s>j_h4P#YOaeAF$>E1+PGfsA2?l+r3 z@@nT(&`1@vVs!YX;cmcfG2WE~T@%-0)Gh2oW>+=7bRmgTFUy91hV!m3-shm+_PPYN zct!l4=lfyQdMNe?uO8!%z$@z0sP6rpSbW);6t8!h-1K8sa;x*P9wcvrBn=KEnpof* zbhZgq^#GhV89a>A?eJ^<-b}~aq^otpz4fr0dQl@#yiCU%(d~CSM>^^=iy$3+XU@&U zYt`aToEWTZ<{m~FLe1;|Hm`$&S{x_7MB~d|gwZj&q4%;s;~3~{C>JxN#!Y#^bEdNE z2;+TV^xoRx1IAuijQ4=CI~KzS>|6n3R$vzj7;^%dHTFFJvk9(B$8<{xh>330H$z|#pQdQg&%0OKB5plfFHB{F0 z9YbIpOFR|V!4vf>ZTU(rCesNV8fE>wJYKf4|&i?ng4n5 z*b;MGnVCEM|A?F;(vu%saw0RM3@e+txsr)XPUd(im+`+W9$RwQH|9NFv$89l;~cKq zn%Re9ylKhApeJ{A6N{OR>F>Q<#%Ej_W^HZILDX?yH*-PHJCOO_z--;-2PButF(=~S zzn~jiV&jj@zJQ^Bs+*dv9+}^1F!axLV{2!J%szqHS+Y;qFKB0ZFK^^v^IHht54P+P z-ygS?`8_Yn{r||5xxAui__BBK__1>@6rKGT60uY4&9ZXQ2fkNuY?$X25j((~t<6}D z|BwwnS4H@Nf6uXNInMmQ<=BLHa92b<)D33qxh|f1rbIT^4e{W%o}1#SXIf-!ZixrC z_1qSZAGodOj(G55Ju{NQT@m%rH!vHQ|4gXS%8$ikQ&;zy{k#YpaQ4R)Q78NIM8wXq iXT(Ovo>=%UiP#x*>=rUQc4pP!nU1|d{-bSK6#WI_YM9&r diff --git a/src/shaders_spirv/geometry_vert.inc b/src/shaders_spirv/geometry_vert.inc index 9ccc366..c1d6221 100644 --- a/src/shaders_spirv/geometry_vert.inc +++ b/src/shaders_spirv/geometry_vert.inc @@ -1,70 +1,66 @@ // Auto-generated from geometry.vert.spv -// Size: 2160 bytes (540 words) - 0x07230203u, 0x00010000u, 0x0008000bu, 0x00000040u, 0x00000000u, 0x00020011u, 0x00000001u, 0x0006000bu, +// Size: 2024 bytes (506 words) + 0x07230203u, 0x00010000u, 0x0008000bu, 0x0000003cu, 0x00000000u, 0x00020011u, 0x00000001u, 0x0006000bu, 0x00000001u, 0x4c534c47u, 0x6474732eu, 0x3035342eu, 0x00000000u, 0x0003000eu, 0x00000000u, 0x00000001u, - 0x000b000fu, 0x00000000u, 0x00000004u, 0x6e69616du, 0x00000000u, 0x0000000fu, 0x00000030u, 0x00000038u, - 0x0000003au, 0x0000003du, 0x0000003eu, 0x00030003u, 0x00000002u, 0x000001c2u, 0x00040005u, 0x00000004u, - 0x6e69616du, 0x00000000u, 0x00060005u, 0x00000008u, 0x64726168u, 0x65646f63u, 0x64695764u, 0x00006874u, - 0x00060005u, 0x0000000au, 0x64726168u, 0x65646f63u, 0x69654864u, 0x00746867u, 0x00040005u, 0x0000000cu, - 0x5863646eu, 0x00000000u, 0x00050005u, 0x0000000fu, 0x6f506e69u, 0x69746973u, 0x00006e6fu, 0x00070005u, - 0x00000015u, 0x66696e55u, 0x426d726fu, 0x65666675u, 0x6a624f72u, 0x00746365u, 0x00050006u, 0x00000015u, - 0x00000000u, 0x656d6974u, 0x00000000u, 0x00050006u, 0x00000015u, 0x00000001u, 0x58736572u, 0x00000000u, - 0x00050006u, 0x00000015u, 0x00000002u, 0x59736572u, 0x00000000u, 0x00060006u, 0x00000015u, 0x00000003u, - 0x61746f72u, 0x6e6f6974u, 0x00000000u, 0x00060006u, 0x00000015u, 0x00000004u, 0x65766177u, 0x73616850u, - 0x00000065u, 0x00060006u, 0x00000015u, 0x00000005u, 0x64646170u, 0x31676e69u, 0x00000000u, 0x00060006u, - 0x00000015u, 0x00000006u, 0x64646170u, 0x32676e69u, 0x00000000u, 0x00030005u, 0x00000017u, 0x006f6275u, - 0x00040005u, 0x00000022u, 0x5963646eu, 0x00000000u, 0x00060005u, 0x0000002eu, 0x505f6c67u, 0x65567265u, - 0x78657472u, 0x00000000u, 0x00060006u, 0x0000002eu, 0x00000000u, 0x505f6c67u, 0x7469736fu, 0x006e6f69u, - 0x00070006u, 0x0000002eu, 0x00000001u, 0x505f6c67u, 0x746e696fu, 0x657a6953u, 0x00000000u, 0x00070006u, - 0x0000002eu, 0x00000002u, 0x435f6c67u, 0x4470696cu, 0x61747369u, 0x0065636eu, 0x00070006u, 0x0000002eu, - 0x00000003u, 0x435f6c67u, 0x446c6c75u, 0x61747369u, 0x0065636eu, 0x00030005u, 0x00000030u, 0x00000000u, - 0x00050005u, 0x00000038u, 0x67617266u, 0x6f6c6f43u, 0x00000072u, 0x00040005u, 0x0000003au, 0x6f436e69u, - 0x00726f6cu, 0x00060005u, 0x0000003du, 0x67617266u, 0x43786554u, 0x64726f6fu, 0x00000000u, 0x00050005u, - 0x0000003eu, 0x65546e69u, 0x6f6f4378u, 0x00006472u, 0x00040047u, 0x0000000fu, 0x0000001eu, 0x00000000u, - 0x00030047u, 0x00000015u, 0x00000002u, 0x00050048u, 0x00000015u, 0x00000000u, 0x00000023u, 0x00000000u, - 0x00050048u, 0x00000015u, 0x00000001u, 0x00000023u, 0x00000004u, 0x00050048u, 0x00000015u, 0x00000002u, - 0x00000023u, 0x00000008u, 0x00050048u, 0x00000015u, 0x00000003u, 0x00000023u, 0x0000000cu, 0x00050048u, - 0x00000015u, 0x00000004u, 0x00000023u, 0x00000010u, 0x00050048u, 0x00000015u, 0x00000005u, 0x00000023u, - 0x00000014u, 0x00050048u, 0x00000015u, 0x00000006u, 0x00000023u, 0x00000018u, 0x00040047u, 0x00000017u, - 0x00000021u, 0x00000000u, 0x00040047u, 0x00000017u, 0x00000022u, 0x00000000u, 0x00030047u, 0x0000002eu, - 0x00000002u, 0x00050048u, 0x0000002eu, 0x00000000u, 0x0000000bu, 0x00000000u, 0x00050048u, 0x0000002eu, - 0x00000001u, 0x0000000bu, 0x00000001u, 0x00050048u, 0x0000002eu, 0x00000002u, 0x0000000bu, 0x00000003u, - 0x00050048u, 0x0000002eu, 0x00000003u, 0x0000000bu, 0x00000004u, 0x00040047u, 0x00000038u, 0x0000001eu, - 0x00000000u, 0x00040047u, 0x0000003au, 0x0000001eu, 0x00000001u, 0x00040047u, 0x0000003du, 0x0000001eu, - 0x00000001u, 0x00040047u, 0x0000003eu, 0x0000001eu, 0x00000002u, 0x00020013u, 0x00000002u, 0x00030021u, - 0x00000003u, 0x00000002u, 0x00030016u, 0x00000006u, 0x00000020u, 0x00040020u, 0x00000007u, 0x00000007u, - 0x00000006u, 0x0004002bu, 0x00000006u, 0x00000009u, 0x443d0000u, 0x0004002bu, 0x00000006u, 0x0000000bu, - 0x43d48000u, 0x00040017u, 0x0000000du, 0x00000006u, 0x00000002u, 0x00040020u, 0x0000000eu, 0x00000001u, - 0x0000000du, 0x0004003bu, 0x0000000eu, 0x0000000fu, 0x00000001u, 0x00040015u, 0x00000010u, 0x00000020u, - 0x00000000u, 0x0004002bu, 0x00000010u, 0x00000011u, 0x00000000u, 0x00040020u, 0x00000012u, 0x00000001u, - 0x00000006u, 0x0009001eu, 0x00000015u, 0x00000006u, 0x00000006u, 0x00000006u, 0x00000006u, 0x00000006u, - 0x00000006u, 0x00000006u, 0x00040020u, 0x00000016u, 0x00000002u, 0x00000015u, 0x0004003bu, 0x00000016u, - 0x00000017u, 0x00000002u, 0x00040015u, 0x00000018u, 0x00000020u, 0x00000001u, 0x0004002bu, 0x00000018u, - 0x00000019u, 0x00000001u, 0x00040020u, 0x0000001au, 0x00000002u, 0x00000006u, 0x0004002bu, 0x00000006u, - 0x0000001eu, 0x40000000u, 0x0004002bu, 0x00000006u, 0x00000020u, 0x3f800000u, 0x0004002bu, 0x00000010u, - 0x00000023u, 0x00000001u, 0x0004002bu, 0x00000018u, 0x00000026u, 0x00000002u, 0x00040017u, 0x0000002cu, - 0x00000006u, 0x00000004u, 0x0004001cu, 0x0000002du, 0x00000006u, 0x00000023u, 0x0006001eu, 0x0000002eu, - 0x0000002cu, 0x00000006u, 0x0000002du, 0x0000002du, 0x00040020u, 0x0000002fu, 0x00000003u, 0x0000002eu, - 0x0004003bu, 0x0000002fu, 0x00000030u, 0x00000003u, 0x0004002bu, 0x00000018u, 0x00000031u, 0x00000000u, - 0x0004002bu, 0x00000006u, 0x00000034u, 0x00000000u, 0x00040020u, 0x00000036u, 0x00000003u, 0x0000002cu, - 0x0004003bu, 0x00000036u, 0x00000038u, 0x00000003u, 0x00040020u, 0x00000039u, 0x00000001u, 0x0000002cu, - 0x0004003bu, 0x00000039u, 0x0000003au, 0x00000001u, 0x00040020u, 0x0000003cu, 0x00000003u, 0x0000000du, - 0x0004003bu, 0x0000003cu, 0x0000003du, 0x00000003u, 0x0004003bu, 0x0000000eu, 0x0000003eu, 0x00000001u, - 0x00050036u, 0x00000002u, 0x00000004u, 0x00000000u, 0x00000003u, 0x000200f8u, 0x00000005u, 0x0004003bu, - 0x00000007u, 0x00000008u, 0x00000007u, 0x0004003bu, 0x00000007u, 0x0000000au, 0x00000007u, 0x0004003bu, - 0x00000007u, 0x0000000cu, 0x00000007u, 0x0004003bu, 0x00000007u, 0x00000022u, 0x00000007u, 0x0003003eu, - 0x00000008u, 0x00000009u, 0x0003003eu, 0x0000000au, 0x0000000bu, 0x00050041u, 0x00000012u, 0x00000013u, - 0x0000000fu, 0x00000011u, 0x0004003du, 0x00000006u, 0x00000014u, 0x00000013u, 0x00050041u, 0x0000001au, - 0x0000001bu, 0x00000017u, 0x00000019u, 0x0004003du, 0x00000006u, 0x0000001cu, 0x0000001bu, 0x00050088u, - 0x00000006u, 0x0000001du, 0x00000014u, 0x0000001cu, 0x00050085u, 0x00000006u, 0x0000001fu, 0x0000001du, - 0x0000001eu, 0x00050083u, 0x00000006u, 0x00000021u, 0x0000001fu, 0x00000020u, 0x0003003eu, 0x0000000cu, - 0x00000021u, 0x00050041u, 0x00000012u, 0x00000024u, 0x0000000fu, 0x00000023u, 0x0004003du, 0x00000006u, - 0x00000025u, 0x00000024u, 0x00050041u, 0x0000001au, 0x00000027u, 0x00000017u, 0x00000026u, 0x0004003du, - 0x00000006u, 0x00000028u, 0x00000027u, 0x00050088u, 0x00000006u, 0x00000029u, 0x00000025u, 0x00000028u, - 0x00050085u, 0x00000006u, 0x0000002au, 0x00000029u, 0x0000001eu, 0x00050083u, 0x00000006u, 0x0000002bu, - 0x0000002au, 0x00000020u, 0x0003003eu, 0x00000022u, 0x0000002bu, 0x0004003du, 0x00000006u, 0x00000032u, - 0x0000000cu, 0x0004003du, 0x00000006u, 0x00000033u, 0x00000022u, 0x00070050u, 0x0000002cu, 0x00000035u, - 0x00000032u, 0x00000033u, 0x00000034u, 0x00000020u, 0x00050041u, 0x00000036u, 0x00000037u, 0x00000030u, - 0x00000031u, 0x0003003eu, 0x00000037u, 0x00000035u, 0x0004003du, 0x0000002cu, 0x0000003bu, 0x0000003au, - 0x0003003eu, 0x00000038u, 0x0000003bu, 0x0004003du, 0x0000000du, 0x0000003fu, 0x0000003eu, 0x0003003eu, - 0x0000003du, 0x0000003fu, 0x000100fdu, 0x00010038u + 0x000b000fu, 0x00000000u, 0x00000004u, 0x6e69616du, 0x00000000u, 0x0000000bu, 0x0000002cu, 0x00000034u, + 0x00000036u, 0x00000039u, 0x0000003au, 0x00030003u, 0x00000002u, 0x000001c2u, 0x00040005u, 0x00000004u, + 0x6e69616du, 0x00000000u, 0x00040005u, 0x00000008u, 0x5863646eu, 0x00000000u, 0x00050005u, 0x0000000bu, + 0x6f506e69u, 0x69746973u, 0x00006e6fu, 0x00070005u, 0x00000011u, 0x66696e55u, 0x426d726fu, 0x65666675u, + 0x6a624f72u, 0x00746365u, 0x00050006u, 0x00000011u, 0x00000000u, 0x656d6974u, 0x00000000u, 0x00050006u, + 0x00000011u, 0x00000001u, 0x58736572u, 0x00000000u, 0x00050006u, 0x00000011u, 0x00000002u, 0x59736572u, + 0x00000000u, 0x00060006u, 0x00000011u, 0x00000003u, 0x61746f72u, 0x6e6f6974u, 0x00000000u, 0x00060006u, + 0x00000011u, 0x00000004u, 0x65766177u, 0x73616850u, 0x00000065u, 0x00060006u, 0x00000011u, 0x00000005u, + 0x64646170u, 0x31676e69u, 0x00000000u, 0x00060006u, 0x00000011u, 0x00000006u, 0x64646170u, 0x32676e69u, + 0x00000000u, 0x00030005u, 0x00000013u, 0x006f6275u, 0x00040005u, 0x0000001eu, 0x5963646eu, 0x00000000u, + 0x00060005u, 0x0000002au, 0x505f6c67u, 0x65567265u, 0x78657472u, 0x00000000u, 0x00060006u, 0x0000002au, + 0x00000000u, 0x505f6c67u, 0x7469736fu, 0x006e6f69u, 0x00070006u, 0x0000002au, 0x00000001u, 0x505f6c67u, + 0x746e696fu, 0x657a6953u, 0x00000000u, 0x00070006u, 0x0000002au, 0x00000002u, 0x435f6c67u, 0x4470696cu, + 0x61747369u, 0x0065636eu, 0x00070006u, 0x0000002au, 0x00000003u, 0x435f6c67u, 0x446c6c75u, 0x61747369u, + 0x0065636eu, 0x00030005u, 0x0000002cu, 0x00000000u, 0x00050005u, 0x00000034u, 0x67617266u, 0x6f6c6f43u, + 0x00000072u, 0x00040005u, 0x00000036u, 0x6f436e69u, 0x00726f6cu, 0x00060005u, 0x00000039u, 0x67617266u, + 0x43786554u, 0x64726f6fu, 0x00000000u, 0x00050005u, 0x0000003au, 0x65546e69u, 0x6f6f4378u, 0x00006472u, + 0x00040047u, 0x0000000bu, 0x0000001eu, 0x00000000u, 0x00030047u, 0x00000011u, 0x00000002u, 0x00050048u, + 0x00000011u, 0x00000000u, 0x00000023u, 0x00000000u, 0x00050048u, 0x00000011u, 0x00000001u, 0x00000023u, + 0x00000004u, 0x00050048u, 0x00000011u, 0x00000002u, 0x00000023u, 0x00000008u, 0x00050048u, 0x00000011u, + 0x00000003u, 0x00000023u, 0x0000000cu, 0x00050048u, 0x00000011u, 0x00000004u, 0x00000023u, 0x00000010u, + 0x00050048u, 0x00000011u, 0x00000005u, 0x00000023u, 0x00000014u, 0x00050048u, 0x00000011u, 0x00000006u, + 0x00000023u, 0x00000018u, 0x00040047u, 0x00000013u, 0x00000021u, 0x00000000u, 0x00040047u, 0x00000013u, + 0x00000022u, 0x00000000u, 0x00030047u, 0x0000002au, 0x00000002u, 0x00050048u, 0x0000002au, 0x00000000u, + 0x0000000bu, 0x00000000u, 0x00050048u, 0x0000002au, 0x00000001u, 0x0000000bu, 0x00000001u, 0x00050048u, + 0x0000002au, 0x00000002u, 0x0000000bu, 0x00000003u, 0x00050048u, 0x0000002au, 0x00000003u, 0x0000000bu, + 0x00000004u, 0x00040047u, 0x00000034u, 0x0000001eu, 0x00000000u, 0x00040047u, 0x00000036u, 0x0000001eu, + 0x00000001u, 0x00040047u, 0x00000039u, 0x0000001eu, 0x00000001u, 0x00040047u, 0x0000003au, 0x0000001eu, + 0x00000002u, 0x00020013u, 0x00000002u, 0x00030021u, 0x00000003u, 0x00000002u, 0x00030016u, 0x00000006u, + 0x00000020u, 0x00040020u, 0x00000007u, 0x00000007u, 0x00000006u, 0x00040017u, 0x00000009u, 0x00000006u, + 0x00000002u, 0x00040020u, 0x0000000au, 0x00000001u, 0x00000009u, 0x0004003bu, 0x0000000au, 0x0000000bu, + 0x00000001u, 0x00040015u, 0x0000000cu, 0x00000020u, 0x00000000u, 0x0004002bu, 0x0000000cu, 0x0000000du, + 0x00000000u, 0x00040020u, 0x0000000eu, 0x00000001u, 0x00000006u, 0x0009001eu, 0x00000011u, 0x00000006u, + 0x00000006u, 0x00000006u, 0x00000006u, 0x00000006u, 0x00000006u, 0x00000006u, 0x00040020u, 0x00000012u, + 0x00000002u, 0x00000011u, 0x0004003bu, 0x00000012u, 0x00000013u, 0x00000002u, 0x00040015u, 0x00000014u, + 0x00000020u, 0x00000001u, 0x0004002bu, 0x00000014u, 0x00000015u, 0x00000001u, 0x00040020u, 0x00000016u, + 0x00000002u, 0x00000006u, 0x0004002bu, 0x00000006u, 0x0000001au, 0x40000000u, 0x0004002bu, 0x00000006u, + 0x0000001cu, 0x3f800000u, 0x0004002bu, 0x0000000cu, 0x0000001fu, 0x00000001u, 0x0004002bu, 0x00000014u, + 0x00000022u, 0x00000002u, 0x00040017u, 0x00000028u, 0x00000006u, 0x00000004u, 0x0004001cu, 0x00000029u, + 0x00000006u, 0x0000001fu, 0x0006001eu, 0x0000002au, 0x00000028u, 0x00000006u, 0x00000029u, 0x00000029u, + 0x00040020u, 0x0000002bu, 0x00000003u, 0x0000002au, 0x0004003bu, 0x0000002bu, 0x0000002cu, 0x00000003u, + 0x0004002bu, 0x00000014u, 0x0000002du, 0x00000000u, 0x0004002bu, 0x00000006u, 0x00000030u, 0x00000000u, + 0x00040020u, 0x00000032u, 0x00000003u, 0x00000028u, 0x0004003bu, 0x00000032u, 0x00000034u, 0x00000003u, + 0x00040020u, 0x00000035u, 0x00000001u, 0x00000028u, 0x0004003bu, 0x00000035u, 0x00000036u, 0x00000001u, + 0x00040020u, 0x00000038u, 0x00000003u, 0x00000009u, 0x0004003bu, 0x00000038u, 0x00000039u, 0x00000003u, + 0x0004003bu, 0x0000000au, 0x0000003au, 0x00000001u, 0x00050036u, 0x00000002u, 0x00000004u, 0x00000000u, + 0x00000003u, 0x000200f8u, 0x00000005u, 0x0004003bu, 0x00000007u, 0x00000008u, 0x00000007u, 0x0004003bu, + 0x00000007u, 0x0000001eu, 0x00000007u, 0x00050041u, 0x0000000eu, 0x0000000fu, 0x0000000bu, 0x0000000du, + 0x0004003du, 0x00000006u, 0x00000010u, 0x0000000fu, 0x00050041u, 0x00000016u, 0x00000017u, 0x00000013u, + 0x00000015u, 0x0004003du, 0x00000006u, 0x00000018u, 0x00000017u, 0x00050088u, 0x00000006u, 0x00000019u, + 0x00000010u, 0x00000018u, 0x00050085u, 0x00000006u, 0x0000001bu, 0x00000019u, 0x0000001au, 0x00050083u, + 0x00000006u, 0x0000001du, 0x0000001bu, 0x0000001cu, 0x0003003eu, 0x00000008u, 0x0000001du, 0x00050041u, + 0x0000000eu, 0x00000020u, 0x0000000bu, 0x0000001fu, 0x0004003du, 0x00000006u, 0x00000021u, 0x00000020u, + 0x00050041u, 0x00000016u, 0x00000023u, 0x00000013u, 0x00000022u, 0x0004003du, 0x00000006u, 0x00000024u, + 0x00000023u, 0x00050088u, 0x00000006u, 0x00000025u, 0x00000021u, 0x00000024u, 0x00050085u, 0x00000006u, + 0x00000026u, 0x00000025u, 0x0000001au, 0x00050083u, 0x00000006u, 0x00000027u, 0x00000026u, 0x0000001cu, + 0x0003003eu, 0x0000001eu, 0x00000027u, 0x0004003du, 0x00000006u, 0x0000002eu, 0x00000008u, 0x0004003du, + 0x00000006u, 0x0000002fu, 0x0000001eu, 0x00070050u, 0x00000028u, 0x00000031u, 0x0000002eu, 0x0000002fu, + 0x00000030u, 0x0000001cu, 0x00050041u, 0x00000032u, 0x00000033u, 0x0000002cu, 0x0000002du, 0x0003003eu, + 0x00000033u, 0x00000031u, 0x0004003du, 0x00000028u, 0x00000037u, 0x00000036u, 0x0003003eu, 0x00000034u, + 0x00000037u, 0x0004003du, 0x00000009u, 0x0000003bu, 0x0000003au, 0x0003003eu, 0x00000039u, 0x0000003bu, + 0x000100fdu, 0x00010038u diff --git a/version.sh b/version.sh index 91fb0a8..adaec69 100644 --- a/version.sh +++ b/version.sh @@ -4,10 +4,10 @@ # DO NOT EDIT THIS FILE MANUALLY - Edit CMakeLists.txt instead # This file is sourced by shell scripts to get version information -APP_VERSION_MAJOR=1 -APP_VERSION_MINOR=3 +APP_VERSION_MAJOR=3 +APP_VERSION_MINOR=0 APP_VERSION_PATCH=0 -APP_VERSION="1.3.0" +APP_VERSION="3.0.0" # Export for use in other scripts export APP_VERSION_MAJOR