diff options
Diffstat (limited to 'src/plugins')
15 files changed, 287 insertions, 265 deletions
diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp index 028ae6d682a..6154f4121d2 100644 --- a/src/plugins/platforms/android/androidjniaccessibility.cpp +++ b/src/plugins/platforms/android/androidjniaccessibility.cpp @@ -726,9 +726,18 @@ namespace QtAndroidAccessibility break; } + float min = info.minValue.toFloat(); + float max = info.maxValue.toFloat(); + float current = info.currentValue.toFloat(); + if (info.role == QAccessible::ProgressBar) { + rangeType = 2; // RANGE_TYPE_PERCENT + current = 100 * (current - min) / (max - min); + min = 0.0f; + max = 100.0f; + } + QJniObject rangeInfo("android/view/accessibility/AccessibilityNodeInfo$RangeInfo", - "(IFFF)V", rangeType, info.minValue.toFloat(), - info.maxValue.toFloat(), info.currentValue.toFloat()); + "(IFFF)V", rangeType, min, max, current); if (rangeInfo.isValid()) { env->CallVoidMethod(node, m_setRangeInfoMethodID, rangeInfo.object()); diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp index c8555cdc659..f64742ff133 100644 --- a/src/plugins/platforms/android/qandroidplatformscreen.cpp +++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp @@ -291,7 +291,7 @@ void QAndroidPlatformScreen::topVisibleWindowChanged() if (w && w->handle()) { QAndroidPlatformWindow *platformWindow = static_cast<QAndroidPlatformWindow *>(w->handle()); if (platformWindow) { - platformWindow->updateSystemUiVisibility(); + platformWindow->updateSystemUiVisibility(w->windowStates(), w->flags()); platformWindow->updateFocusedEditText(); } } diff --git a/src/plugins/platforms/android/qandroidplatformwindow.cpp b/src/plugins/platforms/android/qandroidplatformwindow.cpp index 96c4bfa06f1..c4245998772 100644 --- a/src/plugins/platforms/android/qandroidplatformwindow.cpp +++ b/src/plugins/platforms/android/qandroidplatformwindow.cpp @@ -56,15 +56,12 @@ void QAndroidPlatformWindow::initialize() isForeignWindow(), m_nativeParentQtWindow, listener); m_nativeViewId = m_nativeQtWindow.callMethod<jint>("getId"); - m_windowFlags = Qt::Widget; - m_windowState = Qt::WindowNoState; // the surfaceType is overwritten in QAndroidPlatformOpenGLWindow ctor so let's save // the fact that it's a raster window for now m_isRaster = window->surfaceType() == QSurface::RasterSurface; - setWindowState(window->windowStates()); // the following is in relation to the virtual geometry - const bool forceMaximize = m_windowState & (Qt::WindowMaximized | Qt::WindowFullScreen); + const bool forceMaximize = window->windowStates() & (Qt::WindowMaximized | Qt::WindowFullScreen); const QRect nativeScreenGeometry = platformScreen()->availableGeometry(); if (forceMaximize) { setGeometry(nativeScreenGeometry); @@ -123,7 +120,7 @@ void QAndroidPlatformWindow::raise() QWindowSystemInterface::handleFocusWindowChanged(window(), Qt::ActiveWindowFocusReason); return; } - updateSystemUiVisibility(); + updateSystemUiVisibility(window()->windowStates(), window()->flags()); platformScreen()->raise(this); } @@ -167,13 +164,13 @@ void QAndroidPlatformWindow::setVisible(bool visible) if (!visible && window() == qGuiApp->focusWindow()) { platformScreen()->topVisibleWindowChanged(); } else { - updateSystemUiVisibility(); - if ((m_windowState & Qt::WindowFullScreen) - || (window()->flags() & Qt::ExpandedClientAreaHint)) { + const Qt::WindowStates states = window()->windowStates(); + const Qt::WindowFlags flags = window()->flags(); + updateSystemUiVisibility(states, flags); + if (states & Qt::WindowFullScreen || flags & Qt::ExpandedClientAreaHint) setGeometry(platformScreen()->geometry()); - } else if (m_windowState & Qt::WindowMaximized) { + else if (states & Qt::WindowMaximized) setGeometry(platformScreen()->availableGeometry()); - } requestActivateWindow(); } } @@ -188,27 +185,18 @@ void QAndroidPlatformWindow::setVisible(bool visible) void QAndroidPlatformWindow::setWindowState(Qt::WindowStates state) { - if (m_windowState == state) - return; - QPlatformWindow::setWindowState(state); - m_windowState = state; if (window()->isVisible()) - updateSystemUiVisibility(); + updateSystemUiVisibility(state, window()->flags()); } void QAndroidPlatformWindow::setWindowFlags(Qt::WindowFlags flags) { - if (m_windowFlags == flags) - return; + QPlatformWindow::setWindowFlags(flags); - m_windowFlags = flags; -} - -Qt::WindowFlags QAndroidPlatformWindow::windowFlags() const -{ - return m_windowFlags; + if (window()->isVisible()) + updateSystemUiVisibility(window()->windowStates(), flags); } void QAndroidPlatformWindow::setParent(const QPlatformWindow *window) @@ -256,16 +244,15 @@ void QAndroidPlatformWindow::requestActivateWindow() raise(); } -void QAndroidPlatformWindow::updateSystemUiVisibility() +void QAndroidPlatformWindow::updateSystemUiVisibility(Qt::WindowStates states, Qt::WindowFlags flags) { - const int flags = window()->flags(); const bool isNonRegularWindow = flags & (Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window; if (!isNonRegularWindow) { auto iface = qGuiApp->nativeInterface<QNativeInterface::QAndroidApplication>(); iface->runOnAndroidMainThread([=]() { using namespace QtJniTypes; auto activity = iface->context().object<Activity>(); - if (m_windowState & Qt::WindowFullScreen) + if (states & Qt::WindowFullScreen) QtWindowInsetsController::callStaticMethod("showFullScreen", activity); else if (flags & Qt::ExpandedClientAreaHint) QtWindowInsetsController::callStaticMethod("showExpanded", activity); diff --git a/src/plugins/platforms/android/qandroidplatformwindow.h b/src/plugins/platforms/android/qandroidplatformwindow.h index 07f4e12b35c..826a8d30ade 100644 --- a/src/plugins/platforms/android/qandroidplatformwindow.h +++ b/src/plugins/platforms/android/qandroidplatformwindow.h @@ -43,7 +43,6 @@ public: void setWindowState(Qt::WindowStates state) override; void setWindowFlags(Qt::WindowFlags flags) override; - Qt::WindowFlags windowFlags() const; void setParent(const QPlatformWindow *window) override; WId winId() const override; @@ -58,7 +57,7 @@ public: void propagateSizeHints() override; void requestActivateWindow() override; - void updateSystemUiVisibility(); + void updateSystemUiVisibility(Qt::WindowStates states, Qt::WindowFlags flags); void updateFocusedEditText(); inline bool isRaster() const { return m_isRaster; } bool isExposed() const override; @@ -82,8 +81,6 @@ protected: bool isEmbeddingContainer() const; virtual void clearSurface() {} - Qt::WindowFlags m_windowFlags; - Qt::WindowStates m_windowState; bool m_isRaster; int m_nativeViewId = -1; diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index d4c5d0f0425..e0ef6cec794 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -161,7 +161,8 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions; bool selectable = (m_options->acceptMode() == QFileDialogOptions::AcceptSave) || [self panel:m_panel shouldEnableURL:url]; - m_panel.nameFieldStringValue = selectable ? info.fileName().toNSString() : @""; + if (!openpanel_cast(m_panel)) + m_panel.nameFieldStringValue = selectable ? info.fileName().toNSString() : @""; [self updateProperties]; diff --git a/src/plugins/platforms/cocoa/qnsview_keys.mm b/src/plugins/platforms/cocoa/qnsview_keys.mm index aab01a7b439..e9ef769ec4b 100644 --- a/src/plugins/platforms/cocoa/qnsview_keys.mm +++ b/src/plugins/platforms/cocoa/qnsview_keys.mm @@ -114,6 +114,9 @@ static bool sendAsShortcut(const KeyEvent &keyEvent, QWindow *window) qCDebug(lcQpaKeys) << "Interpreting key event for focus object" << focusObject; m_currentlyInterpretedKeyEvent = nsevent; + // Asking the input context to handle the event will involve both + // the current input method, as well as NSKeyBindingManager, which + // may result in action callbacks to doCommandBySelector. if (![self.inputContext handleEvent:nsevent]) { qCDebug(lcQpaKeys) << "Input context did not consume event"; m_sendKeyEvent = true; diff --git a/src/plugins/platforms/ios/qiosdocumentpickercontroller.mm b/src/plugins/platforms/ios/qiosdocumentpickercontroller.mm index 4e019b69cc4..6ca6554f673 100644 --- a/src/plugins/platforms/ios/qiosdocumentpickercontroller.mm +++ b/src/plugins/platforms/ios/qiosdocumentpickercontroller.mm @@ -7,8 +7,10 @@ #include "qiosdocumentpickercontroller.h" +#include <QtCore/qpointer.h> + @implementation QIOSDocumentPickerController { - QIOSFileDialog *m_fileDialog; + QPointer<QIOSFileDialog> m_fileDialog; } - (instancetype)initWithQIOSFileDialog:(QIOSFileDialog *)fileDialog @@ -61,6 +63,9 @@ { Q_UNUSED(controller); + if (!m_fileDialog) + return; + QList<QUrl> files; for (NSURL* url in urls) files.append(QUrl::fromNSURL(url)); @@ -71,12 +76,18 @@ - (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller { + if (!m_fileDialog) + return; + Q_UNUSED(controller); emit m_fileDialog->reject(); } - (void)presentationControllerDidDismiss:(UIPresentationController *)presentationController { + if (!m_fileDialog) + return; + Q_UNUSED(presentationController); // "Called on the delegate when the user has taken action to dismiss the diff --git a/src/plugins/platforms/wasm/qwasmaccessibility.cpp b/src/plugins/platforms/wasm/qwasmaccessibility.cpp index 35e804531bc..5fa79482217 100644 --- a/src/plugins/platforms/wasm/qwasmaccessibility.cpp +++ b/src/plugins/platforms/wasm/qwasmaccessibility.cpp @@ -323,8 +323,9 @@ void QWasmAccessibility::setProperty(emscripten::val element, const std::string } -void QWasmAccessibility::addEventListener(emscripten::val element, const char *eventType) +void QWasmAccessibility::addEventListener(QAccessibleInterface *iface, emscripten::val element, const char *eventType) { + element.set("data-qta11yinterface", reinterpret_cast<size_t>(iface)); element.call<void>("addEventListener", emscripten::val(eventType), QWasmSuspendResumeControl::get()->jsEventHandlerAt(m_eventHandlerIndex), true); @@ -352,7 +353,7 @@ emscripten::val QWasmAccessibility::createHtmlElement(QAccessibleInterface *ifac case QAccessible::Button: { element = document.call<emscripten::val>("createElement", std::string("button")); - addEventListener(element, "click"); + addEventListener(iface, element, "click"); } break; case QAccessible::CheckBox: { @@ -360,7 +361,7 @@ emscripten::val QWasmAccessibility::createHtmlElement(QAccessibleInterface *ifac setAttribute(element, "type", "checkbox"); setAttribute(element, "checked", iface->state().checked); setProperty(element, "indeterminate", iface->state().checkStateMixed); - addEventListener(element, "change"); + addEventListener(iface, element, "change"); } break; case QAccessible::Switch: { @@ -371,7 +372,7 @@ emscripten::val QWasmAccessibility::createHtmlElement(QAccessibleInterface *ifac setAttribute(element, "aria-checked", "true"); else setAttribute(element, "aria-checked", "false"); - addEventListener(element, "change"); + addEventListener(iface, element, "change"); } break; case QAccessible::RadioButton: { @@ -379,7 +380,7 @@ emscripten::val QWasmAccessibility::createHtmlElement(QAccessibleInterface *ifac setAttribute(element, "type", "radio"); setAttribute(element, "checked", iface->state().checked); setProperty(element, "name", "buttonGroup"); - addEventListener(element, "change"); + addEventListener(iface, element, "change"); } break; case QAccessible::SpinBox: @@ -413,7 +414,7 @@ emscripten::val QWasmAccessibility::createHtmlElement(QAccessibleInterface *ifac element = document.call<emscripten::val>("createElement", std::string("button")); setAttribute(element, "role", "tab"); setAttribute(element, "title", text.toStdString()); - addEventListener(element, "click"); + addEventListener(iface, element, "click"); } break; case QAccessible::ScrollBar: { @@ -422,7 +423,7 @@ emscripten::val QWasmAccessibility::createHtmlElement(QAccessibleInterface *ifac element = document.call<emscripten::val>("createElement", std::string("div")); setAttribute(element, "role", "scrollbar"); setAttribute(element, "aria-valuenow", valueString); - addEventListener(element, "change"); + addEventListener(iface, element, "change"); } break; case QAccessible::StaticText: { @@ -436,7 +437,7 @@ emscripten::val QWasmAccessibility::createHtmlElement(QAccessibleInterface *ifac element = document.call<emscripten::val>("createElement", std::string("div")); setAttribute(element, "role", "toolbar"); setAttribute(element, "title", text.toStdString()); - addEventListener(element, "click"); + addEventListener(iface, element, "click"); }break; case QAccessible::MenuItem: case QAccessible::ButtonMenu: { @@ -444,7 +445,7 @@ emscripten::val QWasmAccessibility::createHtmlElement(QAccessibleInterface *ifac element = document.call<emscripten::val>("createElement", std::string("button")); setAttribute(element, "role", "menuitem"); setAttribute(element, "title", text.toStdString()); - addEventListener(element, "click"); + addEventListener(iface, element, "click"); }break; case QAccessible::MenuBar: case QAccessible::PopupMenu: { @@ -471,7 +472,7 @@ emscripten::val QWasmAccessibility::createHtmlElement(QAccessibleInterface *ifac element = document.call<emscripten::val>("createElement", std::string("div")); } - addEventListener(element, "focus"); + addEventListener(iface, element, "focus"); return element; }(); @@ -542,6 +543,7 @@ void QWasmAccessibility::linkToParent(QAccessibleInterface *iface) { emscripten::val element = getHtmlElement(iface); emscripten::val container = getElementContainer(iface); + if (container.isUndefined() || element.isUndefined()) return; @@ -554,21 +556,21 @@ void QWasmAccessibility::linkToParent(QAccessibleInterface *iface) emscripten::val next = emscripten::val::undefined(); const int thisIndex = iface->parent()->indexOfChild(iface); - Q_ASSERT(thisIndex >= 0 && thisIndex < iface->parent()->childCount()); - for (int i = thisIndex + 1; i < iface->parent()->childCount(); ++i) { - const auto elementI = getHtmlElement(iface->parent()->child(i)); - if (!elementI.isUndefined() && - elementI["parentElement"] == container) { - next = elementI; - break; + if (thisIndex >= 0) { + Q_ASSERT(thisIndex < iface->parent()->childCount()); + for (int i = thisIndex + 1; i < iface->parent()->childCount(); ++i) { + const auto elementI = getHtmlElement(iface->parent()->child(i)); + if (!elementI.isUndefined() && + elementI["parentElement"] == container) { + next = elementI; + break; + } } + if (next.isUndefined()) + container.call<void>("appendChild", element); + else + container.call<void>("insertBefore", element, next); } - if (next.isUndefined()) { - container.call<void>("appendChild", element); - } else { - container.call<void>("insertBefore", element, next); - } - const auto activeElementAfter = emscripten::val::take_ownership( getActiveElement_js(emscripten::val::undefined().as_handle())); if (activeElementBefore != activeElementAfter) { @@ -712,22 +714,26 @@ void QWasmAccessibility::handleLineEditUpdate(QAccessibleEvent *event) void QWasmAccessibility::handleEventFromHtmlElement(const emscripten::val event) { - QAccessibleInterface *iface = m_elements.key(event["target"]); + if (event["target"].isNull() || event["target"].isUndefined()) + return; - if (iface == nullptr) { + if (event["target"]["data-qta11yinterface"].isNull() || event["target"]["data-qta11yinterface"].isUndefined()) return; - } else { - QString eventType = QString::fromStdString(event["type"].as<std::string>()); - const auto& actionNames = QAccessibleBridgeUtils::effectiveActionNames(iface); - - if (eventType == "focus") { - if (actionNames.contains(QAccessibleActionInterface::setFocusAction())) - iface->actionInterface()->doAction(QAccessibleActionInterface::setFocusAction()); - } else if (actionNames.contains(QAccessibleActionInterface::pressAction())) { - iface->actionInterface()->doAction(QAccessibleActionInterface::pressAction()); - } else if (actionNames.contains(QAccessibleActionInterface::toggleAction())) { - iface->actionInterface()->doAction(QAccessibleActionInterface::toggleAction()); - } + + auto iface = reinterpret_cast<QAccessibleInterface *>(event["target"]["data-qta11yinterface"].as<size_t>()); + if (m_elements.find(iface) == m_elements.end()) + return; + + const QString eventType = QString::fromStdString(event["type"].as<std::string>()); + const auto& actionNames = QAccessibleBridgeUtils::effectiveActionNames(iface); + + if (eventType == "focus") { + if (actionNames.contains(QAccessibleActionInterface::setFocusAction())) + iface->actionInterface()->doAction(QAccessibleActionInterface::setFocusAction()); + } else if (actionNames.contains(QAccessibleActionInterface::pressAction())) { + iface->actionInterface()->doAction(QAccessibleActionInterface::pressAction()); + } else if (actionNames.contains(QAccessibleActionInterface::toggleAction())) { + iface->actionInterface()->doAction(QAccessibleActionInterface::toggleAction()); } } diff --git a/src/plugins/platforms/wasm/qwasmaccessibility.h b/src/plugins/platforms/wasm/qwasmaccessibility.h index 2b4716d64e7..26f3e0e9afe 100644 --- a/src/plugins/platforms/wasm/qwasmaccessibility.h +++ b/src/plugins/platforms/wasm/qwasmaccessibility.h @@ -116,7 +116,7 @@ private: void setProperty(emscripten::val element, const std::string &attr, const char *val); void setProperty(emscripten::val element, const std::string &attr, bool val); - void addEventListener(emscripten::val element, const char *eventType); + void addEventListener(QAccessibleInterface *, emscripten::val element, const char *eventType); private: static QWasmAccessibility *s_instance; diff --git a/src/plugins/platforms/wasm/qwasminputcontext.cpp b/src/plugins/platforms/wasm/qwasminputcontext.cpp index 614d5bd25a3..18a457198f1 100644 --- a/src/plugins/platforms/wasm/qwasminputcontext.cpp +++ b/src/plugins/platforms/wasm/qwasminputcontext.cpp @@ -225,8 +225,8 @@ void QWasmInputContext::updateGeometry() qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO << "propagating inputItemRectangle:" << inputItemRectangle; m_inputElement["style"].set("left", std::to_string(inputItemRectangle.x()) + "px"); m_inputElement["style"].set("top", std::to_string(inputItemRectangle.y()) + "px"); - m_inputElement["style"].set("width", std::to_string(inputItemRectangle.width()) + "px"); - m_inputElement["style"].set("height", std::to_string(inputItemRectangle.height()) + "px"); + m_inputElement["style"].set("width", "1px"); + m_inputElement["style"].set("height", "1px"); } } diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 82a86d6ff3a..01716fba60c 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -4019,9 +4019,11 @@ void QWindowsWindow::requestUpdate() // request or we are waiting for the event loop to process // the Posted event on the GUI thread. if (m_vsyncUpdatePending.testAndSetAcquire(UpdateState::Requested, UpdateState::Posted)) { - QMetaObject::invokeMethod(w, [w] { + QWindowsWindow *oldSelf = this; + QMetaObject::invokeMethod(w, [w, oldSelf] { + // 'oldSelf' is only used for comparison, don't access it directly! auto *self = static_cast<QWindowsWindow *>(w->handle()); - if (self) { + if (self && self == oldSelf) { // The platform window is still alive self->m_vsyncUpdatePending.storeRelease(UpdateState::Ready); self->deliverUpdateRequest(); diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index 5ba6f3e1649..0b05a31ca5c 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -5849,6 +5849,9 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex const auto aquaSize = d->effectiveAquaSizeConstrain(opt, widget); const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::Stepper, aquaSize); NSStepperCell *cell = static_cast<NSStepperCell *>(d->cocoaCell(cw)); + const auto controlSize = cell.controlSize; + if (qt_apple_runningWithLiquidGlass()) + cell.controlSize = NSControlSizeMini; cell.enabled = (sb->state & State_Enabled); const CGRect newRect = [cell drawingRectForBounds:updown.toCGRect()]; @@ -5869,6 +5872,8 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex [cell stopTracking:pressPoint at:pressPoint inView:d->backingStoreNSView mouseIsUp:NO]; d->restoreNSGraphicsContext(cg); + if (qt_apple_runningWithLiquidGlass()) + cell.controlSize = controlSize; } } break; diff --git a/src/plugins/styles/modernwindows/qwindows11style.cpp b/src/plugins/styles/modernwindows/qwindows11style.cpp index 25142612c4f..27a944a33e2 100644 --- a/src/plugins/styles/modernwindows/qwindows11style.cpp +++ b/src/plugins/styles/modernwindows/qwindows11style.cpp @@ -44,7 +44,8 @@ using namespace Qt::StringLiterals; static constexpr int topLevelRoundingRadius = 8; //Radius for toplevel items like popups for round corners static constexpr int secondLevelRoundingRadius = 4; //Radius for second level items like hovered menu item round corners - +static constexpr int contentItemHMargin = 4; // margin between content items (e.g. text and icon) +static constexpr int contentHMargin = 2 * 3; // margin between rounded border and content (= rounded border margin * 3) namespace StyleOptionHelper { inline bool isChecked(const QStyleOption *option) @@ -121,9 +122,9 @@ static constexpr int percentToAlpha(double percent) return qRound(percent * 255. / 100.); } -static constexpr std::array<QColor, 32> WINUI3ColorsLight { - QColor(0x00,0x00,0x00,0x09), //subtleHighlightColor - QColor(0x00,0x00,0x00,0x06), //subtlePressedColor +static constexpr std::array<QColor, 33> WINUI3ColorsLight { + QColor(0x00,0x00,0x00,percentToAlpha(3.73)), // subtleHighlightColor (fillSubtleSecondary) + QColor(0x00,0x00,0x00,percentToAlpha(2.41)), // subtlePressedColor (fillSubtleTertiary) QColor(0x00,0x00,0x00,0x0F), //frameColorLight QColor(0x00,0x00,0x00,percentToAlpha(60.63)), //frameColorStrong QColor(0x00,0x00,0x00,percentToAlpha(21.69)), //frameColorStrongDisabled @@ -154,11 +155,12 @@ static constexpr std::array<QColor, 32> WINUI3ColorsLight { QColor(0xFF,0xFF,0xFF,percentToAlpha(100)), // textOnAccentPrimary QColor(0xFF,0xFF,0xFF,percentToAlpha(70)), // textOnAccentSecondary QColor(0xFF,0xFF,0xFF,percentToAlpha(100)), // textOnAccentDisabled + QColor(0x00,0x00,0x00,percentToAlpha(8.03)), // dividerStrokeDefault }; -static constexpr std::array<QColor, 32> WINUI3ColorsDark { - QColor(0xFF,0xFF,0xFF,0x0F), //subtleHighlightColor - QColor(0xFF,0xFF,0xFF,0x0A), //subtlePressedColor +static constexpr std::array<QColor, 33> WINUI3ColorsDark { + QColor(0xFF,0xFF,0xFF,percentToAlpha(6.05)), // subtleHighlightColor (fillSubtleSecondary) + QColor(0xFF,0xFF,0xFF,percentToAlpha(4.19)), // subtlePressedColor (fillSubtleTertiary) QColor(0xFF,0xFF,0xFF,0x12), //frameColorLight QColor(0xFF,0xFF,0xFF,percentToAlpha(60.47)), //frameColorStrong QColor(0xFF,0xFF,0xFF,percentToAlpha(15.81)), //frameColorStrongDisabled @@ -189,9 +191,10 @@ static constexpr std::array<QColor, 32> WINUI3ColorsDark { QColor(0x00,0x00,0x00,percentToAlpha(100)), // textOnAccentPrimary QColor(0x00,0x00,0x00,percentToAlpha(70)), // textOnAccentSecondary QColor(0xFF,0xFF,0xFF,percentToAlpha(53.02)), // textOnAccentDisabled + QColor(0xFF,0xFF,0xFF,percentToAlpha(8.37)), // dividerStrokeDefault }; -static constexpr std::array<std::array<QColor,32>, 2> WINUI3Colors { +static constexpr std::array<std::array<QColor,33>, 2> WINUI3Colors { WINUI3ColorsLight, WINUI3ColorsDark }; @@ -923,15 +926,13 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption case PE_IndicatorRadioButton: { const bool isRtl = option->direction == Qt::RightToLeft; const bool isOn = option->state & State_On; - qreal innerRadius = 7.0f; + qreal innerRadius = radioButtonInnerRadius(state); if (d->transitionsEnabled() && option->styleObject) { if (option->styleObject->property("_q_end_radius").isNull()) option->styleObject->setProperty("_q_end_radius", innerRadius); QNumberStyleAnimation *animation = qobject_cast<QNumberStyleAnimation *>(d->animation(option->styleObject)); innerRadius = animation ? animation->currentValue() : option->styleObject->property("_q_end_radius").toFloat(); option->styleObject->setProperty("_q_inner_radius", innerRadius); - } else { - innerRadius = radioButtonInnerRadius(state); } QRectF rect = isRtl ? option->rect.adjusted(0, 0, -2, 0) : option->rect.adjusted(2, 0, 0, 0); @@ -1423,80 +1424,57 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op break; #endif // QT_CONFIG(progressbar) case CE_PushButtonLabel: - if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) { - QRect textRect = btn->rect; + if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) { + using namespace StyleOptionHelper; + const bool isEnabled = !isDisabled(option); - int tf = Qt::AlignVCenter|Qt::TextShowMnemonic; + 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->features & QStyleOptionButton::HasMenu) { - int indicatorSize = proxy()->pixelMetric(PM_MenuButtonIndicator, btn, widget); - QLineF menuSplitter; - QRectF indicatorRect; - painter->save(); - painter->setFont(d->assetFont); + QPainterStateGuard psg(painter); - if (btn->direction == Qt::LeftToRight) { - indicatorRect = QRect(textRect.x() + textRect.width() - indicatorSize - 4, textRect.y(),2 * 4 + indicatorSize, textRect.height()); - indicatorRect.adjust(0.5,-0.5,0.5,0.5); - menuSplitter = QLineF(indicatorRect.topLeft(),indicatorRect.bottomLeft()); - textRect = textRect.adjusted(0, 0, -indicatorSize, 0); - } else { - indicatorRect = QRect(textRect.x(), textRect.y(), textRect.x() + indicatorSize + 4, textRect.height()); - indicatorRect.adjust(-0.5,-0.5,-0.5,0.5); - menuSplitter = QLineF(indicatorRect.topRight(),indicatorRect.bottomRight()); - textRect = textRect.adjusted(indicatorSize, 0, 0, 0); - } - painter->drawText(indicatorRect, Qt::AlignCenter, ChevronDownMed); - painter->setPen(WINUI3Colors[colorSchemeIndex][controlStrokePrimary]); - painter->drawLine(menuSplitter); - painter->restore(); + const auto indSize = proxy()->pixelMetric(PM_MenuButtonIndicator, btn, widget); + const auto indRect = QRect(btn->rect.right() - indSize - contentItemHMargin, textRect.top(), + indSize + contentItemHMargin, btn->rect.height()); + const auto vindRect = visualRect(btn->direction, btn->rect, indRect); + textRect.setWidth(textRect.width() - indSize); + + int fontSize = painter->font().pointSize(); + QFont f(d->assetFont); + f.setPointSize(qRound(fontSize * 0.9f)); // a little bit smaller + painter->setFont(f); + QColor penColor = option->palette.color(isEnabled ? QPalette::Active : QPalette::Disabled, + QPalette::Text); + if (isEnabled) + penColor.setAlpha(percentToAlpha(60.63)); // fillColorTextSecondary + painter->setPen(penColor); + painter->drawText(vindRect, Qt::AlignCenter, ChevronDownMed); } if (!btn->icon.isNull()) { //Center both icon and text - QIcon::Mode mode = btn->state & State_Enabled ? QIcon::Normal : QIcon::Disabled; + QIcon::Mode mode = isEnabled ? QIcon::Normal : QIcon::Disabled; if (mode == QIcon::Normal && btn->state & State_HasFocus) mode = QIcon::Active; - QIcon::State state = QIcon::Off; - if (btn->state & State_On) - state = QIcon::On; - - QPixmap pixmap = btn->icon.pixmap(btn->iconSize, painter->device()->devicePixelRatio(), mode, state); - int pixmapWidth = pixmap.width() / pixmap.devicePixelRatio(); - int pixmapHeight = pixmap.height() / pixmap.devicePixelRatio(); - int labelWidth = pixmapWidth; - int labelHeight = pixmapHeight; - int iconSpacing = 4;//### 4 is currently hardcoded in QPushButton::sizeHint() - if (!btn->text.isEmpty()) { - int textWidth = btn->fontMetrics.boundingRect(option->rect, tf, btn->text).width(); - labelWidth += (textWidth + iconSpacing); - } + QIcon::State state = isChecked(btn) ? QIcon::On : QIcon::Off; - QRect iconRect = QRect(textRect.x() + (textRect.width() - labelWidth) / 2, - textRect.y() + (textRect.height() - labelHeight) / 2, - pixmapWidth, pixmapHeight); + int iconSpacing = 4;//### 4 is currently hardcoded in QPushButton::sizeHint() - iconRect = visualRect(btn->direction, textRect, iconRect); + 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 (btn->direction == Qt::RightToLeft) { - tf |= Qt::AlignRight; - textRect.setRight(iconRect.left() - iconSpacing / 2); - } else { - tf |= Qt::AlignLeft; //left align, we adjust the text-rect instead - textRect.setLeft(iconRect.left() + iconRect.width() + iconSpacing / 2); - } - - if (btn->state & (State_On | State_Sunken)) - iconRect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, option, widget), - proxy()->pixelMetric(PM_ButtonShiftVertical, option, widget)); - painter->drawPixmap(iconRect, pixmap); - } else { - tf |= Qt::AlignHCenter; + 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, textRect, tf, option->palette,btn->state & State_Enabled, btn->text); + proxy()->drawItemText(painter, vTextRect, tf, option->palette, isEnabled, btn->text); } break; case CE_PushButtonBevel: @@ -1526,39 +1504,38 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op painter->setPen(defaultButton ? WINUI3Colors[colorSchemeIndex][controlStrokeOnAccentSecondary] : WINUI3Colors[colorSchemeIndex][controlStrokeSecondary]); - if (flags & State_Raised) - painter->drawLine(rect.bottomLeft() + QPointF(4.0,0.0), rect.bottomRight() + QPointF(-4,0.0)); } } break; case CE_MenuBarItem: if (const auto *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) { + using namespace StyleOptionHelper; + constexpr int hPadding = 11; constexpr int topPadding = 4; constexpr int bottomPadding = 6; - bool active = mbi->state & State_Selected; - bool hasFocus = mbi->state & State_HasFocus; - bool down = mbi->state & State_Sunken; - bool enabled = mbi->state & State_Enabled; QStyleOptionMenuItem newMbi = *mbi; + + if (auto mbiV2 = qstyleoption_cast<const QStyleOptionMenuItemV2 *>(option)) + newMbi.state.setFlag(State_Sunken, mbiV2->mouseDown); + newMbi.font.setPointSize(10); - if (enabled && active) { - if (down) - painter->setBrushOrigin(painter->brushOriginF() + QPoint(1, 1)); - if (hasFocus) { - if (highContrastTheme) - painter->setPen(QPen(newMbi.palette.highlight().color(), 2)); - else - painter->setPen(Qt::NoPen); - painter->setBrush(highContrastTheme ? newMbi.palette.window().color() : WINUI3Colors[colorSchemeIndex][subtleHighlightColor]); - QRect rect = mbi->rect.marginsRemoved(QMargins(5,0,5,0)); - painter->drawRoundedRect(rect,secondLevelRoundingRadius,secondLevelRoundingRadius, Qt::AbsoluteSize); + newMbi.palette.setColor(QPalette::ButtonText, controlTextColor(&newMbi)); + if (!isDisabled(&newMbi)) { + QPen pen(Qt::NoPen); + QBrush brush(Qt::NoBrush); + if (highContrastTheme) { + pen = QPen(newMbi.palette.highlight().color(), 2); + brush = newMbi.palette.window(); + } else if (isPressed(&newMbi)) { + brush = winUI3Color(subtlePressedColor); + } else if (isHover(&newMbi)) { + brush = winUI3Color(subtleHighlightColor); + } + if (pen != Qt::NoPen || brush != Qt::NoBrush) { + const QRect rect = mbi->rect.marginsRemoved(QMargins(5, 0, 5, 0)); + drawRoundedRect(painter, rect, pen, brush); } - } else if (enabled && highContrastTheme) { - painter->setPen(QPen(newMbi.palette.windowText().color(), 2)); - painter->setBrush(newMbi.palette.window().color()); - QRect rect = mbi->rect.marginsRemoved(QMargins(5,0,5,0)); - painter->drawRoundedRect(rect,secondLevelRoundingRadius,secondLevelRoundingRadius, Qt::AbsoluteSize); } newMbi.rect.adjust(hPadding,topPadding,-hPadding,-bottomPadding); painter->setFont(newMbi.font); @@ -1572,96 +1549,89 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op case CE_MenuItem: if (const auto *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) { - int x, y, w, h; - menuitem->rect.getRect(&x, &y, &w, &h); - int tab = menuitem->reservedShortcutWidth; + const auto visualMenuRect = [&](const QRect &rect) { + return visualRect(option->direction, menuitem->rect, rect); + }; bool dis = !(menuitem->state & State_Enabled); bool checked = menuitem->checkType != QStyleOptionMenuItem::NotCheckable ? menuitem->checked : false; bool act = menuitem->state & State_Selected; - // windows always has a check column, regardless whether we have an icon or not - int checkcol = qMax<int>(menuitem->maxIconWidth, 32); - - QBrush fill = (act == true && dis == false) ? (highContrastTheme ? menuitem->palette.brush(QPalette::Highlight) : QBrush(WINUI3Colors[colorSchemeIndex][subtleHighlightColor])) : menuitem->palette.brush(QPalette::Button); - painter->setBrush(fill); - painter->setPen(Qt::NoPen); const QRect rect = menuitem->rect.marginsRemoved(QMargins(2,2,2,2)); - if (act && dis == false) - painter->drawRoundedRect(rect, secondLevelRoundingRadius, secondLevelRoundingRadius, Qt::AbsoluteSize); - - if (menuitem->menuItemType == QStyleOptionMenuItem::Separator){ - int yoff = 4; - painter->setPen(highContrastTheme == true ? menuitem->palette.buttonText().color() : WINUI3Colors[colorSchemeIndex][frameColorLight]); - painter->drawLine(x, y + yoff, x + w, y + yoff ); + if (act && dis == false) { + drawRoundedRect(painter, rect, Qt::NoPen, highContrastTheme ? menuitem->palette.brush(QPalette::Highlight) + : QBrush(winUI3Color(subtleHighlightColor))); + } + if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) { + constexpr int yoff = 1; + painter->setPen(highContrastTheme ? menuitem->palette.buttonText().color() : winUI3Color(dividerStrokeDefault)); + painter->drawLine(menuitem->rect.topLeft() + QPoint(0, yoff), + menuitem->rect.topRight() + QPoint(0, yoff)); break; } - QRect vCheckRect = visualRect(option->direction, menuitem->rect, QRect(menuitem->rect.x(), menuitem->rect.y(), checkcol, menuitem->rect.height())); - if (!menuitem->icon.isNull() && checked) { - if (act) { - qDrawShadePanel(painter, vCheckRect, - menuitem->palette, true, 1, - &menuitem->palette.brush(QPalette::Button)); - } else { - QBrush fill(menuitem->palette.light().color(), Qt::Dense4Pattern); - qDrawShadePanel(painter, vCheckRect, menuitem->palette, true, 1, &fill); - } + int xOffset = contentHMargin; + // WinUI3 draws, in contrast to former windows styles, the checkmark and icon separately + const auto checkMarkWidth = proxy()->pixelMetric(PM_IndicatorWidth, option, widget); + if (checked) { + QRect vRect(visualMenuRect(QRect(rect.x() + xOffset, rect.y(), + checkMarkWidth, rect.height()))); + QPainterStateGuard psg(painter); + painter->setFont(d->assetFont); + painter->setPen(option->palette.text().color()); + const auto textToDraw = QStringLiteral(u"\uE73E"); + painter->drawText(vRect, Qt::AlignCenter, textToDraw); } - // On Windows Style, if we have a checkable item and an icon we - // draw the icon recessed to indicate an item is checked. If we - // have no icon, we draw a checkmark instead. + if (menuitem->menuHasCheckableItems) + xOffset += checkMarkWidth + contentItemHMargin; if (!menuitem->icon.isNull()) { + // 4 is added to maxIconWidth in qmenu.cpp to PM_SmallIconSize + QRect vRect(visualMenuRect(QRect(rect.x() + xOffset, + rect.y(), + menuitem->maxIconWidth - 4, + rect.height()))); QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal; if (act && !dis) mode = QIcon::Active; const auto size = proxy()->pixelMetric(PM_SmallIconSize, option, widget); QRect pmr(QPoint(0, 0), QSize(size, size)); - pmr.moveCenter(vCheckRect.center()); + pmr.moveCenter(vRect.center()); menuitem->icon.paint(painter, pmr, Qt::AlignCenter, mode, checked ? QIcon::On : QIcon::Off); - } else if (checked) { - painter->save(); - if (dis) - painter->setPen(menuitem->palette.text().color()); - painter->setFont(d->assetFont); - const int text_flags = Qt::AlignVCenter | Qt::AlignHCenter | Qt::TextDontClip | Qt::TextSingleLine; - painter->setPen(option->palette.text().color()); - painter->drawText(vCheckRect, text_flags, CheckMark); - painter->restore(); } - painter->setPen(act ? menuitem->palette.highlightedText().color() : menuitem->palette.buttonText().color()); - - QColor discol = menuitem->palette.text().color(); - if (dis) - discol = menuitem->palette.color(QPalette::Disabled, QPalette::WindowText); + if (menuitem->maxIconWidth > 0) + xOffset += menuitem->maxIconWidth - 4 + contentItemHMargin; QStringView s(menuitem->text); if (!s.isEmpty()) { // draw text - int xm = QWindowsStylePrivate::windowsItemFrame + checkcol + QWindowsStylePrivate::windowsItemHMargin; - int xpos = menuitem->rect.x() + xm; - QRect textRect(xpos, y + QWindowsStylePrivate::windowsItemVMargin, - w - xm - QWindowsStylePrivate::windowsRightBorder - tab + 1, h - 2 * QWindowsStylePrivate::windowsItemVMargin); - QRect vTextRect = visualRect(option->direction, menuitem->rect, textRect); + QPoint tl(rect.left() + xOffset, rect.top()); + QPoint br(rect.right() - menuitem->reservedShortcutWidth - contentHMargin, + rect.bottom()); + QRect textRect(tl, br); + QRect vRect(visualMenuRect(textRect)); - painter->save(); qsizetype t = s.indexOf(u'\t'); int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine; if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget)) text_flags |= Qt::TextHideMnemonic; text_flags |= Qt::AlignLeft; - if (t >= 0) { - QRect vShortcutRect = visualRect(option->direction, menuitem->rect, - QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom()))); - const QString textToDraw = s.mid(t + 1).toString(); - if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option, widget)) { - painter->setPen(menuitem->palette.light().color()); - painter->drawText(vShortcutRect.adjusted(1, 1, 1, 1), text_flags, textToDraw); + // a submenu doesn't paint a possible shortcut in WinUI3 + if (t >= 0 && menuitem->menuItemType != QStyleOptionMenuItem::SubMenu) { + QRect shortcutRect(QPoint(textRect.right(), textRect.top()), + QPoint(rect.right(), textRect.bottom())); + QRect vShortcutRect(visualMenuRect(shortcutRect)); + QColor penColor; + if (highContrastTheme) { + penColor = menuitem->palette.color(act ? QPalette::HighlightedText + : QPalette::Text); + } else { + penColor = menuitem->palette.color(dis ? QPalette::Disabled + : QPalette::Active, QPalette::Text); + if (!dis) + penColor.setAlpha(percentToAlpha(60.63)); // fillColorTextSecondary } - if (highContrastTheme) - painter->setPen(act ? menuitem->palette.highlightedText().color() : menuitem->palette.buttonText().color()); - else - painter->setPen(menuitem->palette.color(QPalette::Disabled, QPalette::Text)); + painter->setPen(penColor); + const QString textToDraw = s.mid(t + 1).toString(); painter->drawText(vShortcutRect, text_flags, textToDraw); s = s.left(t); } @@ -1669,32 +1639,30 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem) font.setBold(true); painter->setFont(font); + QColor penColor; + if (highContrastTheme && act) + penColor = menuitem->palette.color(QPalette::HighlightedText); + else + penColor = menuitem->palette.color(dis ? QPalette::Disabled + : QPalette::Current, QPalette::Text); + painter->setPen(penColor); const QString textToDraw = s.left(t).toString(); - painter->setPen(highContrastTheme && act ? menuitem->palette.highlightedText().color() : discol); - painter->drawText(vTextRect, text_flags, textToDraw); - painter->restore(); + painter->drawText(vRect, text_flags, textToDraw); } if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow - int dim = (h - 2 * QWindowsStylePrivate::windowsItemFrame) / 2; - int xpos = x + w - QWindowsStylePrivate::windowsArrowHMargin - QWindowsStylePrivate::windowsItemFrame - dim; - QRect vSubMenuRect = visualRect(option->direction, menuitem->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim)); - QStyleOptionMenuItem newMI = *menuitem; - newMI.rect = vSubMenuRect; - newMI.state = dis ? State_None : State_Enabled; - if (act) - newMI.palette.setColor(QPalette::ButtonText, - newMI.palette.highlightedText().color()); - painter->save(); - painter->setFont(d->assetFont); - int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine; - if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget)) - text_flags |= Qt::TextHideMnemonic; - text_flags |= Qt::AlignLeft; + int fontSize = menuitem->font.pointSize(); + QFont f(d->assetFont); + f.setPointSize(qRound(fontSize * 0.9f)); // a little bit smaller + painter->setFont(f); + int yOfs = qRound(fontSize / 3.0f); // an offset to align the '>' with the baseline of the text + QPoint tl(rect.right() - 2 * QWindowsStylePrivate::windowsArrowHMargin - contentItemHMargin, + rect.top() + yOfs); + QRect submenuRect(tl, rect.bottomRight()); + QRect vSubMenuRect = visualMenuRect(submenuRect); painter->setPen(option->palette.text().color()); const bool isReverse = option->direction == Qt::RightToLeft; const auto str = isReverse ? ChevronLeftMed : ChevronRightMed; painter->drawText(vSubMenuRect, Qt::AlignCenter, str); - painter->restore(); } } break; @@ -1931,6 +1899,11 @@ QRect QWindows11Style::subElementRect(QStyle::SubElement element, const QStyleOp case QStyle::SE_HeaderArrow: ret = QCommonStyle::subElementRect(element, option, widget); break; + case SE_PushButtonContents: { + int border = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget); + ret = option->rect.marginsRemoved(QMargins(border, border, border, border)); + break; + } default: ret = QWindowsVistaStyle::subElementRect(element, option, widget); } @@ -2121,12 +2094,11 @@ QSize QWindows11Style::sizeFromContents(ContentsType type, const QStyleOption *o #if QT_CONFIG(menu) case CT_MenuItem: if (const auto *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) { - const int checkcol = qMax<int>(menuItem->maxIconWidth, 32); int width = size.width(); int height; if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) { width = 10; - height = 6; + height = 3; } else { height = menuItem->fontMetrics.height() + 8; if (!menuItem->icon.isNull()) { @@ -2136,22 +2108,29 @@ QSize QWindows11Style::sizeFromContents(ContentsType type, const QStyleOption *o } } if (menuItem->text.contains(u'\t')) - width += menuItem->reservedShortcutWidth; - else if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu) - width += 2 * QWindowsStylePrivate::windowsArrowHMargin; - else if (menuItem->menuItemType == QStyleOptionMenuItem::DefaultItem) { + width += contentItemHMargin; // the text width is already in + if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu) + width += 2 * QWindowsStylePrivate::windowsArrowHMargin + contentItemHMargin; + if (menuItem->menuItemType == QStyleOptionMenuItem::DefaultItem) { const QFontMetrics fm(menuItem->font); QFont fontBold = menuItem->font; fontBold.setBold(true); const QFontMetrics fmBold(fontBold); width += fmBold.horizontalAdvance(menuItem->text) - fm.horizontalAdvance(menuItem->text); } - width += checkcol; - width += 2 * QWindowsStylePrivate::windowsItemFrame; - if (!menuItem->text.isEmpty()) { - width += QWindowsStylePrivate::windowsItemHMargin; - width += QWindowsStylePrivate::windowsRightBorder; + // in contrast to windowsvista, the checkmark and icon are drawn separately + if (menuItem->menuHasCheckableItems) { + const auto checkMarkWidth = proxy()->pixelMetric(PM_IndicatorWidth, option, widget); + width += checkMarkWidth + contentItemHMargin * 2; } + // we have an icon and it's already in the given size, only add margins + // 4 is added in qmenu.cpp to PM_SmallIconSize + if (menuItem->maxIconWidth > 0) + width += contentItemHMargin * 2 + menuItem->maxIconWidth - 4; + width += 2 * 2; // margins for rounded border + width += 2 * contentHMargin; + if (width < 100) // minimum size + width = 100; contentSize = QSize(width, height); } break; @@ -2193,11 +2172,13 @@ QSize QWindows11Style::sizeFromContents(ContentsType type, const QStyleOption *o if (size.width() == 0) contentSize.rwidth() += 2; break; - case CT_PushButton: + case CT_PushButton: { contentSize = QWindowsVistaStyle::sizeFromContents(type, option, size, widget); - contentSize.rwidth() += 2 * 2; // the CE_PushButtonBevel draws a rounded rect with - // QMargins(2, 2, 2, 2) removed + // we want our own horizontal spacing + const int oldMargin = proxy()->pixelMetric(PM_ButtonMargin, option, widget); + contentSize.rwidth() += 2 * contentHMargin - oldMargin; break; + } default: contentSize = QWindowsVistaStyle::sizeFromContents(type, option, size, widget); break; @@ -2212,6 +2193,7 @@ QSize QWindows11Style::sizeFromContents(ContentsType type, const QStyleOption *o */ int QWindows11Style::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const { + Q_D(const QWindows11Style); int res = 0; switch (metric) { @@ -2247,6 +2229,26 @@ int QWindows11Style::pixelMetric(PixelMetric metric, const QStyleOption *option, case QStyle::PM_SubMenuOverlap: res = -1; break; + case PM_MenuButtonIndicator: { + res = contentItemHMargin; + if (widget) { + const int fontSize = widget->font().pointSize(); + QFont f(d->assetFont); + f.setPointSize(qRound(fontSize * 0.9f)); // a little bit smaller + QFontMetrics fm(f); + res += fm.horizontalAdvance(ChevronDownMed); + } else { + res += 12; + } + break; + } + case PM_DefaultFrameWidth: + res = 2; + break; + case PM_ButtonShiftHorizontal: + case PM_ButtonShiftVertical: + res = 0; + break; default: res = QWindowsVistaStyle::pixelMetric(metric, option, widget); } @@ -2452,9 +2454,6 @@ void QWindows11Style::polish(QPalette& result) SET_IF_UNRESOLVED(QPalette::Inactive, QPalette::Text, result.text().color()); SET_IF_UNRESOLVED(QPalette::Inactive, QPalette::WindowText, result.windowText().color()); - if (highContrastTheme) - result.setColor(QPalette::Active, QPalette::HighlightedText, result.windowText().color()); - auto *d = const_cast<QWindows11StylePrivate *>(d_func()); d->m_titleBarMinIcon = QIcon(); d->m_titleBarMaxIcon = QIcon(); diff --git a/src/plugins/styles/modernwindows/qwindows11style_p.h b/src/plugins/styles/modernwindows/qwindows11style_p.h index ae185370a53..130a96430da 100644 --- a/src/plugins/styles/modernwindows/qwindows11style_p.h +++ b/src/plugins/styles/modernwindows/qwindows11style_p.h @@ -56,6 +56,7 @@ enum WINUI3Color { textOnAccentPrimary, // text of default/hovered control on accent color textOnAccentSecondary, // text of pressed control on accent color textOnAccentDisabled, // text of disabled control on accent color + dividerStrokeDefault, // divider color (alpha) }; class QWindows11Style : public QWindowsVistaStyle diff --git a/src/plugins/tls/schannel/qtls_schannel.cpp b/src/plugins/tls/schannel/qtls_schannel.cpp index 12c2625f39d..667f2d8a6c3 100644 --- a/src/plugins/tls/schannel/qtls_schannel.cpp +++ b/src/plugins/tls/schannel/qtls_schannel.cpp @@ -1238,9 +1238,10 @@ bool TlsCryptographSchannel::createContext() }; #endif + const QString encodedTargetName = QUrl::fromUserInput(targetName()).host(QUrl::EncodeUnicode); auto status = InitializeSecurityContext(&credentialHandle, // phCredential nullptr, // phContext - const_reinterpret_cast<SEC_WCHAR *>(targetName().utf16()), // pszTargetName + const_reinterpret_cast<SEC_WCHAR *>(encodedTargetName.utf16()), // pszTargetName contextReq, // fContextReq 0, // Reserved1 0, // TargetDataRep (unused) |
