diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index d0107145af1..c26e3bc1a89 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -2011,6 +2011,10 @@ void QWindowsWindow::handleDpiChanged(HWND hwnd, WPARAM wParam, LPARAM lParam) prcNewWindow->right - prcNewWindow->left, prcNewWindow->bottom - prcNewWindow->top, SWP_NOZORDER | SWP_NOACTIVATE); } + + // Re-apply mask now that we have a new DPI, which have resulted in + // a new scale factor. + setMask(QHighDpi::toNativeLocalRegion(window()->mask(), window())); } void QWindowsWindow::handleDpiChangedAfterParent(HWND hwnd) diff --git a/tests/manual/CMakeLists.txt b/tests/manual/CMakeLists.txt index 71dd87f5753..abe9ac42353 100644 --- a/tests/manual/CMakeLists.txt +++ b/tests/manual/CMakeLists.txt @@ -64,6 +64,7 @@ endif() add_subdirectory(xmlstreamlint) add_subdirectory(shortcuts) add_subdirectory(dialogs) +add_subdirectory(windowmask) add_subdirectory(windowtransparency) add_subdirectory(unc) add_subdirectory(qtabbar) diff --git a/tests/manual/windowmask/CMakeLists.txt b/tests/manual/windowmask/CMakeLists.txt new file mode 100644 index 00000000000..e1417bedbe3 --- /dev/null +++ b/tests/manual/windowmask/CMakeLists.txt @@ -0,0 +1,14 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +##################################################################### +## windowmask Binary: +##################################################################### + +qt_internal_add_manual_test(windowmask + SOURCES + main.cpp + LIBRARIES + Qt::Gui + Qt::Widgets +) diff --git a/tests/manual/windowmask/main.cpp b/tests/manual/windowmask/main.cpp new file mode 100644 index 00000000000..d6588caba71 --- /dev/null +++ b/tests/manual/windowmask/main.cpp @@ -0,0 +1,124 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include + +template +class Circle : public Paintable +{ +public: + using Paintable::setMinimumSize; + using Paintable::setMaximumSize; + using Paintable::width; + using Paintable::height; + using Paintable::screen; + using Paintable::devicePixelRatio; + using Paintable::metaObject; + using Paintable::setMask; + using Paintable::frameGeometry; + using Paintable::setPosition; + using Paintable::startSystemMove; + using Paintable::setFlags; + using Paintable::requestUpdate; + + Circle() + { + setMinimumSize({200, 200}); + setMaximumSize({200, 200}); + setFlags(Qt::Window | Qt::FramelessWindowHint); + } + +protected: + void paintEvent(QPaintEvent *) override + { + qWarning() << "Painting into a" << this << "with DPR" << devicePixelRatio() + << "on a screen with DPR" << screen()->devicePixelRatio(); + QPainter painter(static_cast(this)); + painter.fillRect(0, 0, width(), height(), devicePixelRatio() == 1 ? Qt::red : Qt::green); + painter.setPen(QPen(Qt::black, 5)); + painter.drawRect(10, 10, width() - 20, height() - 20); + painter.drawText(0, 0, width(), height(), Qt::AlignHCenter | Qt::AlignVCenter, metaObject()->className()); + } + void mousePressEvent(QMouseEvent *event) override + { + if (event->button() == Qt::LeftButton) { + if (event->modifiers() & Qt::ControlModifier) + requestUpdate(); + else if (event->modifiers() & Qt::AltModifier) + updateMask(); + else if (event->modifiers() & Qt::ShiftModifier && startSystemMove()) + dragPosition = {}; + else + dragPosition = event->globalPosition() - frameGeometry().topLeft(); + } + } + void mouseMoveEvent(QMouseEvent *event) override + { + if (event->buttons() & Qt::LeftButton && !dragPosition.isNull()) + setPosition((event->globalPosition() - dragPosition).toPoint()); + } + void resizeEvent(QResizeEvent *) override + { + updateMask(); + } + + void updateMask() + { + int side = qMin(width(), height()); + QRegion maskedRegion(width() / 2 - side / 2, height() / 2 - side / 2, side, + side, QRegion::Ellipse); + qDebug() << "Updating mask for" << this << "to" << maskedRegion.boundingRect(); + setMask(maskedRegion); + } + + QPointF dragPosition; +}; + +class WindowLikeWidget : public QWidget +{ +public: + void setPosition(const QPoint &point) { QWidget::move(point); } + bool startSystemMove() { return windowHandle()->startSystemMove(); } + void setFlags(Qt::WindowFlags flags) { setWindowFlags(flags); } + void requestUpdate() { update(); } +}; + +class Widget : public Circle +{ +public: + Widget() + { + setAttribute(Qt::WA_TranslucentBackground); + } +}; + +class Window : public Circle +{ +}; + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + Widget widget; + widget.show(); + + Window window; + window.show(); + + auto dumpScreenData = [](QScreen *screen){ + qDebug() << "- name:" << screen->name(); + qDebug() << "- dpr :" << screen->devicePixelRatio(); + }; + + QObject::connect(widget.windowHandle(), &QWindow::screenChanged, &widget, [&]{ + qDebug() << "Screen changed for" << &widget; + dumpScreenData(widget.screen()); + }); + QObject::connect(&window, &QWindow::screenChanged, &window, [&]{ + qDebug() << "Screen changed for" << &window; + dumpScreenData(window.screen()); + }); + + return app.exec(); +}