Minor tweaks.
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
parent
c3d54c616d
commit
955961cf9b
|
@ -1,6 +1,7 @@
|
|||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>qml/main.qml</file>
|
||||
<file alias="qml/+windows/main.qml">qml/main_windows.qml</file>
|
||||
<file alias="qml/+unix/main.qml">qml/main_unix.qml</file>
|
||||
<file>qml/MinimizeButton.qml</file>
|
||||
<file>qml/MaximizeButton.qml</file>
|
||||
<file>qml/CloseButton.qml</file>
|
||||
|
|
|
@ -50,9 +50,8 @@ Window {
|
|||
Text {
|
||||
id: titleBarText
|
||||
text: window.title
|
||||
font.family: "Noto Sans CJK SC"
|
||||
font.pointSize: 13
|
||||
color: "black"
|
||||
color: window.active ? "black" : "gray"
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 15
|
||||
anchors.verticalCenter: parent.verticalCenter
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (C) 2020 by wangwenx190 (Yuhang Zhao)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Window 2.15
|
||||
import wangwenx190.Utils 1.0
|
||||
|
||||
Window {
|
||||
id: window
|
||||
visible: true
|
||||
width: 800
|
||||
height: 600
|
||||
title: qsTr("Hello, World!")
|
||||
|
||||
FramelessHelper {
|
||||
id: framelessHelper
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: titleBar
|
||||
height: framelessHelper.titleBarHeight
|
||||
color: (window.active && framelessHelper.colorizationEnabled) ? framelessHelper.colorizationColor : "white"
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
|
||||
Text {
|
||||
id: titleBarText
|
||||
text: window.title
|
||||
font.pointSize: 13
|
||||
color: window.active ? (framelessHelper.colorizationEnabled ? "white" : "black") : "gray"
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 15
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Row {
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
|
||||
MinimizeButton {
|
||||
id: minimizeButton
|
||||
onClicked: window.showMinimized()
|
||||
Component.onCompleted: framelessHelper.addIgnoreObject(
|
||||
minimizeButton)
|
||||
}
|
||||
|
||||
MaximizeButton {
|
||||
id: maximizeButton
|
||||
maximized: window.visibility === Window.Maximized
|
||||
onClicked: {
|
||||
if (maximized) {
|
||||
window.showNormal()
|
||||
} else {
|
||||
window.showMaximized()
|
||||
}
|
||||
}
|
||||
Component.onCompleted: framelessHelper.addIgnoreObject(
|
||||
maximizeButton)
|
||||
}
|
||||
|
||||
CloseButton {
|
||||
id: closeButton
|
||||
onClicked: window.close()
|
||||
Component.onCompleted: framelessHelper.addIgnoreObject(
|
||||
closeButton)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: content
|
||||
color: "#f0f0f0"
|
||||
anchors {
|
||||
top: titleBar.bottom
|
||||
bottom: parent.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: topFrame
|
||||
visible: framelessHelper.canHaveWindowFrame && (window.visibility === Window.Windowed)
|
||||
color: window.active ? (framelessHelper.colorizationEnabled ? framelessHelper.colorizationColor : "#707070") : "#aaaaaa"
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
height: 1
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
framelessHelper.setWindowFrameVisible(framelessHelper.canHaveWindowFrame)
|
||||
framelessHelper.removeWindowFrame(true)
|
||||
}
|
||||
}
|
|
@ -24,7 +24,6 @@
|
|||
|
||||
#include "widget.h"
|
||||
#include "../../winnativeeventfilter.h"
|
||||
#include <dwmapi.h>
|
||||
#include <QCheckBox>
|
||||
#include <QColorDialog>
|
||||
#include <QEvent>
|
||||
|
@ -34,7 +33,6 @@
|
|||
#include <QOperatingSystemVersion>
|
||||
#include <QPainter>
|
||||
#include <QPushButton>
|
||||
#include <QSettings>
|
||||
#include <QSpacerItem>
|
||||
#include <QVBoxLayout>
|
||||
#include <qt_windows.h>
|
||||
|
@ -54,12 +52,7 @@
|
|||
|
||||
namespace {
|
||||
|
||||
enum : WORD { DwmwaUseImmersiveDarkMode = 20, DwmwaUseImmersiveDarkModeBefore20h1 = 19 };
|
||||
|
||||
const Widget::Win10Version g_vAcrylicEffectVersion = Widget::Win10Version::Win10_1803;
|
||||
const Widget::Win10Version g_vLightThemeVersion = Widget::Win10Version::Win10_1809;
|
||||
const Widget::Win10Version g_vDarkThemeVersion = g_vLightThemeVersion; // check
|
||||
const Widget::Win10Version g_vDarkFrameVersion = g_vDarkThemeVersion; // check
|
||||
|
||||
const QColor g_cDefaultActiveBorderColor = {"#707070"};
|
||||
const QColor g_cDefaultInactiveBorderColor = {"#aaaaaa"};
|
||||
|
@ -70,10 +63,6 @@ const char g_sPreserveWindowFrame[] = "WNEF_FORCE_PRESERVE_WINDOW_FRAME";
|
|||
const char g_sForceUseAcrylicEffect[] = "WNEF_FORCE_ACRYLIC_ON_WIN10";
|
||||
const char g_sDontExtendFrame[] = "WNEF_DO_NOT_EXTEND_FRAME";
|
||||
|
||||
const QLatin1String g_sDwmRegistryKey(R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM)");
|
||||
const QLatin1String g_sPersonalizeRegistryKey(
|
||||
R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)");
|
||||
|
||||
const QLatin1String g_sSystemButtonsStyleSheet(R"(
|
||||
#iconButton, #minimizeButton, #maximizeButton, #closeButton {
|
||||
background-color: transparent;
|
||||
|
@ -296,17 +285,18 @@ bool Widget::shouldDrawBorder(const bool ignoreWindowState) const
|
|||
|
||||
bool Widget::shouldDrawThemedBorder(const bool ignoreWindowState) const
|
||||
{
|
||||
return (shouldDrawBorder(ignoreWindowState) && colorizationColorEnabled());
|
||||
return (shouldDrawBorder(ignoreWindowState) && WinNativeEventFilter::colorizationEnabled());
|
||||
}
|
||||
|
||||
bool Widget::shouldDrawThemedTitleBar() const
|
||||
{
|
||||
return m_bIsWin10OrGreater && colorizationColorEnabled();
|
||||
return m_bIsWin10OrGreater && WinNativeEventFilter::colorizationEnabled();
|
||||
}
|
||||
|
||||
QColor Widget::activeBorderColor()
|
||||
{
|
||||
return colorizationColorEnabled() ? g_cColorizationColor : g_cDefaultActiveBorderColor;
|
||||
return WinNativeEventFilter::colorizationEnabled() ? g_cColorizationColor
|
||||
: g_cDefaultActiveBorderColor;
|
||||
}
|
||||
|
||||
QColor Widget::inactiveBorderColor()
|
||||
|
@ -330,91 +320,6 @@ bool Widget::isWin10OrGreater(const Win10Version subVer)
|
|||
static_cast<int>(subVer))));
|
||||
}
|
||||
|
||||
QColor Widget::colorizationColor()
|
||||
{
|
||||
#if 0
|
||||
DWORD color = 0;
|
||||
BOOL opaqueBlend = FALSE;
|
||||
return SUCCEEDED(DwmGetColorizationColor(&color, &opaqueBlend)) ? QColor::fromRgba(color)
|
||||
: Qt::white;
|
||||
#else
|
||||
bool ok = false;
|
||||
const QSettings registry(g_sDwmRegistryKey, QSettings::NativeFormat);
|
||||
const quint64 color = registry.value(QLatin1String("ColorizationColor"), 0).toULongLong(&ok);
|
||||
return ok ? QColor::fromRgba(color) : Qt::white;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Widget::colorizationColorEnabled()
|
||||
{
|
||||
if (!isWin10OrGreater()) {
|
||||
return false;
|
||||
}
|
||||
bool ok = false;
|
||||
const QSettings registry(g_sDwmRegistryKey, QSettings::NativeFormat);
|
||||
const bool colorPrevalence = registry.value(QLatin1String("ColorPrevalence"), 0).toULongLong(&ok)
|
||||
!= 0;
|
||||
return (ok && colorPrevalence);
|
||||
}
|
||||
|
||||
bool Widget::lightThemeEnabled()
|
||||
{
|
||||
if (!isWin10OrGreater(g_vLightThemeVersion)) {
|
||||
return false;
|
||||
}
|
||||
bool ok = false;
|
||||
const QSettings registry(g_sPersonalizeRegistryKey, QSettings::NativeFormat);
|
||||
const bool appsUseLightTheme
|
||||
= registry.value(QLatin1String("AppsUseLightTheme"), 0).toULongLong(&ok) != 0;
|
||||
return (ok && appsUseLightTheme);
|
||||
}
|
||||
|
||||
bool Widget::darkThemeEnabled()
|
||||
{
|
||||
if (!isWin10OrGreater(g_vDarkThemeVersion)) {
|
||||
return false;
|
||||
}
|
||||
return !lightThemeEnabled();
|
||||
}
|
||||
|
||||
bool Widget::highContrastModeEnabled()
|
||||
{
|
||||
HIGHCONTRASTW hc;
|
||||
SecureZeroMemory(&hc, sizeof(hc));
|
||||
hc.cbSize = sizeof(hc);
|
||||
return SystemParametersInfoW(SPI_GETHIGHCONTRAST, 0, &hc, 0) ? (hc.dwFlags & HCF_HIGHCONTRASTON)
|
||||
: false;
|
||||
}
|
||||
|
||||
bool Widget::darkFrameEnabled(void *handle)
|
||||
{
|
||||
Q_ASSERT(handle);
|
||||
if (!isWin10OrGreater(g_vDarkFrameVersion)) {
|
||||
return false;
|
||||
}
|
||||
const auto hwnd = reinterpret_cast<HWND>(handle);
|
||||
BOOL result = FALSE;
|
||||
const bool ok
|
||||
= SUCCEEDED(DwmGetWindowAttribute(hwnd, DwmwaUseImmersiveDarkMode, &result, sizeof(result)))
|
||||
|| SUCCEEDED(DwmGetWindowAttribute(hwnd,
|
||||
DwmwaUseImmersiveDarkModeBefore20h1,
|
||||
&result,
|
||||
sizeof(result)));
|
||||
return (ok && result);
|
||||
}
|
||||
|
||||
bool Widget::transparencyEffectEnabled()
|
||||
{
|
||||
if (!isWin10OrGreater()) {
|
||||
return false;
|
||||
}
|
||||
bool ok = false;
|
||||
const QSettings registry(g_sPersonalizeRegistryKey, QSettings::NativeFormat);
|
||||
const bool enableTransparency
|
||||
= registry.value(QLatin1String("EnableTransparency"), 0).toULongLong(&ok) != 0;
|
||||
return (ok && enableTransparency);
|
||||
}
|
||||
|
||||
void *Widget::rawHandle() const
|
||||
{
|
||||
return reinterpret_cast<void *>(winId());
|
||||
|
@ -650,7 +555,7 @@ void Widget::setupConnections()
|
|||
}
|
||||
WinNativeEventFilter::setBlurEffectEnabled(rawHandle(), enable, color);
|
||||
updateWindow();
|
||||
if (useAcrylicEffect && enable && transparencyEffectEnabled()) {
|
||||
if (useAcrylicEffect && enable && WinNativeEventFilter::transparencyEffectEnabled()) {
|
||||
QMessageBox::warning(this,
|
||||
tr("BUG Warning!"),
|
||||
tr("You have enabled the transparency effect in the personalize "
|
||||
|
@ -697,7 +602,7 @@ void Widget::initializeVariables()
|
|||
m_bIsWin10OrGreater = isWin10OrGreater();
|
||||
if (m_bIsWin10OrGreater) {
|
||||
m_bCanAcrylicBeEnabled = isWin10OrGreater(g_vAcrylicEffectVersion);
|
||||
g_cColorizationColor = colorizationColor();
|
||||
g_cColorizationColor = WinNativeEventFilter::colorizationColor();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -80,13 +80,6 @@ public:
|
|||
QColor borderColor() const;
|
||||
|
||||
static bool isWin10OrGreater(const Win10Version subVer = Win10Version::Windows10);
|
||||
static QColor colorizationColor();
|
||||
static bool colorizationColorEnabled();
|
||||
static bool lightThemeEnabled();
|
||||
static bool darkThemeEnabled();
|
||||
static bool highContrastModeEnabled();
|
||||
static bool darkFrameEnabled(void *handle);
|
||||
static bool transparencyEffectEnabled();
|
||||
|
||||
public Q_SLOTS:
|
||||
void retranslateUi();
|
||||
|
|
|
@ -26,8 +26,26 @@
|
|||
|
||||
#include "framelesswindowsmanager.h"
|
||||
#include <QQuickWindow>
|
||||
#ifdef Q_OS_WINDOWS
|
||||
#include "winnativeeventfilter.h"
|
||||
#include <QOperatingSystemVersion>
|
||||
#endif
|
||||
|
||||
FramelessQuickHelper::FramelessQuickHelper(QQuickItem *parent) : QQuickItem(parent) {}
|
||||
#ifdef Q_OS_WINDOWS
|
||||
namespace {
|
||||
|
||||
const char g_sPreserveWindowFrame[] = "WNEF_FORCE_PRESERVE_WINDOW_FRAME";
|
||||
const char g_sDontExtendFrame[] = "WNEF_DO_NOT_EXTEND_FRAME";
|
||||
|
||||
} // namespace
|
||||
#endif
|
||||
|
||||
FramelessQuickHelper::FramelessQuickHelper(QQuickItem *parent) : QQuickItem(parent)
|
||||
{
|
||||
#ifdef Q_OS_WINDOWS
|
||||
startTimer(500);
|
||||
#endif
|
||||
}
|
||||
|
||||
int FramelessQuickHelper::borderWidth() const
|
||||
{
|
||||
|
@ -84,6 +102,23 @@ void FramelessQuickHelper::setTitleBarEnabled(const bool val)
|
|||
Q_EMIT titleBarEnabledChanged(val);
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
bool FramelessQuickHelper::canHaveWindowFrame() const
|
||||
{
|
||||
return QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10;
|
||||
}
|
||||
|
||||
bool FramelessQuickHelper::colorizationEnabled() const
|
||||
{
|
||||
return WinNativeEventFilter::colorizationEnabled();
|
||||
}
|
||||
|
||||
QColor FramelessQuickHelper::colorizationColor() const
|
||||
{
|
||||
return WinNativeEventFilter::colorizationColor();
|
||||
}
|
||||
#endif
|
||||
|
||||
QSize FramelessQuickHelper::minimumSize() const
|
||||
{
|
||||
return FramelessWindowsManager::getMinimumSize(window());
|
||||
|
@ -152,3 +187,23 @@ void FramelessQuickHelper::addDraggableObject(QQuickItem *val)
|
|||
Q_ASSERT(val);
|
||||
FramelessWindowsManager::addDraggableObject(window(), val);
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
void FramelessQuickHelper::timerEvent(QTimerEvent *event)
|
||||
{
|
||||
QQuickItem::timerEvent(event);
|
||||
Q_EMIT colorizationEnabledChanged(colorizationEnabled());
|
||||
Q_EMIT colorizationColorChanged(colorizationColor());
|
||||
}
|
||||
|
||||
void FramelessQuickHelper::setWindowFrameVisible(const bool value)
|
||||
{
|
||||
if (value) {
|
||||
qputenv(g_sPreserveWindowFrame, "1");
|
||||
qputenv(g_sDontExtendFrame, "1");
|
||||
} else {
|
||||
qunsetenv(g_sPreserveWindowFrame);
|
||||
qunsetenv(g_sDontExtendFrame);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -27,6 +27,11 @@
|
|||
#include "framelesshelper_global.h"
|
||||
#include <QQuickItem>
|
||||
|
||||
#if (defined(Q_OS_WIN) || defined(Q_OS_WIN32) || defined(Q_OS_WIN64) || defined(Q_OS_WINRT)) \
|
||||
&& !defined(Q_OS_WINDOWS)
|
||||
#define Q_OS_WINDOWS
|
||||
#endif
|
||||
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 13, 0))
|
||||
#define Q_DISABLE_MOVE(Class) \
|
||||
Class(Class &&) = delete; \
|
||||
|
@ -53,6 +58,11 @@ class FRAMELESSHELPER_EXPORT FramelessQuickHelper : public QQuickItem
|
|||
Q_PROPERTY(QSize maximumSize READ maximumSize WRITE setMaximumSize NOTIFY maximumSizeChanged)
|
||||
Q_PROPERTY(bool titleBarEnabled READ titleBarEnabled WRITE setTitleBarEnabled NOTIFY
|
||||
titleBarEnabledChanged)
|
||||
#ifdef Q_OS_WINDOWS
|
||||
Q_PROPERTY(bool canHaveWindowFrame READ canHaveWindowFrame CONSTANT)
|
||||
Q_PROPERTY(bool colorizationEnabled READ colorizationEnabled NOTIFY colorizationEnabledChanged)
|
||||
Q_PROPERTY(QColor colorizationColor READ colorizationColor NOTIFY colorizationColorChanged)
|
||||
#endif
|
||||
|
||||
public:
|
||||
explicit FramelessQuickHelper(QQuickItem *parent = nullptr);
|
||||
|
@ -79,6 +89,12 @@ public:
|
|||
bool titleBarEnabled() const;
|
||||
void setTitleBarEnabled(const bool val);
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
bool canHaveWindowFrame() const;
|
||||
bool colorizationEnabled() const;
|
||||
QColor colorizationColor() const;
|
||||
#endif
|
||||
|
||||
public Q_SLOTS:
|
||||
void removeWindowFrame(const bool center = false);
|
||||
|
||||
|
@ -94,6 +110,15 @@ public Q_SLOTS:
|
|||
void addIgnoreObject(QQuickItem *val);
|
||||
void addDraggableObject(QQuickItem *val);
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
void setWindowFrameVisible(const bool value = true);
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
protected:
|
||||
void timerEvent(QTimerEvent *event) override;
|
||||
#endif
|
||||
|
||||
Q_SIGNALS:
|
||||
void borderWidthChanged(int);
|
||||
void borderHeightChanged(int);
|
||||
|
@ -102,4 +127,8 @@ Q_SIGNALS:
|
|||
void minimumSizeChanged(const QSize &);
|
||||
void maximumSizeChanged(const QSize &);
|
||||
void titleBarEnabledChanged(bool);
|
||||
#ifdef Q_OS_WINDOWS
|
||||
void colorizationEnabledChanged(bool);
|
||||
void colorizationColorChanged(const QColor &);
|
||||
#endif
|
||||
};
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include <QLibrary>
|
||||
#include <QMargins>
|
||||
#include <QScreen>
|
||||
#include <QSettings>
|
||||
#include <QWindow>
|
||||
#include <QtMath>
|
||||
#include <qt_windows.h>
|
||||
|
@ -154,6 +155,8 @@ Q_DECLARE_METATYPE(QMargins)
|
|||
|
||||
namespace {
|
||||
|
||||
enum : WORD { DwmwaUseImmersiveDarkMode = 20, DwmwaUseImmersiveDarkModeBefore20h1 = 19 };
|
||||
|
||||
using WINDOWCOMPOSITIONATTRIB = enum _WINDOWCOMPOSITIONATTRIB { WCA_ACCENT_POLICY = 19 };
|
||||
|
||||
using WINDOWCOMPOSITIONATTRIBDATA = struct _WINDOWCOMPOSITIONATTRIBDATA
|
||||
|
@ -198,6 +201,15 @@ bool isWin8Point1OrGreater()
|
|||
#endif
|
||||
}
|
||||
|
||||
bool isWin10OrGreater()
|
||||
{
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
|
||||
return QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10;
|
||||
#else
|
||||
return QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS10;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool isWin10OrGreater(const int ver)
|
||||
{
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
|
||||
|
@ -487,6 +499,7 @@ using WNEF_CORE_DATA = struct _WNEF_CORE_DATA
|
|||
WNEF_GENERATE_WINAPI(TrackPopupMenu, BOOL, HMENU, UINT, int, int, int, HWND, CONST RECT *)
|
||||
WNEF_GENERATE_WINAPI(PostMessageW, BOOL, HWND, UINT, WPARAM, LPARAM)
|
||||
WNEF_GENERATE_WINAPI(GetMessagePos, DWORD)
|
||||
WNEF_GENERATE_WINAPI(SystemParametersInfoW, BOOL, UINT, UINT, PVOID, UINT)
|
||||
|
||||
#endif // WNEF_LINK_SYSLIB
|
||||
|
||||
|
@ -566,6 +579,7 @@ using WNEF_CORE_DATA = struct _WNEF_CORE_DATA
|
|||
}
|
||||
resolved = true;
|
||||
// Available since Windows 2000.
|
||||
WNEF_RESOLVE_WINAPI(User32, SystemParametersInfoW)
|
||||
WNEF_RESOLVE_WINAPI(User32, GetMessagePos)
|
||||
WNEF_RESOLVE_WINAPI(User32, GetSystemMenu)
|
||||
WNEF_RESOLVE_WINAPI(User32, SetMenuItemInfoW)
|
||||
|
@ -685,11 +699,7 @@ bool shouldHaveWindowFrame()
|
|||
if (should) {
|
||||
// If you preserve the window frame on Win7~8.1,
|
||||
// the window will have a terrible appearance.
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
|
||||
return QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10;
|
||||
#else
|
||||
return QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS10;
|
||||
#endif
|
||||
return isWin10OrGreater();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -1208,6 +1218,10 @@ const int m_defaultBorderWidth = 8, m_defaultBorderHeight = 8, m_defaultTitleBar
|
|||
const int kAutoHideTaskbarThicknessPx = 2;
|
||||
const int kAutoHideTaskbarThicknessPy = kAutoHideTaskbarThicknessPx;
|
||||
|
||||
const QLatin1String g_sDwmRegistryKey(R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM)");
|
||||
const QLatin1String g_sPersonalizeRegistryKey(
|
||||
R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)");
|
||||
|
||||
} // namespace
|
||||
|
||||
WinNativeEventFilter::WinNativeEventFilter()
|
||||
|
@ -2489,3 +2503,97 @@ void WinNativeEventFilter::setWindowResizable(void *handle, const bool resizable
|
|||
updateWindow(hwnd, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
bool WinNativeEventFilter::colorizationEnabled()
|
||||
{
|
||||
if (!isWin10OrGreater()) {
|
||||
return false;
|
||||
}
|
||||
bool ok = false;
|
||||
const QSettings registry(g_sDwmRegistryKey, QSettings::NativeFormat);
|
||||
const bool colorPrevalence = registry.value(QLatin1String("ColorPrevalence"), 0).toULongLong(&ok)
|
||||
!= 0;
|
||||
return (ok && colorPrevalence);
|
||||
}
|
||||
|
||||
QColor WinNativeEventFilter::colorizationColor()
|
||||
{
|
||||
/*
|
||||
DWORD color = 0;
|
||||
BOOL opaqueBlend = FALSE;
|
||||
return SUCCEEDED(DwmGetColorizationColor(&color, &opaqueBlend)) ? QColor::fromRgba(color)
|
||||
: Qt::white;
|
||||
*/
|
||||
bool ok = false;
|
||||
const QSettings registry(g_sDwmRegistryKey, QSettings::NativeFormat);
|
||||
const quint64 color = registry.value(QLatin1String("ColorizationColor"), 0).toULongLong(&ok);
|
||||
return ok ? QColor::fromRgba(color) : Qt::white;
|
||||
}
|
||||
|
||||
bool WinNativeEventFilter::lightThemeEnabled()
|
||||
{
|
||||
if (!isWin10OrGreater(17763)) {
|
||||
return false;
|
||||
}
|
||||
bool ok = false;
|
||||
const QSettings registry(g_sPersonalizeRegistryKey, QSettings::NativeFormat);
|
||||
const bool appsUseLightTheme
|
||||
= registry.value(QLatin1String("AppsUseLightTheme"), 0).toULongLong(&ok) != 0;
|
||||
return (ok && appsUseLightTheme);
|
||||
}
|
||||
|
||||
bool WinNativeEventFilter::darkThemeEnabled()
|
||||
{
|
||||
if (!isWin10OrGreater(17763)) {
|
||||
return false;
|
||||
}
|
||||
return !lightThemeEnabled();
|
||||
}
|
||||
|
||||
bool WinNativeEventFilter::highContrastModeEnabled()
|
||||
{
|
||||
HIGHCONTRASTW hc;
|
||||
SecureZeroMemory(&hc, sizeof(hc));
|
||||
hc.cbSize = sizeof(hc);
|
||||
return WNEF_EXECUTE_WINAPI_RETURN(SystemParametersInfoW, FALSE, SPI_GETHIGHCONTRAST, 0, &hc, 0)
|
||||
? (hc.dwFlags & HCF_HIGHCONTRASTON)
|
||||
: false;
|
||||
}
|
||||
|
||||
bool WinNativeEventFilter::darkFrameEnabled(void *handle)
|
||||
{
|
||||
Q_ASSERT(handle);
|
||||
if (!isWin10OrGreater(17763)) {
|
||||
return false;
|
||||
}
|
||||
const auto hwnd = reinterpret_cast<HWND>(handle);
|
||||
if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, hwnd)) {
|
||||
BOOL result = FALSE;
|
||||
const bool ok = SUCCEEDED(WNEF_EXECUTE_WINAPI_RETURN(DwmGetWindowAttribute,
|
||||
E_FAIL,
|
||||
hwnd,
|
||||
DwmwaUseImmersiveDarkMode,
|
||||
&result,
|
||||
sizeof(result)))
|
||||
|| SUCCEEDED(WNEF_EXECUTE_WINAPI_RETURN(DwmGetWindowAttribute,
|
||||
E_FAIL,
|
||||
hwnd,
|
||||
DwmwaUseImmersiveDarkModeBefore20h1,
|
||||
&result,
|
||||
sizeof(result)));
|
||||
return (ok && result);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WinNativeEventFilter::transparencyEffectEnabled()
|
||||
{
|
||||
if (!isWin10OrGreater()) {
|
||||
return false;
|
||||
}
|
||||
bool ok = false;
|
||||
const QSettings registry(g_sPersonalizeRegistryKey, QSettings::NativeFormat);
|
||||
const bool enableTransparency
|
||||
= registry.value(QLatin1String("EnableTransparency"), 0).toULongLong(&ok) != 0;
|
||||
return (ok && enableTransparency);
|
||||
}
|
||||
|
|
|
@ -153,6 +153,27 @@ public:
|
|||
// window can only be moved and minimized, it can't be resized and maximized.
|
||||
static void setWindowResizable(void *handle /* HWND */, const bool resizable = true);
|
||||
|
||||
// Query whether colorization is enabled or not.
|
||||
static bool colorizationEnabled();
|
||||
|
||||
// Acquire the theme/colorization color set by the user.
|
||||
static QColor colorizationColor();
|
||||
|
||||
// Query whether the user is using the light theme or not.
|
||||
static bool lightThemeEnabled();
|
||||
|
||||
// Query whether the user is using the dark theme or not.
|
||||
static bool darkThemeEnabled();
|
||||
|
||||
// Query whether the high contrast mode is enabled or not.
|
||||
static bool highContrastModeEnabled();
|
||||
|
||||
// Query whether the given window is using dark frame or not.
|
||||
static bool darkFrameEnabled(void *handle /* HWND */);
|
||||
|
||||
// Query whether the transparency effect is enabled or not.
|
||||
static bool transparencyEffectEnabled();
|
||||
|
||||
///////////////////////////////////////////////
|
||||
/// CORE FUNCTION - THE SOUL OF THIS CODE
|
||||
///////////////////////////////////////////////
|
||||
|
|
Loading…
Reference in New Issue