4#include <QtCore/qt_windows.h>
12#if QT_CONFIG(systemtrayicon)
19#include <commoncontrols.h>
22#include <QtCore/qapplicationstatic.h>
23#include <QtCore/qvariant.h>
24#include <QtCore/qcoreapplication.h>
25#include <QtCore/qdebug.h>
26#include <QtCore/qsysinfo.h>
27#include <QtCore/qcache.h>
28#include <QtCore/qthread.h>
29#include <QtCore/qqueue.h>
30#include <QtCore/qmutex.h>
31#include <QtCore/qwaitcondition.h>
32#include <QtCore/qoperatingsystemversion.h>
33#include <QtGui/qcolor.h>
34#include <QtGui/qpalette.h>
35#include <QtGui/qguiapplication.h>
36#include <QtGui/qpainter.h>
37#include <QtGui/qpixmapcache.h>
38#include <qpa/qwindowsysteminterface.h>
39#include <QtGui/private/qabstractfileiconengine_p.h>
40#include <QtGui/private/qwindowsfontdatabase_p.h>
41#include <private/qhighdpiscaling_p.h>
42#include <private/qsystemlibrary_p.h>
43#include <private/qwinregistry_p.h>
44#include <QtCore/private/qfunctions_win_p.h>
48#if QT_CONFIG(cpp_winrt)
49# include <QtCore/private/qt_winrtbase_p.h>
51# include <winrt/Windows.UI.ViewManagement.h>
61 if (SystemParametersInfo(what, 0, &
result, 0))
69 if (SystemParametersInfo(what, 0, &
result, 0))
76 return {(c1.
red() +
c2.red()) / 2,
78 (c1.
blue() +
c2.blue()) / 2};
87#if QT_CONFIG(cpp_winrt)
96#if QT_CONFIG(cpp_winrt)
97 using namespace winrt::Windows::UI::ViewManagement;
103 const QWinRegistryKey registry(HKEY_CURRENT_USER, LR
"(Software\Microsoft\Windows\DWM)");
107 if (!
value.isValid())
116 const QColor accentDarkest = accent.
darker(120 * 120 * 120);
119 return accentDarkest;
127 COLORREF cr = GetSysColor(
index);
128 return QColor(GetRValue(cr), GetGValue(cr), GetBValue(cr));
175 if (!m_taskQueue.isEmpty())
176 return m_taskQueue.dequeue();
177 m_waitForTaskCondition.
wait(&m_waitForTaskMutex);
184 QComHelper comHelper(COINIT_MULTITHREADED);
190 const bool result = SHGetFileInfo(
reinterpret_cast<const wchar_t *
>(
task->fileName.utf16()),
191 task->attributes, &
info,
sizeof(SHFILEINFO),
197 task->finished =
true;
204 std::chrono::milliseconds
timeout = std::chrono::milliseconds(5000))
208 m_taskQueue.enqueue(
task);
209 m_waitForTaskCondition.
wakeAll();
223 m_waitForTaskCondition.
wakeAll();
227 QQueue<QSharedPointer<Task>> m_taskQueue;
231 QMutex m_waitForTaskMutex;
236static inline QPalette standardPalette()
238 QColor backgroundColor(0xd4, 0xd0, 0xc8);
241 const QBrush darkBrush(darkColor);
262void QWindowsTheme::populateLightSystemBasePalette(
QPalette &
result)
270 const QColor linkColor = accent;
271 const QColor btnFace = background;
302void QWindowsTheme::populateDarkSystemBasePalette(
QPalette &
result)
304 QColor foreground, background,
305 accent, accentDark, accentDarker, accentDarkest,
306 accentLight, accentLighter, accentLightest;
307#if QT_CONFIG(cpp_winrt)
308 using namespace winrt::Windows::UI::ViewManagement;
320 systemBackground =
QColor(0x1E, 0x1E, 0x1E);
321 return systemBackground;
336 background =
QColor(0x1E, 0x1E, 0x1E);
338 accentDark = accent.
darker(120);
339 accentDarker = accentDark.
darker(120);
340 accentDarkest = accentDarker.
darker(120);
341 accentLight = accent.
lighter(120);
342 accentLighter = accentLight.
lighter(120);
343 accentLightest = accentLighter.
lighter(120);
345 const QColor linkColor = accent;
407 return systemPalette;
421 const QColor highlightColor =
getSysColor(isFlat ? COLOR_MENUHILIGHT : COLOR_HIGHLIGHT);
463 s_colorScheme = QWindowsTheme::queryColorScheme();
464 std::fill(m_fonts, m_fonts +
NFonts,
nullptr);
465 std::fill(m_palettes, m_palettes +
NPalettes,
nullptr);
467 refreshIconPixmapSizes();
474 m_instance =
nullptr;
537 if (scrollLines != DWORD(-1))
538 result = int(scrollLines);
542 return GetSystemMetrics(SM_CXDOUBLECLK);
553 return QWindowsTheme::effectiveColorScheme();
558 if (queryHighContrast())
561 return s_colorSchemeOverride;
563 return s_colorScheme;
564 return queryColorScheme();
569 s_colorSchemeOverride = scheme;
575 const auto oldColorScheme = s_colorScheme;
577 const auto newColorScheme = effectiveColorScheme();
578 const bool colorSchemeChanged = newColorScheme != oldColorScheme;
579 s_colorScheme = newColorScheme;
581 integration->updateApplicationBadge();
582 if (integration->darkModeHandling().testFlag(QWindowsApplication::DarkModeStyle)) {
584 QWindowSystemInterface::handleThemeChange<QWindowSystemInterface::SynchronousDelivery>();
586 if (colorSchemeChanged) {
592void QWindowsTheme::clearPalettes()
595 std::fill(m_palettes, m_palettes +
NPalettes,
nullptr);
598void QWindowsTheme::refreshPalettes()
628 populateLightSystemBasePalette(
result);
631 populateDarkSystemBasePalette(
result);
660void QWindowsTheme::clearFonts()
663 std::fill(m_fonts, m_fonts +
NFonts,
nullptr);
672#ifndef QT_NO_DEBUG_STREAM
678 d <<
"NONCLIENTMETRICS(iMenu=" <<
m.iMenuWidth <<
'x' <<
m.iMenuHeight
679 <<
", lfCaptionFont=";
681 d <<
", lfSmCaptionFont=";
683 d <<
", lfMenuFont=";
685 d <<
", lfMessageFont=";
687 d <<
", lfStatusFont=";
701 NONCLIENTMETRICS ncm;
703 qCDebug(lcQpaWindow) << __FUNCTION__ << ncm;
712 LOGFONT lfIconTitleFont;
713 SystemParametersInfoForDpi(SPI_GETICONTITLELOGFONT,
sizeof(lfIconTitleFont), &lfIconTitleFont, 0, dpi);
747#if QT_CONFIG(systemtrayicon)
762void QWindowsTheme::refreshIconPixmapSizes()
773 qCDebug(lcQpaWindow) << __FUNCTION__ << m_fileIconSizes;
781 if (
const HMODULE hmod = QSystemLibrary::load(L
"shell32")) {
783 static_cast<HICON
>(LoadImage(hmod, MAKEINTRESOURCE(resourceId),
784 IMAGE_ICON,
int(
size.width()),
int(
size.height()), 0));
787 DestroyIcon(iconHandle);
797 SHSTOCKICONID stockId = SIID_INVALID;
799 LPCTSTR iconName =
nullptr;
802 stockId = SIID_DRIVECD;
806 stockId = SIID_DRIVEDVD;
810 stockId = SIID_DRIVENET;
814 stockId = SIID_DRIVEFIXED;
818 stockId = SIID_DRIVE35;
822 stockFlags = SHGSI_LINKOVERLAY;
825 stockId = SIID_DOCNOASSOC;
829 stockFlags = SHGSI_LINKOVERLAY;
833 stockId = SIID_FOLDER;
843 stockFlags = SHGSI_LINKOVERLAY;
846 stockId = SIID_FOLDEROPEN;
850 stockId = SIID_FOLDER;
857 stockId = SIID_RECYCLER;
862 iconName = IDI_INFORMATION;
865 stockId = SIID_WARNING;
866 iconName = IDI_WARNING;
869 stockId = SIID_ERROR;
870 iconName = IDI_ERROR;
874 iconName = IDI_QUESTION;
877 stockId = SIID_SHIELD;
883 if (stockId != SIID_INVALID) {
884 SHSTOCKICONINFO iconInfo;
885 memset(&iconInfo, 0,
sizeof(iconInfo));
886 iconInfo.cbSize =
sizeof(iconInfo);
887 stockFlags |= SHGSI_ICONLOCATION;
888 if (SHGetStockIconInfo(stockId, stockFlags, &iconInfo) == S_OK) {
889 const auto iconSize = pixmapSize.width();
891 if (SHDefExtractIcon(iconInfo.szPath, iconInfo.iIcon, 0, &
icon,
nullptr,
iconSize) == S_OK) {
899 if (resourceId != -1) {
905 painter.
drawPixmap(0, 0,
int(pixmapSize.width()),
int(pixmapSize.height()), link);
912 HICON iconHandle = LoadIcon(
nullptr, iconName);
914 DestroyIcon(iconHandle);
932 switch (imageListSize) {
948 static_assert(
sizeof(T) <=
sizeof(
void *),
"FakePointers can only go that far.");
960 void operator delete (
void *) {}
969 static const IID iID_IImageList = {0x46eb5926, 0x582e, 0x4017, {0x9f, 0xdf, 0xe8, 0x99, 0x8d, 0xaa, 0x9, 0x50}};
971 IImageList *imageList =
nullptr;
972 HRESULT hr = SHGetImageList(iImageList, iID_IImageList,
reinterpret_cast<void **
>(&imageList));
976 hr = imageList->GetIcon(iIcon, ILD_TRANSPARENT, &hIcon);
981 imageList->Release();
1021 QComHelper comHelper;
1023 static QCache<QString, FakePointer<int> > dirIconEntryCache(1000);
1024 Q_CONSTINIT
static QMutex mx;
1025 static int defaultFolderIIcon = -1;
1032 const int requestedImageListSize =
1037 if (cacheableDirIcon) {
1039 int iIcon = (useDefaultFolderIcon && defaultFolderIIcon >= 0) ? defaultFolderIIcon
1040 : **dirIconEntryCache.object(filePath);
1045 dirIconEntryCache.remove(filePath);
1051 unsigned int flags = SHGFI_ICON |
iconSize | SHGFI_SYSICONINDEX | SHGFI_ADDOVERLAYS | SHGFI_OVERLAYINDEX;
1052 DWORD attributes = 0;
1054 if (cacheableDirIcon && useDefaultFolderIcon) {
1055 flags |= SHGFI_USEFILEATTRIBUTES;
1056 attributes |= FILE_ATTRIBUTE_DIRECTORY;
1059 flags |= SHGFI_USEFILEATTRIBUTES;
1060 attributes |= FILE_ATTRIBUTE_NORMAL;
1062 auto task = QSharedPointer<QShGetFileInfoThread::Task>(
1064 s_shGetFileInfoThread()->runWithParams(
task);
1066 if (
task->resultValid()) {
1068 if (cacheableDirIcon) {
1069 if (useDefaultFolderIcon && defaultFolderIIcon < 0)
1070 defaultFolderIIcon =
task->iIcon;
1082 if (requestedImageListSize) {
1090 if (cacheableDirIcon) {
1096 qWarning(
"QWindowsTheme::fileIconPixmap() no icon found");
1125 for (
const QWindow *
t : topLevels) {
1126 if (
t->inherits(
"QQuickApplicationWindow"))
1140 if (queryHighContrast())
1143 const auto setting =
QWinRegistryKey(HKEY_CURRENT_USER, LR
"(Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)")
1148bool QWindowsTheme::queryHighContrast()
1150 HIGHCONTRAST hcf = {};
1151 hcf.cbSize =
static_cast<UINT
>(
sizeof(HIGHCONTRAST));
1152 if (SystemParametersInfo(SPI_GETHIGHCONTRAST, hcf.cbSize, &hcf, FALSE))
1153 return hcf.dwFlags & HCF_HIGHCONTRASTON;
1159 qCDebug(lcQpaMenus) << __FUNCTION__;
1165 qCDebug(lcQpaMenus) << __FUNCTION__;
1175 qCDebug(lcQpaMenus) << __FUNCTION__;
1181 qCDebug(lcQpaMenus) << __FUNCTION__;
static FakePointer * create(T thing)
Helper base class for retrieving icons for files for usage by QFileIconProvider and related.
QFileInfo fileInfo() const
QPlatformTheme::IconOptions options() const
static QList< QSize > toSizeList(It i1, It i2)
const QColor & color() const
Returns the brush color.
The QColor class provides colors based on RGB, HSV or CMYK values.
QColor darker(int f=200) const noexcept
static QColor fromRgb(QRgb rgb) noexcept
Static convenience function that returns a QColor constructed from the given QRgb value rgb.
int lightness() const noexcept
static QColor fromRgba(QRgb rgba) noexcept
Static convenience function that returns a QColor constructed from the given QRgb value rgba.
int red() const noexcept
Returns the red color component of this color.
int blue() const noexcept
Returns the blue color component of this color.
int green() const noexcept
Returns the green color component of this color.
void setAlpha(int alpha)
Sets the alpha of this color to alpha.
QColor lighter(int f=150) const noexcept
static QCoreApplication * instance() noexcept
Returns a pointer to the application's QCoreApplication (or QGuiApplication/QApplication) instance.
static QString applicationDirPath()
Returns the directory that contains the application executable.
static QString toNativeSeparators(const QString &pathName)
QString suffix() const
Returns the suffix (extension) of the file.
bool isRoot() const
Returns true if the object points to a directory or to a symbolic link to a directory,...
bool isDir() const
Returns true if this object points to a directory or to a symbolic link to a directory.
void setStyleHint(StyleHint, StyleStrategy=PreferDefault)
Sets the style hint and strategy to hint and strategy, respectively.
static QWindowList topLevelWindows()
Returns a list of the top-level windows in the application.
static bool desktopSettingsAware()
Returns true if Qt is set to use the system's standard colors, fonts, etc.; otherwise returns false.
The QIconEngine class provides an abstract base class for QIcon renderers.
The QIcon class provides scalable icons in different modes and states.
Mode
This enum type describes the mode for which a pixmap is intended to be used.
State
This enum describes the state for which a pixmap is intended to be used.
Native interface to QPlatformWindow. \inmodule QtGui.
static Q_CORE_EXPORT QOperatingSystemVersionBase current()
static constexpr QOperatingSystemVersionBase Windows11
\variable QOperatingSystemVersion::Windows11
The QPainter class performs low-level painting on widgets and other paint devices.
void drawPixmap(const QRectF &targetRect, const QPixmap &pixmap, const QRectF &sourceRect)
Draws the rectangular portion source of the given pixmap into the given target in the paint device.
The QPalette class contains color groups for each widget state.
const QBrush & button() const
Returns the button brush of the current color group.
const QColor & color(ColorGroup cg, ColorRole cr) const
Returns the color in the specified color group, used for the given color role.
void setColor(ColorGroup cg, ColorRole cr, const QColor &color)
Sets the color in the specified color group, used for the given color role, to the specified solid co...
const QBrush & buttonText() const
Returns the button text foreground brush of the current color group.
static bool find(const QString &key, QPixmap *pixmap)
Looks for a cached pixmap associated with the given key in the cache.
static bool insert(const QString &key, const QPixmap &pixmap)
Inserts a copy of the pixmap pixmap associated with the key into the cache.
QString key() const override
\variable QIconEngine::ScaledPixmapArgument::size
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
void runWithParams(const QSharedPointer< Task > &task, std::chrono::milliseconds timeout=std::chrono::milliseconds(5000))
QSharedPointer< Task > getNextTask()
\macro QT_RESTRICTED_CAST_FROM_ASCII
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
int compare(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QString toUpper() const &
bool isInterruptionRequested() const
bool wait(QDeadlineTimer deadline=QDeadlineTimer(QDeadlineTimer::Forever))
void requestInterruption()
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
bool wait(QMutex *, QDeadlineTimer=QDeadlineTimer(QDeadlineTimer::Forever))
std::pair< DWORD, bool > dwordValue(QStringView subKey) const
QVariant value(QStringView subKey) const
static void handleThemeChange(QWindow *window=nullptr)
static bool nonClientMetrics(NONCLIENTMETRICS *ncm, unsigned dpi=0)
static QWindowsContext * instance()
QList< QSize > availableSizes(QIcon::Mode=QIcon::Normal, QIcon::State=QIcon::Off) override
QPixmap filePixmap(const QSize &size, QIcon::Mode mode, QIcon::State) override
QWindowsFileIconEngine(const QFileInfo &info, QPlatformTheme::IconOptions opts)
QString cacheKey() const override
static QFont systemDefaultFont()
static QFont LOGFONT_to_QFont(const LOGFONT &lf, int verticalDPI=0)
static void debugFormat(QDebug &d, const LOGFONT &lf)
static QWindowsIntegration * instance()
Windows native system tray icon.
static bool useNativeMenus()
static void handleSettingsChanged()
void requestColorScheme(Qt::ColorScheme scheme) override
void windowsThemeChanged(QWindow *window)
void showPlatformMenuBar() override
QIconEngine * createIconEngine(const QString &iconName) const override
Factory function for the QIconEngine used by QIcon::fromTheme().
QPlatformMenuBar * createPlatformMenuBar() const override
bool usePlatformNativeDialog(DialogType type) const override
QPlatformMenuItem * createPlatformMenuItem() const override
Qt::ColorScheme colorScheme() const override
static QPalette systemPalette(Qt::ColorScheme)
QVariant themeHint(ThemeHint) const override
~QWindowsTheme() override
QIcon fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions iconOptions={}) const override
Return an icon for fileInfo, observing iconOptions.
QPlatformDialogHelper * createPlatformDialogHelper(DialogType type) const override
static QWindowsTheme * instance()
QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const override
QPlatformMenu * createPlatformMenu() const override
qDeleteAll(list.begin(), list.end())
Combined button and popup list for selecting options.
bool useHelper(QPlatformTheme::DialogType type)
QPlatformDialogHelper * createHelper(QPlatformTheme::DialogType type)
#define Q_APPLICATION_STATIC(TYPE, NAME,...)
QList< QString > QStringList
Constructs a string list that contains the given string, str.
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
int qRound(qfloat16 d) noexcept
#define qCDebug(category,...)
GLenum GLuint GLint level
GLfloat GLfloat GLfloat w
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLbitfield GLuint64 timeout
[4]
GLsizei const GLchar *const * path
QPixmap qt_pixmapFromWinHICON(HICON icon)
#define QStringLiteral(str)
static QT_BEGIN_NAMESPACE QVariant hint(QPlatformIntegration::StyleHint h)
#define SPI_GETMENUANIMATION
#define SPI_GETTOOLTIPANIMATION
#define SPI_GETCOMBOBOXANIMATION
QDebug operator<<(QDebug d, const NONCLIENTMETRICS &m)
static QPixmap pixmapFromShellImageList(int iImageList, int iIcon)
static QStringList styleNames()
static bool doUseNativeMenus()
static QPalette toolTipPalette(const QPalette &systemPalette, bool light)
static QStringList iconThemeSearchPaths()
static QColor qt_accentColor(AccentColorLevel level)
static QColor getSysColor(int index)
static int fileIconSizes[FileIconSizeCount]
static QString dirIconPixmapCacheKey(int iIcon, int iconSize, int imageListSize)
static QColor mixColors(const QColor &c1, const QColor &c2)
static QColor placeHolderColor(QColor textColor)
static DWORD dWordSystemParametersInfo(UINT what, DWORD defaultValue)
Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon)
static QPalette menuPalette(const QPalette &systemPalette, bool light)
static QPixmap loadIconFromShell32(int resourceId, QSizeF size)
static QPalette * menuBarPalette(const QPalette &menuPalette, bool light)
static bool booleanSystemParametersInfo(UINT what, bool defaultValue)
QSettings settings("MySoft", "Star Runner")
[0]
Q_DISABLE_COPY(Task) ~Task()
Task(const QString &fn, DWORD a, UINT f)