diff --git a/README.md b/README.md index a925f67..3d3a423 100644 --- a/README.md +++ b/README.md @@ -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(widget.winId()); +#else + const auto id = static_cast(&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(mainWindow->winId()); +#else +const auto id = static_cast(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 diff --git a/README_win32.md b/README_win32.md index aac7b02..f35280c 100644 --- a/README_win32.md +++ b/README_win32.md @@ -32,7 +32,7 @@ ```cpp QWidget widget; // Do this before the widget is shown. -WinNativeEventFilter::addFramelessWindow(&widget); +WinNativeEventFilter::addFramelessWindow(reinterpret_cast(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(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(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 diff --git a/examples/QMainWindow/main.cpp b/examples/QMainWindow/main.cpp index 362d5b3..3355aa0 100644 --- a/examples/QMainWindow/main.cpp +++ b/examples/QMainWindow/main.cpp @@ -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(mainWindow->winId()); +#else + const auto id = static_cast(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(); diff --git a/examples/QWidget/main.cpp b/examples/QWidget/main.cpp index d59cfa0..7c24f08 100644 --- a/examples/QWidget/main.cpp +++ b/examples/QWidget/main.cpp @@ -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(widget.winId()); +#else + const auto id = static_cast(&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(); diff --git a/examples/Quick/Quick.pro b/examples/Quick/Quick.pro index c7a4817..d8ed467 100644 --- a/examples/Quick/Quick.pro +++ b/examples/Quick/Quick.pro @@ -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) diff --git a/examples/Win32Demo/widget.cpp b/examples/Win32Demo/widget.cpp index a3ff285..5c4e635 100644 --- a/examples/Win32Demo/widget.cpp +++ b/examples/Win32Demo/widget.cpp @@ -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); } diff --git a/examples/common.pri b/examples/common.pri index 1319968..2c5fda7 100644 --- a/examples/common.pri +++ b/examples/common.pri @@ -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 } diff --git a/framelesshelper.cpp b/framelesshelper.cpp index c94703e..b85bbfc 100644 --- a/framelesshelper.cpp +++ b/framelesshelper.cpp @@ -407,29 +407,31 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event) if (!obj) { continue; } -#ifdef QT_WIDGETS_LIB - const auto widget = qobject_cast(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(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, diff --git a/framelessquickhelper.cpp b/framelessquickhelper.cpp index 54cbed6..8c38008 100644 --- a/framelessquickhelper.cpp +++ b/framelessquickhelper.cpp @@ -31,15 +31,34 @@ #include #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(object); + if (!window) { + qWarning() << "Failed to convert" << object << "to QWindow!"; + return nullptr; + } +#ifdef Q_OS_WINDOWS + return reinterpret_cast(window->winId()); +#else + return static_cast(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(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 diff --git a/framelessquickhelper.h b/framelessquickhelper.h index d8576eb..d3b6567 100644 --- a/framelessquickhelper.h +++ b/framelessquickhelper.h @@ -24,7 +24,6 @@ #pragma once -#include "framelesshelper_global.h" #include #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: diff --git a/framelesswindowsmanager.cpp b/framelesswindowsmanager.cpp index 3f47746..b1270d9 100644 --- a/framelesswindowsmanager.cpp +++ b/framelesswindowsmanager.cpp @@ -24,16 +24,9 @@ #include "framelesswindowsmanager.h" +#ifndef Q_OS_WINDOWS #include -#include #include -#ifdef QT_WIDGETS_LIB -#include -#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(object) : nullptr; } -QScreen *getCurrentScreenFromWindow(QObject *window) -{ - Q_ASSERT(window); - if (window->isWindowType()) { - return qobject_cast(window)->screen(); - } -#ifdef QT_WIDGETS_LIB - else if (window->isWidgetType()) { -#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) - return qobject_cast(window)->screen(); -#else - QWindow *win = qobject_cast(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(qobject_cast(window)->winId()); - } -#ifdef QT_WIDGETS_LIB - else if (window->isWidgetType()) { - return reinterpret_cast(qobject_cast(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(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(window); - if (widget && widget->isTopLevel()) { - windowSize = widget->size(); - screenSize = getDesktopAvailableSize(widget); - screenGeometry = getDesktopAvailableGeometry(widget); - } - } -#endif - else { - reportError(); - } - const int newX = qRound(static_cast(screenSize.width() - windowSize.width()) / 2.0); - const int newY = qRound(static_cast(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(window); - if (win) { - win->setX(x); - win->setY(y); - } - } -#ifdef QT_WIDGETS_LIB - else if (window->isWidgetType()) { - const auto widget = qobject_cast(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(window)->minimumSize(); - } -#ifdef QT_WIDGETS_LIB - else if (window->isWidgetType()) { - return qobject_cast(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(window)->setMinimumSize(value); - } -#ifdef QT_WIDGETS_LIB - else if (window->isWidgetType()) { - qobject_cast(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(window)->maximumSize(); - } -#ifdef QT_WIDGETS_LIB - else if (window->isWidgetType()) { - return qobject_cast(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(window)->setMaximumSize(value); - } -#ifdef QT_WIDGETS_LIB - else if (window->isWidgetType()) { - qobject_cast(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 diff --git a/framelesswindowsmanager.h b/framelesswindowsmanager.h index 83a4d02..39fcf17 100644 --- a/framelesswindowsmanager.h +++ b/framelesswindowsmanager.h @@ -27,6 +27,11 @@ #include "framelesshelper_global.h" #include +#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); }; diff --git a/lib.pro b/lib.pro index d2dd0db..662a21c 100644 --- a/lib.pro +++ b/lib.pro @@ -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 diff --git a/winnativeeventfilter.cpp b/winnativeeventfilter.cpp index 900cd5d..ab43611 100644 --- a/winnativeeventfilter.cpp +++ b/winnativeeventfilter.cpp @@ -46,12 +46,6 @@ #else #include #endif -#ifdef QT_QUICK_LIB -#include -#endif -#ifdef QT_WIDGETS_LIB -#include -#endif #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) #include #else @@ -1115,25 +1109,6 @@ void qCoreAppFixup() } } -HWND getHWNDFromQObject(QObject *object) -{ - Q_ASSERT(object); - WId wid = 0; - if (object->isWindowType()) { - wid = qobject_cast(object)->winId(); - } -#ifdef QT_WIDGETS_LIB - else if (object->isWidgetType()) { - wid = qobject_cast(object)->winId(); - } -#endif - else { - qFatal( - "Can't acquire the window handle: only top level QWidgets and QWindows are accepted."); - } - return reinterpret_cast(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 &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 &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(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(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); @@ -2071,7 +2009,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; @@ -2107,12 +2045,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); @@ -2125,12 +2057,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; @@ -2337,10 +2263,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(handle); @@ -2376,15 +2299,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); diff --git a/winnativeeventfilter.h b/winnativeeventfilter.h index f95c1ff..55ed9b6 100644 --- a/winnativeeventfilter.h +++ b/winnativeeventfilter.h @@ -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.