WinNativeEventFilter:
1. Removed all unused functions and macros.
Win32 API prototypes are not touched because
we may still need them in the future.
2. Don't store data through SetWindowLongPtrW,
using dynamic properties of QWindow instead.
People may rely on GetWindowLongPtrW(hwnd, GWLP_USERDATA)
to do their own work.
3. Some helper functions are removed, such as
moveWindowToDesktopCenter(). You can implement them
yourself. Keep them in the source code will keep
pulling in new dependencies so I have to get rid
of them.
4. Some blocks are removed, such as WM_GETMINMAXIINFO.
It's not needed. You can call Qt's standard API now,
such as setMaximumSize() and setMinimumSize().

FramelessQuickHelper:
1. Removed all functions that can be replaced by Qt's
own API, such as setMaximumSize() and setMinimumSize().
2. Removed helper functions, such as moveWindowToDesktopCenter().
You can implement them yourself. Just few lines of code.

FramelessWindowsManager:
Adapt to the above changes.

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
Yuhang Zhao 2020-11-27 18:52:26 +08:00
parent b601d083bf
commit 68bc4c31ed
9 changed files with 357 additions and 1418 deletions

View File

@ -1,6 +1,6 @@
TARGET = Win32Demo
TEMPLATE = app
QT += widgets
QT += gui-private widgets
HEADERS += widget.h
SOURCES += widget.cpp main.cpp
include($$PWD/../common.pri)

View File

