Windows QPA: Add detection of dark mode
Read the dark mode setting and make it accessible via native interface. Add a command line option to set the support level. Task-number: QTBUG-72028 Change-Id: I1e9fe296a6b1bda81512d003183038b866b67545 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
This commit is contained in:
parent
1278995778
commit
12f085e538
@ -592,6 +592,21 @@ static QWindowGeometrySpecification windowGeometrySpecification = Q_WINDOW_GEOME
|
|||||||
\list
|
\list
|
||||||
\li \c {altgr}, detect the key \c {AltGr} found on some keyboards as
|
\li \c {altgr}, detect the key \c {AltGr} found on some keyboards as
|
||||||
Qt::GroupSwitchModifier (since Qt 5.12).
|
Qt::GroupSwitchModifier (since Qt 5.12).
|
||||||
|
\li \c {darkmode=[1|2]} controls how Qt responds to the activation
|
||||||
|
of the \e{Dark Mode for applications} introduced in Windows 10
|
||||||
|
1903 (since Qt 5.15).
|
||||||
|
|
||||||
|
A value of 1 causes Qt to switch the window borders to black
|
||||||
|
when \e{Dark Mode for applications} is activated and no High
|
||||||
|
Contrast Theme is in use. This is intended for applications
|
||||||
|
that implement their own theming.
|
||||||
|
|
||||||
|
A value of 2 will in addition cause the Windows Vista style to
|
||||||
|
be deactivated and switch to the Windows style using a
|
||||||
|
simplified palette in dark mode. This is currently
|
||||||
|
experimental pending the introduction of new style that
|
||||||
|
properly adapts to dark mode.
|
||||||
|
|
||||||
\li \c {dialogs=[xp|none]}, \c xp uses XP-style native dialogs and
|
\li \c {dialogs=[xp|none]}, \c xp uses XP-style native dialogs and
|
||||||
\c none disables them.
|
\c none disables them.
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
#include "qwindowsintegration.h"
|
#include "qwindowsintegration.h"
|
||||||
#include "qwindowswindow.h"
|
#include "qwindowswindow.h"
|
||||||
#include "qwindowskeymapper.h"
|
#include "qwindowskeymapper.h"
|
||||||
|
#include "qwindowsnativeinterface.h"
|
||||||
#include "qwindowsmousehandler.h"
|
#include "qwindowsmousehandler.h"
|
||||||
#include "qwindowspointerhandler.h"
|
#include "qwindowspointerhandler.h"
|
||||||
#include "qtwindowsglobal.h"
|
#include "qtwindowsglobal.h"
|
||||||
@ -277,8 +278,11 @@ struct QWindowsContextPrivate {
|
|||||||
bool m_asyncExpose = false;
|
bool m_asyncExpose = false;
|
||||||
HPOWERNOTIFY m_powerNotification = nullptr;
|
HPOWERNOTIFY m_powerNotification = nullptr;
|
||||||
HWND m_powerDummyWindow = nullptr;
|
HWND m_powerDummyWindow = nullptr;
|
||||||
|
static bool m_darkMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool QWindowsContextPrivate::m_darkMode = false;
|
||||||
|
|
||||||
QWindowsContextPrivate::QWindowsContextPrivate()
|
QWindowsContextPrivate::QWindowsContextPrivate()
|
||||||
: m_oleInitializeResult(OleInitialize(nullptr))
|
: m_oleInitializeResult(OleInitialize(nullptr))
|
||||||
{
|
{
|
||||||
@ -293,6 +297,7 @@ QWindowsContextPrivate::QWindowsContextPrivate()
|
|||||||
m_systemInfo |= QWindowsContext::SI_RTL_Extensions;
|
m_systemInfo |= QWindowsContext::SI_RTL_Extensions;
|
||||||
m_keyMapper.setUseRTLExtensions(true);
|
m_keyMapper.setUseRTLExtensions(true);
|
||||||
}
|
}
|
||||||
|
m_darkMode = QWindowsTheme::queryDarkMode();
|
||||||
if (FAILED(m_oleInitializeResult)) {
|
if (FAILED(m_oleInitializeResult)) {
|
||||||
qWarning() << "QWindowsContext: OleInitialize() failed: "
|
qWarning() << "QWindowsContext: OleInitialize() failed: "
|
||||||
<< QWindowsContext::comErrorString(m_oleInitializeResult);
|
<< QWindowsContext::comErrorString(m_oleInitializeResult);
|
||||||
@ -485,6 +490,11 @@ void QWindowsContext::setProcessDpiAwareness(QtWindows::ProcessDpiAwareness dpiA
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QWindowsContext::isDarkMode()
|
||||||
|
{
|
||||||
|
return QWindowsContextPrivate::m_darkMode;
|
||||||
|
}
|
||||||
|
|
||||||
QWindowsContext *QWindowsContext::instance()
|
QWindowsContext *QWindowsContext::instance()
|
||||||
{
|
{
|
||||||
return m_instance;
|
return m_instance;
|
||||||
@ -1203,9 +1213,17 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
|
|||||||
t->displayChanged();
|
t->displayChanged();
|
||||||
QWindowsWindow::displayChanged();
|
QWindowsWindow::displayChanged();
|
||||||
return d->m_screenManager.handleDisplayChange(wParam, lParam);
|
return d->m_screenManager.handleDisplayChange(wParam, lParam);
|
||||||
case QtWindows::SettingChangedEvent:
|
case QtWindows::SettingChangedEvent: {
|
||||||
QWindowsWindow::settingsChanged();
|
QWindowsWindow::settingsChanged();
|
||||||
|
const bool darkMode = QWindowsTheme::queryDarkMode();
|
||||||
|
if (darkMode != QWindowsContextPrivate::m_darkMode) {
|
||||||
|
QWindowsContextPrivate::m_darkMode = darkMode;
|
||||||
|
auto nativeInterface =
|
||||||
|
static_cast<QWindowsNativeInterface *>(QWindowsIntegration::instance()->nativeInterface());
|
||||||
|
emit nativeInterface->darkModeChanged(darkMode);
|
||||||
|
}
|
||||||
return d->m_screenManager.handleScreenChanges();
|
return d->m_screenManager.handleScreenChanges();
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,8 @@ public:
|
|||||||
void setProcessDpiAwareness(QtWindows::ProcessDpiAwareness dpiAwareness);
|
void setProcessDpiAwareness(QtWindows::ProcessDpiAwareness dpiAwareness);
|
||||||
static int processDpiAwareness();
|
static int processDpiAwareness();
|
||||||
|
|
||||||
|
static bool isDarkMode();
|
||||||
|
|
||||||
void setDetectAltGrModifier(bool a);
|
void setDetectAltGrModifier(bool a);
|
||||||
|
|
||||||
// Returns a combination of SystemInfoFlags
|
// Returns a combination of SystemInfoFlags
|
||||||
|
@ -219,6 +219,10 @@ static inline unsigned parseOptions(const QStringList ¶mList,
|
|||||||
options |= QWindowsIntegration::DontUseWMPointer;
|
options |= QWindowsIntegration::DontUseWMPointer;
|
||||||
} else if (param == u"reverse") {
|
} else if (param == u"reverse") {
|
||||||
options |= QWindowsIntegration::RtlEnabled;
|
options |= QWindowsIntegration::RtlEnabled;
|
||||||
|
} else if (param == u"darkmode=1") {
|
||||||
|
options |= QWindowsIntegration::DarkModeWindowFrames;
|
||||||
|
} else if (param == u"darkmode=2") {
|
||||||
|
options |= QWindowsIntegration::DarkModeWindowFrames | QWindowsIntegration::DarkModeStyle;
|
||||||
} else {
|
} else {
|
||||||
qWarning() << "Unknown option" << param;
|
qWarning() << "Unknown option" << param;
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,9 @@ public:
|
|||||||
NoNativeMenus = 0x200,
|
NoNativeMenus = 0x200,
|
||||||
DontUseWMPointer = 0x400,
|
DontUseWMPointer = 0x400,
|
||||||
DetectAltGrModifier = 0x800,
|
DetectAltGrModifier = 0x800,
|
||||||
RtlEnabled = 0x1000
|
RtlEnabled = 0x1000,
|
||||||
|
DarkModeWindowFrames = 0x2000,
|
||||||
|
DarkModeStyle = 0x4000
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit QWindowsIntegration(const QStringList ¶mList);
|
explicit QWindowsIntegration(const QStringList ¶mList);
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
#include "qwindowsopengltester.h"
|
#include "qwindowsopengltester.h"
|
||||||
#include "qwindowsintegration.h"
|
#include "qwindowsintegration.h"
|
||||||
#include "qwindowsmime.h"
|
#include "qwindowsmime.h"
|
||||||
|
#include "qwindowstheme.h"
|
||||||
#include "qwin10helpers.h"
|
#include "qwin10helpers.h"
|
||||||
|
|
||||||
#include <QtGui/qwindow.h>
|
#include <QtGui/qwindow.h>
|
||||||
@ -316,4 +317,15 @@ QVariant QWindowsNativeInterface::gpuList() const
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QWindowsNativeInterface::isDarkMode() const
|
||||||
|
{
|
||||||
|
return QWindowsContext::isDarkMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dark mode support level 2 (style)
|
||||||
|
bool QWindowsNativeInterface::isDarkModeStyle() const
|
||||||
|
{
|
||||||
|
return (QWindowsIntegration::instance()->options() & QWindowsIntegration::DarkModeStyle) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -65,6 +65,8 @@ class QWindowsNativeInterface : public QPlatformNativeInterface
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(bool asyncExpose READ asyncExpose WRITE setAsyncExpose)
|
Q_PROPERTY(bool asyncExpose READ asyncExpose WRITE setAsyncExpose)
|
||||||
|
Q_PROPERTY(bool darkMode READ isDarkMode STORED false NOTIFY darkModeChanged)
|
||||||
|
Q_PROPERTY(bool darkModeStyle READ isDarkModeStyle STORED false)
|
||||||
Q_PROPERTY(QVariant gpu READ gpu STORED false)
|
Q_PROPERTY(QVariant gpu READ gpu STORED false)
|
||||||
Q_PROPERTY(QVariant gpuList READ gpuList STORED false)
|
Q_PROPERTY(QVariant gpuList READ gpuList STORED false)
|
||||||
|
|
||||||
@ -92,6 +94,9 @@ public:
|
|||||||
bool asyncExpose() const;
|
bool asyncExpose() const;
|
||||||
void setAsyncExpose(bool value);
|
void setAsyncExpose(bool value);
|
||||||
|
|
||||||
|
bool isDarkMode() const;
|
||||||
|
bool isDarkModeStyle() const;
|
||||||
|
|
||||||
QVariant gpu() const;
|
QVariant gpu() const;
|
||||||
QVariant gpuList() const;
|
QVariant gpuList() const;
|
||||||
|
|
||||||
@ -109,6 +114,9 @@ public:
|
|||||||
|
|
||||||
QFunctionPointer platformFunction(const QByteArray &function) const override;
|
QFunctionPointer platformFunction(const QByteArray &function) const override;
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void darkModeChanged(bool);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static QWindowsWindowFunctions::WindowActivationBehavior m_windowActivationBehavior;
|
static QWindowsWindowFunctions::WindowActivationBehavior m_windowActivationBehavior;
|
||||||
};
|
};
|
||||||
|
@ -63,6 +63,7 @@
|
|||||||
#include <QtCore/qcoreapplication.h>
|
#include <QtCore/qcoreapplication.h>
|
||||||
#include <QtCore/qdebug.h>
|
#include <QtCore/qdebug.h>
|
||||||
#include <QtCore/qtextstream.h>
|
#include <QtCore/qtextstream.h>
|
||||||
|
#include <QtCore/qoperatingsystemversion.h>
|
||||||
#include <QtCore/qsysinfo.h>
|
#include <QtCore/qsysinfo.h>
|
||||||
#include <QtCore/qcache.h>
|
#include <QtCore/qcache.h>
|
||||||
#include <QtCore/qthread.h>
|
#include <QtCore/qthread.h>
|
||||||
@ -78,6 +79,7 @@
|
|||||||
#include <QtFontDatabaseSupport/private/qwindowsfontdatabase_p.h>
|
#include <QtFontDatabaseSupport/private/qwindowsfontdatabase_p.h>
|
||||||
#include <private/qhighdpiscaling_p.h>
|
#include <private/qhighdpiscaling_p.h>
|
||||||
#include <private/qsystemlibrary_p.h>
|
#include <private/qsystemlibrary_p.h>
|
||||||
|
#include <private/qwinregistry_p.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@ -946,6 +948,23 @@ bool QWindowsTheme::useNativeMenus()
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QWindowsTheme::queryDarkMode()
|
||||||
|
{
|
||||||
|
if (QOperatingSystemVersion::current()
|
||||||
|
< QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 17763)
|
||||||
|
|| queryHighContrast()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const auto setting = QWinRegistryKey(HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)")
|
||||||
|
.dwordValue(L"AppsUseLightTheme");
|
||||||
|
return setting.second && setting.first == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QWindowsTheme::queryHighContrast()
|
||||||
|
{
|
||||||
|
return booleanSystemParametersInfo(SPI_GETHIGHCONTRAST, false);
|
||||||
|
}
|
||||||
|
|
||||||
QPlatformMenuItem *QWindowsTheme::createPlatformMenuItem() const
|
QPlatformMenuItem *QWindowsTheme::createPlatformMenuItem() const
|
||||||
{
|
{
|
||||||
qCDebug(lcQpaMenus) << __FUNCTION__;
|
qCDebug(lcQpaMenus) << __FUNCTION__;
|
||||||
|
@ -84,6 +84,8 @@ public:
|
|||||||
void showPlatformMenuBar() override;
|
void showPlatformMenuBar() override;
|
||||||
|
|
||||||
static bool useNativeMenus();
|
static bool useNativeMenus();
|
||||||
|
static bool queryDarkMode();
|
||||||
|
static bool queryHighContrast();
|
||||||
|
|
||||||
void refreshFonts();
|
void refreshFonts();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user