diff options
Diffstat (limited to 'src/plugins/platforms/windows/qwindowswindow.cpp')
-rw-r--r-- | src/plugins/platforms/windows/qwindowswindow.cpp | 83 |
1 files changed, 66 insertions, 17 deletions
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index a795328bdf..d1a017b6cb 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -33,6 +33,7 @@ #include <private/qguiapplication_p.h> #include <private/qhighdpiscaling_p.h> #include <qpa/qwindowsysteminterface.h> +#include <qpa/qplatformtheme.h> #include <QtCore/qdebug.h> #include <QtCore/qlibraryinfo.h> @@ -850,8 +851,9 @@ static inline bool shouldApplyDarkFrame(const QWindow *w) { if (!w->isTopLevel() || w->flags().testFlag(Qt::FramelessWindowHint)) return false; - if (QWindowsIntegration::instance()->darkModeHandling().testFlag(QWindowsApplication::DarkModeStyle)) - return true; + // the application has explicitly opted out of dark frames + if (!QWindowsIntegration::instance()->darkModeHandling().testFlag(QWindowsApplication::DarkModeWindowFrames)) + return false; // if the application supports a dark border, and the palette is dark (window background color // is darker than the text), then turn dark-border support on, otherwise use a light border. const QPalette defaultPalette; @@ -887,7 +889,8 @@ QWindowsWindowData style, exStyle)); QWindowsContext::instance()->setWindowCreationContext(context); - const bool hasFrame = (style & (WS_DLGFRAME | WS_THICKFRAME)); + const bool hasFrame = (style & (WS_DLGFRAME | WS_THICKFRAME)) + && !(result.flags & Qt::FramelessWindowHint); QMargins invMargins = topLevel && hasFrame && QWindowsGeometryHint::positionIncludesFrame(w) ? invisibleMargins(QPoint(context->frameX, context->frameY)) : QMargins(); @@ -926,11 +929,8 @@ QWindowsWindowData return result; } - if (QWindowsContext::isDarkMode() - && QWindowsIntegration::instance()->darkModeHandling().testFlag(QWindowsApplication::DarkModeWindowFrames) - && shouldApplyDarkFrame(w)) { - QWindowsWindow::setDarkBorderToWindow(result.hwnd, true); - } + QWindowsWindow::setDarkBorderToWindow(result.hwnd, QWindowsContext::isDarkMode() + && shouldApplyDarkFrame(w)); if (mirrorParentWidth != 0) { context->obtainedPos.setX(mirrorParentWidth - context->obtainedSize.width() @@ -1408,13 +1408,16 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w, const QScreen * requestedGeometry(geometry), obtainedPos(geometryIn.topLeft()), obtainedSize(geometryIn.size()), - margins(QWindowsGeometryHint::frame(w, geometry, style, exStyle)), - customMargins(cm) + margins(QWindowsGeometryHint::frame(w, geometry, style, exStyle)) { // Geometry of toplevels does not consider window frames. // TODO: No concept of WA_wasMoved yet that would indicate a // CW_USEDEFAULT unless set. For now, assume that 0,0 means 'default' // for toplevels. + + if (!(w->flags() & Qt::FramelessWindowHint)) + customMargins = cm; + if (geometry.isValid() || !qt_window_private(const_cast<QWindow *>(w))->resizeAutomatic) { frameX = geometry.x(); @@ -1969,7 +1972,15 @@ void QWindowsWindow::handleDpiScaledSize(WPARAM wParam, LPARAM lParam, LRESULT * const qreal scale = QHighDpiScaling::roundScaleFactor(qreal(dpi) / QWindowsScreen::baseDpi) / QHighDpiScaling::roundScaleFactor(qreal(savedDpi()) / QWindowsScreen::baseDpi); const QMargins margins = QWindowsGeometryHint::frame(window(), style(), exStyle(), dpi); - const QSize windowSize = (geometry().size() * scale).grownBy(margins); + if (!(m_data.flags & Qt::FramelessWindowHint)) { + // We need to update the custom margins to match the current DPI, because + // we don't want our users manually hook into this message just to set a + // new margin, but here we can't call setCustomMargins() directly, that + // function will change the window geometry which conflicts with what we + // are currently doing. + m_data.customMargins *= scale; + } + const QSize windowSize = (geometry().size() * scale).grownBy(margins + customMargins()); SIZE *size = reinterpret_cast<SIZE *>(lParam); size->cx = windowSize.width(); size->cy = windowSize.height(); @@ -2119,7 +2130,7 @@ void QWindowsWindow::setGeometry(const QRect &rectIn) if (m_data.geometry != rect && (isVisible() || QLibraryInfo::isDebugBuild())) { const auto warning = msgUnableToSetGeometry(this, rectIn, m_data.geometry, - m_data.fullFrameMargins, m_data.customMargins); + fullFrameMargins(), customMargins()); qWarning("%s: %s", __FUNCTION__, qPrintable(warning)); } } else { @@ -2303,9 +2314,22 @@ static inline bool isSoftwareGl() } bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message, - WPARAM, LPARAM, LRESULT *result) + WPARAM wParam, LPARAM, LRESULT *result) { if (message == WM_ERASEBKGND) { // Backing store - ignored. + if (!m_firstBgDraw && QWindowsIntegration::instance()->darkModeHandling().testFlag(QWindowsApplication::DarkModeStyle)) { + // Get system background color + const QColor bgColor = QGuiApplicationPrivate::platformTheme()->palette()->color(QPalette::Window); + HBRUSH bgBrush = CreateSolidBrush(RGB(bgColor.red(), bgColor.green(), bgColor.blue())); + // Fill rectangle with system background color + RECT rc; + auto hdc = reinterpret_cast<HDC>(wParam); + GetClientRect(hwnd, &rc); + FillRect(hdc, &rc, bgBrush); + DeleteObject(bgBrush); + // Brush the window with system background color only for first time + m_firstBgDraw = true; + } *result = 1; return true; } @@ -2375,7 +2399,8 @@ QWindowsWindowData QWindowsWindow::setWindowFlags_sys(Qt::WindowFlags wt, QWindowsWindowData result = m_data; result.flags = creationData.flags; result.embedded = creationData.embedded; - result.hasFrame = (creationData.style & (WS_DLGFRAME | WS_THICKFRAME)); + result.hasFrame = (creationData.style & (WS_DLGFRAME | WS_THICKFRAME)) + && !(creationData.flags & Qt::FramelessWindowHint); return result; } @@ -2594,6 +2619,9 @@ void QWindowsWindow::setExStyle(unsigned s) const bool QWindowsWindow::windowEvent(QEvent *event) { switch (event->type()) { + case QEvent::ApplicationPaletteChange: + setDarkBorder(QWindowsContext::isDarkMode()); + break; case QEvent::WindowBlocked: // Blocked by another modal window. setEnabled(false); setFlag(BlockedByModal); @@ -2662,6 +2690,8 @@ bool QWindowsWindow::handleGeometryChanging(MSG *message) const void QWindowsWindow::setFullFrameMargins(const QMargins &newMargins) { + if (m_data.flags & Qt::FramelessWindowHint) + return; if (m_data.fullFrameMargins != newMargins) { qCDebug(lcQpaWindows) << __FUNCTION__ << window() << m_data.fullFrameMargins << "->" << newMargins; m_data.fullFrameMargins = newMargins; @@ -2679,12 +2709,14 @@ void QWindowsWindow::updateFullFrameMargins() void QWindowsWindow::calculateFullFrameMargins() { + if (m_data.flags & Qt::FramelessWindowHint) + return; // Normally obtained from WM_NCCALCSIZE. This calculation only works // when no native menu is present. const auto systemMargins = testFlag(DisableNonClientScaling) ? QWindowsGeometryHint::frameOnPrimaryScreen(window(), m_data.hwnd) : frameMargins_sys(); - setFullFrameMargins(systemMargins + m_data.customMargins); + setFullFrameMargins(systemMargins + customMargins()); } QMargins QWindowsWindow::frameMargins() const @@ -2697,6 +2729,8 @@ QMargins QWindowsWindow::frameMargins() const QMargins QWindowsWindow::fullFrameMargins() const { + if (m_data.flags & Qt::FramelessWindowHint) + return {}; return m_data.fullFrameMargins; } @@ -3165,8 +3199,12 @@ bool QWindowsWindow::setDarkBorderToWindow(HWND hwnd, bool d) void QWindowsWindow::setDarkBorder(bool d) { - if (shouldApplyDarkFrame(window()) && queryDarkBorder(m_data.hwnd) != d) - setDarkBorderToWindow(m_data.hwnd, d); + // respect explicit opt-out and incompatible palettes or styles + d = d && shouldApplyDarkFrame(window()); + if (queryDarkBorder(m_data.hwnd) == d) + return; + + setDarkBorderToWindow(m_data.hwnd, d); } QWindowsMenuBar *QWindowsWindow::menuBar() const @@ -3179,6 +3217,13 @@ void QWindowsWindow::setMenuBar(QWindowsMenuBar *mb) m_menuBar = mb; } +QMargins QWindowsWindow::customMargins() const +{ + if (m_data.flags & Qt::FramelessWindowHint) + return {}; + return m_data.customMargins; +} + /*! \brief Sets custom margins to be added to the default margins determined by the windows style in the handling of the WM_NCCALCSIZE message. @@ -3191,6 +3236,10 @@ void QWindowsWindow::setMenuBar(QWindowsMenuBar *mb) void QWindowsWindow::setCustomMargins(const QMargins &newCustomMargins) { + if (m_data.flags & Qt::FramelessWindowHint) { + qCWarning(lcQpaWindows) << "You should not set custom margins for a frameless window."; + return; + } if (newCustomMargins != m_data.customMargins) { const QMargins oldCustomMargins = m_data.customMargins; m_data.customMargins = newCustomMargins; |