@ -27,6 +27,7 @@
#include <QCheckBox>
#include <QColorDialog>
#include <QEvent>
#include <QGuiApplication>
#include <QHBoxLayout>
#include <QLabel>
#include <QMessageBox>
@ -35,7 +36,16 @@
#include <QPushButton>
#include <QSpacerItem>
#include <QVBoxLayout>
#include <QWindow>
#include <qt_windows.h>
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
#include <qpa/qplatformnativeinterface.h>
#else
#include <qpa/qplatformwindow.h>
#include <qpa/qplatformwindow_p.h>
#endif
Q_DECLARE_METATYPE(QMargins)
// Some old SDK doesn't have this value.
#ifndef WM_DPICHANGED
@ -57,7 +67,6 @@ QColor g_cColorizationColor = Qt::white;
const char g_sUseNativeTitleBar[] = "WNEF_USE_NATIVE_TITLE_BAR";
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_sSystemButtonsStyleSheet(R"(
#iconButton, #minimizeButton, #maximizeButton, #closeButton {
@ -130,6 +139,27 @@ const QLatin1String g_sMaximizeButtonImageLight(":/images/button_maximize_white.
const QLatin1String g_sRestoreButtonImageLight(":/images/button_restore_white.svg");
const QLatin1String g_sCloseButtonImageLight(":/images/button_close_white.svg");
void updateQtFrame(const QWindow *window, const int tbh)
{
Q_ASSERT(window);
QMargins margins = {0, -tbh, 0, 0};
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
QPlatformWindow *platformWindow = window->handle();
if (platformWindow) {
QGuiApplication::platformNativeInterface()->setWindowProperty(platformWindow,
QString::fromUtf8(
"WindowsCustomMargins"),
QVariant::fromValue(margins));
}
#else
auto *platformWindow = dynamic_cast<QNativeInterface::Private::QWindowsWindow *>(
window->handle());
if (platformWindow) {
platformWindow->setCustomMargins(margins);
}
#endif
}
} // namespace
Widget::Widget(QWidget *parent) : QWidget(parent)
@ -138,6 +168,18 @@ Widget::Widget(QWidget *parent) : QWidget(parent)
initializeWindow();
}
void Widget::triggerFrameChange()
{
SetWindowPos(reinterpret_cast<HWND>(windowHandle()->winId()),
nullptr,
0,
0,
0,
0,
SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER
| SWP_NOOWNERZORDER);
}
void Widget::retranslateUi()
{
setWindowTitle(tr("Widget"));
@ -152,7 +194,6 @@ void Widget::retranslateUi()
extendToTitleBarCB->setText(tr("Extend to title bar"));
forceAcrylicCB->setText(tr("Force enabling Acrylic effect"));
resizableCB->setText(tr("Resizable"));
moveCenterButton->setText(tr("Move to desktop center"));
}
void Widget::setupUi()
@ -168,7 +209,8 @@ void Widget::setupUi()
titleBarWidget->setSizePolicy(sizePolicy);
const int titleBarHeight
= WinNativeEventFilter::getSystemMetric(windowHandle(),
WinNativeEventFilter::SystemMetric::TitleBarHeight);
WinNativeEventFilter::SystemMetric::TitleBarHeight,
false);
titleBarWidget->setMinimumSize(QSize(0, titleBarHeight));
titleBarWidget->setMaximumSize(QSize(16777215, titleBarHeight));
horizontalLayout = new QHBoxLayout(titleBarWidget);
@ -282,9 +324,6 @@ void Widget::setupUi()
horizontalLayout_3 = new QHBoxLayout();
horizontalSpacer_5 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_3->addSpacerItem(horizontalSpacer_5);
moveCenterButton = new QPushButton(contentsWidget);
moveCenterButton->setFont(font1);
horizontalLayout_3->addWidget(moveCenterButton);
horizontalSpacer_6 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_3->addSpacerItem(horizontalSpacer_6);
verticalLayout_2->addLayout(horizontalLayout_3);
@ -361,7 +400,6 @@ bool Widget::eventFilter(QObject *object, QEvent *event)
}
}
updateTitleBar();
moveCenterButton->setEnabled(isNormaled());
break;
}
case QEvent::WinIdChange:
@ -390,25 +428,14 @@ bool Widget::nativeEvent(const QByteArray &eventType, void *message, long *resul
if (customizeTitleBarCB && customizeTitleBarCB->isChecked()) {
const auto msg = static_cast<LPMSG>(message);
switch (msg->message) {
case WM_NCRBUTTONUP: {
if (msg->wParam == HTCAPTION) {
if (WinNativeEventFilter::displaySystemMenu(windowHandle())) {
*result = 0;
return true;
}
}
break;
}
case WM_DWMCOLORIZATIONCOLORCHANGED: {
g_cColorizationColor = QColor::fromRgba(msg->wParam);
if (shouldDrawThemedBorder()) {
updateWindow();
update();
}
break;
}
case WM_DPICHANGED:
updateWindow();
break;
case WM_NCPAINT:
update();
break;
@ -434,13 +461,6 @@ void Widget::paintEvent(QPaintEvent *event)
}
}
void Widget::updateWindow()
{
WinNativeEventFilter::updateFrameMargins(windowHandle());
WinNativeEventFilter::updateWindow(windowHandle(), true, true);
update();
}
void Widget::updateTitleBar()
{
const bool themedTitleBar = shouldDrawThemedTitleBar() && isActiveWindow();
@ -494,7 +514,7 @@ void Widget::initializeOptions()
if (m_bIsWin10OrGreater) {
//preserveWindowFrameCB->click();
if (m_bCanAcrylicBeEnabled) {
//forceAcrylicCB->click();
forceAcrylicCB->click();
}
}
customizeTitleBarCB->click();
@ -515,43 +535,42 @@ void Widget::setupConnections()
}
});
connect(closeButton, &QPushButton::clicked, this, &Widget::close);
connect(moveCenterButton, &QPushButton::clicked, this, [this]() {
WinNativeEventFilter::moveWindowToDesktopCenter(windowHandle());
});
connect(this, &Widget::windowTitleChanged, titleLabel, &QLabel::setText);
connect(this, &Widget::windowIconChanged, iconButton, &QPushButton::setIcon);
connect(customizeTitleBarCB, &QCheckBox::stateChanged, this, [this](int state) {
const bool enable = state == Qt::Checked;
preserveWindowFrameCB->setEnabled(enable);
WinNativeEventFilter::updateQtFrame(windowHandle(),
enable ? WinNativeEventFilter::getSystemMetric(
windowHandle(),
WinNativeEventFilter::SystemMetric::TitleBarHeight)
: 0);
updateQtFrame(windowHandle(),
enable ? WinNativeEventFilter::getSystemMetric(
windowHandle(),
WinNativeEventFilter::SystemMetric::TitleBarHeight,
true,
true)
: 0);
titleBarWidget->setVisible(enable);
if (enable) {
qunsetenv(g_sUseNativeTitleBar);
} else {
qputenv(g_sUseNativeTitleBar, "1");
}
updateWindow();
triggerFrameChange();
update();
});
connect(preserveWindowFrameCB, &QCheckBox::stateChanged, this, [this](int state) {
const bool enable = state == Qt::Checked;
if (enable) {
qputenv(g_sPreserveWindowFrame, "1");
qputenv(g_sDontExtendFrame, "1");
} else {
qunsetenv(g_sPreserveWindowFrame);
qunsetenv(g_sDontExtendFrame);
}
if (!enable && shouldDrawBorder()) {
layout()->setContentsMargins(1, 1, 1, 1);
} else {
layout()->setContentsMargins(0, 0, 0, 0);
}
triggerFrameChange();
updateTitleBar();
updateWindow();
update();
});
connect(blurEffectCB, &QCheckBox::stateChanged, this, [this](int state) {
const bool enable = state == Qt::Checked;
@ -575,7 +594,7 @@ void Widget::setupConnections()
}
setPalette(palette);
WinNativeEventFilter::setBlurEffectEnabled(windowHandle(), enable, color);
updateWindow();
update();
if (useAcrylicEffect && enable && WinNativeEventFilter::isTransparencyEffectEnabled()) {
QMessageBox::warning(this,
tr("BUG Warning!"),
@ -606,15 +625,16 @@ void Widget::setupConnections()
connect(resizableCB, &QCheckBox::stateChanged, this, [this](int state) {
const bool enable = state == Qt::Checked;
maximizeButton->setEnabled(enable);
WinNativeEventFilter::setWindowResizable(windowHandle(), enable);
setWindowFlag(Qt::MSWindowsFixedSizeDialogHint, !enable);
show();
});
}
void Widget::initializeFramelessFunctions()
{
WinNativeEventFilter::WINDOWDATA data = {};
data.ignoreObjects << iconButton << minimizeButton << maximizeButton << closeButton;
WinNativeEventFilter::addFramelessWindow(windowHandle(), &data);
WinNativeEventFilter::addFramelessWindow(windowHandle());
WinNativeEventFilter::setIgnoredObjects(windowHandle(),
{minimizeButton, maximizeButton, closeButton});
installEventFilter(this);
}

View File

@ -94,13 +94,13 @@ protected:
private:
void setupUi();
void updateWindow();
void updateTitleBar();
void initializeOptions();
void setupConnections();
void initializeFramelessFunctions();
void initializeVariables();
void initializeWindow();
void triggerFrameChange();
private:
bool m_bIsWin10OrGreater = false, m_bCanAcrylicBeEnabled = false, m_bExtendToTitleBar = false,
@ -115,7 +115,7 @@ private:
*verticalSpacer = nullptr, *horizontalSpacer_5 = nullptr,
*horizontalSpacer_6 = nullptr;
QPushButton *iconButton = nullptr, *minimizeButton = nullptr, *maximizeButton = nullptr,
*closeButton = nullptr, *moveCenterButton = nullptr;
*closeButton = nullptr;
QLabel *titleLabel = nullptr;
QCheckBox *customizeTitleBarCB = nullptr, *preserveWindowFrameCB = nullptr,
*blurEffectCB = nullptr, *extendToTitleBarCB = nullptr, *forceAcrylicCB = nullptr,

View File

@ -35,7 +35,6 @@
namespace {
const char g_sPreserveWindowFrame[] = "WNEF_FORCE_PRESERVE_WINDOW_FRAME";
const char g_sDontExtendFrame[] = "WNEF_DO_NOT_EXTEND_FRAME";
const char g_sForceUseAcrylicEffect[] = "WNEF_FORCE_ACRYLIC_ON_WIN10";
} // namespace
@ -92,17 +91,6 @@ void FramelessQuickHelper::setResizable(const bool val)
Q_EMIT resizableChanged(val);
}
bool FramelessQuickHelper::titleBarEnabled() const
{
return FramelessWindowsManager::getTitleBarEnabled(window());
}
void FramelessQuickHelper::setTitleBarEnabled(const bool val)
{
FramelessWindowsManager::setTitleBarEnabled(window(), val);
Q_EMIT titleBarEnabledChanged(val);
}
#ifdef Q_OS_WINDOWS
bool FramelessQuickHelper::canHaveWindowFrame() const
{
@ -145,46 +133,9 @@ bool FramelessQuickHelper::transparencyEffectEnabled() const
}
#endif
QSize FramelessQuickHelper::minimumSize() const
void FramelessQuickHelper::removeWindowFrame()
{
return FramelessWindowsManager::getMinimumSize(window());
}
void FramelessQuickHelper::setMinimumSize(const QSize &val)
{
FramelessWindowsManager::setMinimumSize(window(), val);
Q_EMIT minimumSizeChanged(val);
}
QSize FramelessQuickHelper::maximumSize() const
{
return FramelessWindowsManager::getMaximumSize(window());
}
void FramelessQuickHelper::setMaximumSize(const QSize &val)
{
FramelessWindowsManager::setMaximumSize(window(), val);
Q_EMIT maximumSizeChanged(val);
}
void FramelessQuickHelper::removeWindowFrame(const bool center)
{
FramelessWindowsManager::addWindow(window(), center);
}
void FramelessQuickHelper::moveWindowToDesktopCenter()
{
FramelessWindowsManager::moveWindowToDesktopCenter(window());
}
void FramelessQuickHelper::addIgnoreArea(const QRect &val)
{
FramelessWindowsManager::addIgnoreArea(window(), val);
}
void FramelessQuickHelper::addDraggableArea(const QRect &val)
{
FramelessWindowsManager::addDraggableArea(window(), val);
FramelessWindowsManager::addWindow(window());
}
void FramelessQuickHelper::addIgnoreObject(QQuickItem *val)
@ -193,12 +144,6 @@ void FramelessQuickHelper::addIgnoreObject(QQuickItem *val)
FramelessWindowsManager::addIgnoreObject(window(), val);
}
void FramelessQuickHelper::addDraggableObject(QQuickItem *val)
{
Q_ASSERT(val);
FramelessWindowsManager::addDraggableObject(window(), val);
}
#ifdef Q_OS_WINDOWS
void FramelessQuickHelper::timerEvent(QTimerEvent *event)
{
@ -216,18 +161,11 @@ void FramelessQuickHelper::setWindowFrameVisible(const bool value)
{
if (value) {
qputenv(g_sPreserveWindowFrame, "1");
qputenv(g_sDontExtendFrame, "1");
} else {
qunsetenv(g_sPreserveWindowFrame);
qunsetenv(g_sDontExtendFrame);
}
}
void FramelessQuickHelper::displaySystemMenu(const QPointF &pos)
{
WinNativeEventFilter::displaySystemMenu(window(), pos);
}
void FramelessQuickHelper::setBlurEffectEnabled(const bool enabled,
const bool forceAcrylic,
const QColor &gradientColor)

View File

@ -53,10 +53,6 @@ class FramelessQuickHelper : public QQuickItem
Q_PROPERTY(
int titleBarHeight READ titleBarHeight WRITE setTitleBarHeight NOTIFY titleBarHeightChanged)
Q_PROPERTY(bool resizable READ resizable WRITE setResizable NOTIFY resizableChanged)
Q_PROPERTY(QSize minimumSize READ minimumSize WRITE setMinimumSize NOTIFY minimumSizeChanged)
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)
@ -86,15 +82,6 @@ public:
bool resizable() const;
void setResizable(const bool val);
QSize minimumSize() const;
void setMinimumSize(const QSize &val);
QSize maximumSize() const;
void setMaximumSize(const QSize &val);
bool titleBarEnabled() const;
void setTitleBarEnabled(const bool val);
#ifdef Q_OS_WINDOWS
bool canHaveWindowFrame() const;
bool colorizationEnabled() const;
@ -107,19 +94,12 @@ public:
#endif
public Q_SLOTS:
void removeWindowFrame(const bool center = false);
void moveWindowToDesktopCenter();
void addIgnoreArea(const QRect &val);
void addDraggableArea(const QRect &val);
void removeWindowFrame();
void addIgnoreObject(QQuickItem *val);
void addDraggableObject(QQuickItem *val);
#ifdef Q_OS_WINDOWS
void setWindowFrameVisible(const bool value = true);
void displaySystemMenu(const QPointF &pos = {});
void setBlurEffectEnabled(const bool enabled = true,
const bool forceAcrylic = false,
const QColor &gradientColor = Qt::white);
@ -135,9 +115,6 @@ Q_SIGNALS:
void borderHeightChanged(int);
void titleBarHeightChanged(int);
void resizableChanged(bool);
void minimumSizeChanged(const QSize &);
void maximumSizeChanged(const QSize &);
void titleBarEnabledChanged(bool);
#ifdef Q_OS_WINDOWS
void colorizationEnabledChanged(bool);
void colorizationColorChanged(const QColor &);

