diff --git a/CMakeLists.txt b/CMakeLists.txt index 2181e15..208c04c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,5 +96,5 @@ target_include_directories(${PROJECT_NAME} PUBLIC ) if(BUILD_EXAMPLES) - #add_subdirectory(examples) + add_subdirectory(examples) endif() diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index d106427..3b02bc1 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,11 +1,11 @@ -find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets) -find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets) +find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets Quick) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets Quick) if(TARGET Qt${QT_VERSION_MAJOR}::Widgets) add_subdirectory(widget) - add_subdirectory(mainwindow) + #add_subdirectory(mainwindow) endif() if(TARGET Qt${QT_VERSION_MAJOR}::Quick) - add_subdirectory(quick) + #add_subdirectory(quick) endif() diff --git a/examples/widget/main.cpp b/examples/widget/main.cpp index b6e11cc..bb6e9c7 100644 --- a/examples/widget/main.cpp +++ b/examples/widget/main.cpp @@ -27,7 +27,6 @@ int main(int argc, char *argv[]) { - QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); diff --git a/examples/widget/widget.cpp b/examples/widget/widget.cpp index 2f74fa0..51b662b 100644 --- a/examples/widget/widget.cpp +++ b/examples/widget/widget.cpp @@ -23,14 +23,12 @@ */ #include "widget.h" -#include #include #include #include #include #include -#include "../../utilities.h" -#include "../../framelesswindowsmanager.h" +#include FRAMELESSHELPER_USE_NAMESPACE @@ -80,8 +78,8 @@ Widget::Widget(QWidget *parent) : QWidget(parent) { setAttribute(Qt::WA_DontCreateNativeAncestors); createWinId(); - setupUi(); - startTimer(500); + //setupUi(); + //startTimer(500); } Widget::~Widget() = default; @@ -92,18 +90,7 @@ void Widget::showEvent(QShowEvent *event) static bool inited = false; if (!inited) { inited = true; - QWindow *win = windowHandle(); - Q_ASSERT(win); - if (!win) { - qFatal("Failed to retrieve the window handle."); - return; - } - FramelessWindowsManager::addWindow(win); - FramelessWindowsManager::setHitTestVisible(win, m_minimizeButton, true); - FramelessWindowsManager::setHitTestVisible(win, m_maximizeButton, true); - FramelessWindowsManager::setHitTestVisible(win, m_closeButton, true); - const auto margin = static_cast(qRound(frameBorderThickness())); - setContentsMargins(margin, margin, margin, margin); + FramelessWindowsManager::addWindow(windowHandle()); } } @@ -118,6 +105,7 @@ void Widget::timerEvent(QTimerEvent *event) void Widget::changeEvent(QEvent *event) { QWidget::changeEvent(event); +#if 0 bool shouldUpdate = false; if (event->type() == QEvent::WindowStateChange) { if (isMaximized() || isFullScreen()) { @@ -135,45 +123,17 @@ void Widget::changeEvent(QEvent *event) if (shouldUpdate) { updateStyleSheet(); } +#endif } void Widget::paintEvent(QPaintEvent *event) { QWidget::paintEvent(event); - if ((windowState() == Qt::WindowNoState) -#ifdef Q_OS_WINDOWS - && !Utilities::isWin11OrGreater() -#endif - ) { - const qreal borderThickness = frameBorderThickness(); - const auto w = static_cast(width()); - const auto h = static_cast(height()); -#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) - using BorderLines = QList; -#else - using BorderLines = QVector; -#endif - const BorderLines lines = { - {0, 0, w, 0}, - {w - borderThickness, 0, w - borderThickness, h}, - {w, h - borderThickness, 0, h - borderThickness}, - {0, h, 0, 0} - }; - const ColorizationArea area = Utilities::getColorizationArea(); - const bool colorizedBorder = ((area == ColorizationArea::TitleBar_WindowBorder) - || (area == ColorizationArea::All)); - const QColor borderColor = (isActiveWindow() ? (colorizedBorder ? Utilities::getColorizationColor() : Qt::black) : Qt::darkGray); - QPainter painter(this); - painter.save(); - painter.setRenderHint(QPainter::Antialiasing, false); - painter.setPen({borderColor, borderThickness}); - painter.drawLines(lines); - painter.restore(); - } } void Widget::setupUi() { +#if 0 setObjectName(QStringLiteral("MainWidget")); setWindowTitle(tr("Hello, World!")); resize(800, 600); @@ -205,7 +165,6 @@ void Widget::setupUi() m_closeButton->setObjectName(QStringLiteral("CloseButton")); connect(m_closeButton, &QPushButton::clicked, this, &Widget::close); updateSystemButtonIcons(); - updateTitleBarSize(); const auto titleBarLayout = new QHBoxLayout(m_titleBarWidget); titleBarLayout->setContentsMargins(0, 0, 0, 0); titleBarLayout->setSpacing(0); @@ -238,66 +197,16 @@ void Widget::setupUi() mainLayout->addStretch(); setLayout(mainLayout); updateStyleSheet(); +#endif } void Widget::updateStyleSheet() { - const bool active = isActiveWindow(); - const bool dark = Utilities::shouldAppsUseDarkMode(); - const ColorizationArea area = Utilities::getColorizationArea(); - const bool colorizedTitleBar = ((area == ColorizationArea::TitleBar_WindowBorder) - || (area == ColorizationArea::All)); - const QColor colorizationColor = Utilities::getColorizationColor(); - const QColor mainWidgetBackgroundColor = (dark ? systemDarkColor : systemLightColor); - const QColor titleBarWidgetBackgroundColor = [active, colorizedTitleBar, &colorizationColor, dark]{ - if (active) { - if (colorizedTitleBar) { - return colorizationColor; - } else { - if (dark) { - return QColor(Qt::black); - } else { - return QColor(Qt::white); - } - } - } else { - if (dark) { - return systemDarkColor; - } else { - return QColor(Qt::white); - } - } - }(); - const QColor windowTitleLabelTextColor = (active ? (dark ? Qt::white : Qt::black) : Qt::darkGray); - const QColor clockLabelTextColor = (dark ? Qt::white : Qt::black); - setStyleSheet(QString::fromUtf8(mainStyleSheet) - .arg(mainWidgetBackgroundColor.name(), - titleBarWidgetBackgroundColor.name(), - windowTitleLabelTextColor.name(), - clockLabelTextColor.name())); - update(); -} - -void Widget::updateTitleBarSize() -{ - const QWindow *win = windowHandle(); - Q_ASSERT(win); - if (!win) { - return; - } - const int titleBarHeight = Utilities::getSystemMetric(win, SystemMetric::TitleBarHeight, false); - const QSize systemButtonSize = {qRound(static_cast(titleBarHeight) * 1.5), titleBarHeight}; - m_minimizeButton->setFixedSize(systemButtonSize); - m_minimizeButton->setIconSize(systemButtonSize); - m_maximizeButton->setFixedSize(systemButtonSize); - m_maximizeButton->setIconSize(systemButtonSize); - m_closeButton->setFixedSize(systemButtonSize); - m_closeButton->setIconSize(systemButtonSize); - m_titleBarWidget->setFixedHeight(titleBarHeight); } void Widget::updateSystemButtonIcons() { +#if 0 Q_ASSERT(m_minimizeButton); Q_ASSERT(m_maximizeButton); Q_ASSERT(m_closeButton); @@ -312,11 +221,7 @@ void Widget::updateSystemButtonIcons() m_maximizeButton->setIcon(QIcon(QStringLiteral(":/images/button_maximize_%1.svg").arg(suffix))); } m_closeButton->setIcon(QIcon(QStringLiteral(":/images/button_close_%1.svg").arg(suffix))); -} - -qreal Widget::frameBorderThickness() const -{ - return (static_cast(Utilities::getWindowVisibleFrameBorderThickness(winId())) / devicePixelRatioF()); +#endif } #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) @@ -325,20 +230,5 @@ bool Widget::nativeEvent(const QByteArray &eventType, void *message, qintptr *re bool Widget::nativeEvent(const QByteArray &eventType, void *message, long *result) #endif { - if (message) { - if (Utilities::isThemeChanged(message)) { - updateStyleSheet(); - updateSystemButtonIcons(); - return true; - } - QPointF pos = {}; - if (Utilities::isSystemMenuRequested(message, &pos)) { - if (Utilities::showSystemMenu(winId(), pos)) { - return true; - } else { - qWarning() << "Failed to display the system menu."; - } - } - } return QWidget::nativeEvent(eventType, message, result); } diff --git a/examples/widget/widget.h b/examples/widget/widget.h index b05a55b..f6f5afa 100644 --- a/examples/widget/widget.h +++ b/examples/widget/widget.h @@ -27,8 +27,8 @@ #include QT_BEGIN_NAMESPACE -QT_FORWARD_DECLARE_CLASS(QLabel) -QT_FORWARD_DECLARE_CLASS(QPushButton) +class QLabel; +class QPushButton; QT_END_NAMESPACE class Widget : public QWidget @@ -53,9 +53,7 @@ protected: private: void setupUi(); void updateStyleSheet(); - void updateTitleBarSize(); void updateSystemButtonIcons(); - qreal frameBorderThickness() const; private: QWidget *m_titleBarWidget = nullptr; diff --git a/framelesshelper_win32.cpp b/framelesshelper_win32.cpp index 6cbe963..0e8d47d 100644 --- a/framelesshelper_win32.cpp +++ b/framelesshelper_win32.cpp @@ -69,6 +69,8 @@ void FramelessHelperWin::addWindow(QWindow *window) Utilities::fixupQtInternals(winId); Utilities::updateInternalWindowFrameMargins(window, true); Utilities::updateWindowFrameMargins(winId, false); + const bool dark = Utilities::shouldAppsUseDarkMode(); + Utilities::updateWindowFrameBorderColor(winId, dark); } void FramelessHelperWin::removeWindow(QWindow *window) diff --git a/framelesswindowsmanager.cpp b/framelesswindowsmanager.cpp index 963ed6c..a82a10c 100644 --- a/framelesswindowsmanager.cpp +++ b/framelesswindowsmanager.cpp @@ -62,21 +62,26 @@ void FramelessWindowsManager::addWindow(QWindow *window) if (!window) { return; } - QMutexLocker locker(&Private::g_manager()->mutex); + Private::g_manager()->mutex.lock(); if (Private::g_manager()->qwindow.contains(window)) { + Private::g_manager()->mutex.unlock(); return; } QVariantHash data = {}; data.insert(kWindow, QVariant::fromValue(window)); + auto qtFramelessHelper = new FramelessHelper(window); if (g_usePureQtImplementation) { - const auto qtFramelessHelper = new FramelessHelper(window); - qtFramelessHelper->addWindow(window); data.insert(kFramelessHelper, QVariant::fromValue(qtFramelessHelper)); + } else { + delete qtFramelessHelper; + qtFramelessHelper = nullptr; } + const QUuid uuid = QUuid::createUuid(); + Private::g_manager()->data.insert(uuid, data); + Private::g_manager()->qwindow.insert(window, uuid); + Private::g_manager()->winId.insert(window->winId(), uuid); + Private::g_manager()->mutex.unlock(); #ifdef Q_OS_WINDOWS - else { - FramelessHelperWin::addWindow(window); - } // Work-around Win32 multi-monitor artifacts. QObject::connect(window, &QWindow::screenChanged, window, [window](QScreen *screen){ Q_UNUSED(screen); @@ -90,10 +95,14 @@ void FramelessWindowsManager::addWindow(QWindow *window) window->resize(window->size()); }); #endif - const QUuid uuid = QUuid::createUuid(); - Private::g_manager()->qwindow.insert(window, uuid); - Private::g_manager()->winId.insert(window->winId(), uuid); - Private::g_manager()->data.insert(uuid, data); + if (g_usePureQtImplementation && qtFramelessHelper) { + qtFramelessHelper->addWindow(window); + } +#ifdef Q_OS_WINDOWS + if (!g_usePureQtImplementation) { + FramelessHelperWin::addWindow(window); + } +#endif } void FramelessWindowsManager::removeWindow(QWindow *window) diff --git a/utilities_win32.cpp b/utilities_win32.cpp index 4c92acb..eb03349 100644 --- a/utilities_win32.cpp +++ b/utilities_win32.cpp @@ -728,8 +728,7 @@ void Utilities::updateWindowFrameBorderColor(const WId winId, const bool dark) const BOOL value = (dark ? TRUE : FALSE); HRESULT hr = pDwmSetWindowAttribute(hwnd, _DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1, &value, sizeof(value)); if (FAILED(hr)) { - qWarning() << __getSystemErrorMessage(QStringLiteral("DwmSetWindowAttribute"), hr); - //return; + // Just eat this error, because it only works on systems before Win10 20H1. } hr = pDwmSetWindowAttribute(hwnd, _DWMWA_USE_IMMERSIVE_DARK_MODE, &value, sizeof(value)); if (FAILED(hr)) {