diff options
Diffstat (limited to 'src/plugins/platforms/windows')
40 files changed, 455 insertions, 269 deletions
diff --git a/src/plugins/platforms/windows/main.cpp b/src/plugins/platforms/windows/main.cpp index 1929f800a4..94d8470ab1 100644 --- a/src/plugins/platforms/windows/main.cpp +++ b/src/plugins/platforms/windows/main.cpp @@ -46,10 +46,9 @@ QT_BEGIN_NAMESPACE /*! - \group qt-lighthouse-win - \title Qt Lighthouse plugin for Windows + \title Qt platform plugin for Windows - \brief Class documentation of the Qt Lighthouse plugin for Windows. + \brief Class documentation of the Qt platform plugin for Windows. \section1 Supported Parameters @@ -78,7 +77,6 @@ QT_BEGIN_NAMESPACE \class QWindowsIntegrationPlugin \brief Plugin. \internal - \ingroup qt-lighthouse-win */ /*! @@ -86,7 +84,6 @@ QT_BEGIN_NAMESPACE \brief Namespace for enumerations, etc. \internal - \ingroup qt-lighthouse-win */ /*! @@ -97,7 +94,6 @@ QT_BEGIN_NAMESPACE With flags that should help to structure the code. \internal - \ingroup qt-lighthouse-win */ class QWindowsIntegrationPlugin : public QPlatformIntegrationPlugin diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.cpp b/src/plugins/platforms/windows/qwindowsbackingstore.cpp index bd7bdc55d1..e3939ca2d7 100644 --- a/src/plugins/platforms/windows/qwindowsbackingstore.cpp +++ b/src/plugins/platforms/windows/qwindowsbackingstore.cpp @@ -55,7 +55,6 @@ QT_BEGIN_NAMESPACE \class QWindowsBackingStore \brief Backing store for windows. \internal - \ingroup qt-lighthouse-win */ QWindowsBackingStore::QWindowsBackingStore(QWindow *window) : diff --git a/src/plugins/platforms/windows/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp index 4e6d3306e1..b23904e978 100644 --- a/src/plugins/platforms/windows/qwindowsclipboard.cpp +++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp @@ -71,7 +71,6 @@ QT_BEGIN_NAMESPACE \note The OLE-functions used in this class require OleInitialize(). \internal - \ingroup qt-lighthouse-win */ #ifndef QT_NO_DEBUG_STREAM @@ -82,7 +81,7 @@ static QDebug operator<<(QDebug d, const QMimeData *mimeData) d << "QMimeData("; if (mimeData) { const QStringList formats = mimeData->formats(); - d << "formats=" << formats.join(QLatin1String(", ")); + d << "formats=" << formats.join(u", "); if (mimeData->hasText()) d << ", text=" << mimeData->text(); if (mimeData->hasHtml()) @@ -110,7 +109,6 @@ static QDebug operator<<(QDebug d, const QMimeData *mimeData) \sa QWindowsInternalMimeDataBase, QWindowsClipboard \internal - \ingroup qt-lighthouse-win */ IDataObject *QWindowsClipboardRetrievalMimeData::retrieveDataObject() const @@ -190,7 +188,7 @@ void QWindowsClipboard::releaseIData() void QWindowsClipboard::registerViewer() { m_clipboardViewer = QWindowsContext::instance()-> - createDummyWindow(QStringLiteral("Qt5ClipboardView"), L"Qt5ClipboardView", + createDummyWindow(QStringLiteral("ClipboardView"), L"QtClipboardView", qClipboardViewerWndProc, WS_OVERLAPPED); // Try format listener API (Vista onwards) first. @@ -339,7 +337,7 @@ void QWindowsClipboard::setMimeData(QMimeData *mimeData, QClipboard::Mode mode) if (src != S_OK) { QString mimeDataFormats = mimeData ? - mimeData->formats().join(QLatin1String(", ")) : QString(QStringLiteral("NULL")); + mimeData->formats().join(u", ") : QString(QStringLiteral("NULL")); qErrnoWarning("OleSetClipboard: Failed to set mime data (%s) on clipboard: %s", qPrintable(mimeDataFormats), QWindowsContext::comErrorString(src).constData()); diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 293faf8a53..0d357b1605 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -42,6 +42,7 @@ #include "qwindowsintegration.h" #include "qwindowswindow.h" #include "qwindowskeymapper.h" +#include "qwindowsnativeinterface.h" #include "qwindowsmousehandler.h" #include "qwindowspointerhandler.h" #include "qtwindowsglobal.h" @@ -72,6 +73,7 @@ #include <QtCore/qset.h> #include <QtCore/qhash.h> +#include <QtCore/qlibraryinfo.h> #include <QtCore/qstringlist.h> #include <QtCore/qdebug.h> #include <QtCore/qoperatingsystemversion.h> @@ -183,7 +185,6 @@ static bool enableNonClientDpiScaling(HWND hwnd) \sa QWindowsShell32DLL \internal - \ingroup qt-lighthouse-win */ void QWindowsUser32DLL::init() @@ -249,7 +250,6 @@ QWindowsContext *QWindowsContext::m_instance = nullptr; Holds state information formerly stored in \c qapplication_win.cpp. \internal - \ingroup qt-lighthouse-win */ typedef QHash<HWND, QWindowsWindow *> HandleBaseWindowHash; @@ -276,8 +276,11 @@ struct QWindowsContextPrivate { bool m_asyncExpose = false; HPOWERNOTIFY m_powerNotification = nullptr; HWND m_powerDummyWindow = nullptr; + static bool m_darkMode; }; +bool QWindowsContextPrivate::m_darkMode = false; + QWindowsContextPrivate::QWindowsContextPrivate() : m_oleInitializeResult(OleInitialize(nullptr)) { @@ -292,6 +295,7 @@ QWindowsContextPrivate::QWindowsContextPrivate() m_systemInfo |= QWindowsContext::SI_RTL_Extensions; m_keyMapper.setUseRTLExtensions(true); } + m_darkMode = QWindowsTheme::queryDarkMode(); if (FAILED(m_oleInitializeResult)) { qWarning() << "QWindowsContext: OleInitialize() failed: " << QWindowsContext::comErrorString(m_oleInitializeResult); @@ -426,7 +430,7 @@ bool QWindowsContext::initPowerNotificationHandler() if (d->m_powerNotification) return false; - d->m_powerDummyWindow = createDummyWindow(QStringLiteral("QtPowerDummyWindow"), L"QtPowerDummyWindow", qWindowsPowerWindowProc); + d->m_powerDummyWindow = createDummyWindow(QStringLiteral("PowerDummyWindow"), L"QtPowerDummyWindow", qWindowsPowerWindowProc); if (!d->m_powerDummyWindow) return false; @@ -484,6 +488,11 @@ void QWindowsContext::setProcessDpiAwareness(QtWindows::ProcessDpiAwareness dpiA } } +bool QWindowsContext::isDarkMode() +{ + return QWindowsContextPrivate::m_darkMode; +} + QWindowsContext *QWindowsContext::instance() { return m_instance; @@ -536,6 +545,23 @@ void QWindowsContext::setKeyGrabber(QWindow *w) d->m_keyMapper.setKeyGrabber(w); } +QString QWindowsContext::classNamePrefix() +{ + static QString result; + if (result.isEmpty()) { + QTextStream str(&result); + str << "Qt" << QT_VERSION_MAJOR << QT_VERSION_MINOR << QT_VERSION_PATCH; + if (QLibraryInfo::isDebugBuild()) + str << 'd'; +#ifdef QT_NAMESPACE +# define xstr(s) str(s) +# define str(s) #s + str << xstr(QT_NAMESPACE); +#endif + } + return result; +} + // Window class registering code (from qapplication_win.cpp) QString QWindowsContext::registerWindowClass(const QWindow *w) @@ -567,8 +593,8 @@ QString QWindowsContext::registerWindowClass(const QWindow *w) break; } // Create a unique name for the flag combination - QString cname; - cname += QLatin1String("Qt5QWindow"); + QString cname = classNamePrefix(); + cname += QLatin1String("QWindow"); switch (type) { case Qt::Tool: cname += QLatin1String("Tool"); @@ -878,7 +904,7 @@ HWND QWindowsContext::createDummyWindow(const QString &classNameIn, { if (!wndProc) wndProc = DefWindowProc; - QString className = registerWindowClass(classNameIn, wndProc); + QString className = registerWindowClass(classNamePrefix() + classNameIn, wndProc); return CreateWindowEx(0, reinterpret_cast<LPCWSTR>(className.utf16()), windowName, style, CW_USEDEFAULT, CW_USEDEFAULT, @@ -1192,9 +1218,27 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, t->displayChanged(); QWindowsWindow::displayChanged(); return d->m_screenManager.handleDisplayChange(wParam, lParam); - case QtWindows::SettingChangedEvent: + case QtWindows::SettingChangedEvent: { 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); + const auto options = QWindowsIntegration::instance()->options(); + if ((options & QWindowsIntegration::DarkModeWindowFrames) != 0) { + for (QWindowsWindow *w : d->m_windows) + w->setDarkBorder(QWindowsContextPrivate::m_darkMode); + } + if ((options & QWindowsIntegration::DarkModeStyle) != 0) { + QWindowsTheme::instance()->refresh(); + for (QWindowsWindow *w : d->m_windows) + QWindowSystemInterface::handleThemeChange(w->window()); + } + } return d->m_screenManager.handleScreenChanges(); + } default: break; } @@ -1627,7 +1671,6 @@ static inline bool isTopLevel(HWND hwnd) There is another one for timers, sockets, etc in QEventDispatcherWin32. - \ingroup qt-lighthouse-win */ extern "C" LRESULT QT_WIN_CALLBACK qWindowsWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h index 07398bd61c..c89b8b91f4 100644 --- a/src/plugins/platforms/windows/qwindowscontext.h +++ b/src/plugins/platforms/windows/qwindowscontext.h @@ -180,6 +180,7 @@ public: int defaultDPI() const; + static QString classNamePrefix(); QString registerWindowClass(const QWindow *w); QString registerWindowClass(QString cname, WNDPROC proc, unsigned style = 0, HBRUSH brush = nullptr, @@ -225,6 +226,8 @@ public: void setProcessDpiAwareness(QtWindows::ProcessDpiAwareness dpiAwareness); static int processDpiAwareness(); + static bool isDarkMode(); + void setDetectAltGrModifier(bool a); // Returns a combination of SystemInfoFlags diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp index 59457f1720..338bb9ff8f 100644 --- a/src/plugins/platforms/windows/qwindowscursor.cpp +++ b/src/plugins/platforms/windows/qwindowscursor.cpp @@ -73,17 +73,16 @@ Q_GUI_EXPORT HBITMAP qt_createIconMask(const QBitmap &bitmap); \brief Cache key for storing values in a QHash with a QCursor as key. \internal - \ingroup qt-lighthouse-win */ QWindowsPixmapCursorCacheKey::QWindowsPixmapCursorCacheKey(const QCursor &c) : bitmapCacheKey(c.pixmap().cacheKey()), maskCacheKey(0) { if (!bitmapCacheKey) { - Q_ASSERT(c.bitmap()); - Q_ASSERT(c.mask()); - bitmapCacheKey = c.bitmap()->cacheKey(); - maskCacheKey = c.mask()->cacheKey(); + Q_ASSERT(!c.bitmap(Qt::ReturnByValue).isNull()); + Q_ASSERT(!c.mask(Qt::ReturnByValue).isNull()); + bitmapCacheKey = c.bitmap(Qt::ReturnByValue).cacheKey(); + maskCacheKey = c.mask(Qt::ReturnByValue).cacheKey(); } } @@ -97,7 +96,6 @@ QWindowsPixmapCursorCacheKey::QWindowsPixmapCursorCacheKey(const QCursor &c) as do the Window manager frames (resize/move handles). \internal - \ingroup qt-lighthouse-win \sa QWindowsWindowCursor */ @@ -169,9 +167,9 @@ static HCURSOR createBitmapCursor(const QImage &bbits, const QImage &mbits, // Create a cursor from image and mask of the format QImage::Format_Mono. static HCURSOR createBitmapCursor(const QCursor &cursor, qreal scaleFactor = 1) { - Q_ASSERT(cursor.shape() == Qt::BitmapCursor && cursor.bitmap()); - QImage bbits = cursor.bitmap()->toImage(); - QImage mbits = cursor.mask()->toImage(); + Q_ASSERT(cursor.shape() == Qt::BitmapCursor && !cursor.bitmap(Qt::ReturnByValue).isNull()); + QImage bbits = cursor.bitmap(Qt::ReturnByValue).toImage(); + QImage mbits = cursor.mask(Qt::ReturnByValue).toImage(); scaleFactor /= bbits.devicePixelRatioF(); if (!qFuzzyCompare(scaleFactor, 1)) { const QSize scaledSize = (QSizeF(bbits.size()) * scaleFactor).toSize(); @@ -816,7 +814,6 @@ HCURSOR QWindowsCursor::hCursor(const QCursor &c) const cursor handle resource. \internal - \ingroup qt-lighthouse-win \sa QWindowsCursor */ diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index b7ab952a1d..37115d5c6e 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -91,7 +91,7 @@ static inline QString guidToString(const GUID &g) str << '{' << g.Data1 << ", " << g.Data2 << ", " << g.Data3; str.setFieldWidth(2); str.setFieldAlignment(QTextStream::AlignRight); - str.setPadChar(QLatin1Char('0')); + str.setPadChar(u'0'); str << ",{" << g.Data4[0] << ", " << g.Data4[1] << ", " << g.Data4[2] << ", " << g.Data4[3] << ", " << g.Data4[4] << ", " << g.Data4[5] << ", " << g.Data4[6] << ", " << g.Data4[7] << "}};"; @@ -128,7 +128,6 @@ namespace QWindowsDialogs remove all those messages (usually 1) and post the last one with a reset button state. - \ingroup qt-lighthouse-win */ void eatMouseMove() @@ -171,7 +170,6 @@ void eatMouseMove() \sa QWindowsDialogHelperBase \internal - \ingroup qt-lighthouse-win */ class QWindowsNativeDialogBase : public QObject @@ -211,7 +209,6 @@ private: \sa QWindowsDialogThread, QWindowsNativeDialogBase \internal - \ingroup qt-lighthouse-win */ template <class BaseClass> @@ -265,7 +262,6 @@ QWindowsNativeDialogBase *QWindowsDialogHelperBase<BaseClass>::ensureNativeDialo \sa QWindowsDialogHelperBase \internal - \ingroup qt-lighthouse-win */ class QWindowsDialogThread : public QThread @@ -406,7 +402,6 @@ void QWindowsDialogHelperBase<BaseClass>::exec() does not reliably work. Provides thread-safe setters (for the non-modal case). \internal - \ingroup qt-lighthouse-win \sa QFileDialogOptions */ @@ -466,14 +461,14 @@ inline void QWindowsFileDialogSharedData::setSelectedNameFilter(const QString &f inline QList<QUrl> QWindowsFileDialogSharedData::selectedFiles() const { m_data->mutex.lock(); - const QList<QUrl> result = m_data->selectedFiles; + const auto result = m_data->selectedFiles; m_data->mutex.unlock(); return result; } inline QString QWindowsFileDialogSharedData::selectedFile() const { - const QList<QUrl> files = selectedFiles(); + const auto files = selectedFiles(); return files.isEmpty() ? QString() : files.front().toLocalFile(); } @@ -500,7 +495,6 @@ inline void QWindowsFileDialogSharedData::fromOptions(const QSharedPointer<QFile \sa QWindowsNativeFileDialogBase, QWindowsFileDialogHelper \internal - \ingroup qt-lighthouse-win */ class QWindowsNativeFileDialogBase; @@ -546,7 +540,6 @@ IFileDialogEvents *QWindowsNativeFileDialogEventHandler::create(QWindowsNativeFi \sa QWindowsNativeFileDialogBase \internal - \ingroup qt-lighthouse-win */ class QWindowsShellItem { @@ -789,7 +782,6 @@ QDebug operator<<(QDebug d, IShellItem *i) \sa QWindowsNativeFileDialogEventHandler, QWindowsFileDialogHelper \internal - \ingroup qt-lighthouse-win */ class QWindowsNativeFileDialogBase : public QWindowsNativeDialogBase @@ -915,7 +907,7 @@ IShellItem *QWindowsNativeFileDialogBase::shellItem(const QUrl &url) return nullptr; } return result; - } else if (url.scheme() == QLatin1String("clsid")) { + } else if (url.scheme() == u"clsid") { // Support for virtual folders via GUID // (see https://msdn.microsoft.com/en-us/library/windows/desktop/dd378457(v=vs.85).aspx) // specified as "clsid:<GUID>" (without '{', '}'). @@ -1040,20 +1032,20 @@ static QList<FilterSpec> filterSpecs(const QStringList &filters, // Split filter specification as 'Texts (*.txt[;] *.doc)', '*.txt[;] *.doc' // into description and filters specification as '*.txt;*.doc' for (const QString &filterString : filters) { - const int openingParenPos = filterString.lastIndexOf(QLatin1Char('(')); + const int openingParenPos = filterString.lastIndexOf(u'('); const int closingParenPos = openingParenPos != -1 ? - filterString.indexOf(QLatin1Char(')'), openingParenPos + 1) : -1; + filterString.indexOf(u')', openingParenPos + 1) : -1; FilterSpec filterSpec; filterSpec.filter = closingParenPos == -1 ? filterString : filterString.mid(openingParenPos + 1, closingParenPos - openingParenPos - 1).trimmed(); if (filterSpec.filter.isEmpty()) - filterSpec.filter += QLatin1Char('*'); + filterSpec.filter += u'*'; filterSpec.filter.replace(filterSeparatorRE, separator); filterSpec.description = filterString; if (hideFilterDetails && openingParenPos != -1) { // Do not show pattern in description filterSpec.description.truncate(openingParenPos); - while (filterSpec.description.endsWith(QLatin1Char(' '))) + while (filterSpec.description.endsWith(u' ')) filterSpec.description.truncate(filterSpec.description.size() - 1); } *totalStringLength += filterSpec.filter.size() + filterSpec.description.size(); @@ -1084,8 +1076,8 @@ void QWindowsNativeFileDialogBase::setNameFilters(const QStringList &filters) // 'AAA files (a.*) (a.*)' QString description = specs[i].description; const QString &filter = specs[i].filter; - if (!m_hideFiltersDetails && !filter.startsWith(QLatin1String("*."))) { - const int pos = description.lastIndexOf(QLatin1Char('(')); + if (!m_hideFiltersDetails && !filter.startsWith(u"*.")) { + const int pos = description.lastIndexOf(u'('); if (pos > 0) description.truncate(pos); } @@ -1151,8 +1143,8 @@ static bool isHexRange(const QString& s, int start, int end) for (;start < end; ++start) { QChar ch = s.at(start); if (!(ch.isDigit() - || (ch >= QLatin1Char('a') && ch <= QLatin1Char('f')) - || (ch >= QLatin1Char('A') && ch <= QLatin1Char('F')))) + || (ch >= u'a' && ch <= u'f') + || (ch >= u'A' && ch <= u'F'))) return false; } return true; @@ -1161,7 +1153,7 @@ static bool isHexRange(const QString& s, int start, int end) static inline bool isClsid(const QString &s) { // detect "374DE290-123F-4565-9164-39C4925E467B". - const QChar dash(QLatin1Char('-')); + const QChar dash(u'-'); return s.size() == 36 && isHexRange(s, 0, 8) && s.at(8) == dash @@ -1204,7 +1196,7 @@ void QWindowsNativeFileDialogBase::selectNameFilter(const QString &filter) if (index < 0) { qWarning("%s: Invalid parameter '%s' not found in '%s'.", __FUNCTION__, qPrintable(filter), - qPrintable(m_nameFilters.join(QLatin1String(", ")))); + qPrintable(m_nameFilters.join(u", "))); return; } m_fileDialog->SetFileTypeIndex(index + 1); // one-based. @@ -1295,7 +1287,6 @@ HRESULT QWindowsNativeFileDialogEventHandler::OnFileOk(IFileDialog *) Implements single-selection methods. \internal - \ingroup qt-lighthouse-win */ class QWindowsNativeSaveFileDialog : public QWindowsNativeFileDialogBase @@ -1313,15 +1304,15 @@ public: // Also handles the simple name filter case "*.txt" -> "txt" static inline QString suffixFromFilter(const QString &filter) { - int suffixPos = filter.indexOf(QLatin1String("*.")); + int suffixPos = filter.indexOf(u"*."); if (suffixPos < 0) return QString(); suffixPos += 2; - int endPos = filter.indexOf(QLatin1Char(' '), suffixPos + 1); + int endPos = filter.indexOf(u' ', suffixPos + 1); if (endPos < 0) - endPos = filter.indexOf(QLatin1Char(';'), suffixPos + 1); + endPos = filter.indexOf(u';', suffixPos + 1); if (endPos < 0) - endPos = filter.indexOf(QLatin1Char(')'), suffixPos + 1); + endPos = filter.indexOf(u')', suffixPos + 1); if (endPos < 0) endPos = filter.size(); return filter.mid(suffixPos, endPos - suffixPos); @@ -1372,7 +1363,6 @@ QList<QUrl> QWindowsNativeSaveFileDialog::selectedFiles() const Implements multi-selection methods. \internal - \ingroup qt-lighthouse-win */ class QWindowsNativeOpenFileDialog : public QWindowsNativeFileDialogBase @@ -1406,27 +1396,27 @@ static void cleanupTemporaryItemCopies() static bool validFileNameCharacter(QChar c) { - return c.isLetterOrNumber() || c == QLatin1Char('_') || c == QLatin1Char('-'); + return c.isLetterOrNumber() || c == u'_' || c == u'-'; } QString tempFilePattern(QString name) { - const int lastSlash = qMax(name.lastIndexOf(QLatin1Char('/')), - name.lastIndexOf(QLatin1Char('\\'))); + const int lastSlash = qMax(name.lastIndexOf(u'/'), + name.lastIndexOf(u'\\')); if (lastSlash != -1) name.remove(0, lastSlash + 1); - int lastDot = name.lastIndexOf(QLatin1Char('.')); + int lastDot = name.lastIndexOf(u'.'); if (lastDot < 0) lastDot = name.size(); name.insert(lastDot, QStringLiteral("_XXXXXX")); for (int i = lastDot - 1; i >= 0; --i) { if (!validFileNameCharacter(name.at(i))) - name[i] = QLatin1Char('_'); + name[i] = u'_'; } - name.prepend(QDir::tempPath() + QLatin1Char('/')); + name.prepend(QDir::tempPath() + u'/'); return name; } @@ -1456,7 +1446,7 @@ static QString createTemporaryItemCopy(QWindowsShellItem &qItem, QString *errorM static QUrl itemToDialogUrl(QWindowsShellItem &qItem, QString *errorMessage) { QUrl url = qItem.url(); - if (url.isLocalFile() || url.scheme().startsWith(QLatin1String("http"))) + if (url.isLocalFile() || url.scheme().startsWith(u"http")) return url; const QString path = qItem.path(); if (path.isEmpty() && !qItem.isDir() && qItem.canStream()) { @@ -1545,7 +1535,6 @@ QWindowsNativeFileDialogBase *QWindowsNativeFileDialogBase::create(QFileDialogOp but only on QQuickWindows, which do not have a fallback. \internal - \ingroup qt-lighthouse-win */ class QWindowsFileDialogHelper : public QWindowsDialogHelperBase<QPlatformFileDialogHelper> @@ -1681,7 +1670,6 @@ QString QWindowsFileDialogHelper::selectedNameFilter() const \internal \sa QWindowsXpFileDialogHelper - \ingroup qt-lighthouse-win */ class QWindowsXpNativeFileDialog : public QWindowsNativeDialogBase @@ -1859,10 +1847,12 @@ void QWindowsXpNativeFileDialog::populateOpenFileName(OPENFILENAME *ofn, HWND ow // for the target. If it contains any invalid character, the dialog // will not show. ofn->nMaxFile = 65535; - const QString initiallySelectedFile = - QDir::toNativeSeparators(m_data.selectedFile()).remove(QLatin1Char('<')). - remove(QLatin1Char('>')).remove(QLatin1Char('"')).remove(QLatin1Char('|')); - ofn->lpstrFile = qStringToWCharArray(initiallySelectedFile, ofn->nMaxFile); + QString initiallySelectedFile = m_data.selectedFile(); + initiallySelectedFile.remove(u'<'); + initiallySelectedFile.remove(u'>'); + initiallySelectedFile.remove(u'"'); + initiallySelectedFile.remove(u'|'); + ofn->lpstrFile = qStringToWCharArray(QDir::toNativeSeparators(initiallySelectedFile), ofn->nMaxFile); ofn->lpstrInitialDir = qStringToWCharArray(QDir::toNativeSeparators(m_data.directory().toLocalFile())); ofn->lpstrTitle = (wchar_t*)m_title.utf16(); // Determine lpstrDefExt. Note that the current MSDN docs document this @@ -1872,7 +1862,7 @@ void QWindowsXpNativeFileDialog::populateOpenFileName(OPENFILENAME *ofn, HWND ow // the extension of the current filter". if (m_options->acceptMode() == QFileDialogOptions::AcceptSave) { QString defaultSuffix = m_options->defaultSuffix(); - if (defaultSuffix.startsWith(QLatin1Char('.'))) + if (defaultSuffix.startsWith(u'.')) defaultSuffix.remove(0, 1); // QTBUG-33156, also create empty strings to trigger the appending mechanism. ofn->lpstrDefExt = qStringToWCharArray(defaultSuffix); @@ -1905,7 +1895,7 @@ QList<QUrl> QWindowsXpNativeFileDialog::execFileNames(HWND owner, int *selectedF wchar_t *ptr = ofn.lpstrFile + dir.size() + 1; if (*ptr) { result.pop_front(); - const QString path = dir + QLatin1Char('/'); + const QString path = dir + u'/'; while (*ptr) { const QString fileName = QString::fromWCharArray(ptr); result.push_back(QUrl::fromLocalFile(path + fileName)); @@ -1927,7 +1917,6 @@ QList<QUrl> QWindowsXpNativeFileDialog::execFileNames(HWND owner, int *selectedF \sa QWindowsXpNativeFileDialog \internal - \ingroup qt-lighthouse-win */ class QWindowsXpFileDialogHelper : public QWindowsDialogHelperBase<QPlatformFileDialogHelper> @@ -2004,7 +1993,6 @@ QString QWindowsXpFileDialogHelper::selectedNameFilter() const \sa QWindowsColorDialogHelper \sa #define USE_NATIVE_COLOR_DIALOG \internal - \ingroup qt-lighthouse-win */ using SharedPointerColor = QSharedPointer<QColor>; @@ -2084,7 +2072,6 @@ void QWindowsNativeColorDialog::doExec(HWND owner) \sa #define USE_NATIVE_COLOR_DIALOG \sa QWindowsNativeColorDialog \internal - \ingroup qt-lighthouse-win */ class QWindowsColorDialogHelper : public QWindowsDialogHelperBase<QPlatformColorDialogHelper> diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp index 3e4c93d47a..bb1e1345dc 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.cpp +++ b/src/plugins/platforms/windows/qwindowsdrag.cpp @@ -75,7 +75,6 @@ QT_BEGIN_NAMESPACE \sa QWindowsOleDropSource \internal - \ingroup qt-lighthouse-win */ class QWindowsDragCursorWindow : public QRasterWindow @@ -135,7 +134,6 @@ void QWindowsDragCursorWindow::setPixmap(const QPixmap &p) \sa QWindowsDrag \internal - \ingroup qt-lighthouse-win */ IDataObject *QWindowsDropMimeData::retrieveDataObject() const @@ -217,7 +215,6 @@ static Qt::MouseButtons lastButtons = Qt::NoButton; \sa QWindowsDrag \internal - \ingroup qt-lighthouse-win */ class QWindowsOleDropSource : public QWindowsComBase<IDropSource> @@ -485,7 +482,6 @@ QWindowsOleDropSource::GiveFeedback(DWORD dwEffect) \sa QWindowsDrag \internal - \ingroup qt-lighthouse-win */ QWindowsOleDropTarget::QWindowsOleDropTarget(QWindow *w) : m_window(w) @@ -659,7 +655,6 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState, \class QWindowsDrag \brief Windows drag implementation. \internal - \ingroup qt-lighthouse-win */ bool QWindowsDrag::m_canceled = false; diff --git a/src/plugins/platforms/windows/qwindowsdropdataobject.cpp b/src/plugins/platforms/windows/qwindowsdropdataobject.cpp index e1a41c0ede..a06a14a980 100644 --- a/src/plugins/platforms/windows/qwindowsdropdataobject.cpp +++ b/src/plugins/platforms/windows/qwindowsdropdataobject.cpp @@ -54,7 +54,6 @@ QT_BEGIN_NAMESPACE (instead of creating local hyperlinks). \internal - \ingroup qt-lighthouse-win */ QWindowsDropDataObject::QWindowsDropDataObject(QMimeData *mimeData) : @@ -95,7 +94,7 @@ bool QWindowsDropDataObject::shouldIgnore(LPFORMATETC pformatetc) const || pformatetc->cfFormat == CF_TEXT || formatName == QStringLiteral("UniformResourceLocator") || formatName == QStringLiteral("UniformResourceLocatorW")) { - QList<QUrl> urls = dropData->urls(); + const auto urls = dropData->urls(); return std::all_of(urls.cbegin(), urls.cend(), [] (const QUrl &u) { return u.isLocalFile(); }); } } diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp index e9f3dc5189..4ae087dfaa 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp @@ -63,7 +63,6 @@ QT_BEGIN_NAMESPACE there is no need to differentiate between dynamic or Angle-only builds in here. \internal - \ingroup qt-lighthouse-win */ QWindowsLibEGL QWindowsEGLStaticContext::libEGL; @@ -88,7 +87,7 @@ static void *resolveFunc(HMODULE lib, const char *name) while (!proc && argSize <= 64) { nameStr = baseNameStr; if (argSize >= 0) - nameStr += QLatin1Char('@') + QString::number(argSize); + nameStr += u'@' + QString::number(argSize); argSize = argSize < 0 ? 0 : argSize + 4; proc = (void *) ::GetProcAddress(lib, nameStr.toLatin1().constData()); } @@ -376,7 +375,6 @@ QSurfaceFormat QWindowsEGLStaticContext::formatFromConfig(EGLDisplay display, EG \endlist \internal - \ingroup qt-lighthouse-win */ QWindowsEGLContext::QWindowsEGLContext(QWindowsEGLStaticContext *staticContext, diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp index 8bf88300e9..6fa5a8a2b3 100644 --- a/src/plugins/platforms/windows/qwindowsglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp @@ -196,6 +196,7 @@ bool QWindowsOpengl32DLL::init(bool softwareRendering) wglShareLists = reinterpret_cast<BOOL (WINAPI *)(HGLRC, HGLRC)>(resolve("wglShareLists")); wglSwapBuffers = reinterpret_cast<BOOL (WINAPI *)(HDC)>(resolve("wglSwapBuffers")); wglSetPixelFormat = reinterpret_cast<BOOL (WINAPI *)(HDC, int, const PIXELFORMATDESCRIPTOR *)>(resolve("wglSetPixelFormat")); + wglDescribePixelFormat = reinterpret_cast<int (WINAPI *)(HDC, int, UINT, PIXELFORMATDESCRIPTOR *)>(resolve("wglDescribePixelFormat")); glGetError = reinterpret_cast<GLenum (APIENTRY *)()>(resolve("glGetError")); glGetIntegerv = reinterpret_cast<void (APIENTRY *)(GLenum , GLint *)>(resolve("glGetIntegerv")); @@ -214,6 +215,11 @@ BOOL QWindowsOpengl32DLL::setPixelFormat(HDC dc, int pf, const PIXELFORMATDESCRI return moduleIsNotOpengl32() ? wglSetPixelFormat(dc, pf, pfd) : SetPixelFormat(dc, pf, pfd); } +int QWindowsOpengl32DLL::describePixelFormat(HDC dc, int pf, UINT size, PIXELFORMATDESCRIPTOR *pfd) +{ + return moduleIsNotOpengl32() ? wglDescribePixelFormat(dc, pf, size, pfd) : DescribePixelFormat(dc, pf, size, pfd); +} + QWindowsOpenGLContext *QOpenGLStaticContext::createContext(QOpenGLContext *context) { return new QWindowsGLContext(this, context); @@ -322,11 +328,11 @@ static inline bool static void describeFormats(HDC hdc) { - const int pfiMax = DescribePixelFormat(hdc, 0, 0, nullptr); + const int pfiMax = QOpenGLStaticContext::opengl32.describePixelFormat(hdc, 0, 0, nullptr); for (int i = 0; i < pfiMax; i++) { PIXELFORMATDESCRIPTOR pfd; initPixelFormatDescriptor(&pfd); - DescribePixelFormat(hdc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd); + QOpenGLStaticContext::opengl32.describePixelFormat(hdc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd); qCDebug(lcQpaGl) << '#' << i << '/' << pfiMax << ':' << pfd; } } @@ -617,7 +623,7 @@ static int choosePixelFormat(HDC hdc, // Verify if format is acceptable. Note that the returned // formats have been observed to not contain PFD_SUPPORT_OPENGL, ignore. initPixelFormatDescriptor(obtainedPfd); - DescribePixelFormat(hdc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), obtainedPfd); + QOpenGLStaticContext::opengl32.describePixelFormat(hdc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), obtainedPfd); if (!isAcceptableFormat(additional, *obtainedPfd, true)) { qCDebug(lcQpaGl) << __FUNCTION__ << " obtained px #" << pixelFormat << " not acceptable=" << *obtainedPfd; @@ -796,7 +802,7 @@ static HGLRC createContext(const QOpenGLStaticContext &staticContext, static inline HWND createDummyGLWindow() { return QWindowsContext::instance()-> - createDummyWindow(QStringLiteral("QtOpenGLDummyWindow"), + createDummyWindow(QStringLiteral("OpenGLDummyWindow"), L"OpenGLDummyWindow", nullptr, WS_OVERLAPPED | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); } @@ -852,7 +858,6 @@ static inline QOpenGLContextData createDummyWindowOpenGLContextData() context and to apply to a QSurfaceFormat. \internal - \ingroup qt-lighthouse-win */ QWindowsOpenGLContextFormat QWindowsOpenGLContextFormat::current() @@ -907,7 +912,6 @@ void QWindowsOpenGLContextFormat::apply(QSurfaceFormat *format) const is a current GL context. \internal - \ingroup qt-lighthouse-win */ class QOpenGLTemporaryContext @@ -940,7 +944,6 @@ QOpenGLTemporaryContext::~QOpenGLTemporaryContext() /*! \class QWindowsOpenGLAdditionalFormat \brief Additional format information that is not in QSurfaceFormat - \ingroup qt-lighthouse-win */ /*! @@ -958,7 +961,6 @@ QOpenGLTemporaryContext::~QOpenGLTemporaryContext() \sa QWindowsGLContext \internal - \ingroup qt-lighthouse-win */ #define SAMPLE_BUFFER_EXTENSION "GL_ARB_multisample" @@ -1045,7 +1047,6 @@ QOpenGLStaticContext *QOpenGLStaticContext::create(bool softwareRendering) QOpenGLContextData and are released in doneCurrent(). \internal - \ingroup qt-lighthouse-win */ QWindowsGLContext::QWindowsGLContext(QOpenGLStaticContext *staticContext, diff --git a/src/plugins/platforms/windows/qwindowsglcontext.h b/src/plugins/platforms/windows/qwindowsglcontext.h index 8b0c33f7d5..8794368fe4 100644 --- a/src/plugins/platforms/windows/qwindowsglcontext.h +++ b/src/plugins/platforms/windows/qwindowsglcontext.h @@ -89,7 +89,7 @@ struct QWindowsOpenGLContextFormat QSurfaceFormat::OpenGLContextProfile profile = QSurfaceFormat::NoProfile; int version = 0; //! majorVersion<<8 + minorVersion - QSurfaceFormat::FormatOptions options = nullptr; + QSurfaceFormat::FormatOptions options; }; #ifndef QT_NO_DEBUG_STREAM @@ -107,6 +107,7 @@ struct QWindowsOpengl32DLL // Wrappers. Always use these instead of SwapBuffers/wglSwapBuffers/etc. BOOL swapBuffers(HDC dc); BOOL setPixelFormat(HDC dc, int pf, const PIXELFORMATDESCRIPTOR *pfd); + int describePixelFormat(HDC dc, int pf, UINT size, PIXELFORMATDESCRIPTOR *pfd); // WGL HGLRC (WINAPI * wglCreateContext)(HDC dc); @@ -130,6 +131,7 @@ private: // For Mesa llvmpipe shipped with a name other than opengl32.dll BOOL (WINAPI * wglSwapBuffers)(HDC dc); BOOL (WINAPI * wglSetPixelFormat)(HDC dc, int pf, const PIXELFORMATDESCRIPTOR *pfd); + int (WINAPI * wglDescribePixelFormat)(HDC dc, int pf, UINT size, PIXELFORMATDESCRIPTOR *pfd); }; class QOpenGLStaticContext : public QWindowsStaticOpenGLContext diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp index 19d632dc10..03be0b9451 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp @@ -160,7 +160,6 @@ Q_CORE_EXPORT QLocale qt_localeFromLCID(LCID id); // from qlocale_win.cpp needs to be checked (mouse grab might interfere with candidate window). \internal - \ingroup qt-lighthouse-win */ @@ -285,7 +284,8 @@ void QWindowsInputContext::showInputPanel() // the Surface seems unnecessary there anyway. But leave it hidden for IME. // Only trigger the native OSK if the Qt OSK is not in use. static bool imModuleEmpty = qEnvironmentVariableIsEmpty("QT_IM_MODULE"); - if (imModuleEmpty + bool nativeVKDisabled = QCoreApplication::testAttribute(Qt::AA_DisableNativeVirtualKeyboard); + if ((imModuleEmpty && !nativeVKDisabled) && QOperatingSystemVersion::current() >= QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 16299)) { ShowCaret(platformWindow->handle()); diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index d37b405db8..f4bf58ee31 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -128,7 +128,6 @@ QT_BEGIN_NAMESPACE QWindowsUser32DLL and QWindowsShell32DLL. All function pointers should go to these structs to avoid lookups in several places. - \ingroup qt-lighthouse-win */ struct QWindowsIntegrationPrivate @@ -162,7 +161,7 @@ bool parseIntOption(const QString ¶meter,const QLatin1String &option, IntType minimumValue, IntType maximumValue, IntType *target) { const int valueLength = parameter.size() - option.size() - 1; - if (valueLength < 1 || !parameter.startsWith(option) || parameter.at(option.size()) != QLatin1Char('=')) + if (valueLength < 1 || !parameter.startsWith(option) || parameter.at(option.size()) != u'=') return false; bool ok; const QStringRef valueRef = parameter.rightRef(valueLength); @@ -186,39 +185,43 @@ static inline unsigned parseOptions(const QStringList ¶mList, { unsigned options = 0; for (const QString ¶m : paramList) { - if (param.startsWith(QLatin1String("fontengine="))) { - if (param.endsWith(QLatin1String("freetype"))) { + if (param.startsWith(u"fontengine=")) { + if (param.endsWith(u"freetype")) { options |= QWindowsIntegration::FontDatabaseFreeType; - } else if (param.endsWith(QLatin1String("native"))) { + } else if (param.endsWith(u"native")) { options |= QWindowsIntegration::FontDatabaseNative; } - } else if (param.startsWith(QLatin1String("dialogs="))) { - if (param.endsWith(QLatin1String("xp"))) { + } else if (param.startsWith(u"dialogs=")) { + if (param.endsWith(u"xp")) { options |= QWindowsIntegration::XpNativeDialogs; - } else if (param.endsWith(QLatin1String("none"))) { + } else if (param.endsWith(u"none")) { options |= QWindowsIntegration::NoNativeDialogs; } - } else if (param == QLatin1String("altgr")) { + } else if (param == u"altgr") { options |= QWindowsIntegration::DetectAltGrModifier; - } else if (param == QLatin1String("gl=gdi")) { + } else if (param == u"gl=gdi") { options |= QWindowsIntegration::DisableArb; - } else if (param == QLatin1String("nodirectwrite")) { + } else if (param == u"nodirectwrite") { options |= QWindowsIntegration::DontUseDirectWriteFonts; - } else if (param == QLatin1String("nocolorfonts")) { + } else if (param == u"nocolorfonts") { options |= QWindowsIntegration::DontUseColorFonts; - } else if (param == QLatin1String("nomousefromtouch")) { + } else if (param == u"nomousefromtouch") { options |= QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch; } else if (parseIntOption(param, QLatin1String("verbose"), 0, INT_MAX, &QWindowsContext::verbose) || parseIntOption(param, QLatin1String("tabletabsoluterange"), 0, INT_MAX, tabletAbsoluteRange) || parseIntOption(param, QLatin1String("dpiawareness"), QtWindows::ProcessDpiUnaware, QtWindows::ProcessPerMonitorDpiAware, dpiAwareness)) { - } else if (param == QLatin1String("menus=native")) { + } else if (param == u"menus=native") { options |= QWindowsIntegration::AlwaysUseNativeMenus; - } else if (param == QLatin1String("menus=none")) { + } else if (param == u"menus=none") { options |= QWindowsIntegration::NoNativeMenus; - } else if (param == QLatin1String("nowmpointer")) { + } else if (param == u"nowmpointer") { options |= QWindowsIntegration::DontUseWMPointer; - } else if (param == QLatin1String("reverse")) { + } else if (param == u"reverse") { options |= QWindowsIntegration::RtlEnabled; + } else if (param == u"darkmode=1") { + options |= QWindowsIntegration::DarkModeWindowFrames; + } else if (param == u"darkmode=2") { + options |= QWindowsIntegration::DarkModeWindowFrames | QWindowsIntegration::DarkModeStyle; } else { qWarning() << "Unknown option" << param; } diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h index b49d21022b..1f16d13769 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.h +++ b/src/plugins/platforms/windows/qwindowsintegration.h @@ -70,7 +70,9 @@ public: NoNativeMenus = 0x200, DontUseWMPointer = 0x400, DetectAltGrModifier = 0x800, - RtlEnabled = 0x1000 + RtlEnabled = 0x1000, + DarkModeWindowFrames = 0x2000, + DarkModeStyle = 0x4000 }; explicit QWindowsIntegration(const QStringList ¶mList); diff --git a/src/plugins/platforms/windows/qwindowsinternalmimedata.cpp b/src/plugins/platforms/windows/qwindowsinternalmimedata.cpp index 44b7523fa6..ad3f02f83b 100644 --- a/src/plugins/platforms/windows/qwindowsinternalmimedata.cpp +++ b/src/plugins/platforms/windows/qwindowsinternalmimedata.cpp @@ -60,7 +60,6 @@ \sa QInternalMimeData, QWindowsMime, QWindowsMimeConverter \internal - \ingroup qt-lighthouse-win */ bool QWindowsInternalMimeData::hasFormat_sys(const QString &mime) const diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp index 4f0f846749..4f46c05f7a 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.cpp +++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp @@ -88,7 +88,6 @@ QT_BEGIN_NAMESPACE \class QWindowsKeyMapper \brief Translates Windows keys to QWindowSystemInterface events. \internal - \ingroup qt-lighthouse-win In addition, handles some special keys to display system menus, etc. The code originates from \c qkeymapper_win.cpp. @@ -1019,14 +1018,14 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, MSG msg, if (dirStatus == VK_LSHIFT && ((msg.wParam == VK_SHIFT && GetKeyState(VK_LCONTROL)) || (msg.wParam == VK_CONTROL && GetKeyState(VK_LSHIFT)))) { - sendExtendedPressRelease(receiver, Qt::Key_Direction_L, nullptr, + sendExtendedPressRelease(receiver, Qt::Key_Direction_L, {}, scancode, vk_key, nModifiers, QString(), false); result = true; dirStatus = 0; } else if (dirStatus == VK_RSHIFT && ( (msg.wParam == VK_SHIFT && GetKeyState(VK_RCONTROL)) || (msg.wParam == VK_CONTROL && GetKeyState(VK_RSHIFT)))) { - sendExtendedPressRelease(receiver, Qt::Key_Direction_R, nullptr, + sendExtendedPressRelease(receiver, Qt::Key_Direction_R, {}, scancode, vk_key, nModifiers, QString(), false); result = true; dirStatus = 0; @@ -1388,7 +1387,7 @@ QList<int> QWindowsKeyMapper::possibleKeys(const QKeyEvent *e) const if (key && key != baseKey && ((keyMods & neededMods) == neededMods)) { const Qt::KeyboardModifiers missingMods = keyMods & ~neededMods; const int matchedKey = int(key) + missingMods; - const QList<int>::iterator it = + const auto it = std::find_if(result.begin(), result.end(), [key] (int k) { return (k & ~Qt::KeyboardModifierMask) == key; }); // QTBUG-67200: Use the match with the least modifiers (prefer diff --git a/src/plugins/platforms/windows/qwindowsmenu.cpp b/src/plugins/platforms/windows/qwindowsmenu.cpp index 221e4ff6ec..5f21bdfa33 100644 --- a/src/plugins/platforms/windows/qwindowsmenu.cpp +++ b/src/plugins/platforms/windows/qwindowsmenu.cpp @@ -65,7 +65,6 @@ QT_BEGIN_NAMESPACE Qt Widgets, either the containers or the items might be deleted first. \internal - \ingroup qt-lighthouse-win */ static uint nextId = 1; @@ -445,7 +444,7 @@ QString QWindowsMenuItem::nativeText() const QString result = m_text; #if QT_CONFIG(shortcut) if (!m_shortcut.isEmpty()) { - result += QLatin1Char('\t'); + result += u'\t'; result += m_shortcut.toString(QKeySequence::NativeText); } #endif diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp index b9d8b191f5..6733ab9fed 100644 --- a/src/plugins/platforms/windows/qwindowsmime.cpp +++ b/src/plugins/platforms/windows/qwindowsmime.cpp @@ -107,7 +107,7 @@ static inline QByteArray msgConversionError(const char *func, const char *format msg += ": Unable to convert DIB image. The image converter plugin for '"; msg += format; msg += "' is not available. Available formats: "; - const QList<QByteArray> &formats = QImageReader::supportedImageFormats(); + const auto &formats = QImageReader::supportedImageFormats(); for (const QByteArray &af : formats) { msg += af; msg += ' '; @@ -447,7 +447,6 @@ QDebug operator<<(QDebug d, IDataObject *dataObj) \class QWindowsMime \brief The QWindowsMime class maps open-standard MIME to Window Clipboard formats. \internal - \ingroup qt-lighthouse-win Qt's drag-and-drop and clipboard facilities use the MIME standard. On X11, this maps trivially to the Xdnd protocol, but on Windows @@ -635,11 +634,11 @@ bool QWindowsMimeText::convertFromMime(const FORMATETC &formatetc, const QMimeDa int ri = 0; bool cr = false; for (int i=0; i < s; ++i) { - if (*u == QLatin1Char('\r')) + if (*u == u'\r') cr = true; else { - if (*u == QLatin1Char('\n') && !cr) - res[ri++] = QLatin1Char('\r'); + if (*u == u'\n' && !cr) + res[ri++] = u'\r'; cr = false; } res[ri++] = *u; @@ -663,7 +662,7 @@ bool QWindowsMimeText::convertFromMime(const FORMATETC &formatetc, const QMimeDa bool QWindowsMimeText::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const { - return mimeType.startsWith(QLatin1String("text/plain")) + return mimeType.startsWith(u"text/plain") && (canGetData(CF_UNICODETEXT, pDataObj) || canGetData(CF_TEXT, pDataObj)); } @@ -680,7 +679,7 @@ QString QWindowsMimeText::mimeForFormat(const FORMATETC &formatetc) const QVector<FORMATETC> QWindowsMimeText::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const { QVector<FORMATETC> formatics; - if (mimeType.startsWith(QLatin1String("text/plain")) && mimeData->hasText()) { + if (mimeType.startsWith(u"text/plain") && mimeData->hasText()) { formatics += setCf(CF_UNICODETEXT); formatics += setCf(CF_TEXT); } @@ -747,7 +746,7 @@ QWindowsMimeURI::QWindowsMimeURI() bool QWindowsMimeURI::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const { if (mimeData->hasUrls() && getCf(formatetc) == CF_HDROP) { - const QList<QUrl> urls = mimeData->urls(); + const auto urls = mimeData->urls(); for (const QUrl &url : urls) { if (url.isLocalFile()) return true; @@ -760,7 +759,7 @@ bool QWindowsMimeURI::convertFromMime(const FORMATETC &formatetc, const QMimeDat { if (canConvertFromMime(formatetc, mimeData)) { if (getCf(formatetc) == CF_HDROP) { - const QList<QUrl> &urls = mimeData->urls(); + const auto &urls = mimeData->urls(); QStringList fileNames; int size = sizeof(DROPFILES)+2; for (const QUrl &url : urls) { @@ -791,7 +790,7 @@ bool QWindowsMimeURI::convertFromMime(const FORMATETC &formatetc, const QMimeDat return setData(result, pmedium); } if (getCf(formatetc) == CF_INETURL_W) { - QList<QUrl> urls = mimeData->urls(); + const auto urls = mimeData->urls(); QByteArray result; if (!urls.isEmpty()) { QString url = urls.at(0).toString(); @@ -803,7 +802,7 @@ bool QWindowsMimeURI::convertFromMime(const FORMATETC &formatetc, const QMimeDat return setData(result, pmedium); } if (getCf(formatetc) == CF_INETURL) { - QList<QUrl> urls = mimeData->urls(); + const auto urls = mimeData->urls(); QByteArray result; if (!urls.isEmpty()) result = urls.at(0).toString().toLocal8Bit(); @@ -816,7 +815,7 @@ bool QWindowsMimeURI::convertFromMime(const FORMATETC &formatetc, const QMimeDat bool QWindowsMimeURI::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const { - return mimeType == QLatin1String("text/uri-list") + return mimeType == u"text/uri-list" && (canGetData(CF_HDROP, pDataObj) || canGetData(CF_INETURL_W, pDataObj) || canGetData(CF_INETURL, pDataObj)); } @@ -831,7 +830,7 @@ QString QWindowsMimeURI::mimeForFormat(const FORMATETC &formatetc) const QVector<FORMATETC> QWindowsMimeURI::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const { QVector<FORMATETC> formatics; - if (mimeType == QLatin1String("text/uri-list")) { + if (mimeType == u"text/uri-list") { if (canConvertFromMime(setCf(CF_HDROP), mimeData)) formatics += setCf(CF_HDROP); if (canConvertFromMime(setCf(CF_INETURL_W), mimeData)) @@ -844,7 +843,7 @@ QVector<FORMATETC> QWindowsMimeURI::formatsForMime(const QString &mimeType, cons QVariant QWindowsMimeURI::convertToMime(const QString &mimeType, LPDATAOBJECT pDataObj, QVariant::Type preferredType) const { - if (mimeType == QLatin1String("text/uri-list")) { + if (mimeType == u"text/uri-list") { if (canGetData(CF_HDROP, pDataObj)) { QList<QVariant> urls; @@ -916,7 +915,7 @@ QWindowsMimeHtml::QWindowsMimeHtml() QVector<FORMATETC> QWindowsMimeHtml::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const { QVector<FORMATETC> formatetcs; - if (mimeType == QLatin1String("text/html") && (!mimeData->html().isEmpty())) + if (mimeType == u"text/html" && (!mimeData->html().isEmpty())) formatetcs += setCf(CF_HTML); return formatetcs; } @@ -930,7 +929,7 @@ QString QWindowsMimeHtml::mimeForFormat(const FORMATETC &formatetc) const bool QWindowsMimeHtml::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const { - return mimeType == QLatin1String("text/html") && canGetData(CF_HTML, pDataObj); + return mimeType == u"text/html" && canGetData(CF_HTML, pDataObj); } @@ -1053,7 +1052,7 @@ QWindowsMimeImage::QWindowsMimeImage() QVector<FORMATETC> QWindowsMimeImage::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const { QVector<FORMATETC> formatetcs; - if (mimeData->hasImage() && mimeType == QLatin1String("application/x-qt-image")) { + if (mimeData->hasImage() && mimeType == u"application/x-qt-image") { //add DIBV5 if image has alpha channel. Do not add CF_PNG here as it will confuse MS Office (QTBUG47656). auto image = qvariant_cast<QImage>(mimeData->imageData()); if (!image.isNull() && image.hasAlphaChannel()) @@ -1075,7 +1074,7 @@ QString QWindowsMimeImage::mimeForFormat(const FORMATETC &formatetc) const bool QWindowsMimeImage::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const { - return mimeType == QLatin1String("application/x-qt-image") + return mimeType == u"application/x-qt-image" && (canGetData(CF_DIB, pDataObj) || canGetData(CF_PNG, pDataObj)); } @@ -1149,7 +1148,7 @@ QVariant QWindowsMimeImage::convertToMime(const QString &mimeType, IDataObject * { Q_UNUSED(preferredType); QVariant result; - if (mimeType != QLatin1String("application/x-qt-image")) + if (mimeType != u"application/x-qt-image") return result; //Try to convert from a format which has more data //DIBV5, use only if its is not synthesized @@ -1220,7 +1219,7 @@ bool QBuiltInMimes::convertFromMime(const FORMATETC &formatetc, const QMimeData { if (canConvertFromMime(formatetc, mimeData)) { QByteArray data; - if (outFormats.value(getCf(formatetc)) == QLatin1String("text/html")) { + if (outFormats.value(getCf(formatetc)) == u"text/html") { // text/html is in wide chars on windows (compatible with mozillia) QString html = mimeData->html(); // same code as in the text converter up above @@ -1232,11 +1231,11 @@ bool QBuiltInMimes::convertFromMime(const FORMATETC &formatetc, const QMimeData int ri = 0; bool cr = false; for (int i=0; i < s; ++i) { - if (*u == QLatin1Char('\r')) + if (*u == u'\r') cr = true; else { - if (*u == QLatin1Char('\n') && !cr) - res[ri++] = QLatin1Char('\r'); + if (*u == u'\n' && !cr) + res[ri++] = u'\r'; cr = false; } res[ri++] = *u; @@ -1285,7 +1284,7 @@ QVariant QBuiltInMimes::convertToMime(const QString &mimeType, IDataObject *pDat QByteArray data = getData(inFormats.key(mimeType), pDataObj); if (!data.isEmpty()) { qCDebug(lcQpaMime) << __FUNCTION__; - if (mimeType == QLatin1String("text/html") && preferredType == QVariant::String) { + if (mimeType == u"text/html" && preferredType == QVariant::String) { // text/html is in wide chars on windows (compatible with Mozilla) val = QString::fromWCharArray(reinterpret_cast<const wchar_t *>(data.constData())); } else { @@ -1404,12 +1403,12 @@ static bool isCustomMimeType(const QString &mimeType) static QString customMimeType(const QString &mimeType, int *lindex = nullptr) { int len = sizeof(x_qt_windows_mime) - 1; - int n = mimeType.lastIndexOf(QLatin1Char('\"')) - len; + int n = mimeType.lastIndexOf(u'\"') - len; QString ret = mimeType.mid(len, n); - const int beginPos = mimeType.indexOf(QLatin1String(";index=")); + const int beginPos = mimeType.indexOf(u";index="); if (beginPos > -1) { - const int endPos = mimeType.indexOf(QLatin1Char(';'), beginPos + 1); + const int endPos = mimeType.indexOf(u';', beginPos + 1); const int indexStartPos = beginPos + 7; if (lindex) *lindex = mimeType.midRef(indexStartPos, endPos == -1 ? endPos : endPos - indexStartPos).toInt(); @@ -1480,7 +1479,7 @@ QString QLastResortMimes::mimeForFormat(const FORMATETC &formatetc) const } } if (!ianaType) - format = QLatin1String(x_qt_windows_mime) + clipFormat + QLatin1Char('\"'); + format = QLatin1String(x_qt_windows_mime) + clipFormat + u'"'; else format = clipFormat; } @@ -1495,7 +1494,6 @@ QString QLastResortMimes::mimeForFormat(const FORMATETC &formatetc) const \class QWindowsMimeConverter \brief Manages the list of QWindowsMime instances. \internal - \ingroup qt-lighthouse-win \sa QWindowsMime */ diff --git a/src/plugins/platforms/windows/qwindowsmime.h b/src/plugins/platforms/windows/qwindowsmime.h index 1c389e8800..f8708f1259 100644 --- a/src/plugins/platforms/windows/qwindowsmime.h +++ b/src/plugins/platforms/windows/qwindowsmime.h @@ -43,7 +43,6 @@ #include <QtCore/qt_windows.h> #include <QtCore/qvector.h> -#include <QtCore/qlist.h> #include <QtCore/qvariant.h> QT_BEGIN_NAMESPACE @@ -95,7 +94,7 @@ public: private: void ensureInitialized() const; - mutable QList<QWindowsMime *> m_mimes; + mutable QVector<QWindowsMime *> m_mimes; mutable int m_internalMimeCount = 0; }; diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp index 6df5e6aa27..1b2d831268 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp +++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp @@ -145,7 +145,6 @@ static inline QTouchDevice *createTouchDevice() Dispatches mouse and touch events. Separate for code cleanliness. \internal - \ingroup qt-lighthouse-win */ QWindowsMouseHandler::QWindowsMouseHandler() = default; @@ -165,7 +164,7 @@ void QWindowsMouseHandler::clearEvents() Qt::MouseButtons QWindowsMouseHandler::queryMouseButtons() { - Qt::MouseButtons result = nullptr; + Qt::MouseButtons result; const bool mouseSwapped = GetSystemMetrics(SM_SWAPBUTTON); if (GetAsyncKeyState(VK_LBUTTON) < 0) result |= mouseSwapped ? Qt::RightButton: Qt::LeftButton; @@ -630,7 +629,7 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND, QTouchPointList touchPoints; touchPoints.reserve(winTouchPointCount); - Qt::TouchPointStates allStates = nullptr; + Qt::TouchPointStates allStates; GetTouchInputInfo(reinterpret_cast<HTOUCHINPUT>(msg.lParam), UINT(msg.wParam), winTouchInputs.data(), sizeof(TOUCHINPUT)); diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp index d1d181d66e..1195f15a59 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp @@ -47,6 +47,7 @@ #include "qwindowsopengltester.h" #include "qwindowsintegration.h" #include "qwindowsmime.h" +#include "qwindowstheme.h" #include "qwin10helpers.h" #include <QtGui/qwindow.h> @@ -316,4 +317,15 @@ QVariant QWindowsNativeInterface::gpuList() const 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 diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.h b/src/plugins/platforms/windows/qwindowsnativeinterface.h index ce395dc5a4..387f65ae8f 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.h +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.h @@ -58,13 +58,14 @@ QT_BEGIN_NAMESPACE \endlist \internal - \ingroup qt-lighthouse-win */ class QWindowsNativeInterface : public QPlatformNativeInterface { Q_OBJECT 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 gpuList READ gpuList STORED false) @@ -92,6 +93,9 @@ public: bool asyncExpose() const; void setAsyncExpose(bool value); + bool isDarkMode() const; + bool isDarkModeStyle() const; + QVariant gpu() const; QVariant gpuList() const; @@ -109,6 +113,9 @@ public: QFunctionPointer platformFunction(const QByteArray &function) const override; +Q_SIGNALS: + void darkModeChanged(bool); + private: static QWindowsWindowFunctions::WindowActivationBehavior m_windowActivationBehavior; }; diff --git a/src/plugins/platforms/windows/qwindowsole.cpp b/src/plugins/platforms/windows/qwindowsole.cpp index f3450e2806..0a7fef6c30 100644 --- a/src/plugins/platforms/windows/qwindowsole.cpp +++ b/src/plugins/platforms/windows/qwindowsole.cpp @@ -70,7 +70,6 @@ QT_BEGIN_NAMESPACE \endlist \internal - \ingroup qt-lighthouse-win */ QWindowsOleDataObject::QWindowsOleDataObject(QMimeData *mimeData) : @@ -228,7 +227,6 @@ QWindowsOleDataObject::EnumDAdvise(LPENUMSTATDATA FAR*) \class QWindowsOleEnumFmtEtc \brief Enumerates the FORMATETC structures supported by QWindowsOleDataObject. \internal - \ingroup qt-lighthouse-win */ QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QVector<FORMATETC> &fmtetcs) diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp index afc1991e2c..72092a4481 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.cpp +++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp @@ -206,7 +206,7 @@ QString GpuDescription::toString() const str << " Card name : " << description << "\n Driver Name : " << driverName << "\n Driver Version : " << driverVersion.toString() - << "\n Vendor ID : 0x" << qSetPadChar(QLatin1Char('0')) + << "\n Vendor ID : 0x" << qSetPadChar(u'0') << Qt::uppercasedigits << Qt::hex << qSetFieldWidth(4) << vendorId << "\n Device ID : 0x" << qSetFieldWidth(4) << deviceId << "\n SubSys ID : 0x" << qSetFieldWidth(8) << subSysId @@ -285,7 +285,7 @@ static inline QString resolveBugListFile(const QString &fileName) // then resolve via QStandardPaths::ConfigLocation. const QString settingsPath = QLibraryInfo::location(QLibraryInfo::SettingsPath); if (!settingsPath.isEmpty()) { // SettingsPath is empty unless specified in qt.conf. - const QFileInfo fi(settingsPath + QLatin1Char('/') + fileName); + const QFileInfo fi(settingsPath + u'/' + fileName); if (fi.isFile()) return fi.absoluteFilePath(); } diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp index b477147da7..fba24d8696 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp @@ -482,7 +482,7 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd, << " message=" << Qt::hex << msg.message << " count=" << Qt::dec << count; - Qt::TouchPointStates allStates = nullptr; + Qt::TouchPointStates allStates; for (quint32 i = 0; i < count; ++i) { if (QWindowsContext::verbose > 1) diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp index df63adf558..9a4f8d152c 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -73,7 +73,7 @@ static inline QDpi monitorDPI(HMONITOR hMonitor) return {0, 0}; } -using WindowsScreenDataList = QList<QWindowsScreenData>; +using WindowsScreenDataList = QVector<QWindowsScreenData>; static bool monitorData(HMONITOR hMonitor, QWindowsScreenData *data) { @@ -87,7 +87,7 @@ static bool monitorData(HMONITOR hMonitor, QWindowsScreenData *data) data->geometry = QRect(QPoint(info.rcMonitor.left, info.rcMonitor.top), QPoint(info.rcMonitor.right - 1, info.rcMonitor.bottom - 1)); data->availableGeometry = QRect(QPoint(info.rcWork.left, info.rcWork.top), QPoint(info.rcWork.right - 1, info.rcWork.bottom - 1)); data->name = QString::fromWCharArray(info.szDevice); - if (data->name == QLatin1String("WinDisc")) { + if (data->name == u"WinDisc") { data->flags |= QWindowsScreenData::LockScreen; } else { if (const HDC hdc = CreateDC(info.szDevice, nullptr, nullptr, nullptr)) { @@ -171,7 +171,6 @@ static QDebug operator<<(QDebug dbg, const QWindowsScreenData &d) \brief Windows screen. \sa QWindowsScreenManager \internal - \ingroup qt-lighthouse-win */ QWindowsScreen::QWindowsScreen(const QWindowsScreenData &data) : @@ -432,7 +431,6 @@ QPlatformScreen::SubpixelAntialiasingType QWindowsScreen::subpixelAntialiasingTy \sa QWindowsScreen \internal - \ingroup qt-lighthouse-win */ QWindowsScreenManager::QWindowsScreenManager() = default; @@ -467,7 +465,7 @@ bool QWindowsScreenManager::handleDisplayChange(WPARAM wParam, LPARAM lParam) return false; } -static inline int indexOfMonitor(const QList<QWindowsScreen *> &screens, +static inline int indexOfMonitor(const QWindowsScreenManager::WindowsScreenList &screens, const QString &monitorName) { for (int i= 0; i < screens.size(); ++i) @@ -476,7 +474,7 @@ static inline int indexOfMonitor(const QList<QWindowsScreen *> &screens, return -1; } -static inline int indexOfMonitor(const QList<QWindowsScreenData> &screenData, +static inline int indexOfMonitor(const WindowsScreenDataList &screenData, const QString &monitorName) { for (int i = 0; i < screenData.size(); ++i) diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h index 2fd56f53cf..5c095808f2 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.h +++ b/src/plugins/platforms/windows/qwindowsscreen.h @@ -127,7 +127,7 @@ private: class QWindowsScreenManager { public: - using WindowsScreenList = QList<QWindowsScreen *>; + using WindowsScreenList = QVector<QWindowsScreen *>; QWindowsScreenManager(); diff --git a/src/plugins/platforms/windows/qwindowsservices.cpp b/src/plugins/platforms/windows/qwindowsservices.cpp index 83b052bb49..6a2708ee26 100644 --- a/src/plugins/platforms/windows/qwindowsservices.cpp +++ b/src/plugins/platforms/windows/qwindowsservices.cpp @@ -92,7 +92,7 @@ static inline QString mailCommand() // "rundll32.exe .. url.dll,MailToProtocolHandler %l" is returned. Launching it // silently fails or brings up a broken dialog after a long time, so exclude it and // fall back to ShellExecute() which brings up the URL assocation dialog. - if (command.isEmpty() || command.contains(QLatin1String(",MailToProtocolHandler"))) + if (command.isEmpty() || command.contains(u",MailToProtocolHandler")) return QString(); wchar_t expandedCommand[MAX_PATH] = {0}; return ExpandEnvironmentStrings(reinterpret_cast<const wchar_t *>(command.utf16()), @@ -108,7 +108,7 @@ static inline bool launchMail(const QUrl &url) return false; } //Make sure the path for the process is in quotes - const QChar doubleQuote = QLatin1Char('"'); + const QChar doubleQuote = u'"'; if (!command.startsWith(doubleQuote)) { const int exeIndex = command.indexOf(QStringLiteral(".exe "), 0, Qt::CaseInsensitive); if (exeIndex != -1) { @@ -140,7 +140,7 @@ static inline bool launchMail(const QUrl &url) bool QWindowsServices::openUrl(const QUrl &url) { const QString scheme = url.scheme(); - if (scheme == QLatin1String("mailto") && launchMail(url)) + if (scheme == u"mailto" && launchMail(url)) return true; return shellExecute(url); } diff --git a/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp b/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp index 9409d2db4d..def011e4bd 100644 --- a/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp +++ b/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp @@ -168,7 +168,7 @@ static inline HWND createTrayIconMessageWindow() return nullptr; // Register window class in the platform plugin. const QString className = - ctx->registerWindowClass(QStringLiteral("QTrayIconMessageWindowClass"), + ctx->registerWindowClass(QWindowsContext::classNamePrefix() + QStringLiteral("TrayIconMessageWindowClass"), qWindowsTrayIconWndProc); const wchar_t windowName[] = L"QTrayIconMessageWindow"; return CreateWindowEx(0, reinterpret_cast<const wchar_t *>(className.utf16()), @@ -184,7 +184,6 @@ static inline HWND createTrayIconMessageWindow() \brief Windows native system tray icon \internal - \ingroup qt-lighthouse-win */ QWindowsSystemTrayIcon::QWindowsSystemTrayIcon() @@ -261,7 +260,7 @@ void QWindowsSystemTrayIcon::showMessage(const QString &title, const QString &me // For empty messages, ensures that they show when only title is set QString message = messageIn; if (message.isEmpty() && !title.isEmpty()) - message.append(QLatin1Char(' ')); + message.append(u' '); NOTIFYICONDATA tnd; initNotifyIconData(tnd); diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp index cd5a78abb6..287ba931d9 100644 --- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp +++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp @@ -173,7 +173,6 @@ QWindowsWinTab32DLL QWindowsTabletSupport::m_winTab32DLL; \brief Functions from wintabl32.dll shipped with WACOM tablets used by QWindowsTabletSupport. \internal - \ingroup qt-lighthouse-win */ bool QWindowsWinTab32DLL::init() @@ -205,7 +204,6 @@ bool QWindowsWinTab32DLL::init() \internal \since 5.2 - \ingroup qt-lighthouse-win */ QWindowsTabletSupport::QWindowsTabletSupport(HWND window, HCTX context) diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index 40f9652cbd..7f47cd712f 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -63,6 +63,7 @@ #include <QtCore/qcoreapplication.h> #include <QtCore/qdebug.h> #include <QtCore/qtextstream.h> +#include <QtCore/qoperatingsystemversion.h> #include <QtCore/qsysinfo.h> #include <QtCore/qcache.h> #include <QtCore/qthread.h> @@ -78,6 +79,7 @@ #include <QtFontDatabaseSupport/private/qwindowsfontdatabase_p.h> #include <private/qhighdpiscaling_p.h> #include <private/qsystemlibrary_p.h> +#include <private/qwinregistry_p.h> #include <algorithm> @@ -96,7 +98,7 @@ static inline QTextStream& operator<<(QTextStream &str, const QColor &c) { str.setIntegerBase(16); str.setFieldWidth(2); - str.setPadChar(QLatin1Char('0')); + str.setPadChar(u'0'); str << " rgb: #" << c.red() << c.green() << c.blue(); str.setIntegerBase(10); str.setFieldWidth(0); @@ -164,7 +166,7 @@ public: QMutexLocker readyLocker(&m_readyMutex); while (!m_cancelled.loadRelaxed()) { if (!m_params && !m_cancelled.loadRelaxed() - && !m_readyCondition.wait(&m_readyMutex, 1000)) + && !m_readyCondition.wait(&m_readyMutex, QDeadlineTimer(1000ll))) continue; if (m_params) { @@ -189,7 +191,7 @@ public: CoUninitialize(); } - bool runWithParams(QShGetFileInfoParams *params, unsigned long timeOutMSecs) + bool runWithParams(QShGetFileInfoParams *params, qint64 timeOutMSecs) { QMutexLocker doneLocker(&m_doneMutex); @@ -198,7 +200,7 @@ public: m_readyCondition.wakeAll(); m_readyMutex.unlock(); - return m_doneCondition.wait(&m_doneMutex, timeOutMSecs); + return m_doneCondition.wait(&m_doneMutex, QDeadlineTimer(timeOutMSecs)); } void cancel() @@ -220,7 +222,7 @@ private: static bool shGetFileInfoBackground(const QString &fileName, DWORD attributes, SHFILEINFO *info, UINT flags, - unsigned long timeOutMSecs = 5000) + qint64 timeOutMSecs = 5000) { static QShGetFileInfoThread *getFileInfoThread = nullptr; if (!getFileInfoThread) { @@ -241,6 +243,14 @@ static bool shGetFileInfoBackground(const QString &fileName, DWORD attributes, return result; } +// Dark Mode constants +enum DarkModeColors : QRgb { + darkModeBtnHighlightRgb = 0xc0c0c0, + darkModeBtnShadowRgb = 0x808080, + darkModeHighlightRgb = 0x0055ff, // deviating from 0x800080 + darkModeMenuHighlightRgb = darkModeHighlightRgb +}; + // from QStyle::standardPalette static inline QPalette standardPalette() { @@ -258,23 +268,55 @@ static inline QPalette standardPalette() return palette; } -static inline QPalette systemPalette() +static void populateLightSystemBasePalette(QPalette &result) { - QPalette result = standardPalette(); result.setColor(QPalette::WindowText, getSysColor(COLOR_WINDOWTEXT)); - result.setColor(QPalette::Button, getSysColor(COLOR_BTNFACE)); - result.setColor(QPalette::Light, getSysColor(COLOR_BTNHIGHLIGHT)); + const QColor btnFace = getSysColor(COLOR_BTNFACE); + result.setColor(QPalette::Button, btnFace); + const QColor btnHighlight = getSysColor(COLOR_BTNHIGHLIGHT); + result.setColor(QPalette::Light, btnHighlight); result.setColor(QPalette::Dark, getSysColor(COLOR_BTNSHADOW)); result.setColor(QPalette::Mid, result.button().color().darker(150)); result.setColor(QPalette::Text, getSysColor(COLOR_WINDOWTEXT)); - result.setColor(QPalette::BrightText, getSysColor(COLOR_BTNHIGHLIGHT)); + result.setColor(QPalette::BrightText, btnHighlight); result.setColor(QPalette::Base, getSysColor(COLOR_WINDOW)); - result.setColor(QPalette::Window, getSysColor(COLOR_BTNFACE)); + result.setColor(QPalette::Window, btnFace); result.setColor(QPalette::ButtonText, getSysColor(COLOR_BTNTEXT)); result.setColor(QPalette::Midlight, getSysColor(COLOR_3DLIGHT)); result.setColor(QPalette::Shadow, getSysColor(COLOR_3DDKSHADOW)); result.setColor(QPalette::Highlight, getSysColor(COLOR_HIGHLIGHT)); result.setColor(QPalette::HighlightedText, getSysColor(COLOR_HIGHLIGHTTEXT)); +} + +static void populateDarkSystemBasePalette(QPalette &result) +{ + const QColor darkModeWindowText = Qt::white; + result.setColor(QPalette::WindowText, darkModeWindowText); + const QColor darkModebtnFace = Qt::black; + result.setColor(QPalette::Button, darkModebtnFace); + const QColor btnHighlight = QColor(darkModeBtnHighlightRgb); + result.setColor(QPalette::Light, btnHighlight); + result.setColor(QPalette::Dark, QColor(darkModeBtnShadowRgb)); + result.setColor(QPalette::Mid, result.button().color().darker(150)); + result.setColor(QPalette::Text, darkModeWindowText); + result.setColor(QPalette::BrightText, btnHighlight); + result.setColor(QPalette::Base, darkModebtnFace); + result.setColor(QPalette::Window, darkModebtnFace); + result.setColor(QPalette::ButtonText, darkModeWindowText); + result.setColor(QPalette::Midlight, darkModeWindowText); + result.setColor(QPalette::Shadow, darkModeWindowText); + result.setColor(QPalette::Highlight, QColor(darkModeHighlightRgb)); + result.setColor(QPalette::HighlightedText, darkModeWindowText); +} + +static QPalette systemPalette(bool light) +{ + QPalette result = standardPalette(); + if (light) + populateLightSystemBasePalette(result); + else + populateDarkSystemBasePalette(result); + result.setColor(QPalette::Link, Qt::blue); result.setColor(QPalette::LinkVisited, Qt::magenta); result.setColor(QPalette::Inactive, QPalette::Button, result.button().color()); @@ -300,19 +342,19 @@ static inline QPalette systemPalette() result.setColor(QPalette::Disabled, QPalette::Text, disabled); result.setColor(QPalette::Disabled, QPalette::ButtonText, disabled); result.setColor(QPalette::Disabled, QPalette::Highlight, - getSysColor(COLOR_HIGHLIGHT)); + light ? getSysColor(COLOR_HIGHLIGHT) : QColor(darkModeHighlightRgb)); result.setColor(QPalette::Disabled, QPalette::HighlightedText, - getSysColor(COLOR_HIGHLIGHTTEXT)); + light ? getSysColor(COLOR_HIGHLIGHTTEXT) : QColor(Qt::white)); result.setColor(QPalette::Disabled, QPalette::Base, result.window().color()); return result; } -static inline QPalette toolTipPalette(const QPalette &systemPalette) +static inline QPalette toolTipPalette(const QPalette &systemPalette, bool light) { QPalette result(systemPalette); - const QColor tipBgColor(getSysColor(COLOR_INFOBK)); - const QColor tipTextColor(getSysColor(COLOR_INFOTEXT)); + const QColor tipBgColor = light ? getSysColor(COLOR_INFOBK) : QColor(Qt::black); + const QColor tipTextColor = light ? getSysColor(COLOR_INFOTEXT) : QColor(Qt::white); result.setColor(QPalette::All, QPalette::Button, tipBgColor); result.setColor(QPalette::All, QPalette::Window, tipBgColor); @@ -337,12 +379,13 @@ static inline QPalette toolTipPalette(const QPalette &systemPalette) return result; } -static inline QPalette menuPalette(const QPalette &systemPalette) +static inline QPalette menuPalette(const QPalette &systemPalette, bool light) { QPalette result(systemPalette); - const QColor menuColor(getSysColor(COLOR_MENU)); - const QColor menuTextColor(getSysColor(COLOR_MENUTEXT)); - const QColor disabled(getSysColor(COLOR_GRAYTEXT)); + const QColor menuColor = light ? getSysColor(COLOR_MENU) : QColor(Qt::black); + const QColor menuTextColor = light ? getSysColor(COLOR_MENUTEXT) : QColor(Qt::white); + const QColor disabled = light + ? getSysColor(COLOR_GRAYTEXT) : QColor(darkModeBtnHighlightRgb); // we might need a special color group for the result. result.setColor(QPalette::Active, QPalette::Button, menuColor); result.setColor(QPalette::Active, QPalette::Text, menuTextColor); @@ -351,8 +394,10 @@ static inline QPalette menuPalette(const QPalette &systemPalette) result.setColor(QPalette::Disabled, QPalette::WindowText, disabled); result.setColor(QPalette::Disabled, QPalette::Text, disabled); const bool isFlat = booleanSystemParametersInfo(SPI_GETFLATMENU, false); - result.setColor(QPalette::Disabled, QPalette::Highlight, - getSysColor(isFlat ? COLOR_MENUHILIGHT : COLOR_HIGHLIGHT)); + const QColor highlightColor = light + ? (getSysColor(isFlat ? COLOR_MENUHILIGHT : COLOR_HIGHLIGHT)) + : QColor(darkModeMenuHighlightRgb); + result.setColor(QPalette::Disabled, QPalette::Highlight, highlightColor); result.setColor(QPalette::Disabled, QPalette::HighlightedText, disabled); result.setColor(QPalette::Disabled, QPalette::Button, result.color(QPalette::Active, QPalette::Button)); @@ -373,12 +418,12 @@ static inline QPalette menuPalette(const QPalette &systemPalette) return result; } -static inline QPalette *menuBarPalette(const QPalette &menuPalette) +static inline QPalette *menuBarPalette(const QPalette &menuPalette, bool light) { QPalette *result = nullptr; if (booleanSystemParametersInfo(SPI_GETFLATMENU, false)) { result = new QPalette(menuPalette); - const QColor menubar(getSysColor(COLOR_MENUBAR)); + const QColor menubar(light ? getSysColor(COLOR_MENUBAR) : QColor(Qt::black)); result->setColor(QPalette::Active, QPalette::Button, menubar); result->setColor(QPalette::Disabled, QPalette::Button, menubar); result->setColor(QPalette::Inactive, QPalette::Button, menubar); @@ -485,10 +530,26 @@ void QWindowsTheme::refreshPalettes() if (!QGuiApplication::desktopSettingsAware()) return; - m_palettes[SystemPalette] = new QPalette(systemPalette()); - m_palettes[ToolTipPalette] = new QPalette(toolTipPalette(*m_palettes[SystemPalette])); - m_palettes[MenuPalette] = new QPalette(menuPalette(*m_palettes[SystemPalette])); - m_palettes[MenuBarPalette] = menuBarPalette(*m_palettes[MenuPalette]); + const bool light = + !QWindowsContext::isDarkMode() + || (QWindowsIntegration::instance()->options() & QWindowsIntegration::DarkModeStyle) == 0; + m_palettes[SystemPalette] = new QPalette(systemPalette(light)); + m_palettes[ToolTipPalette] = new QPalette(toolTipPalette(*m_palettes[SystemPalette], light)); + m_palettes[MenuPalette] = new QPalette(menuPalette(*m_palettes[SystemPalette], light)); + m_palettes[MenuBarPalette] = menuBarPalette(*m_palettes[MenuPalette], light); + if (!light) { + m_palettes[ButtonPalette] = new QPalette(*m_palettes[SystemPalette]); + m_palettes[ButtonPalette]->setColor(QPalette::Button, QColor(0x666666u)); + const QColor checkBoxBlue(0x0078d7u); + const QColor white(Qt::white); + m_palettes[CheckBoxPalette] = new QPalette(*m_palettes[SystemPalette]); + m_palettes[CheckBoxPalette]->setColor(QPalette::Window, checkBoxBlue); + m_palettes[CheckBoxPalette]->setColor(QPalette::Base, checkBoxBlue); + m_palettes[CheckBoxPalette]->setColor(QPalette::Button, checkBoxBlue); + m_palettes[CheckBoxPalette]->setColor(QPalette::ButtonText, white); + m_palettes[RadioButtonPalette] = new QPalette(*m_palettes[CheckBoxPalette]); + + } } void QWindowsTheme::clearFonts() @@ -497,6 +558,12 @@ void QWindowsTheme::clearFonts() std::fill(m_fonts, m_fonts + NFonts, nullptr); } +void QWindowsTheme::refresh() +{ + refreshPalettes(); + refreshFonts(); +} + void QWindowsTheme::refreshFonts() { clearFonts(); @@ -731,13 +798,13 @@ static QString dirIconPixmapCacheKey(int iIcon, int iconSize, int imageListSize) { QString key = QLatin1String("qt_dir_") + QString::number(iIcon); if (iconSize == SHGFI_LARGEICON) - key += QLatin1Char('l'); + key += u'l'; switch (imageListSize) { case sHIL_EXTRALARGE: - key += QLatin1Char('e'); + key += u'e'; break; case sHIL_JUMBO: - key += QLatin1Char('j'); + key += u'j'; break; } return key; @@ -815,9 +882,9 @@ QString QWindowsFileIconEngine::cacheKey() const // It is faster to just look at the file extensions; // avoiding slow QFileInfo::isExecutable() (QTBUG-13182) QString suffix = fileInfo().suffix(); - if (!suffix.compare(QLatin1String("exe"), Qt::CaseInsensitive) - || !suffix.compare(QLatin1String("lnk"), Qt::CaseInsensitive) - || !suffix.compare(QLatin1String("ico"), Qt::CaseInsensitive)) { + if (!suffix.compare(u"exe", Qt::CaseInsensitive) + || !suffix.compare(u"lnk", Qt::CaseInsensitive) + || !suffix.compare(u"ico", Qt::CaseInsensitive)) { return QString(); } return QLatin1String("qt_.") @@ -946,6 +1013,23 @@ bool QWindowsTheme::useNativeMenus() 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 { qCDebug(lcQpaMenus) << __FUNCTION__; diff --git a/src/plugins/platforms/windows/qwindowstheme.h b/src/plugins/platforms/windows/qwindowstheme.h index 07120230ce..af28f2878c 100644 --- a/src/plugins/platforms/windows/qwindowstheme.h +++ b/src/plugins/platforms/windows/qwindowstheme.h @@ -71,7 +71,7 @@ public: QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const override; - QIcon fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions iconOptions = nullptr) const override; + QIcon fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions iconOptions = {}) const override; void windowsThemeChanged(QWindow *window); void displayChanged() { refreshIconPixmapSizes(); } @@ -84,13 +84,15 @@ public: void showPlatformMenuBar() override; static bool useNativeMenus(); + static bool queryDarkMode(); + static bool queryHighContrast(); void refreshFonts(); + void refresh(); static const char *name; private: - void refresh() { refreshPalettes(); refreshFonts(); } void clearPalettes(); void refreshPalettes(); void clearFonts(); diff --git a/src/plugins/platforms/windows/qwindowsthreadpoolrunner.h b/src/plugins/platforms/windows/qwindowsthreadpoolrunner.h index ffe2e62069..a31e00c0ac 100644 --- a/src/plugins/platforms/windows/qwindowsthreadpoolrunner.h +++ b/src/plugins/platforms/windows/qwindowsthreadpoolrunner.h @@ -55,7 +55,6 @@ QT_BEGIN_NAMESPACE to be done by using QWaitCondition/QMutex. \internal - \ingroup qt-lighthouse-win */ class QWindowsThreadPoolRunner { diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 04478d5f1f..6b53e3d4c4 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -253,7 +253,7 @@ QDebug operator<<(QDebug d, const GUID &guid) { QDebugStateSaver saver(d); d.nospace(); - d << '{' << Qt::hex << Qt::uppercasedigits << qSetPadChar(QLatin1Char('0')) + d << '{' << Qt::hex << Qt::uppercasedigits << qSetPadChar(u'0') << qSetFieldWidth(8) << guid.Data1 << qSetFieldWidth(0) << '-' << qSetFieldWidth(4) << guid.Data2 << qSetFieldWidth(0) << '-' << qSetFieldWidth(4) @@ -489,7 +489,6 @@ static QMargins invisibleMargins(QPoint screenPoint) \sa QWindowCreationContext \internal - \ingroup qt-lighthouse-win */ struct WindowCreationData @@ -592,7 +591,7 @@ static QPoint calcPosition(const QWindow *w, const QWindowCreationContextPtr &co return posFrame; // Find the original screen containing the coordinates. - const QList<QScreen *> screens = screenForGL->virtualSiblings(); + const auto screens = screenForGL->virtualSiblings(); const QScreen *orgScreen = nullptr; for (QScreen *screen : screens) { if (screen->handle()->availableGeometry().contains(posFrame)) { @@ -749,6 +748,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 +820,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()); @@ -906,7 +916,6 @@ static QSize toNativeSizeConstrained(QSize dip, const QScreen *s) into account. \internal - \ingroup qt-lighthouse-win */ QMargins QWindowsGeometryHint::frameOnPrimaryScreen(DWORD style, DWORD exStyle) @@ -1076,7 +1085,6 @@ bool QWindowsGeometryHint::positionIncludesFrame(const QWindow *w) \since 5.6 \internal - \ingroup qt-lighthouse-win */ bool QWindowsBaseWindow::isRtlLayout(HWND hwnd) @@ -1165,7 +1173,6 @@ QPoint QWindowsBaseWindow::mapFromGlobal(const QPoint &pos) const \brief Window wrapping GetDesktopWindow not allowing any manipulation. \since 5.6 \internal - \ingroup qt-lighthouse-win */ /*! @@ -1178,7 +1185,6 @@ QPoint QWindowsBaseWindow::mapFromGlobal(const QPoint &pos) const \since 5.6 \internal - \ingroup qt-lighthouse-win */ QWindowsForeignWindow::QWindowsForeignWindow(QWindow *window, HWND hwnd) @@ -1237,7 +1243,6 @@ void QWindowsForeignWindow::setVisible(bool visible) \sa WindowCreationData, QWindowsContext \internal - \ingroup qt-lighthouse-win */ QWindowCreationContext::QWindowCreationContext(const QWindow *w, const QScreen *s, @@ -1307,7 +1312,6 @@ void QWindowCreationContext::applyToMinMaxInfo(MINMAXINFO *mmi) const \endlist \internal - \ingroup qt-lighthouse-win */ const char *QWindowsWindow::embeddedNativeParentHandleProperty = "_q_embedded_native_parent_handle"; @@ -1397,6 +1401,11 @@ void QWindowsWindow::fireExpose(const QRegion ®ion, bool force) QWindowSystemInterface::handleExposeEvent(window(), region); } +void QWindowsWindow::fireFullExpose(bool force) +{ + fireExpose(QRect(QPoint(0, 0), m_data.geometry.size()), force); +} + void QWindowsWindow::destroyWindow() { qCDebug(lcQpaWindows) << __FUNCTION__ << this << window() << m_data.hwnd; @@ -1557,7 +1566,7 @@ void QWindowsWindow::setVisible(bool visible) // over the rendering of the window // There is nobody waiting for this, so we don't need to flush afterwards. if (isLayered()) - fireExpose(QRect(0, 0, win->width(), win->height())); + fireFullExpose(); // QTBUG-44928, QTBUG-7386: This is to resolve the problem where popups are // opened from the system tray and not being implicitly activated @@ -1900,12 +1909,13 @@ void QWindowsWindow::handleResized(int wParam) handleWindowStateChange(m_windowState | Qt::WindowMinimized); return; case SIZE_MAXIMIZED: + handleGeometryChange(); if (!testFlag(WithinSetStyle) && !testFlag(WithinSetGeometry)) handleWindowStateChange(Qt::WindowMaximized | (isFullScreen_sys() ? Qt::WindowFullScreen : Qt::WindowNoState)); - handleGeometryChange(); break; case SIZE_RESTORED: + handleGeometryChange(); if (!testFlag(WithinSetStyle) && !testFlag(WithinSetGeometry)) { if (isFullScreen_sys()) handleWindowStateChange( @@ -1914,7 +1924,6 @@ void QWindowsWindow::handleResized(int wParam) else if (m_windowState != Qt::WindowNoState && !testFlag(MaximizeToFullScreen)) handleWindowStateChange(Qt::WindowNoState); } - handleGeometryChange(); break; } } @@ -1962,7 +1971,7 @@ void QWindowsWindow::handleGeometryChange() && m_data.geometry.size() != previousGeometry.size() // Exclude plain move // One dimension grew -> Windows will send expose, no need to synthesize. && !(m_data.geometry.width() > previousGeometry.width() || m_data.geometry.height() > previousGeometry.height())) { - fireExpose(QRect(QPoint(0, 0), m_data.geometry.size()), true); + fireFullExpose(true); } const bool wasSync = testFlag(SynchronousGeometryChangeEvent); @@ -2161,7 +2170,7 @@ void QWindowsWindow::handleWindowStateChange(Qt::WindowStates state) QWindow *w = window(); bool exposeEventsSent = false; if (isLayered()) { - fireExpose(QRegion(0, 0, w->width(), w->height())); + fireFullExpose(); exposeEventsSent = true; } const QWindowList allWindows = QGuiApplication::allWindows(); @@ -2169,7 +2178,7 @@ void QWindowsWindow::handleWindowStateChange(Qt::WindowStates state) if (child != w && child->isVisible() && child->transientParent() == w) { QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(child); if (platformWindow && platformWindow->isLayered()) { - platformWindow->fireExpose(QRegion(0, 0, child->width(), child->height())); + platformWindow->fireFullExpose(); exposeEventsSent = true; } } @@ -2283,8 +2292,10 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowStates newState) if (!screen) screen = QGuiApplication::primaryScreen(); // That area of the virtual desktop might not be covered by a screen anymore. - if (!screen->geometry().intersects(m_savedFrameGeometry)) - m_savedFrameGeometry.moveTo(screen->geometry().topLeft()); + if (const auto platformScreen = screen->handle()) { + if (!platformScreen->geometry().intersects(m_savedFrameGeometry)) + m_savedFrameGeometry.moveTo(platformScreen->geometry().topLeft()); + } if (newState & Qt::WindowMinimized) { setMinimizedGeometry(m_data.hwnd, m_savedFrameGeometry); @@ -2602,37 +2613,41 @@ bool QWindowsWindow::setMouseGrabEnabled(bool grab) return grab; } -static inline DWORD cornerToWinOrientation(Qt::Corner corner) +static inline DWORD edgesToWinOrientation(Qt::Edges edges) { - switch (corner) { - case Qt::TopLeftCorner: - return 0xf004; // SZ_SIZETOPLEFT; - case Qt::TopRightCorner: - return 0xf005; // SZ_SIZETOPRIGHT - case Qt::BottomLeftCorner: - return 0xf007; // SZ_SIZEBOTTOMLEFT - case Qt::BottomRightCorner: - return 0xf008; // SZ_SIZEBOTTOMRIGHT - } - return 0; + if (edges == Qt::LeftEdge) + return 0xf001; // SC_SIZELEFT; + else if (edges == (Qt::RightEdge)) + return 0xf002; // SC_SIZERIGHT + else if (edges == (Qt::TopEdge)) + return 0xf003; // SC_SIZETOP + else if (edges == (Qt::TopEdge | Qt::LeftEdge)) + return 0xf004; // SC_SIZETOPLEFT + else if (edges == (Qt::TopEdge | Qt::RightEdge)) + return 0xf005; // SC_SIZETOPRIGHT + else if (edges == (Qt::BottomEdge)) + return 0xf006; // SC_SIZEBOTTOM + else if (edges == (Qt::BottomEdge | Qt::LeftEdge)) + return 0xf007; // SC_SIZEBOTTOMLEFT + else if (edges == (Qt::BottomEdge | Qt::RightEdge)) + return 0xf008; // SC_SIZEBOTTOMRIGHT + + return 0xf000; // SC_SIZE } -bool QWindowsWindow::startSystemResize(const QPoint &, Qt::Corner corner) +bool QWindowsWindow::startSystemResize(Qt::Edges edges) { - if (!GetSystemMenu(m_data.hwnd, FALSE)) + if (Q_UNLIKELY(window()->flags().testFlag(Qt::MSWindowsFixedSizeDialogHint))) return false; ReleaseCapture(); - PostMessage(m_data.hwnd, WM_SYSCOMMAND, cornerToWinOrientation(corner), 0); + PostMessage(m_data.hwnd, WM_SYSCOMMAND, edgesToWinOrientation(edges), 0); setFlag(SizeGripOperation); return true; } -bool QWindowsWindow::startSystemMove(const QPoint &) +bool QWindowsWindow::startSystemMove() { - if (!GetSystemMenu(m_data.hwnd, FALSE)) - return false; - ReleaseCapture(); PostMessage(m_data.hwnd, WM_SYSCOMMAND, 0xF012 /*SC_DRAGMOVE*/, 0); return true; @@ -2901,6 +2916,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(); diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index aaf02d2a81..cd6179bf03 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -277,8 +277,8 @@ public: bool setMouseGrabEnabled(bool grab) override; inline bool hasMouseCapture() const { return GetCapture() == m_data.hwnd; } - bool startSystemResize(const QPoint &pos, Qt::Corner corner) override; - bool startSystemMove(const QPoint &pos) override; + bool startSystemResize(Qt::Edges edges) override; + bool startSystemMove() override; void setFrameStrutEventsEnabled(bool enabled) override; bool frameStrutEventsEnabled() const override { return testFlag(FrameStrutEventsEnabled); } @@ -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); @@ -370,6 +373,7 @@ private: void handleWindowStateChange(Qt::WindowStates state); inline void destroyIcon(); void fireExpose(const QRegion ®ion, bool force=false); + void fireFullExpose(bool force=false); void calculateFullFrameMargins(); mutable QWindowsWindowData m_data; diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp index c89dea3dfb..3962d2d27f 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp @@ -166,11 +166,27 @@ void QWindowsUiaMainProvider::notifyValueChange(QAccessibleValueChangeEvent *eve } if (event->value().type() == QVariant::String) { if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) { - // Notifies changes in string values. - VARIANT oldVal, newVal; - clearVariant(&oldVal); - setVariantString(event->value().toString(), &newVal); - QWindowsUiaWrapper::instance()->raiseAutomationPropertyChangedEvent(provider, UIA_ValueValuePropertyId, oldVal, newVal); + + // Tries to notify the change using UiaRaiseNotificationEvent(), which is only available on + // Windows 10 version 1709 or newer. Otherwise uses UiaRaiseAutomationPropertyChangedEvent(). + + BSTR displayString = bStrFromQString(event->value().toString()); + BSTR activityId = bStrFromQString(QString()); + + HRESULT hr = QWindowsUiaWrapper::instance()->raiseNotificationEvent(provider, NotificationKind_Other, + NotificationProcessing_ImportantMostRecent, + displayString, activityId); + + ::SysFreeString(displayString); + ::SysFreeString(activityId); + + if (hr == static_cast<HRESULT>(UIA_E_NOTSUPPORTED)) { + VARIANT oldVal, newVal; + clearVariant(&oldVal); + setVariantString(event->value().toString(), &newVal); + QWindowsUiaWrapper::instance()->raiseAutomationPropertyChangedEvent(provider, UIA_ValueValuePropertyId, oldVal, newVal); + ::SysFreeString(newVal.bstrVal); + } } } else if (QAccessibleValueInterface *valueInterface = accessible->valueInterface()) { if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) { @@ -289,11 +305,9 @@ HRESULT QWindowsUiaMainProvider::GetPatternProvider(PATTERNID idPattern, IUnknow } break; case UIA_TogglePatternId: - // Checkbox controls. - if (accessible->role() == QAccessible::CheckBox - || (accessible->role() == QAccessible::MenuItem && accessible->state().checkable)) { + // Checkboxes and other checkable controls. + if (accessible->state().checkable) *pRetVal = new QWindowsUiaToggleProvider(id()); - } break; case UIA_SelectionPatternId: // Lists of items. @@ -402,12 +416,14 @@ HRESULT QWindowsUiaMainProvider::GetPropertyValue(PROPERTYID idProp, VARIANT *pR // Control type converted from role. auto controlType = roleToControlTypeId(accessible->role()); - // The native OSK should be disbled if the Qt OSK is in use. + // The native OSK should be disbled if the Qt OSK is in use, + // or if disabled via application attribute. static bool imModuleEmpty = qEnvironmentVariableIsEmpty("QT_IM_MODULE"); + bool nativeVKDisabled = QCoreApplication::testAttribute(Qt::AA_DisableNativeVirtualKeyboard); // If we want to disable the native OSK auto-showing // we have to report text fields as non-editable. - if (controlType == UIA_EditControlTypeId && !imModuleEmpty) + if (controlType == UIA_EditControlTypeId && (!imModuleEmpty || nativeVKDisabled)) controlType = UIA_TextControlTypeId; setVariantI4(controlType, pRetVal); @@ -455,6 +471,10 @@ HRESULT QWindowsUiaMainProvider::GetPropertyValue(PROPERTYID idProp, VARIANT *pR setVariantBool(wt == Qt::Popup || wt == Qt::ToolTip || wt == Qt::SplashScreen, pRetVal); } break; + case UIA_IsDialogPropertyId: + setVariantBool(accessible->role() == QAccessible::Dialog + || accessible->role() == QAccessible::AlertMessage, pRetVal); + break; case UIA_FullDescriptionPropertyId: setVariantString(accessible->text(QAccessible::Description), pRetVal); break; @@ -482,7 +502,7 @@ QString QWindowsUiaMainProvider::automationIdForAccessible(const QAccessibleInte if (name.isEmpty()) return QString(); if (!result.isEmpty()) - result.prepend(QLatin1Char('.')); + result.prepend(u'.'); result.prepend(name); obj = obj->parent(); } diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.cpp index 3305e9c5c4..fb41012cf4 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.cpp +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.cpp @@ -49,6 +49,7 @@ #include <QtCore/qloggingcategory.h> #include <QtCore/qstring.h> #include <QtCore/qlist.h> +#include <QtCore/qvector.h> QT_BEGIN_NAMESPACE @@ -78,7 +79,7 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::GetSelection(SAFEARRAY * return UIA_E_ELEMENTNOTAVAILABLE; // First put selected items in a list, then build a safe array with the right size. - QList<QAccessibleInterface *> selectedList; + QVector<QAccessibleInterface *> selectedList; for (int i = 0; i < accessible->childCount(); ++i) { if (QAccessibleInterface *child = accessible->child(i)) { if (child->state().selected) { diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.cpp index 2a94012590..1348ec7cc0 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.cpp +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.cpp @@ -80,7 +80,7 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaTableItemProvider::GetRowHeaderItems(SAFEAR if (!tableCellInterface) return UIA_E_ELEMENTNOTAVAILABLE; - QList<QAccessibleInterface *> headers = tableCellInterface->rowHeaderCells(); + const auto headers = tableCellInterface->rowHeaderCells(); if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, headers.size()))) { for (LONG i = 0; i < headers.size(); ++i) { @@ -110,7 +110,7 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaTableItemProvider::GetColumnHeaderItems(SAF if (!tableCellInterface) return UIA_E_ELEMENTNOTAVAILABLE; - QList<QAccessibleInterface *> headers = tableCellInterface->columnHeaderCells(); + const auto headers = tableCellInterface->columnHeaderCells(); if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, headers.size()))) { for (LONG i = 0; i < headers.size(); ++i) { diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp index ab04384616..682b8c19c0 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp @@ -161,7 +161,7 @@ long roleToControlTypeId(QAccessible::Role role) {QAccessible::Sound, UIA_CustomControlTypeId}, {QAccessible::Cursor, UIA_CustomControlTypeId}, {QAccessible::Caret, UIA_CustomControlTypeId}, - {QAccessible::AlertMessage, UIA_CustomControlTypeId}, + {QAccessible::AlertMessage, UIA_WindowControlTypeId}, {QAccessible::Window, UIA_WindowControlTypeId}, {QAccessible::Client, UIA_GroupControlTypeId}, {QAccessible::PopupMenu, UIA_MenuControlTypeId}, |