diff options
22 files changed, 197 insertions, 138 deletions
diff --git a/src/corelib/kernel/qobject_impl.h b/src/corelib/kernel/qobject_impl.h index b57d7e50ccd..34e6bd84f3f 100644 --- a/src/corelib/kernel/qobject_impl.h +++ b/src/corelib/kernel/qobject_impl.h @@ -1,8 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only -#ifndef Q_QDOC - #ifndef QOBJECT_H #error Do not include qobject_impl.h directly #endif @@ -41,5 +39,3 @@ namespace QtPrivate { QT_END_NAMESPACE - -#endif diff --git a/src/corelib/platform/wasm/qwasmsuspendresumecontrol.cpp b/src/corelib/platform/wasm/qwasmsuspendresumecontrol.cpp index a081edcf542..5fe92926240 100644 --- a/src/corelib/platform/wasm/qwasmsuspendresumecontrol.cpp +++ b/src/corelib/platform/wasm/qwasmsuspendresumecontrol.cpp @@ -77,32 +77,20 @@ void qtRegisterEventHandlerJs(int index) { }[name]; } - function deepShallowClone(parent, obj, depth) { + function deepShallowClone(obj) { if (obj === null) return obj; - if (typeof obj === 'function') { - if (obj.name !== "") - return createNamedFunction(obj.name, parent, obj); - } - - if (depth >= 1) - return obj; - - if (typeof obj !== 'object') + if (!(obj instanceof Event)) return obj; - if (Array.isArray(obj)) { - const arrCopy = []; - for (let i = 0; i < obj.length; i++) - arrCopy[i] = deepShallowClone(obj, obj[i], depth + 1); - - return arrCopy; - } - const objCopy = {}; - for (const key in obj) - objCopy[key] = deepShallowClone(obj, obj[key], depth + 1); + for (const key in obj) { + if (typeof obj[key] === 'function') + objCopy[key] = createNamedFunction(obj[key].name, obj, obj[key]); + else + objCopy[key] = obj[key]; + } return objCopy; } @@ -112,7 +100,7 @@ void qtRegisterEventHandlerJs(int index) { let handler = (arg) => { // Copy the top level object, alias the rest. // functions are copied by creating new forwarding functions. - arg = deepShallowClone(arg, arg, 0); + arg = deepShallowClone(arg); // Add event to event queue control.pendingEvents.push({ diff --git a/src/corelib/text/qlocale_icu.cpp b/src/corelib/text/qlocale_icu.cpp index a10ae1c84b2..7e1dba5ee92 100644 --- a/src/corelib/text/qlocale_icu.cpp +++ b/src/corelib/text/qlocale_icu.cpp @@ -17,10 +17,10 @@ static_assert(std::is_same_v<UChar, char16_t>, namespace QtIcuPrivate { -enum class CaseConversion : bool { Upper, Lower }; +enum class IcuCaseConversion : bool { Upper, Lower }; static bool qt_u_strToCase(const QString &str, QString *out, const char *localeID, - CaseConversion conv) + IcuCaseConversion conv) { Q_ASSERT(out); @@ -34,9 +34,9 @@ static bool qt_u_strToCase(const QString &str, QString *out, const char *localeI // try to be a completely transparent wrapper: using R [[maybe_unused]] = decltype(u_strToUpper(std::forward<decltype(args)>(args)...)); switch (conv) { - case CaseConversion::Upper: + case IcuCaseConversion::Upper: return u_strToUpper(std::forward<decltype(args)>(args)...); - case CaseConversion::Lower: + case IcuCaseConversion::Lower: return u_strToLower(std::forward<decltype(args)>(args)...); }; Q_UNREACHABLE_RETURN(R{0}); @@ -79,7 +79,7 @@ QString QLocalePrivate::toUpper(const QString &str, bool *ok) const Q_ASSERT(ok); using namespace QtIcuPrivate; QString out; - *ok = qt_u_strToCase(str, &out, bcp47Name('_'), CaseConversion::Upper); + *ok = qt_u_strToCase(str, &out, bcp47Name('_'), IcuCaseConversion::Upper); return out; } @@ -88,7 +88,7 @@ QString QLocalePrivate::toLower(const QString &str, bool *ok) const Q_ASSERT(ok); using namespace QtIcuPrivate; QString out; - *ok = qt_u_strToCase(str, &out, bcp47Name('_'), CaseConversion::Lower); + *ok = qt_u_strToCase(str, &out, bcp47Name('_'), IcuCaseConversion::Lower); return out; } diff --git a/src/gui/painting/qcolorspace.cpp b/src/gui/painting/qcolorspace.cpp index c43d133dd1e..9149971b999 100644 --- a/src/gui/painting/qcolorspace.cpp +++ b/src/gui/painting/qcolorspace.cpp @@ -1206,12 +1206,12 @@ QByteArray QColorSpace::iccProfile() const QColorSpace QColorSpace::fromIccProfile(const QByteArray &iccProfile) { // Must detach if input is fromRawData(); nullTerminated() is trick to do that and nothing else - const QByteArray ownedIccProfile(iccProfile.nullTerminated()); + QByteArray ownedIccProfile = iccProfile.nullTerminated(); QColorSpace colorSpace; if (QIcc::fromIccProfile(ownedIccProfile, &colorSpace)) return colorSpace; colorSpace.detach(); - colorSpace.d_ptr->iccProfile = ownedIccProfile; + colorSpace.d_ptr->iccProfile = std::move(ownedIccProfile); return colorSpace; } diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index a3f9f069b69..2b6a8a858f9 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -6474,8 +6474,9 @@ QRectF QPainter::boundingRect(const QRectF &r, const QString &text, const QTextO and height (on both 1x and 2x displays), and produces high-resolution output on 2x displays. - The \a position offset is always in the painter coordinate system, - indepentent of display devicePixelRatio. + The \a position offset is provided in the device independent pixels + relative to the top-left corner of the \a rectangle. The \a position + can be used to align the repeating pattern inside the \a rectangle. \sa drawPixmap() */ @@ -6497,8 +6498,8 @@ void QPainter::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPo qt_painter_thread_test(d->device->devType(), d->engine->type(), "drawTiledPixmap()"); #endif - qreal sw = pixmap.width(); - qreal sh = pixmap.height(); + const qreal sw = pixmap.width() / pixmap.devicePixelRatio(); + const qreal sh = pixmap.height() / pixmap.devicePixelRatio(); qreal sx = sp.x(); qreal sy = sp.y(); if (sx < 0) @@ -6579,8 +6580,12 @@ void QPainter::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPo (\a{x}, \a{y}) specifies the top-left point in the paint device that is to be drawn onto; with the given \a width and \a - height. (\a{sx}, \a{sy}) specifies the top-left point in the \a - pixmap that is to be drawn; this defaults to (0, 0). + height. + + (\a{sx}, \a{sy}) specifies the origin inside the specified rectangle + where the pixmap will be drawn. The origin position is specified in + the device independent pixels relative to (\a{x}, \a{y}). This defaults + to (0, 0). */ #ifndef QT_NO_PICTURE diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index 4c4e5fac962..52540666718 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -733,6 +733,26 @@ bool QCocoaFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModalit return false; } + if (qt_apple_isSandboxed()) { + static bool canRead = qt_mac_processHasEntitlement( + u"com.apple.security.files.user-selected.read-only"_s); + static bool canReadWrite = qt_mac_processHasEntitlement( + u"com.apple.security.files.user-selected.read-write"_s); + + if (options()->acceptMode() == QFileDialogOptions::AcceptSave + && !canReadWrite) { + qWarning() << "Sandboxed application is missing user-selected files" + << "read-write entitlement. Falling back to non-native dialog"; + return false; + } + + if (!canReadWrite && !canRead) { + qWarning() << "Sandboxed application is missing user-selected files" + << "entitlement. Falling back to non-native dialog"; + return false; + } + } + createNSOpenSavePanelDelegate(); return [m_delegate showPanel:windowModality withParent:parent]; diff --git a/src/plugins/platforms/wasm/qwasminputcontext.cpp b/src/plugins/platforms/wasm/qwasminputcontext.cpp index a0546fdc215..6dfb4284149 100644 --- a/src/plugins/platforms/wasm/qwasminputcontext.cpp +++ b/src/plugins/platforms/wasm/qwasminputcontext.cpp @@ -24,13 +24,13 @@ using namespace qstdweb; void QWasmInputContext::inputCallback(emscripten::val event) { - qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO << "isComposing : " << event["isComposing"].as<bool>(); - emscripten::val inputType = event["inputType"]; if (inputType.isNull() || inputType.isUndefined()) return; const auto inputTypeString = inputType.as<std::string>(); + // also may be dataTransfer + // containing rich text emscripten::val inputData = event["data"]; QString inputStr = (!inputData.isNull() && !inputData.isUndefined()) ? QString::fromEcmaString(inputData) : QString(); @@ -44,10 +44,10 @@ void QWasmInputContext::inputCallback(emscripten::val event) QInputMethodQueryEvent queryEvent(Qt::ImQueryAll); QCoreApplication::sendEvent(m_focusObject, &queryEvent); int cursorPosition = queryEvent.value(Qt::ImCursorPosition).toInt(); - int deleteLength = rangesPair.second - rangesPair.first; int deleteFrom = -1; - if (cursorPosition > rangesPair.first) { + + if (cursorPosition >= rangesPair.first) { deleteFrom = -(cursorPosition - rangesPair.first); } QInputMethodEvent e; @@ -65,21 +65,55 @@ void QWasmInputContext::inputCallback(emscripten::val event) event.call<void>("stopImmediatePropagation"); return; } else if (!inputTypeString.compare("insertCompositionText")) { - qCDebug(qLcQpaWasmInputContext) << "inputString : " << inputStr; - insertPreedit(); + qCDebug(qLcQpaWasmInputContext) << "insertCompositionText : " << inputStr; + event.call<void>("stopImmediatePropagation"); + + QInputMethodQueryEvent queryEvent(Qt::ImQueryAll); + QCoreApplication::sendEvent(m_focusObject, &queryEvent); + + int qCursorPosition = queryEvent.value(Qt::ImCursorPosition).toInt() ; + int replaceIndex = (qCursorPosition - rangesPair.first); + int replaceLength = rangesPair.second - rangesPair.first; + + setPreeditString(inputStr, replaceIndex); + insertPreedit(replaceLength); + + rangesPair.first = 0; + rangesPair.second = 0; event.call<void>("stopImmediatePropagation"); return; } else if (!inputTypeString.compare("insertReplacementText")) { - qCDebug(qLcQpaWasmInputContext) << "inputString : " << inputStr; - //auto ranges = event.call<emscripten::val>("getTargetRanges"); - //qCDebug(qLcQpaWasmInputContext) << ranges["length"].as<int>(); - // WA For Korean IME - // insertReplacementText should have targetRanges but - // Safari cannot have it and just it seems to be supposed - // to replace previous input. - insertText(inputStr, true); + // the previous input string up to the space, needs replaced with this + // used on iOS when continuing composition after focus change + // there's no range given + + qCDebug(qLcQpaWasmInputContext) << "insertReplacementText >>>>" << "inputString : " << inputStr; + emscripten::val ranges = event.call<emscripten::val>("getTargetRanges"); + + m_preeditString.clear(); + std::string elementString = m_inputElement["value"].as<std::string>(); + QInputMethodQueryEvent queryEvent(Qt::ImQueryAll); + QCoreApplication::sendEvent(m_focusObject, &queryEvent); + QString textFieldString = queryEvent.value(Qt::ImTextBeforeCursor).toString(); + int qCursorPosition = queryEvent.value(Qt::ImCursorPosition).toInt(); + + if (rangesPair.first != 0 || rangesPair.second != 0) { + + int replaceIndex = (qCursorPosition - rangesPair.first); + int replaceLength = rangesPair.second - rangesPair.first; + replaceText(inputStr, -replaceIndex, replaceLength); + rangesPair.first = 0; + rangesPair.second = 0; + + } else { + int spaceIndex = textFieldString.lastIndexOf(' ') + 1; + int replaceIndex = (qCursorPosition - spaceIndex); + + replaceText(inputStr, -replaceIndex, replaceIndex); + } event.call<void>("stopImmediatePropagation"); + return; } else if (!inputTypeString.compare("deleteCompositionText")) { setPreeditString("", 0); @@ -92,7 +126,25 @@ void QWasmInputContext::inputCallback(emscripten::val event) event.call<void>("stopImmediatePropagation"); return; } else if (!inputTypeString.compare("insertText")) { - insertText(inputStr); + if ((rangesPair.first != 0 || rangesPair.second != 0) + && rangesPair.first != rangesPair.second) { + + QInputMethodQueryEvent queryEvent(Qt::ImQueryAll); + QCoreApplication::sendEvent(m_focusObject, &queryEvent); + + int qCursorPosition = queryEvent.value(Qt::ImCursorPosition).toInt(); + int replaceIndex = (qCursorPosition - rangesPair.first); + int replaceLength = rangesPair.second - rangesPair.first; + + replaceText(inputStr, -replaceIndex, replaceLength); + + rangesPair.first = 0; + rangesPair.second = 0; + + } else { + insertText(inputStr); + } + event.call<void>("stopImmediatePropagation"); #if QT_CONFIG(clipboard) } else if (!inputTypeString.compare("insertFromPaste")) { @@ -112,9 +164,8 @@ void QWasmInputContext::inputCallback(emscripten::val event) void QWasmInputContext::compositionEndCallback(emscripten::val event) { const auto inputStr = QString::fromEcmaString(event["data"]); - qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO << inputStr; - if (preeditString().isEmpty()) + if (preeditString().isEmpty()) // we get final results from inputCallback return; if (inputStr != preeditString()) { @@ -127,27 +178,11 @@ void QWasmInputContext::compositionEndCallback(emscripten::val event) void QWasmInputContext::compositionStartCallback(emscripten::val event) { - Q_UNUSED(event); - qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO; + Q_UNUSED(event); // Do nothing when starting composition } -/* -// Test implementation -static void beforeInputCallback(emscripten::val event) -{ - qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO; - - auto ranges = event.call<emscripten::val>("getTargetRanges"); - auto length = ranges["length"].as<int>(); - for (auto i = 0; i < length; i++) { - qCDebug(qLcQpaWasmInputContext) << ranges.call<emscripten::val>("get", i)["startOffset"].as<int>(); - qCDebug(qLcQpaWasmInputContext) << ranges.call<emscripten::val>("get", i)["endOffset"].as<int>(); - } -} -*/ - void QWasmInputContext::compositionUpdateCallback(emscripten::val event) { const auto compositionStr = QString::fromEcmaString(event["data"]); @@ -317,18 +352,21 @@ void QWasmInputContext::hideInputPanel() void QWasmInputContext::setPreeditString(QString preeditStr, int replaceSize) { + qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO << preeditStr << replaceSize; m_preeditString = preeditStr; - m_replaceSize = replaceSize; + m_replaceIndex = replaceSize; } -void QWasmInputContext::insertPreedit() +void QWasmInputContext::insertPreedit(int replaceLength) { qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO << m_preeditString; + if (replaceLength == 0) + replaceLength = m_preeditString.length(); QList<QInputMethodEvent::Attribute> attributes; { QInputMethodEvent::Attribute attr_cursor(QInputMethodEvent::Cursor, - m_preeditString.length(), + 0, 1); attributes.append(attr_cursor); @@ -336,21 +374,19 @@ void QWasmInputContext::insertPreedit() format.setFontUnderline(true); format.setUnderlineStyle(QTextCharFormat::SingleUnderline); QInputMethodEvent::Attribute attr_format(QInputMethodEvent::TextFormat, - 0, - m_preeditString.length(), format); + 0, + replaceLength, format); attributes.append(attr_format); } QInputMethodEvent e(m_preeditString, attributes); - if (m_replaceSize > 0) - e.setCommitString("", -m_replaceSize, m_replaceSize); + if (m_replaceIndex > 0) + e.setCommitString("", -m_replaceIndex, replaceLength); QCoreApplication::sendEvent(m_focusObject, &e); } void QWasmInputContext::commitPreeditAndClear() { - qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO << m_preeditString; - if (m_preeditString.isEmpty()) return; QInputMethodEvent e; @@ -360,7 +396,8 @@ void QWasmInputContext::commitPreeditAndClear() } void QWasmInputContext::insertText(QString inputStr, bool replace) -{ +{ // commitString + qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO << inputStr << replace; Q_UNUSED(replace); if (!inputStr.isEmpty()) { const int replaceLen = 0; @@ -370,4 +407,35 @@ void QWasmInputContext::insertText(QString inputStr, bool replace) } } +/* This will replace the text in the focusobject at replaceFrom position, and replaceSize length + with the text in inputStr. */ + + void QWasmInputContext::replaceText(QString inputStr, int replaceFrom, int replaceSize) + { + qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO << inputStr << replaceFrom << replaceSize; + + QList<QInputMethodEvent::Attribute> attributes; + { + QInputMethodEvent::Attribute attr_cursor(QInputMethodEvent::Cursor, + 0, // start + 1); // length + attributes.append(attr_cursor); + + QTextCharFormat format; + format.setFontUnderline(true); + format.setUnderlineStyle(QTextCharFormat::SingleUnderline); + QInputMethodEvent::Attribute attr_format(QInputMethodEvent::TextFormat, + 0, + replaceSize, + format); + attributes.append(attr_format); + } + + QInputMethodEvent e1(QString(), attributes); + e1.setCommitString(inputStr, replaceFrom, replaceSize); + QCoreApplication::sendEvent(m_focusObject, &e1); + + m_preeditString.clear(); + } + QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/qwasminputcontext.h b/src/plugins/platforms/wasm/qwasminputcontext.h index 97415451b2a..006a03455d7 100644 --- a/src/plugins/platforms/wasm/qwasminputcontext.h +++ b/src/plugins/platforms/wasm/qwasminputcontext.h @@ -33,10 +33,11 @@ public: const QString preeditString() { return m_preeditString; } void setPreeditString(QString preeditStr, int replaceSize); - void insertPreedit(); + void insertPreedit(int repalcementLength = 0); void commitPreeditAndClear(); void insertText(QString inputStr, bool replace = false); + void replaceText(QString inputString, int replaceFrom, int replaceSize); bool usingTextInput() const { return m_inputMethodAccepted; } void setFocusObject(QObject *object) override; @@ -58,7 +59,7 @@ private: private: QString m_preeditString; - int m_replaceSize = 0; + int m_replaceIndex = 0; bool m_inputMethodAccepted = false; QObject *m_focusObject = nullptr; diff --git a/src/plugins/platforms/wasm/qwasmwindow.cpp b/src/plugins/platforms/wasm/qwasmwindow.cpp index a88299975d0..d318c977a90 100644 --- a/src/plugins/platforms/wasm/qwasmwindow.cpp +++ b/src/plugins/platforms/wasm/qwasmwindow.cpp @@ -761,12 +761,10 @@ void QWasmWindow::handleCompositionEndEvent(emscripten::val event) void QWasmWindow::handleBeforeInputEvent(emscripten::val event) { - qWarning() << Q_FUNC_INFO; - if (QWasmInputContext *inputContext = QWasmIntegration::get()->wasmInputContext(); inputContext->isActive()) inputContext->beforeInputCallback(event); - // else - // m_focusHelper.set("innerHTML", std::string()); + else + m_focusHelper.set("innerHTML", std::string()); } void QWasmWindow::handlePointerEnterLeaveEvent(const PointerEvent &event) diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 3013de1c068..156351987cb 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -696,7 +696,7 @@ HWND QWindowsContext::createDummyWindow(const QString &classNameIn, { if (!wndProc) wndProc = DefWindowProc; - QString className = d->m_windowClassRegistry.registerWindowClass(QWindowsWindowClassRegistry::classNamePrefix() + classNameIn, wndProc); + QString className = d->m_windowClassRegistry.registerWindowClass(classNameIn, wndProc); return CreateWindowEx(0, reinterpret_cast<LPCWSTR>(className.utf16()), windowName, style, CW_USEDEFAULT, CW_USEDEFAULT, diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp index 9139ec0c463..2bd2f0c9e3d 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -704,7 +704,7 @@ void QWindowsScreenManager::initialize() qCDebug(lcQpaScreen) << "Initializing screen manager"; auto className = QWindowsWindowClassRegistry::instance()->registerWindowClass( - QWindowsWindowClassRegistry::classNamePrefix() + QLatin1String("ScreenChangeObserverWindow"), + QLatin1String("ScreenChangeObserverWindow"), qDisplayChangeObserverWndProc); // HWND_MESSAGE windows do not get WM_DISPLAYCHANGE, so we need to create diff --git a/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp b/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp index a2ce1e86a4d..beeab1a089e 100644 --- a/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp +++ b/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp @@ -119,9 +119,9 @@ static inline HWND createTrayIconMessageWindow() if (!ctx) return nullptr; // Register window class in the platform plugin. - const QString className = - ctx->registerWindowClass(QWindowsWindowClassRegistry::classNamePrefix() + "TrayIconMessageWindowClass"_L1, - qWindowsTrayIconWndProc); + const QString className = ctx->registerWindowClass( + "TrayIconMessageWindowClass"_L1, + qWindowsTrayIconWndProc); const wchar_t windowName[] = L"QTrayIconMessageWindow"; return CreateWindowEx(0, reinterpret_cast<const wchar_t *>(className.utf16()), windowName, WS_OVERLAPPED, diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index 33d7c4124ac..d132bbb6130 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -549,7 +549,7 @@ QWindowsTheme::QWindowsTheme() refreshIconPixmapSizes(); auto className = QWindowsWindowClassRegistry::instance()->registerWindowClass( - QWindowsWindowClassRegistry::classNamePrefix() + QLatin1String("ThemeChangeObserverWindow"), + QLatin1String("ThemeChangeObserverWindow"), qThemeChangeObserverWndProc); // HWND_MESSAGE windows do not get the required theme events, // so we use a real top-level window that we never show. diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 26d0f907b92..ed391009423 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -887,9 +887,12 @@ QWindowsWindowData const auto appinst = reinterpret_cast<HINSTANCE>(GetModuleHandle(nullptr)); const QString windowClassName = QWindowsWindowClassRegistry::instance()->registerWindowClass(w); - const QString windowTitlebarName = QWindowsWindowClassRegistry::instance()->registerWindowClass({ - QStringLiteral("_q_titlebar"), DefWindowProc, CS_VREDRAW | CS_HREDRAW - }); + + QWindowsWindowClassDescription windowTitlebarDescription; + windowTitlebarDescription.name = QStringLiteral("_q_titlebar"); + windowTitlebarDescription.style = CS_VREDRAW | CS_HREDRAW; + windowTitlebarDescription.shouldAddPrefix = false; + const QString windowTitlebarName = QWindowsWindowClassRegistry::instance()->registerWindowClass(windowTitlebarDescription); const QScreen *screen{}; const QRect rect = QPlatformWindow::initialGeometry(w, data.geometry, diff --git a/src/plugins/platforms/windows/qwindowswindowclassdescription.cpp b/src/plugins/platforms/windows/qwindowswindowclassdescription.cpp index cb862bba47c..63e16260b62 100644 --- a/src/plugins/platforms/windows/qwindowswindowclassdescription.cpp +++ b/src/plugins/platforms/windows/qwindowswindowclassdescription.cpp @@ -49,8 +49,7 @@ QWindowsWindowClassDescription QWindowsWindowClassDescription::fromWindow(const break; } // Create a unique name for the flag combination - description.name = QWindowsWindowClassRegistry::classNamePrefix(); - description.name += "QWindow"_L1; + description.name = "QWindow"_L1; switch (type) { case Qt::Tool: description.name += "Tool"_L1; diff --git a/src/plugins/platforms/windows/qwindowswindowclassdescription.h b/src/plugins/platforms/windows/qwindowswindowclassdescription.h index ece48e4343c..9423abf9d2d 100644 --- a/src/plugins/platforms/windows/qwindowswindowclassdescription.h +++ b/src/plugins/platforms/windows/qwindowswindowclassdescription.h @@ -22,6 +22,7 @@ struct QWindowsWindowClassDescription unsigned int style{ 0 }; HBRUSH brush{ nullptr }; bool hasIcon{ false }; + bool shouldAddPrefix{ true }; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowswindowclassregistry.cpp b/src/plugins/platforms/windows/qwindowswindowclassregistry.cpp index e367350d55e..c330720a09c 100644 --- a/src/plugins/platforms/windows/qwindowswindowclassregistry.cpp +++ b/src/plugins/platforms/windows/qwindowswindowclassregistry.cpp @@ -59,6 +59,9 @@ QString QWindowsWindowClassRegistry::registerWindowClass(const QWindowsWindowCla { QString className = description.name; + if (description.shouldAddPrefix) + className = classNamePrefix() + className; + // since multiple Qt versions can be used in one process // each one has to have window class names with a unique name // The first instance gets the unmodified name; if the class diff --git a/src/plugins/platforms/windows/qwindowswindowclassregistry.h b/src/plugins/platforms/windows/qwindowswindowclassregistry.h index d1f10310dc8..c19b4f616fb 100644 --- a/src/plugins/platforms/windows/qwindowswindowclassregistry.h +++ b/src/plugins/platforms/windows/qwindowswindowclassregistry.h @@ -27,13 +27,13 @@ public: static QWindowsWindowClassRegistry *instance(); - static QString classNamePrefix(); - QString registerWindowClass(const QWindowsWindowClassDescription &description); QString registerWindowClass(const QWindow *window); QString registerWindowClass(QString name, WNDPROC procedure); private: + static QString classNamePrefix(); + void unregisterWindowClasses(); static QWindowsWindowClassRegistry *m_instance; diff --git a/src/plugins/styles/modernwindows/qwindows11style.cpp b/src/plugins/styles/modernwindows/qwindows11style.cpp index bf4b3c6a9bc..ffba4f775c8 100644 --- a/src/plugins/styles/modernwindows/qwindows11style.cpp +++ b/src/plugins/styles/modernwindows/qwindows11style.cpp @@ -24,6 +24,7 @@ #if QT_CONFIG(mdiarea) #include <QtWidgets/qmdiarea.h> #endif +#include <QtWidgets/qplaintextedit.h> #include <QtWidgets/qtextedit.h> #include <QtWidgets/qtreeview.h> #if QT_CONFIG(datetimeedit) @@ -1027,7 +1028,9 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption if (frame->frameShape == QFrame::NoFrame) break; - drawLineEditFrame(painter, rect, option, qobject_cast<const QTextEdit *>(widget) != nullptr); + const bool isEditable = qobject_cast<const QTextEdit *>(widget) != nullptr + || qobject_cast<const QPlainTextEdit *>(widget) != nullptr; + drawLineEditFrame(painter, rect, option, isEditable); } break; } @@ -1452,36 +1455,10 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op #endif // QT_CONFIG(progressbar) case CE_PushButtonLabel: if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) { - using namespace StyleOptionHelper; - const bool isEnabled = !isDisabled(option); - - QRect textRect = btn->rect.marginsRemoved(QMargins(contentHMargin, 0, contentHMargin, 0)); - int tf = Qt::AlignCenter | Qt::TextShowMnemonic; - if (!proxy()->styleHint(SH_UnderlineShortcut, btn, widget)) - tf |= Qt::TextHideMnemonic; - - if (!btn->icon.isNull()) { - //Center both icon and text - QIcon::Mode mode = isEnabled ? QIcon::Normal : QIcon::Disabled; - if (mode == QIcon::Normal && btn->state & State_HasFocus) - mode = QIcon::Active; - QIcon::State state = isChecked(btn) ? QIcon::On : QIcon::Off; - - int iconSpacing = 4;//### 4 is currently hardcoded in QPushButton::sizeHint() - - QRect iconRect = QRect(textRect.x(), textRect.y(), btn->iconSize.width(), textRect.height()); - QRect vIconRect = visualRect(btn->direction, btn->rect, iconRect); - textRect.setLeft(textRect.left() + iconRect.width() + iconSpacing); - - if (isChecked(btn) || isPressed(btn)) - vIconRect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, option, widget), - proxy()->pixelMetric(PM_ButtonShiftVertical, option, widget)); - btn->icon.paint(painter, vIconRect, Qt::AlignCenter, mode, state); - } - - auto vTextRect = visualRect(btn->direction, btn->rect, textRect); - painter->setPen(controlTextColor(option)); - proxy()->drawItemText(painter, vTextRect, tf, option->palette, isEnabled, btn->text); + QStyleOptionButton btnCopy(*btn); + btnCopy.rect = btn->rect.marginsRemoved(QMargins(contentHMargin, 0, contentHMargin, 0)); + btnCopy.palette.setBrush(QPalette::ButtonText, controlTextColor(option)); + QCommonStyle::drawControl(element, &btnCopy, painter, widget); } break; case CE_PushButtonBevel: @@ -2625,7 +2602,7 @@ QIcon QWindows11Style::standardIcon(StandardPixmap standardIcon, switch (standardIcon) { case SP_LineEditClearButton: { if (d->m_lineEditClearButton.isNull()) { - auto e = new WinFontIconEngine(Clear.at(0), d->assetFont); + auto e = new WinFontIconEngine(Clear, d->assetFont); d->m_lineEditClearButton = QIcon(e); } return d->m_lineEditClearButton; diff --git a/tests/auto/tools/moc/allmocs_baseline_in.json b/tests/auto/tools/moc/allmocs_baseline_in.json index 363ade3d53c..d8e6c4df538 100644 --- a/tests/auto/tools/moc/allmocs_baseline_in.json +++ b/tests/auto/tools/moc/allmocs_baseline_in.json @@ -2501,7 +2501,7 @@ { "isClass": false, "isFlag": false, - "lineNumber": 14, + "lineNumber": 13, "name": "SomeEnum", "values": [ "SomeEnumValue" diff --git a/tests/auto/tools/moc/related-metaobjects-in-namespaces.h b/tests/auto/tools/moc/related-metaobjects-in-namespaces.h index efd82107673..2513094ed0c 100644 --- a/tests/auto/tools/moc/related-metaobjects-in-namespaces.h +++ b/tests/auto/tools/moc/related-metaobjects-in-namespaces.h @@ -9,9 +9,9 @@ namespace QTBUG_2151 { class A : public QObject { Q_OBJECT - Q_ENUMS(SomeEnum) public: enum SomeEnum { SomeEnumValue = 0 }; + Q_ENUM(SomeEnum) }; class B : public QObject diff --git a/tests/auto/tools/moc/related-metaobjects-name-conflict.h b/tests/auto/tools/moc/related-metaobjects-name-conflict.h index cccd97e4e74..d88826f696a 100644 --- a/tests/auto/tools/moc/related-metaobjects-name-conflict.h +++ b/tests/auto/tools/moc/related-metaobjects-name-conflict.h @@ -9,15 +9,15 @@ #define DECLARE_GADGET_AND_OBJECT_CLASSES \ class Gadget { \ Q_GADGET \ - Q_ENUMS(SomeEnum) \ public: \ enum SomeEnum { SomeEnumValue = 0 }; \ + Q_ENUM(SomeEnum) \ }; \ class Object : public QObject{ \ Q_OBJECT \ - Q_ENUMS(SomeEnum) \ public: \ enum SomeEnum { SomeEnumValue = 0 }; \ + Q_ENUM(SomeEnum) \ }; #define DECLARE_DEPENDING_CLASSES \ |