View File

@ -38,52 +38,13 @@ Q_GLOBAL_STATIC(FramelessHelper, framelessHelper)
FramelessWindowsManager::FramelessWindowsManager() = default;
void FramelessWindowsManager::addWindow(const QWindow *window, const bool center)
void FramelessWindowsManager::addWindow(const QWindow *window)
{
Q_ASSERT(window);
#ifdef Q_OS_WINDOWS
WinNativeEventFilter::addFramelessWindow(window);
WinNativeEventFilter::addFramelessWindow(const_cast<QWindow *>(window));
#else
framelessHelper()->removeWindowFrame(window);
#endif
if (center) {
moveWindowToDesktopCenter(window);
}
}
void FramelessWindowsManager::moveWindowToDesktopCenter(const QWindow *window)
{
Q_ASSERT(window);
#ifdef Q_OS_WINDOWS
WinNativeEventFilter::moveWindowToDesktopCenter(window);
#else
FramelessHelper::moveWindowToDesktopCenter(window);
#endif
}
void FramelessWindowsManager::addIgnoreArea(const QWindow *window, const QRect &area)
{
Q_ASSERT(window);
#ifdef Q_OS_WINDOWS
const auto data = WinNativeEventFilter::getWindowData(window);
if (data) {
data->ignoreAreas.append(area);
}
#else
framelessHelper()->addIgnoreArea(window, area);
#endif
}
void FramelessWindowsManager::addDraggableArea(const QWindow *window, const QRect &area)
{
Q_ASSERT(window);
#ifdef Q_OS_WINDOWS
const auto data = WinNativeEventFilter::getWindowData(window);
if (data) {
data->draggableAreas.append(area);
}
#else
framelessHelper()->addDraggableArea(window, area);
#endif
}
@ -91,34 +52,21 @@ void FramelessWindowsManager::addIgnoreObject(const QWindow *window, QObject *ob
{
Q_ASSERT(window);
#ifdef Q_OS_WINDOWS
const auto data = WinNativeEventFilter::getWindowData(window);
if (data) {
data->ignoreObjects.append(object);
}
QObjectList objects = WinNativeEventFilter::getIgnoredObjects(window);
objects.append(object);
WinNativeEventFilter::setIgnoredObjects(const_cast<QWindow *>(window), objects);
#else
framelessHelper()->addIgnoreObject(window, object);
#endif
}
void FramelessWindowsManager::addDraggableObject(const QWindow *window, QObject *object)
{
Q_ASSERT(window);
#ifdef Q_OS_WINDOWS
const auto data = WinNativeEventFilter::getWindowData(window);
if (data) {
data->draggableObjects.append(object);
}
#else
framelessHelper()->addDraggableObject(window, object);
#endif
}
int FramelessWindowsManager::getBorderWidth(const QWindow *window)
{
#ifdef Q_OS_WINDOWS
Q_ASSERT(window);
return WinNativeEventFilter::getSystemMetric(window,
WinNativeEventFilter::SystemMetric::BorderWidth);
WinNativeEventFilter::SystemMetric::BorderWidth,
false);
#else
Q_UNUSED(window)
return framelessHelper()->getBorderWidth();
@ -129,10 +77,7 @@ void FramelessWindowsManager::setBorderWidth(const QWindow *window, const int va
{
#ifdef Q_OS_WINDOWS
Q_ASSERT(window);
const auto data = WinNativeEventFilter::getWindowData(window);
if (data) {
data->borderWidth = value;
}
WinNativeEventFilter::setBorderWidth(const_cast<QWindow *>(window), value);
#else
Q_UNUSED(window)
framelessHelper()->setBorderWidth(value);
@ -144,7 +89,8 @@ int FramelessWindowsManager::getBorderHeight(const QWindow *window)
#ifdef Q_OS_WINDOWS
Q_ASSERT(window);
return WinNativeEventFilter::getSystemMetric(window,
WinNativeEventFilter::SystemMetric::BorderHeight);
WinNativeEventFilter::SystemMetric::BorderHeight,
false);
#else
Q_UNUSED(window)
return framelessHelper()->getBorderHeight();
@ -155,10 +101,7 @@ void FramelessWindowsManager::setBorderHeight(const QWindow *window, const int v
{
#ifdef Q_OS_WINDOWS
Q_ASSERT(window);
const auto data = WinNativeEventFilter::getWindowData(window);
if (data) {
data->borderHeight = value;
}
WinNativeEventFilter::setBorderHeight(const_cast<QWindow *>(window), value);
#else
Q_UNUSED(window)
framelessHelper()->setBorderHeight(value);
@ -170,7 +113,8 @@ int FramelessWindowsManager::getTitleBarHeight(const QWindow *window)
#ifdef Q_OS_WINDOWS
Q_ASSERT(window);
return WinNativeEventFilter::getSystemMetric(window,
WinNativeEventFilter::SystemMetric::TitleBarHeight);
WinNativeEventFilter::SystemMetric::TitleBarHeight,
false);
#else
Q_UNUSED(window)
return framelessHelper()->getTitleBarHeight();
@ -181,10 +125,7 @@ void FramelessWindowsManager::setTitleBarHeight(const QWindow *window, const int
{
#ifdef Q_OS_WINDOWS
Q_ASSERT(window);
const auto data = WinNativeEventFilter::getWindowData(window);
if (data) {
data->titleBarHeight = value;
}
WinNativeEventFilter::setTitleBarHeight(const_cast<QWindow *>(window), value);
#else
Q_UNUSED(window)
framelessHelper()->setTitleBarHeight(value);
@ -195,8 +136,15 @@ bool FramelessWindowsManager::getResizable(const QWindow *window)
{
Q_ASSERT(window);
#ifdef Q_OS_WINDOWS
const auto data = WinNativeEventFilter::getWindowData(window);
return data ? !data->fixedSize : true;
if (window->flags().testFlag(Qt::MSWindowsFixedSizeDialogHint)) {
return false;
}
const QSize minSize = window->minimumSize();
const QSize maxSize = window->maximumSize();
if (!minSize.isEmpty() && !maxSize.isEmpty() && minSize == maxSize) {
return false;
}
return true;
#else
return framelessHelper()->getResizable(window);
#endif
@ -206,80 +154,8 @@ void FramelessWindowsManager::setResizable(const QWindow *window, const bool val
{
Q_ASSERT(window);
#ifdef Q_OS_WINDOWS
WinNativeEventFilter::setWindowResizable(window, value);
const_cast<QWindow *>(window)->setFlag(Qt::MSWindowsFixedSizeDialogHint, !value);
#else
framelessHelper()->setResizable(window, value);
#endif
}
QSize FramelessWindowsManager::getMinimumSize(const QWindow *window)
{
Q_ASSERT(window);
#ifdef Q_OS_WINDOWS
const auto data = WinNativeEventFilter::getWindowData(window);
return data ? data->minimumSize : QSize();
#else
return window->minimumSize();
#endif
}
void FramelessWindowsManager::setMinimumSize(const QWindow *window, const QSize &value)
{
Q_ASSERT(window);
#ifdef Q_OS_WINDOWS
const auto data = WinNativeEventFilter::getWindowData(window);
if (data) {
data->minimumSize = value;
}
#else
window->setMinimumSize(value);
#endif
}
QSize FramelessWindowsManager::getMaximumSize(const QWindow *window)
{
Q_ASSERT(window);
#ifdef Q_OS_WINDOWS
const auto data = WinNativeEventFilter::getWindowData(window);
return data ? data->maximumSize : QSize();
#else
return window->maximumSize();
#endif
}
void FramelessWindowsManager::setMaximumSize(const QWindow *window, const QSize &value)
{
Q_ASSERT(window);
#ifdef Q_OS_WINDOWS
const auto data = WinNativeEventFilter::getWindowData(window);
if (data) {
data->maximumSize = value;
}
#else
window->setMaximumSize(value);
#endif
}
bool FramelessWindowsManager::getTitleBarEnabled(const QWindow *window)
{
Q_ASSERT(window);
#ifdef Q_OS_WINDOWS
const auto data = WinNativeEventFilter::getWindowData(window);
return data ? !data->disableTitleBar : true;
#else
return framelessHelper()->getTitleBarEnabled(window);
#endif
}
void FramelessWindowsManager::setTitleBarEnabled(const QWindow *window, const bool value)
{
Q_ASSERT(window);
#ifdef Q_OS_WINDOWS
const auto data = WinNativeEventFilter::getWindowData(window);
if (data) {
data->disableTitleBar = !value;
}
#else
framelessHelper()->setTitleBarEnabled(window, value);
#endif
}

View File

@ -55,15 +55,9 @@ public:
explicit FramelessWindowsManager();
~FramelessWindowsManager() = default;
static void addWindow(const QWindow *window, const bool center = false);
static void moveWindowToDesktopCenter(const QWindow *window);
static void addIgnoreArea(const QWindow *window, const QRect &area);
static void addDraggableArea(const QWindow *window, const QRect &area);
static void addWindow(const QWindow *window);
static void addIgnoreObject(const QWindow *window, QObject *object);
static void addDraggableObject(const QWindow *window, QObject *object);
static int getBorderWidth(const QWindow *window);
static void setBorderWidth(const QWindow *window, const int value);
@ -76,13 +70,4 @@ public:
static bool getResizable(const QWindow *window);
static void setResizable(const QWindow *window, const bool value = true);
static QSize getMinimumSize(const QWindow *window);
static void setMinimumSize(const QWindow *window, const QSize &value);
static QSize getMaximumSize(const QWindow *window);
static void setMaximumSize(const QWindow *window, const QSize &value);
static bool getTitleBarEnabled(const QWindow *window);
static void setTitleBarEnabled(const QWindow *window, const bool value = true);
};

File diff suppressed because it is too large Load Diff

View File

@ -27,9 +27,7 @@
#include "framelesshelper_global.h"
#include <QAbstractNativeEventFilter>
#include <QColor>
#include <QList>
#include <QObject>
#include <QRect>
QT_BEGIN_NAMESPACE
QT_FORWARD_DECLARE_CLASS(QWindow)
@ -50,97 +48,33 @@ class FRAMELESSHELPER_EXPORT WinNativeEventFilter : public QAbstractNativeEventF
Q_DISABLE_COPY_MOVE(WinNativeEventFilter)
public:
using WINDOWDATA = struct _WINDOWDATA
{
bool initialized = false /* Internal use only, don't modify it from outside */,
fixedSize = false, mouseTransparent = false, restoreDefaultWindowStyle = false,
enableLayeredWindow = false, disableTitleBar = false, enableBlurBehindWindow = false,
framelessModeEnabled = false;
int borderWidth = -1, borderHeight = -1, titleBarHeight = -1;
QList<QRect> ignoreAreas = {}, draggableAreas = {};
QObjectList ignoreObjects = {}, draggableObjects = {};
QSize maximumSize = {}, minimumSize = {};
QString currentScreen = {};
};
enum class SystemMetric { BorderWidth, BorderHeight, TitleBarHeight };
explicit WinNativeEventFilter();
~WinNativeEventFilter() override = default;
~WinNativeEventFilter() override;
// Make the given window become frameless.
// The width and height will be scaled automatically according to DPI. Don't
// scale them yourself. Just pass the original value. If you don't want to
// change them, pass negative values to the parameters.
static void addFramelessWindow(const QWindow *window,
const WINDOWDATA *data = nullptr,
const bool center = false,
const int x = -1,
const int y = -1,
const int width = -1,
const int height = -1);
static void removeFramelessWindow(const QWindow *window);
static void addFramelessWindow(QWindow *window);
static bool isWindowFrameless(const QWindow *window);
static void removeFramelessWindow(QWindow *window);
// Set borderWidth, borderHeight or titleBarHeight to a negative value to
// restore default behavior.
// Note that it can only affect one specific window.
// If you want to change these values globally, use setBorderWidth instead.
static void setWindowData(const QWindow *window, const WINDOWDATA *data);
// You can modify the given window's data directly, it's the same with using
// setWindowData.
static WINDOWDATA *getWindowData(const QWindow *window);
static void setIgnoredObjects(QWindow *window, const QObjectList &objects);
static QObjectList getIgnoredObjects(const QWindow *window);
// Change settings globally, not a specific window.
// These values will be scaled automatically according to DPI, don't scale
// them yourself. Just pass the original value.
static void setBorderWidth(const int bw);
static void setBorderHeight(const int bh);
static void setTitleBarHeight(const int tbh);
static void setBorderWidth(QWindow *window, const int bw);
static void setBorderHeight(QWindow *window, const int bh);
static void setTitleBarHeight(QWindow *window, const int tbh);
// System metric value of the given window (if the pointer is null,
// return the system's standard value).
static int getSystemMetric(const QWindow *window,
const SystemMetric metric,
const bool dpiAware = false,
const bool dpiAware,
const bool forceSystemValue = false);
// Use this function to trigger a frame change event or redraw a
// specific window. Useful when you want to let some changes
// in effect immediately.
static void updateWindow(const QWindow *window,
const bool triggerFrameChange = true,
const bool redraw = true);
// Change the geometry of a window through Win32 API.
// The width and height will be scaled automatically according to DPI. So
// just pass the original value.
static void setWindowGeometry(
const QWindow *window, const int x, const int y, const int width, const int height);
// Move the window to the center of the desktop.
static void moveWindowToDesktopCenter(const QWindow *window);
// Update Qt's internal data about the window frame, otherwise Qt will
// take the size of the window frame into account when anyone is trying to
// change the geometry of the window. That's not what we want.
static void updateQtFrame(QWindow *window, const int titleBarHeight);
// Display the system context menu.
static bool displaySystemMenu(const QWindow *window, const QPointF &pos = {});
// Enable or disable the blur effect for a specific window.
// On Win10 it's the Acrylic effect.
static bool setBlurEffectEnabled(const QWindow *window,
const bool enabled = true,
const bool enabled,
const QColor &gradientColor = Qt::white);
// Thin wrapper of DwmExtendFrameIntoClientArea().
static void updateFrameMargins(const QWindow *window);
// A resizable window can be resized and maximized, however, a fixed size
// window can only be moved and minimized, it can't be resized and maximized.
static void setWindowResizable(const QWindow *window, const bool resizable = true);
// Query whether colorization is enabled or not.
static bool isColorizationEnabled();
@ -162,9 +96,6 @@ public:
// Query whether the transparency effect is enabled or not.
static bool isTransparencyEffectEnabled();
///////////////////////////////////////////////
/// CORE FUNCTION - THE SOUL OF THIS CODE
///////////////////////////////////////////////
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) override;
#else