Windows QPA: Add setting of dark window borders

Implement dark mode support level 1: change the
window borders to dark and back, tracking the
activation of dark mode.

Task-number: QTBUG-72028
Change-Id: I6e8b31e7ee574f4d90438405f361cd940faee7fd
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
This commit is contained in:
Friedemann Kleint 2020-01-03 16:10:40 +01:00
parent 12f085e538
commit eb26563dd5
3 changed files with 52 additions and 0 deletions

View File

@ -1221,6 +1221,11 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
auto nativeInterface =
static_cast<QWindowsNativeInterface *>(QWindowsIntegration::instance()->nativeInterface());
emit nativeInterface->darkModeChanged(darkMode);
const auto options = QWindowsIntegration::instance()->options();
if ((options & QWindowsIntegration::DarkModeWindowFrames) != 0) {
for (QWindowsWindow *w : d->m_windows)
w->setDarkBorder(QWindowsContextPrivate::m_darkMode);
}
}
return d->m_screenManager.handleScreenChanges();
}

View File

@ -749,6 +749,11 @@ void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flag
}
}
static inline bool shouldApplyDarkFrame(const QWindow *w)
{
return w->isTopLevel() && !w->flags().testFlag(Qt::FramelessWindowHint);
}
QWindowsWindowData
WindowCreationData::create(const QWindow *w, const WindowData &data, QString title) const
{
@ -816,6 +821,12 @@ QWindowsWindowData
return result;
}
if (QWindowsContext::isDarkMode()
&& (QWindowsIntegration::instance()->options() & QWindowsIntegration::DarkModeWindowFrames) != 0
&& shouldApplyDarkFrame(w)) {
QWindowsWindow::setDarkBorderToWindow(result.hwnd, true);
}
if (mirrorParentWidth != 0) {
context->obtainedPos.setX(mirrorParentWidth - context->obtainedSize.width()
- context->obtainedPos.x());
@ -2892,6 +2903,39 @@ bool QWindowsWindow::isTopLevel() const
return window()->isTopLevel() && !m_data.embedded;
}
enum : WORD {
DwmwaUseImmersiveDarkMode = 20,
DwmwaUseImmersiveDarkModeBefore20h1 = 19
};
static bool queryDarkBorder(HWND hwnd)
{
BOOL result = FALSE;
const bool ok =
SUCCEEDED(DwmGetWindowAttribute(hwnd, DwmwaUseImmersiveDarkMode, &result, sizeof(result)))
|| SUCCEEDED(DwmGetWindowAttribute(hwnd, DwmwaUseImmersiveDarkModeBefore20h1, &result, sizeof(result)));
if (!ok)
qWarning("%s: Unable to retrieve dark window border setting.", __FUNCTION__);
return result == TRUE;
}
bool QWindowsWindow::setDarkBorderToWindow(HWND hwnd, bool d)
{
const BOOL darkBorder = d ? TRUE : FALSE;
const bool ok =
SUCCEEDED(DwmSetWindowAttribute(hwnd, DwmwaUseImmersiveDarkMode, &darkBorder, sizeof(darkBorder)))
|| SUCCEEDED(DwmSetWindowAttribute(hwnd, DwmwaUseImmersiveDarkModeBefore20h1, &darkBorder, sizeof(darkBorder)));
if (!ok)
qWarning("%s: Unable to set dark window border.", __FUNCTION__);
return ok;
}
void QWindowsWindow::setDarkBorder(bool d)
{
if (shouldApplyDarkFrame(window()) && queryDarkBorder(m_data.hwnd) != d)
setDarkBorderToWindow(m_data.hwnd, d);
}
QWindowsMenuBar *QWindowsWindow::menuBar() const
{
return m_menuBar.data();

View File

@ -287,6 +287,9 @@ public:
HWND handle() const override { return m_data.hwnd; }
bool isTopLevel() const override;
static bool setDarkBorderToWindow(HWND hwnd, bool d);
void setDarkBorder(bool d);
QWindowsMenuBar *menuBar() const;
void setMenuBar(QWindowsMenuBar *mb);