Win32: Remove the dependency of the widgets and quick module

This commit totally removed the dependency of the widgets
and quick modules for the Windows platform. Now the library
itself only depends on the core and gui modules. Currently
no bug can be found. But there are some side effects: one is
we can't set a palette for a widget due to we can't access
QWidget specific functions so if you want to enable blur
effect, you will have to do this by yourself. Another one is
you now have to pass the window handle to WinNativeEventFilter
instead of the pointer of a QObject. Before this patch, I'm
using QWidget::winId() to get the window handle, now we have
get rid of the widgets dependency so I can't get the window
handle now, you have to pass it explicitly. And it leads to
huge refactoring of the whole repository. But I think it's
worth doing. If anyone knows how to get the window handle
without introducing new dependencies, please tell me. It will
help me a lot.

To remove the quick dependency, the FramelessQuickHelper class
is moved out of the library now. If your project needs it,
please copy the files to your project and include them directly.

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
Yuhang Zhao 2020-11-16 17:05:39 +08:00
parent 9cb3392ce4
commit b672851f51
15 changed files with 260 additions and 471 deletions

View File

@ -53,7 +53,12 @@ If you are using part of or all the code from this repository in your own projec
int main(int argc, char *argv[]) {
QWidget widget;
// Do this before the widget is shown.
FramelessWindowsManager::addWindow(&widget);
#ifdef Q_OS_WIN
const auto id = reinterpret_cast<FramelessWindowsManager::WindowId>(widget.winId());
#else
const auto id = static_cast<FramelessWindowsManager::WindowId>(&widget);
#endif
FramelessWindowsManager::addWindow(id);
widget.show();
}
```
@ -65,29 +70,34 @@ Please refer to [the QWidget example](/examples/QWidget/main.cpp) for more detai
```cpp
// Only **TOP LEVEL** QWidgets and QWindows are supported.
QMainWindow *mainWindow = new QMainWindow;
#ifdef Q_OS_WIN
const auto id = reinterpret_cast<FramelessWindowsManager::WindowId>(mainWindow->winId());
#else
const auto id = static_cast<FramelessWindowsManager::WindowId>(mainWindow);
#endif
// Disable resizing of the given window. Resizing is enabled by default.
FramelessWindowsManager::setResizable(mainWindow, false);
FramelessWindowsManager::setResizable(id, false);
// All the following values should not be DPI-aware, just use the
// original numbers, assuming the scale factor is 1.0, don't scale
// them yourself, this code will do the scaling according to DPI
// internally and automatically.
// Maximum window size
FramelessWindowsManager::setMaximumSize(mainWindow, {1280, 720});
FramelessWindowsManager::setMaximumSize(id, {1280, 720});
// Minimum window size
FramelessWindowsManager::setMinimumSize(mainWindow, {800, 540});
FramelessWindowsManager::setMinimumSize(id, {800, 540});
// How to set ignore areas:
// The geometry of something you already know, in window coordinates
FramelessWindowsManager::addIgnoreArea(mainWindow, {100, 0, 30, 30});
FramelessWindowsManager::addIgnoreArea(id, {100, 0, 30, 30});
// The geometry of a widget, in window coordinates.
// It won't update automatically when the geometry of that widget has
// changed, so if you want to add a widget, which is in a layout and
// it's geometry will possibly change, to the ignore list, try the
// next method (addIgnoreObject) instead.
FramelessWindowsManager::addIgnoreArea(mainWindow, pushButton_close.geometry());
FramelessWindowsManager::addIgnoreArea(id, pushButton_close.geometry());
// The **POINTER** of a QWidget or QQuickItem
FramelessWindowsManager::addIgnoreObject(mainWindow, ui->pushButton_minimize);
FramelessWindowsManager::addIgnoreObject(id, ui->pushButton_minimize);
// Move a QWidget or QWindow to the center of its current desktop.
FramelessWindowsManager::moveWindowToDesktopCenter(mainWindow);
FramelessWindowsManager::moveWindowToDesktopCenter(id);
```
## Supported Platforms
@ -108,7 +118,7 @@ A not too old version of Linux and macOS, 32 bit & 64 bit.
| Component | Requirement | Additional Information |
| --- | --- | --- |
| Qt | >= 5.6 | Only the `gui` module is required explicitly, but to make full use of this repository, you'd better install the `widgets` and `quick` modules as well |
| Qt | >= 5.6 | Only the `core` and `gui` modules are required |
| Compiler | >= C++11 | MSVC, MinGW, Clang-CL, Intel-CL or cross compile from Linux/macOS are all supported |
### UNIX

View File

@ -32,7 +32,7 @@
```cpp
QWidget widget;
// Do this before the widget is shown.
WinNativeEventFilter::addFramelessWindow(&widget);
WinNativeEventFilter::addFramelessWindow(reinterpret_cast<void *>(widget.winId()));
widget.show();
```
@ -41,6 +41,8 @@ Please refer to [the QWidget example](/examples/QWidget/main.cpp) for more detai
### Ignore areas and etc
```cpp
// Get the window handle (HWND) first.
const auto handle = reinterpret_cast<void *>(widget.winId());
WinNativeEventFilter::WINDOWDATA data = {};
// All the following values should not be DPI-aware, just use the
// original numbers, assuming the scale factor is 1.0, don't scale
@ -62,18 +64,18 @@ data.ignoreAreas.append(pushButton_close.geometry());
// The **POINTER** of a QWidget or QQuickItem
data.ignoreObjects.append(ui->pushButton_minimize);
// Pass data as the second parameter
WinNativeEventFilter::addFramelessWindow(&widget, &data);
WinNativeEventFilter::addFramelessWindow(handle, &data);
// Or
WinNativeEventFilter::setWindowData(&widget, &data);
WinNativeEventFilter::setWindowData(handle, &data);
// Or modify the window data of a specific window directly:
const auto data = WinNativeEventFilter::getWindowData(&widget);
const auto data = WinNativeEventFilter::getWindowData(handle);
if (data) {
data->borderWidth = 5;
data->borderHeight = 5;
data->titleBarHeight = 30;
}
// The frameless window is resizable by default.
WinNativeEventFilter::setWindowResizable(reinterpret_cast<void *>(mainWindow->winId()), false);
WinNativeEventFilter::setWindowResizable(handle, false);
```
## Supported Platforms
@ -86,7 +88,7 @@ The code itself should be able to work on Windows Vista in theory, but Qt5 has d
| Component | Requirement | Additional Information |
| --- | --- | --- |
| Qt | >= 5.6 | Only the `gui` module is required explicitly, but to make full use of this repository, you'd better install the `widgets` and `quick` modules as well |
| Qt | >= 5.6 | Only the `core` and `gui` modules are required |
| Compiler | >= C++11 | MSVC, MinGW, Clang-CL, Intel-CL or cross compile from Linux are all supported |
## Known Bugs

View File

@ -103,17 +103,21 @@ int main(int argc, char *argv[])
mainWindow->setWindowIcon(icon);
mainWindow->setWindowTitle(QObject::tr("Hello, World!"));
FramelessWindowsManager::addWindow(mainWindow);
#ifdef Q_OS_WIN
const auto id = reinterpret_cast<FramelessWindowsManager::WindowId>(mainWindow->winId());
#else
const auto id = static_cast<FramelessWindowsManager::WindowId>(mainWindow);
#endif
FramelessWindowsManager::addIgnoreObject(mainWindow, titleBarWidget.minimizeButton);
FramelessWindowsManager::addIgnoreObject(mainWindow, titleBarWidget.maximizeButton);
FramelessWindowsManager::addIgnoreObject(mainWindow, titleBarWidget.closeButton);
FramelessWindowsManager::addIgnoreObject(mainWindow, appMainWindow.menubar);
FramelessWindowsManager::addWindow(id);
FramelessWindowsManager::addIgnoreObject(id, titleBarWidget.minimizeButton);
FramelessWindowsManager::addIgnoreObject(id, titleBarWidget.maximizeButton);
FramelessWindowsManager::addIgnoreObject(id, titleBarWidget.closeButton);
FramelessWindowsManager::addIgnoreObject(id, appMainWindow.menubar);
mainWindow->resize(800, 600);
//FramelessWindowsManager::moveWindowToDesktopCenter(mainWindow);
mainWindow->show();
return QApplication::exec();

View File

@ -94,16 +94,20 @@ int main(int argc, char *argv[])
widget.setLayout(mainLayout);
widget.setWindowTitle(QObject::tr("Hello, World!"));
FramelessWindowsManager::addWindow(&widget);
#ifdef Q_OS_WIN
const auto id = reinterpret_cast<FramelessWindowsManager::WindowId>(widget.winId());
#else
const auto id = static_cast<FramelessWindowsManager::WindowId>(&widget);
#endif
FramelessWindowsManager::addIgnoreObject(&widget, minimizeButton);
FramelessWindowsManager::addIgnoreObject(&widget, maximizeButton);
FramelessWindowsManager::addIgnoreObject(&widget, closeButton);
FramelessWindowsManager::addWindow(id);
FramelessWindowsManager::addIgnoreObject(id, minimizeButton);
FramelessWindowsManager::addIgnoreObject(id, maximizeButton);
FramelessWindowsManager::addIgnoreObject(id, closeButton);
widget.resize(800, 600);
//FramelessWindowsManager::moveWindowToDesktopCenter(&widget);
widget.show();
return QApplication::exec();

View File

@ -1,6 +1,7 @@
TARGET = Quick
TEMPLATE = app
QT += quick
SOURCES += main.cpp
HEADERS += ../../framelessquickhelper.h
SOURCES += ../../framelessquickhelper.cpp main.cpp
RESOURCES += qml.qrc
include($$PWD/../common.pri)

View File

@ -138,6 +138,7 @@ const QLatin1String g_sCloseButtonImageLight(":/images/button_close_white.svg");
Widget::Widget(QWidget *parent) : QWidget(parent)
{
createWinId(); // Internal function
initializeWindow();
}
@ -373,7 +374,7 @@ bool Widget::eventFilter(QObject *object, QEvent *event)
break;
}
case QEvent::WinIdChange:
WinNativeEventFilter::addFramelessWindow(this);
WinNativeEventFilter::addFramelessWindow(rawHandle());
break;
case QEvent::WindowActivate:
case QEvent::WindowDeactivate:
@ -400,9 +401,7 @@ bool Widget::nativeEvent(const QByteArray &eventType, void *message, long *resul
switch (msg->message) {
case WM_NCRBUTTONUP: {
if (msg->wParam == HTCAPTION) {
const int x = GET_X_LPARAM(msg->lParam);
const int y = GET_Y_LPARAM(msg->lParam);
if (WinNativeEventFilter::displaySystemMenu(msg->hwnd, false, x, y)) {
if (WinNativeEventFilter::displaySystemMenu(msg->hwnd)) {
*result = 0;
return true;
}
@ -581,6 +580,15 @@ void Widget::setupConnections()
QColorDialog::ShowAlphaChannel);
}
}
// Qt will paint a solid white background to the window,
// it will cover the blurred effect, so we need to
// make the background become totally transparent. Achieve
// this by setting a palette to the window.
QPalette palette = {};
if (enable) {
palette.setColor(QPalette::Window, Qt::transparent);
}
setPalette(palette);
WinNativeEventFilter::setBlurEffectEnabled(rawHandle(), enable, color);
updateWindow();
if (useAcrylicEffect && enable && WinNativeEventFilter::isTransparencyEffectEnabled()) {
@ -621,7 +629,7 @@ void Widget::initializeFramelessFunctions()
{
WinNativeEventFilter::WINDOWDATA data = {};
data.ignoreObjects << iconButton << minimizeButton << maximizeButton << closeButton;
WinNativeEventFilter::addFramelessWindow(this, &data);
WinNativeEventFilter::addFramelessWindow(rawHandle(), &data);
installEventFilter(this);
}

View File

@ -14,10 +14,9 @@ win32 {
RC_FILE = $$PWD/windows.rc
OTHER_FILES += $$PWD/windows.manifest
}
CONFIG(debug, debug|release) {
LIBS += -L$$OUT_PWD/../../debug
win32: LIBS += -lFramelessHelperd
else: unix: LIBS += -lFramelessHelper_debug
} else: CONFIG(release, debug|release) {
LIBS += -L$$OUT_PWD/../../release -lFramelessHelper
win32 {
CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../../debug -lFramelessHelperd
else: CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../../release -lFramelessHelper
} else: unix {
LIBS += -L$$OUT_PWD/../../bin -lFramelessHelper
}

View File

@ -407,29 +407,31 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
if (!obj) {
continue;
}
#ifdef QT_WIDGETS_LIB
const auto widget = qobject_cast<QWidget *>(obj);
if (widget) {
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
const QPointF pos = widget->mapToGlobal(QPointF{0, 0});
#else
const QPoint pos = widget->mapToGlobal(QPoint{0, 0});
#endif
if (QRectF(pos.x(), pos.y(), widget->width(), widget->height()).contains(mousePos)) {
return true;
}
const bool isWidget = obj->inherits("QWidget");
const bool isQuickItem = obj->inherits("QQuickItem");
if (!isWidget && !isQuickItem) {
qWarning() << obj << "is not a QWidget or QQuickItem!";
continue;
}
#endif
#ifdef QT_QUICK_LIB
const auto quickItem = qobject_cast<QQuickItem *>(obj);
if (quickItem) {
const QPointF pos = quickItem->mapToGlobal({0, 0});
if (QRectF(pos.x(), pos.y(), quickItem->width(), quickItem->height())
.contains(mousePos)) {
return true;
const auto mapOriginPointToWindow = [](const QObject *obj) -> QPointF {
Q_ASSERT(obj);
QPointF point = {obj->property("x").toReal(), obj->property("y").toReal()};
for (QObject *parent = obj->parent(); parent; parent = parent->parent()) {
point += {parent->property("x").toReal(),
parent->property("y").toReal()};
}
return point;
};
const QPointF originPoint = mapOriginPointToWindow(obj);
const qreal width = obj->property("width").toReal();
const qreal height = obj->property("height").toReal();
if (QRectF(originPoint.x(),
originPoint.y(),
width,
height)
.contains(mousePos)) {
return true;
}
#endif
}
return false;
};
@ -441,13 +443,7 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
const auto isInIgnoreObjects = [this, &isInSpecificObjects](const QPointF &point,
QObject *window) -> bool {
Q_ASSERT(window);
#if defined(QT_WIDGETS_LIB) || defined(QT_QUICK_LIB)
return isInSpecificObjects(point, getIgnoreObjects(window));
#else
Q_UNUSED(point)
Q_UNUSED(window)
return false;
#endif
};
const auto isInDraggableAreas = [this, &isInSpecificAreas](const QPointF &point,
QObject *window) -> bool {
@ -458,14 +454,8 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
const auto isInDraggableObjects = [this, &isInSpecificObjects](const QPointF &point,
QObject *window) -> bool {
Q_ASSERT(window);
#if defined(QT_WIDGETS_LIB) || defined(QT_QUICK_LIB)
const auto objs = getDraggableObjects(window);
return (objs.isEmpty() ? true : isInSpecificObjects(point, objs));
#else
Q_UNUSED(point)
Q_UNUSED(window)
return true;
#endif
};
const auto isResizePermitted = [&isInIgnoreAreas, &isInIgnoreObjects](const QPointF &globalPoint,
const QPointF &point,

View File

@ -31,15 +31,34 @@
#include <QOperatingSystemVersion>
#endif
#ifdef Q_OS_WINDOWS
namespace {
#ifdef Q_OS_WINDOWS
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";
#endif
FramelessWindowsManager::WindowId getWindowId(QObject *object)
{
Q_ASSERT(object);
if (!object->isWindowType()) {
qWarning() << object << "is not a window!";
return nullptr;
}
const auto window = qobject_cast<QWindow *>(object);
if (!window) {
qWarning() << "Failed to convert" << object << "to QWindow!";
return nullptr;
}
#ifdef Q_OS_WINDOWS
return reinterpret_cast<FramelessWindowsManager::WindowId>(window->winId());
#else
return static_cast<FramelessWindowsManager::WindowId>(window);
#endif
}
} // namespace
#endif
FramelessQuickHelper::FramelessQuickHelper(QQuickItem *parent) : QQuickItem(parent)
{
@ -50,56 +69,56 @@ FramelessQuickHelper::FramelessQuickHelper(QQuickItem *parent) : QQuickItem(pare
int FramelessQuickHelper::borderWidth() const
{
return FramelessWindowsManager::getBorderWidth(window());
return FramelessWindowsManager::getBorderWidth(getWindowId(window()));
}
void FramelessQuickHelper::setBorderWidth(const int val)
{
FramelessWindowsManager::setBorderWidth(window(), val);
FramelessWindowsManager::setBorderWidth(getWindowId(window()), val);
Q_EMIT borderWidthChanged(val);
}
int FramelessQuickHelper::borderHeight() const
{
return FramelessWindowsManager::getBorderHeight(window());
return FramelessWindowsManager::getBorderHeight(getWindowId(window()));
}
void FramelessQuickHelper::setBorderHeight(const int val)
{
FramelessWindowsManager::setBorderHeight(window(), val);
FramelessWindowsManager::setBorderHeight(getWindowId(window()), val);
Q_EMIT borderHeightChanged(val);
}
int FramelessQuickHelper::titleBarHeight() const
{
return FramelessWindowsManager::getTitleBarHeight(window());
return FramelessWindowsManager::getTitleBarHeight(getWindowId(window()));
}
void FramelessQuickHelper::setTitleBarHeight(const int val)
{
FramelessWindowsManager::setTitleBarHeight(window(), val);
FramelessWindowsManager::setTitleBarHeight(getWindowId(window()), val);
Q_EMIT titleBarHeightChanged(val);
}
bool FramelessQuickHelper::resizable() const
{
return FramelessWindowsManager::getResizable(window());
return FramelessWindowsManager::getResizable(getWindowId(window()));
}
void FramelessQuickHelper::setResizable(const bool val)
{
FramelessWindowsManager::setResizable(window(), val);
FramelessWindowsManager::setResizable(getWindowId(window()), val);
Q_EMIT resizableChanged(val);
}
bool FramelessQuickHelper::titleBarEnabled() const
{
return FramelessWindowsManager::getTitleBarEnabled(window());
return FramelessWindowsManager::getTitleBarEnabled(getWindowId(window()));
}
void FramelessQuickHelper::setTitleBarEnabled(const bool val)
{
FramelessWindowsManager::setTitleBarEnabled(window(), val);
FramelessWindowsManager::setTitleBarEnabled(getWindowId(window()), val);
Q_EMIT titleBarEnabledChanged(val);
}
@ -136,7 +155,7 @@ bool FramelessQuickHelper::highContrastModeEnabled() const
bool FramelessQuickHelper::darkFrameEnabled() const
{
return WinNativeEventFilter::isDarkFrameEnabled(rawHandle());
return WinNativeEventFilter::isDarkFrameEnabled(rawWindowHandle());
}
bool FramelessQuickHelper::transparencyEffectEnabled() const
@ -147,71 +166,56 @@ bool FramelessQuickHelper::transparencyEffectEnabled() const
QSize FramelessQuickHelper::minimumSize() const
{
return FramelessWindowsManager::getMinimumSize(window());
return FramelessWindowsManager::getMinimumSize(getWindowId(window()));
}
void FramelessQuickHelper::setMinimumSize(const QSize &val)
{
FramelessWindowsManager::setMinimumSize(window(), val);
FramelessWindowsManager::setMinimumSize(getWindowId(window()), val);
Q_EMIT minimumSizeChanged(val);
}
QSize FramelessQuickHelper::maximumSize() const
{
return FramelessWindowsManager::getMaximumSize(window());
return FramelessWindowsManager::getMaximumSize(getWindowId(window()));
}
void FramelessQuickHelper::setMaximumSize(const QSize &val)
{
FramelessWindowsManager::setMaximumSize(window(), val);
FramelessWindowsManager::setMaximumSize(getWindowId(window()), val);
Q_EMIT maximumSizeChanged(val);
}
void FramelessQuickHelper::removeWindowFrame(const bool center)
{
FramelessWindowsManager::addWindow(window(), center);
FramelessWindowsManager::addWindow(getWindowId(window()), center);
}
QSize FramelessQuickHelper::desktopSize() const
void FramelessQuickHelper::moveWindowToDesktopCenter()
{
return FramelessWindowsManager::getDesktopSize(window());
}
QRect FramelessQuickHelper::desktopAvailableGeometry() const
{
return FramelessWindowsManager::getDesktopAvailableGeometry(window());
}
QSize FramelessQuickHelper::desktopAvailableSize() const
{
return FramelessWindowsManager::getDesktopAvailableSize(window());
}
void FramelessQuickHelper::moveWindowToDesktopCenter(const bool realCenter)
{
FramelessWindowsManager::moveWindowToDesktopCenter(window(), realCenter);
FramelessWindowsManager::moveWindowToDesktopCenter(getWindowId(window()));
}
void FramelessQuickHelper::addIgnoreArea(const QRect &val)
{
FramelessWindowsManager::addIgnoreArea(window(), val);
FramelessWindowsManager::addIgnoreArea(getWindowId(window()), val);
}
void FramelessQuickHelper::addDraggableArea(const QRect &val)
{
FramelessWindowsManager::addDraggableArea(window(), val);
FramelessWindowsManager::addDraggableArea(getWindowId(window()), val);
}
void FramelessQuickHelper::addIgnoreObject(QQuickItem *val)
{
Q_ASSERT(val);
FramelessWindowsManager::addIgnoreObject(window(), val);
FramelessWindowsManager::addIgnoreObject(getWindowId(window()), val);
}
void FramelessQuickHelper::addDraggableObject(QQuickItem *val)
{
Q_ASSERT(val);
FramelessWindowsManager::addDraggableObject(window(), val);
FramelessWindowsManager::addDraggableObject(getWindowId(window()), val);
}
#ifdef Q_OS_WINDOWS
@ -227,9 +231,9 @@ void FramelessQuickHelper::timerEvent(QTimerEvent *event)
Q_EMIT transparencyEffectEnabledChanged(transparencyEffectEnabled());
}
void *FramelessQuickHelper::rawHandle() const
void *FramelessQuickHelper::rawWindowHandle() const
{
QWindow *win = window();
const QWindow *win = window();
if (win) {
return reinterpret_cast<void *>(win->winId());
}
@ -247,9 +251,9 @@ void FramelessQuickHelper::setWindowFrameVisible(const bool value)
}
}
void FramelessQuickHelper::displaySystemMenu(const int x, const int y, const bool isRtl)
void FramelessQuickHelper::displaySystemMenu(const QPointF &pos)
{
WinNativeEventFilter::displaySystemMenu(rawHandle(), isRtl, x, y);
WinNativeEventFilter::displaySystemMenu(rawWindowHandle(), pos);
}
void FramelessQuickHelper::setBlurEffectEnabled(const bool enabled,
@ -261,6 +265,6 @@ void FramelessQuickHelper::setBlurEffectEnabled(const bool enabled,
} else {
qunsetenv(g_sForceUseAcrylicEffect);
}
WinNativeEventFilter::setBlurEffectEnabled(rawHandle(), enabled, gradientColor);
WinNativeEventFilter::setBlurEffectEnabled(rawWindowHandle(), enabled, gradientColor);
}
#endif

View File

@ -24,7 +24,6 @@
#pragma once
#include "framelesshelper_global.h"
#include <QQuickItem>
#if (defined(Q_OS_WIN) || defined(Q_OS_WIN32) || defined(Q_OS_WIN64) || defined(Q_OS_WINRT)) \
@ -42,7 +41,7 @@
Q_DISABLE_MOVE(Class)
#endif
class FRAMELESSHELPER_EXPORT FramelessQuickHelper : public QQuickItem
class FramelessQuickHelper : public QQuickItem
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(FramelessQuickHelper)
@ -110,11 +109,7 @@ public:
public Q_SLOTS:
void removeWindowFrame(const bool center = false);
void moveWindowToDesktopCenter(const bool realCenter = true);
QSize desktopSize() const;
QRect desktopAvailableGeometry() const;
QSize desktopAvailableSize() const;
void moveWindowToDesktopCenter();
void addIgnoreArea(const QRect &val);
void addDraggableArea(const QRect &val);
@ -124,7 +119,7 @@ public Q_SLOTS:
#ifdef Q_OS_WINDOWS
void setWindowFrameVisible(const bool value = true);
void displaySystemMenu(const int x, const int y, const bool isRtl = false);
void displaySystemMenu(const QPointF &pos = {});
void setBlurEffectEnabled(const bool enabled = true,
const bool forceAcrylic = false,
const QColor &gradientColor = Qt::white);
@ -135,7 +130,7 @@ protected:
void timerEvent(QTimerEvent *event) override;
private:
void *rawHandle() const;
void *rawWindowHandle() const;
#endif
Q_SIGNALS:

View File

@ -24,16 +24,9 @@
#include "framelesswindowsmanager.h"
#ifndef Q_OS_WINDOWS
#include <QGuiApplication>
#include <QScreen>
#include <QWindow>
#ifdef QT_WIDGETS_LIB
#include <QWidget>
#endif
#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
#ifdef Q_OS_WINDOWS
@ -42,70 +35,30 @@
#include "framelesshelper.h"
#endif
#ifndef Q_OS_WINDOWS
namespace {
void reportError()
QWindow *toWindow(QObject *object)
{
qFatal("Only top level QWidgets and QWindows are accepted.");
Q_ASSERT(object);
return object->isWindowType() ? qobject_cast<QWindow *>(object) : nullptr;
}
QScreen *getCurrentScreenFromWindow(QObject *window)
{
Q_ASSERT(window);
if (window->isWindowType()) {
return qobject_cast<QWindow *>(window)->screen();
}
#ifdef QT_WIDGETS_LIB
else if (window->isWidgetType()) {
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
return qobject_cast<QWidget *>(window)->screen();
#else
QWindow *win = qobject_cast<QWidget *>(window)->windowHandle();
return win ? win->screen() : nullptr;
#endif
}
#endif
else {
reportError();
}
return nullptr;
}
#ifdef Q_OS_WINDOWS
void *getRawHandleFromWindow(QObject *window)
{
Q_ASSERT(window);
if (window->isWindowType()) {
return reinterpret_cast<void *>(qobject_cast<QWindow *>(window)->winId());
}
#ifdef QT_WIDGETS_LIB
else if (window->isWidgetType()) {
return reinterpret_cast<void *>(qobject_cast<QWidget *>(window)->winId());
}
#endif
else {
reportError();
}
return nullptr;
}
#endif
#ifndef Q_OS_WINDOWS
using FLWM_CORE_DATA = struct _FLWM_CORE_DATA
{
FramelessHelper framelessHelper;
};
#endif
} // namespace
#endif
#ifndef Q_OS_WINDOWS
Q_GLOBAL_STATIC(FLWM_CORE_DATA, coreData)
#endif
FramelessWindowsManager::FramelessWindowsManager() {}
FramelessWindowsManager::FramelessWindowsManager() = default;
void FramelessWindowsManager::addWindow(QObject *window, const bool center)
void FramelessWindowsManager::addWindow(WindowId window, const bool center)
{
Q_ASSERT(window);
#ifdef Q_OS_WINDOWS
@ -118,86 +71,17 @@ void FramelessWindowsManager::addWindow(QObject *window, const bool center)
}
}
void FramelessWindowsManager::moveWindowToDesktopCenter(QObject *window, const bool realCenter)
void FramelessWindowsManager::moveWindowToDesktopCenter(WindowId window)
{
Q_ASSERT(window);
if (realCenter) {
#ifdef Q_OS_WINDOWS
WinNativeEventFilter::moveWindowToDesktopCenter(getRawHandleFromWindow(window));
WinNativeEventFilter::moveWindowToDesktopCenter(window);
#else
FramelessHelper::moveWindowToDesktopCenter(window);
FramelessHelper::moveWindowToDesktopCenter(window);
#endif
} else {
QSize windowSize = {}, screenSize = {};
QRect screenGeometry = {};
if (window->isWindowType()) {
const auto win = qobject_cast<QWindow *>(window);
if (win) {
windowSize = win->size();
screenSize = getDesktopAvailableSize(win);
screenGeometry = getDesktopAvailableGeometry(win);
}
}
#ifdef QT_WIDGETS_LIB
else if (window->isWidgetType()) {
const auto widget = qobject_cast<QWidget *>(window);
if (widget && widget->isTopLevel()) {
windowSize = widget->size();
screenSize = getDesktopAvailableSize(widget);
screenGeometry = getDesktopAvailableGeometry(widget);
}
}
#endif
else {
reportError();
}
const int newX = qRound(static_cast<qreal>(screenSize.width() - windowSize.width()) / 2.0);
const int newY = qRound(static_cast<qreal>(screenSize.height() - windowSize.height()) / 2.0);
const int x = newX + screenGeometry.x();
const int y = newY + screenGeometry.y();
if (window->isWindowType()) {
const auto win = qobject_cast<QWindow *>(window);
if (win) {
win->setX(x);
win->setY(y);
}
}
#ifdef QT_WIDGETS_LIB
else if (window->isWidgetType()) {
const auto widget = qobject_cast<QWidget *>(window);
if (widget && widget->isTopLevel()) {
widget->move(x, y);
}
}
#endif
else {
reportError();
}
}
}
QSize FramelessWindowsManager::getDesktopSize(QObject *window)
{
const QScreen *screen = window ? getCurrentScreenFromWindow(window)
: QGuiApplication::primaryScreen();
return screen ? screen->size() : QSize();
}
QRect FramelessWindowsManager::getDesktopAvailableGeometry(QObject *window)
{
const QScreen *screen = window ? getCurrentScreenFromWindow(window)
: QGuiApplication::primaryScreen();
return screen ? screen->availableGeometry() : QRect();
}
QSize FramelessWindowsManager::getDesktopAvailableSize(QObject *window)
{
const QScreen *screen = window ? getCurrentScreenFromWindow(window)
: QGuiApplication::primaryScreen();
return screen ? screen->availableSize() : QSize();
}
void FramelessWindowsManager::addIgnoreArea(QObject *window, const QRect &area)
void FramelessWindowsManager::addIgnoreArea(WindowId window, const QRect &area)
{
Q_ASSERT(window);
#ifdef Q_OS_WINDOWS
@ -210,7 +94,7 @@ void FramelessWindowsManager::addIgnoreArea(QObject *window, const QRect &area)
#endif
}
void FramelessWindowsManager::addDraggableArea(QObject *window, const QRect &area)
void FramelessWindowsManager::addDraggableArea(WindowId window, const QRect &area)
{
Q_ASSERT(window);
#ifdef Q_OS_WINDOWS
@ -223,7 +107,7 @@ void FramelessWindowsManager::addDraggableArea(QObject *window, const QRect &are
#endif
}
void FramelessWindowsManager::addIgnoreObject(QObject *window, QObject *object)
void FramelessWindowsManager::addIgnoreObject(WindowId window, QObject *object)
{
Q_ASSERT(window);
#ifdef Q_OS_WINDOWS
@ -236,7 +120,7 @@ void FramelessWindowsManager::addIgnoreObject(QObject *window, QObject *object)
#endif
}
void FramelessWindowsManager::addDraggableObject(QObject *window, QObject *object)
void FramelessWindowsManager::addDraggableObject(WindowId window, QObject *object)
{
Q_ASSERT(window);
#ifdef Q_OS_WINDOWS
@ -249,11 +133,11 @@ void FramelessWindowsManager::addDraggableObject(QObject *window, QObject *objec
#endif
}
int FramelessWindowsManager::getBorderWidth(QObject *window)
int FramelessWindowsManager::getBorderWidth(WindowId window)
{
#ifdef Q_OS_WINDOWS
Q_ASSERT(window);
return WinNativeEventFilter::getSystemMetric(getRawHandleFromWindow(window),
return WinNativeEventFilter::getSystemMetric(window,
WinNativeEventFilter::SystemMetric::BorderWidth);
#else
Q_UNUSED(window)
@ -261,7 +145,7 @@ int FramelessWindowsManager::getBorderWidth(QObject *window)
#endif
}
void FramelessWindowsManager::setBorderWidth(QObject *window, const int value)
void FramelessWindowsManager::setBorderWidth(WindowId window, const int value)
{
#ifdef Q_OS_WINDOWS
Q_ASSERT(window);
@ -275,11 +159,11 @@ void FramelessWindowsManager::setBorderWidth(QObject *window, const int value)
#endif
}
int FramelessWindowsManager::getBorderHeight(QObject *window)
int FramelessWindowsManager::getBorderHeight(WindowId window)
{
#ifdef Q_OS_WINDOWS
Q_ASSERT(window);
return WinNativeEventFilter::getSystemMetric(getRawHandleFromWindow(window),
return WinNativeEventFilter::getSystemMetric(window,
WinNativeEventFilter::SystemMetric::BorderHeight);
#else
Q_UNUSED(window)
@ -287,7 +171,7 @@ int FramelessWindowsManager::getBorderHeight(QObject *window)
#endif
}
void FramelessWindowsManager::setBorderHeight(QObject *window, const int value)
void FramelessWindowsManager::setBorderHeight(WindowId window, const int value)
{
#ifdef Q_OS_WINDOWS
Q_ASSERT(window);
@ -301,11 +185,11 @@ void FramelessWindowsManager::setBorderHeight(QObject *window, const int value)
#endif
}
int FramelessWindowsManager::getTitleBarHeight(QObject *window)
int FramelessWindowsManager::getTitleBarHeight(WindowId window)
{
#ifdef Q_OS_WINDOWS
Q_ASSERT(window);
return WinNativeEventFilter::getSystemMetric(getRawHandleFromWindow(window),
return WinNativeEventFilter::getSystemMetric(window,
WinNativeEventFilter::SystemMetric::TitleBarHeight);
#else
Q_UNUSED(window)
@ -313,7 +197,7 @@ int FramelessWindowsManager::getTitleBarHeight(QObject *window)
#endif
}
void FramelessWindowsManager::setTitleBarHeight(QObject *window, const int value)
void FramelessWindowsManager::setTitleBarHeight(WindowId window, const int value)
{
#ifdef Q_OS_WINDOWS
Q_ASSERT(window);
@ -327,7 +211,7 @@ void FramelessWindowsManager::setTitleBarHeight(QObject *window, const int value
#endif
}
bool FramelessWindowsManager::getResizable(QObject *window)
bool FramelessWindowsManager::getResizable(WindowId window)
{
Q_ASSERT(window);
#ifdef Q_OS_WINDOWS
@ -338,39 +222,29 @@ bool FramelessWindowsManager::getResizable(QObject *window)
#endif
}
void FramelessWindowsManager::setResizable(QObject *window, const bool value)
void FramelessWindowsManager::setResizable(WindowId window, const bool value)
{
Q_ASSERT(window);
#ifdef Q_OS_WINDOWS
WinNativeEventFilter::setWindowResizable(getRawHandleFromWindow(window), value);
WinNativeEventFilter::setWindowResizable(window, value);
#else
coreData()->framelessHelper.setResizable(window, value);
#endif
}
QSize FramelessWindowsManager::getMinimumSize(QObject *window)
QSize FramelessWindowsManager::getMinimumSize(WindowId window)
{
Q_ASSERT(window);
#ifdef Q_OS_WINDOWS
const auto data = WinNativeEventFilter::getWindowData(window);
return data ? data->minimumSize : QSize();
#else
if (window->isWindowType()) {
return qobject_cast<QWindow *>(window)->minimumSize();
}
#ifdef QT_WIDGETS_LIB
else if (window->isWidgetType()) {
return qobject_cast<QWidget *>(window)->minimumSize();
}
#endif
else {
reportError();
}
return {};
const auto win = toWindow(window);
return win ? win->minimumSize() : QSize();
#endif
}
void FramelessWindowsManager::setMinimumSize(QObject *window, const QSize &value)
void FramelessWindowsManager::setMinimumSize(WindowId window, const QSize &value)
{
Q_ASSERT(window);
#ifdef Q_OS_WINDOWS
@ -379,43 +253,26 @@ void FramelessWindowsManager::setMinimumSize(QObject *window, const QSize &value
data->minimumSize = value;
}
#else
if (window->isWindowType()) {
qobject_cast<QWindow *>(window)->setMinimumSize(value);
}
#ifdef QT_WIDGETS_LIB
else if (window->isWidgetType()) {
qobject_cast<QWidget *>(window)->setMinimumSize(value);
}
#endif
else {
reportError();
const auto win = toWindow(window);
if (win) {
win->setMinimumSize(value);
}
#endif
}
QSize FramelessWindowsManager::getMaximumSize(QObject *window)
QSize FramelessWindowsManager::getMaximumSize(WindowId window)
{
Q_ASSERT(window);
#ifdef Q_OS_WINDOWS
const auto data = WinNativeEventFilter::getWindowData(window);
return data ? data->maximumSize : QSize();
#else
if (window->isWindowType()) {
return qobject_cast<QWindow *>(window)->maximumSize();
}
#ifdef QT_WIDGETS_LIB
else if (window->isWidgetType()) {
return qobject_cast<QWidget *>(window)->maximumSize();
}
#endif
else {
reportError();
}
return {};
const auto win = toWindow(window);
return win ? win->maximumSize() : QSize();
#endif
}
void FramelessWindowsManager::setMaximumSize(QObject *window, const QSize &value)
void FramelessWindowsManager::setMaximumSize(WindowId window, const QSize &value)
{
Q_ASSERT(window);
#ifdef Q_OS_WINDOWS
@ -424,21 +281,14 @@ void FramelessWindowsManager::setMaximumSize(QObject *window, const QSize &value
data->maximumSize = value;
}
#else
if (window->isWindowType()) {
qobject_cast<QWindow *>(window)->setMaximumSize(value);
}
#ifdef QT_WIDGETS_LIB
else if (window->isWidgetType()) {
qobject_cast<QWidget *>(window)->setMaximumSize(value);
}
#endif
else {
reportError();
const auto win = toWindow(window);
if (win) {
win->setMaximumSize(value);
}
#endif
}
bool FramelessWindowsManager::getTitleBarEnabled(QObject *window)
bool FramelessWindowsManager::getTitleBarEnabled(WindowId window)
{
Q_ASSERT(window);
#ifdef Q_OS_WINDOWS
@ -449,7 +299,7 @@ bool FramelessWindowsManager::getTitleBarEnabled(QObject *window)
#endif
}
void FramelessWindowsManager::setTitleBarEnabled(QObject *window, const bool value)
void FramelessWindowsManager::setTitleBarEnabled(WindowId window, const bool value)
{
Q_ASSERT(window);
#ifdef Q_OS_WINDOWS

View File

@ -27,6 +27,11 @@
#include "framelesshelper_global.h"
#include <QRect>
#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
QT_BEGIN_NAMESPACE
QT_FORWARD_DECLARE_CLASS(QObject)
QT_END_NAMESPACE
@ -46,41 +51,45 @@ class FRAMELESSHELPER_EXPORT FramelessWindowsManager
Q_DISABLE_COPY_MOVE(FramelessWindowsManager)
public:
using WindowId =
#ifdef Q_OS_WINDOWS
void *
#else
QObject *
#endif
;
explicit FramelessWindowsManager();
~FramelessWindowsManager() = default;
static void addWindow(QObject *window, const bool center = false);
static void addWindow(WindowId window, const bool center = false);
static void moveWindowToDesktopCenter(QObject *window, const bool realCenter = true);
static void moveWindowToDesktopCenter(WindowId window);
static QSize getDesktopSize(QObject *window = nullptr);
static QRect getDesktopAvailableGeometry(QObject *window = nullptr);
static QSize getDesktopAvailableSize(QObject *window = nullptr);
static void addIgnoreArea(WindowId window, const QRect &area);
static void addDraggableArea(WindowId window, const QRect &area);
static void addIgnoreArea(QObject *window, const QRect &area);
static void addDraggableArea(QObject *window, const QRect &area);
static void addIgnoreObject(WindowId window, QObject *object);
static void addDraggableObject(WindowId window, QObject *object);
static void addIgnoreObject(QObject *window, QObject *object);
static void addDraggableObject(QObject *window, QObject *object);
static int getBorderWidth(WindowId window);
static void setBorderWidth(WindowId window, const int value);
static int getBorderWidth(QObject *window);
static void setBorderWidth(QObject *window, const int value);
static int getBorderHeight(WindowId window);
static void setBorderHeight(WindowId window, const int value);
static int getBorderHeight(QObject *window);
static void setBorderHeight(QObject *window, const int value);
static int getTitleBarHeight(WindowId window);
static void setTitleBarHeight(WindowId window, const int value);
static int getTitleBarHeight(QObject *window);
static void setTitleBarHeight(QObject *window, const int value);
static bool getResizable(WindowId window);
static void setResizable(WindowId window, const bool value = true);
static bool getResizable(QObject *window);
static void setResizable(QObject *window, const bool value = true);
static QSize getMinimumSize(WindowId window);
static void setMinimumSize(WindowId window, const QSize &value);
static QSize getMinimumSize(QObject *window);
static void setMinimumSize(QObject *window, const QSize &value);
static QSize getMaximumSize(WindowId window);
static void setMaximumSize(WindowId window, const QSize &value);
static QSize getMaximumSize(QObject *window);
static void setMaximumSize(QObject *window, const QSize &value);
static bool getTitleBarEnabled(QObject *window);
static void setTitleBarEnabled(QObject *window, const bool value = true);
static bool getTitleBarEnabled(WindowId window);
static void setTitleBarEnabled(WindowId window, const bool value = true);
};

10
lib.pro
View File

@ -3,8 +3,10 @@ TEMPLATE = lib
win32: DLLDESTDIR = $$OUT_PWD/bin
else: unix: DESTDIR = $$OUT_PWD/bin
QT += gui-private
qtHaveModule(widgets): QT += widgets
qtHaveModule(quick): QT += quick
unix {
qtHaveModule(widgets): QT += widgets
qtHaveModule(quick): QT += quick
}
CONFIG += c++17 strict_c++ utf8_source warn_on
DEFINES += \
QT_NO_CAST_FROM_ASCII \
@ -14,10 +16,6 @@ HEADERS += \
framelesshelper_global.h \
framelesswindowsmanager.h
SOURCES += framelesswindowsmanager.cpp
qtHaveModule(quick) {
HEADERS += framelessquickhelper.h
SOURCES += framelessquickhelper.cpp
}
win32 {
DEFINES += WIN32_LEAN_AND_MEAN _CRT_SECURE_NO_WARNINGS
CONFIG += LINK_TO_SYSTEM_DLL

View File

@ -46,12 +46,6 @@
#else
#include <QSysInfo>
#endif
#ifdef QT_QUICK_LIB
#include <QQuickItem>
#endif
#ifdef QT_WIDGETS_LIB
#include <QWidget>
#endif
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
#include <qpa/qplatformnativeinterface.h>
#else
@ -1115,25 +1109,6 @@ void qCoreAppFixup()
}
}
HWND getHWNDFromQObject(QObject *object)
{
Q_ASSERT(object);
WId wid = 0;
if (object->isWindowType()) {
wid = qobject_cast<QWindow *>(object)->winId();
}
#ifdef QT_WIDGETS_LIB
else if (object->isWidgetType()) {
wid = qobject_cast<QWidget *>(object)->winId();
}
#endif
else {
qFatal(
"Can't acquire the window handle: only top level QWidgets and QWindows are accepted.");
}
return reinterpret_cast<HWND>(wid);
}
void updateQtFrame_internal(const HWND handle, const bool resetToDefault = false)
{
Q_ASSERT(handle);
@ -1149,21 +1124,17 @@ void updateQtFrame_internal(const HWND handle, const bool resetToDefault = false
}
}
bool displaySystemMenu_internal(const HWND handle, const bool isRtl, const LPARAM lParam)
bool displaySystemMenu_internal(const HWND handle, const LPARAM lParam)
{
Q_ASSERT(handle);
if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) {
const POINT globalMouse{GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
POINT localMouse = globalMouse;
POINT localMouse = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
WNEF_EXECUTE_WINAPI(ScreenToClient, handle, &localMouse)
const int tbh = WinNativeEventFilter::getSystemMetric(
handle, WinNativeEventFilter::SystemMetric::TitleBarHeight, true);
const bool isTitleBar = localMouse.y <= tbh;
if (isTitleBar && !IsFullScreen(handle)) {
return WinNativeEventFilter::displaySystemMenu(handle,
isRtl,
globalMouse.x,
globalMouse.y);
return WinNativeEventFilter::displaySystemMenu(handle);
}
}
return false;
@ -1256,18 +1227,6 @@ void WinNativeEventFilter::addFramelessWindow(void *window,
}
}
void WinNativeEventFilter::addFramelessWindow(QObject *window,
const WINDOWDATA *data,
const bool center,
const int x,
const int y,
const int width,
const int height)
{
Q_ASSERT(window);
addFramelessWindow(getHWNDFromQObject(window), data, center, x, y, width, height);
}
void WinNativeEventFilter::removeFramelessWindow(void *window)
{
Q_ASSERT(window);
@ -1282,12 +1241,6 @@ void WinNativeEventFilter::removeFramelessWindow(void *window)
updateWindow(window, true, false);
}
void WinNativeEventFilter::removeFramelessWindow(QObject *window)
{
Q_ASSERT(window);
removeFramelessWindow(getHWNDFromQObject(window));
}
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType,
void *message,
@ -1775,6 +1728,7 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType,
*result = HTTRANSPARENT;
return true;
}
const auto isInSpecificAreas =
[](const QPointF &mousePos, const QList<QRect> &areas, const qreal dpr) -> bool {
if (areas.isEmpty()) {
@ -1794,7 +1748,6 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType,
}
return false;
};
#if defined(QT_WIDGETS_LIB) || defined(QT_QUICK_LIB)
const auto isInSpecificObjects = [](const QPointF &mousePos,
const QList<QObject *> &objects,
const qreal dpr) -> bool {
@ -1805,40 +1758,34 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType,
if (!object) {
continue;
}
#ifdef QT_WIDGETS_LIB
const auto widget = qobject_cast<QWidget *>(object);
if (widget) {
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
const QPointF pos = widget->mapToGlobal(QPointF{0, 0});
#else
const QPoint pos = widget->mapToGlobal(QPoint{0, 0});
#endif
if (QRectF(pos.x() * dpr,
pos.y() * dpr,
widget->width() * dpr,
widget->height() * dpr)
.contains(mousePos)) {
return true;
}
const bool isWidget = object->inherits("QWidget");
const bool isQuickItem = object->inherits("QQuickItem");
if (!isWidget && !isQuickItem) {
qWarning() << object << "is not a QWidget or QQuickItem!";
continue;
}
#endif
#ifdef QT_QUICK_LIB
const auto quickItem = qobject_cast<QQuickItem *>(object);
if (quickItem) {
const QPointF pos = quickItem->mapToGlobal(QPointF{0, 0});
if (QRectF(pos.x() * dpr,
pos.y() * dpr,
quickItem->width() * dpr,
quickItem->height() * dpr)
.contains(mousePos)) {
return true;
const auto mapOriginPointToWindow = [](const QObject *obj) -> QPointF {
Q_ASSERT(obj);
QPointF point = {obj->property("x").toReal(), obj->property("y").toReal()};
for (QObject *parent = obj->parent(); parent; parent = parent->parent()) {
point += {parent->property("x").toReal(),
parent->property("y").toReal()};
}
return point;
};
const QPointF originPoint = mapOriginPointToWindow(object);
const qreal width = object->property("width").toReal();
const qreal height = object->property("height").toReal();
if (QRectF(originPoint.x() * dpr,
originPoint.y() * dpr,
width * dpr,
height * dpr)
.contains(mousePos)) {
return true;
}
#endif
}
return false;
};
#endif
const qreal dpr = GetDevicePixelRatioForWindow(msg->hwnd);
const QPointF globalMouse = QCursor::pos() * dpr;
POINT winLocalMouse = {qRound(globalMouse.x()), qRound(globalMouse.y())};
@ -1852,7 +1799,6 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType,
data->draggableAreas,
dpr)
: true;
#if defined(QT_WIDGETS_LIB) || defined(QT_QUICK_LIB)
const bool isInIgnoreObjects = isInSpecificObjects(globalMouse,
data->ignoreObjects,
dpr);
@ -1862,14 +1808,6 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType,
data->draggableObjects,
dpr)
: true;
#else
// Don't block resizing if both of the Qt Widgets module and Qt
// Quick module are not compiled in, although there's not much
// significance of using this code in this case.
const bool isInIgnoreObjects = false;
const bool isInDraggableObjects = true;
const bool customDragObjects = false;
#endif
const bool customDrag = customDragAreas || customDragObjects;
const bool isResizePermitted = !isInIgnoreAreas && !isInIgnoreObjects;
const int bh = getSystemMetric(msg->hwnd, SystemMetric::BorderHeight, true);
@ -2074,7 +2012,7 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType,
// (SHIFT + F10 or the context menu key), lParam will be -1.
const LPARAM lParam = (msg->lParam == -1) ? WNEF_EXECUTE_WINAPI_RETURN(GetMessagePos, 0)
: msg->lParam;
if (displaySystemMenu_internal(msg->hwnd, false, lParam)) {
if (displaySystemMenu_internal(msg->hwnd, lParam)) {
// The WM_CONTEXTMENU message has no return value so there's
// no need to modify *result.
return true;
@ -2110,12 +2048,6 @@ void WinNativeEventFilter::setWindowData(void *window, const WINDOWDATA *data)
}
}
void WinNativeEventFilter::setWindowData(QObject *window, const WINDOWDATA *data)
{
Q_ASSERT(window);
setWindowData(getHWNDFromQObject(window), data);
}
WinNativeEventFilter::WINDOWDATA *WinNativeEventFilter::getWindowData(void *window)
{
Q_ASSERT(window);
@ -2128,12 +2060,6 @@ WinNativeEventFilter::WINDOWDATA *WinNativeEventFilter::getWindowData(void *wind
return nullptr;
}
WinNativeEventFilter::WINDOWDATA *WinNativeEventFilter::getWindowData(QObject *window)
{
Q_ASSERT(window);
return getWindowData(getHWNDFromQObject(window));
}
void WinNativeEventFilter::setBorderWidth(const int bw)
{
coreData()->m_borderWidth = bw;
@ -2338,10 +2264,7 @@ void WinNativeEventFilter::updateQtFrame(QWindow *window, const int titleBarHeig
}
}
bool WinNativeEventFilter::displaySystemMenu(void *handle,
const bool isRtl,
const int x,
const int y)
bool WinNativeEventFilter::displaySystemMenu(void *handle, const QPointF &pos)
{
Q_ASSERT(handle);
const auto hwnd = reinterpret_cast<HWND>(handle);
@ -2377,15 +2300,20 @@ bool WinNativeEventFilter::displaySystemMenu(void *handle,
WNEF_EXECUTE_WINAPI(SetMenuItemInfoW, hMenu, SC_RESTORE, FALSE, &mii)
}
}
const QPointF mousePos = pos.isNull()
? QCursor::pos() * GetDevicePixelRatioForWindow(hwnd)
: pos;
const LPARAM cmd = WNEF_EXECUTE_WINAPI_RETURN(TrackPopupMenu,
0,
hMenu,
(TPM_LEFTBUTTON | TPM_RIGHTBUTTON
| TPM_RETURNCMD | TPM_TOPALIGN
| (isRtl ? TPM_RIGHTALIGN
: TPM_LEFTALIGN)),
x,
y,
| (QGuiApplication::layoutDirection()
== Qt::RightToLeft
? TPM_RIGHTALIGN
: TPM_LEFTALIGN)),
qRound(mousePos.x()),
qRound(mousePos.y()),
0,
hwnd,
nullptr);

View File

@ -79,26 +79,16 @@ public:
const int y = -1,
const int width = -1,
const int height = -1);
static void addFramelessWindow(QObject *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(void *window /* HWND */);
static void removeFramelessWindow(QObject *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(void *window /* HWND */, const WINDOWDATA *data);
static void setWindowData(QObject *window, const WINDOWDATA *data);
// You can modify the given window's data directly, it's the same with using
// setWindowData.
static WINDOWDATA *getWindowData(void *window /* HWND */);
static WINDOWDATA *getWindowData(QObject *window);
// Change settings globally, not a specific window.
// These values will be scaled automatically according to DPI, don't scale
@ -135,10 +125,7 @@ public:
static void updateQtFrame(QWindow *window, const int titleBarHeight);
// Display the system context menu.
static bool displaySystemMenu(void *handle /* HWND */,
const bool isRtl,
const int x,
const int y);
static bool displaySystemMenu(void *handle /* HWND */, const QPointF &pos = {});
// Enable or disable the blur effect for a specific window.
// On Win10 it's the Acrylic effect.