summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/windows/qwindowswindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/windows/qwindowswindow.cpp')
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp83
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;