summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibility.mm1
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm19
-rw-r--r--src/plugins/platforms/ios/qiostheme.h1
-rw-r--r--src/plugins/platforms/ios/qiostheme.mm6
-rw-r--r--src/plugins/platforms/ios/quiwindow.mm2
-rw-r--r--src/plugins/platforms/wasm/qwasmaccessibility.cpp19
-rw-r--r--src/plugins/platforms/wasm/qwasmaccessibility.h1
-rw-r--r--src/plugins/platforms/wayland/CMakeLists.txt8
-rw-r--r--src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgtopleveliconv1.cpp1
-rw-r--r--src/plugins/platforms/wayland/qwaylandinputdevice.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.cpp5
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp15
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp1
-rw-r--r--src/plugins/platforms/xcb/qxcbatom.cpp1
-rw-r--r--src/plugins/styles/modernwindows/qwindows11style.cpp205
-rw-r--r--src/plugins/styles/modernwindows/qwindows11style_p.h9
-rw-r--r--src/plugins/styles/modernwindows/qwindowsvistastyle.cpp21
-rw-r--r--src/plugins/styles/modernwindows/qwindowsvistastyle_p_p.h2
18 files changed, 266 insertions, 55 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
index 08c9f5d5ba2..2989b4d6df3 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
@@ -161,6 +161,7 @@ static void populateRoleMap()
roleMap[QAccessible::Graphic] = NSAccessibilityImageRole;
roleMap[QAccessible::Tree] = NSAccessibilityOutlineRole;
roleMap[QAccessible::BlockQuote] = NSAccessibilityGroupRole;
+ roleMap[QAccessible::LayeredPane] = NSAccessibilityGroupRole;
}
/*
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
index 144c0519155..238f2ea2307 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
@@ -714,6 +714,25 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
iface->setText(QAccessible::Description, QString::fromNSString(label));
}
+- (NSAccessibilityOrientation)accessibilityOrientation {
+ QAccessibleInterface *iface = self.qtInterface;
+ if (!iface)
+ return NSAccessibilityOrientationUnknown;
+
+ NSAccessibilityOrientation nsOrientation = NSAccessibilityOrientationUnknown;
+ if (QAccessibleAttributesInterface *attributesIface = iface->attributesInterface()) {
+ const QVariant orientationVariant =
+ attributesIface->attributeValue(QAccessible::Attribute::Orientation);
+ if (orientationVariant.isValid()) {
+ Q_ASSERT(orientationVariant.canConvert<Qt::Orientation>());
+ const Qt::Orientation orientation = orientationVariant.value<Qt::Orientation>();
+ nsOrientation = orientation == Qt::Horizontal ? NSAccessibilityOrientationHorizontal
+ : NSAccessibilityOrientationVertical;
+ }
+ }
+ return nsOrientation;
+}
+
- (id) accessibilityValue {
if (QAccessibleInterface *iface = self.qtInterface) {
// VoiceOver asks for the value attribute for all elements. Return nil
diff --git a/src/plugins/platforms/ios/qiostheme.h b/src/plugins/platforms/ios/qiostheme.h
index b7ff3bb2a58..7af9cf80355 100644
--- a/src/plugins/platforms/ios/qiostheme.h
+++ b/src/plugins/platforms/ios/qiostheme.h
@@ -26,6 +26,7 @@ public:
Qt::ColorScheme colorScheme() const override;
void requestColorScheme(Qt::ColorScheme scheme) override;
+ Qt::ContrastPreference contrastPreference() const override;
#if !defined(Q_OS_TVOS) && !defined(Q_OS_VISIONOS)
QPlatformMenuItem* createPlatformMenuItem() const override;
diff --git a/src/plugins/platforms/ios/qiostheme.mm b/src/plugins/platforms/ios/qiostheme.mm
index cdf669f921c..435c21bf579 100644
--- a/src/plugins/platforms/ios/qiostheme.mm
+++ b/src/plugins/platforms/ios/qiostheme.mm
@@ -202,6 +202,12 @@ void QIOSTheme::requestColorScheme(Qt::ColorScheme scheme)
#endif
}
+Qt::ContrastPreference QIOSTheme::contrastPreference() const
+{
+ return UIAccessibilityDarkerSystemColorsEnabled() ? Qt::ContrastPreference::HighContrast : Qt::ContrastPreference::NoPreference;
+}
+
+
void QIOSTheme::applyTheme(UIWindow *window)
{
const UIUserInterfaceStyle style = []{
diff --git a/src/plugins/platforms/ios/quiwindow.mm b/src/plugins/platforms/ios/quiwindow.mm
index bb4268e1c88..62fd9c5d770 100644
--- a/src/plugins/platforms/ios/quiwindow.mm
+++ b/src/plugins/platforms/ios/quiwindow.mm
@@ -54,7 +54,9 @@
if (self.screen == UIScreen.mainScreen) {
// Check if the current userInterfaceStyle reports a different appearance than
// the platformTheme's appearance. We might have set that one based on the UIScreen
+ // Check for changes in the "Increase contrast" setting too.
if (previousTraitCollection.userInterfaceStyle != self.traitCollection.userInterfaceStyle
+ || previousTraitCollection.accessibilityContrast != self.traitCollection.accessibilityContrast
|| QGuiApplicationPrivate::platformTheme()->colorScheme() != colorScheme) {
QIOSTheme::initializeSystemPalette();
QWindowSystemInterface::handleThemeChange<QWindowSystemInterface::SynchronousDelivery>();
diff --git a/src/plugins/platforms/wasm/qwasmaccessibility.cpp b/src/plugins/platforms/wasm/qwasmaccessibility.cpp
index 5fa79482217..a87c33c8346 100644
--- a/src/plugins/platforms/wasm/qwasmaccessibility.cpp
+++ b/src/plugins/platforms/wasm/qwasmaccessibility.cpp
@@ -401,6 +401,7 @@ emscripten::val QWasmAccessibility::createHtmlElement(QAccessibleInterface *ifac
case QAccessible::PageTabList:{
element = document.call<emscripten::val>("createElement", std::string("div"));
setAttribute(element, "role", "tablist");
+ setHtmlElementOrientation(element, iface);
m_elements[iface] = element;
@@ -423,6 +424,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);
+ setHtmlElementOrientation(element, iface);
addEventListener(iface, element, "change");
} break;
@@ -437,6 +439,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());
+ setHtmlElementOrientation(element, iface);
addEventListener(iface, element, "click");
}break;
case QAccessible::MenuItem:
@@ -453,6 +456,7 @@ emscripten::val QWasmAccessibility::createHtmlElement(QAccessibleInterface *ifac
element = document.call<emscripten::val>("createElement", std::string("div"));
setAttribute(element, "role", "menubar");
setAttribute(element, "title", text.toStdString());
+ setHtmlElementOrientation(element, iface);
m_elements[iface] = element;
for (int i = 0; i < iface->childCount(); ++i) {
@@ -661,6 +665,21 @@ void QWasmAccessibility::setHtmlElementDisabled(QAccessibleInterface *iface)
setAttribute(element, "aria-disabled", iface->state().disabled);
}
+void QWasmAccessibility::setHtmlElementOrientation(emscripten::val element, QAccessibleInterface *iface)
+{
+ Q_ASSERT(iface);
+ if (QAccessibleAttributesInterface *attributesIface = iface->attributesInterface()) {
+ const QVariant orientationVariant =
+ attributesIface->attributeValue(QAccessible::Attribute::Orientation);
+ if (orientationVariant.isValid()) {
+ Q_ASSERT(orientationVariant.canConvert<Qt::Orientation>());
+ const Qt::Orientation orientation = orientationVariant.value<Qt::Orientation>();
+ const std::string value = orientation == Qt::Horizontal ? "horizontal" : "vertical";
+ setAttribute(element, "aria-orientation", value);
+ }
+ }
+}
+
void QWasmAccessibility::handleStaticTextUpdate(QAccessibleEvent *event)
{
switch (event->type()) {
diff --git a/src/plugins/platforms/wasm/qwasmaccessibility.h b/src/plugins/platforms/wasm/qwasmaccessibility.h
index 26f3e0e9afe..ddbfec918d6 100644
--- a/src/plugins/platforms/wasm/qwasmaccessibility.h
+++ b/src/plugins/platforms/wasm/qwasmaccessibility.h
@@ -77,6 +77,7 @@ private:
void setHtmlElementTextNameLE(QAccessibleInterface *iface);
void setHtmlElementFocus(QAccessibleInterface *iface);
void setHtmlElementDisabled(QAccessibleInterface *iface);
+ void setHtmlElementOrientation(emscripten::val element, QAccessibleInterface *iface);
void handleStaticTextUpdate(QAccessibleEvent *event);
void handleButtonUpdate(QAccessibleEvent *event);
diff --git a/src/plugins/platforms/wayland/CMakeLists.txt b/src/plugins/platforms/wayland/CMakeLists.txt
index 7e3589def6b..0ce9a4b091c 100644
--- a/src/plugins/platforms/wayland/CMakeLists.txt
+++ b/src/plugins/platforms/wayland/CMakeLists.txt
@@ -17,14 +17,6 @@ qt_internal_add_module(WaylandGlobalPrivate
NO_GENERATE_CPP_EXPORTS
)
-# Work around 115101.
-# If nothing depends on the WaylandGlobalPrivate target it doesn't run custom commands that the
-# target depends on. WaylandGlobalPrivate_ensure_sync_headers makes sure that 'all' depends on
-# WaylandGlobalPrivate_sync_headers.
-# TODO: This needs to be removed once the fix for QTBUG-115101 is merged in qtbase.
-add_custom_target(WaylandGlobalPrivate_ensure_sync_headers ALL)
-add_dependencies(WaylandGlobalPrivate_ensure_sync_headers WaylandGlobalPrivate_sync_headers)
-
# special case begin
# TODO: Ideally these macros would be part of the qtwaylandscanner tool, and not the compositor/client
include(../../../../src/tools/qtwaylandscanner/Qt6WaylandClientMacros.cmake)
diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgtopleveliconv1.cpp b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgtopleveliconv1.cpp
index 84ecc289c59..9aa8af39090 100644
--- a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgtopleveliconv1.cpp
+++ b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgtopleveliconv1.cpp
@@ -2,7 +2,6 @@
// Copyright (C) 2024 David Edmundson <[email protected]>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-#include "qwaylandshmbackingstore_p.h"
#include "qwaylandxdgtopleveliconv1_p.h"
#include <QtWaylandClient/private/qwaylanddisplay_p.h>
diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp
index 6ce43714a35..34b32da289c 100644
--- a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp
+++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp
@@ -729,11 +729,11 @@ public:
void QWaylandInputDevice::Pointer::pointer_leave(uint32_t serial, struct wl_surface *surface)
{
+ Q_UNUSED(serial);
+
invalidateFocus();
mButtons = Qt::NoButton;
- mParent->mSerial = serial;
-
// The event may arrive after destroying the window, indicated by
// a null surface.
if (!surface)
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
index 53548622dfc..482810d5b7e 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -553,12 +553,14 @@ void QWindowsScreen::handleChanges(const QWindowsScreenData &newData)
const bool orientationChanged = m_data.orientation != newData.orientation;
const bool primaryChanged = (newData.flags & QWindowsScreenData::PrimaryScreen)
&& !(m_data.flags & QWindowsScreenData::PrimaryScreen);
+ const bool refreshRateChanged = m_data.refreshRateHz != newData.refreshRateHz;
m_data.dpi = newData.dpi;
m_data.orientation = newData.orientation;
m_data.geometry = newData.geometry;
m_data.availableGeometry = newData.availableGeometry;
m_data.flags = (m_data.flags & ~QWindowsScreenData::PrimaryScreen)
| (newData.flags & QWindowsScreenData::PrimaryScreen);
+ m_data.refreshRateHz = newData.refreshRateHz;
if (dpiChanged) {
QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen(),
@@ -573,6 +575,9 @@ void QWindowsScreen::handleChanges(const QWindowsScreenData &newData)
}
if (primaryChanged)
QWindowSystemInterface::handlePrimaryScreenChanged(this);
+
+ if (refreshRateChanged)
+ QWindowSystemInterface::handleScreenRefreshRateChange(screen(), newData.refreshRateHz);
}
HMONITOR QWindowsScreen::handle() const
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
index 0144786ce5e..b7bf97f5c4b 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
@@ -654,6 +654,21 @@ HRESULT QWindowsUiaMainProvider::GetPropertyValue(PROPERTYID idProp, VARIANT *pR
*pRetVal = QComVariant{ name }.release();
break;
}
+ case UIA_OrientationPropertyId: {
+ OrientationType orientationType = OrientationType_None;
+ if (QAccessibleAttributesInterface *attributesIface = accessible->attributesInterface()) {
+ const QVariant orientationVariant =
+ attributesIface->attributeValue(QAccessible::Attribute::Orientation);
+ if (orientationVariant.isValid()) {
+ Q_ASSERT(orientationVariant.canConvert<Qt::Orientation>());
+ const Qt::Orientation orientation = orientationVariant.value<Qt::Orientation>();
+ orientationType = orientation == Qt::Horizontal ? OrientationType_Horizontal
+ : OrientationType_Vertical;
+ }
+ }
+ *pRetVal = QComVariant{ long(orientationType) }.release();
+ break;
+ }
case UIA_StyleIdAttributeId:
setStyle(accessible, pRetVal);
break;
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp
index b2675d5b884..835499d3554 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp
@@ -154,6 +154,7 @@ long roleToControlTypeId(QAccessible::Role role)
{QAccessible::WebDocument, UIA_DocumentControlTypeId},
{QAccessible::Heading, UIA_TextControlTypeId},
{QAccessible::BlockQuote, UIA_GroupControlTypeId},
+ {QAccessible::LayeredPane, UIA_PaneControlTypeId},
};
long controlType = mapping.value(role, UIA_CustomControlTypeId);
diff --git a/src/plugins/platforms/xcb/qxcbatom.cpp b/src/plugins/platforms/xcb/qxcbatom.cpp
index 5f712d33d56..e609b84ad5f 100644
--- a/src/plugins/platforms/xcb/qxcbatom.cpp
+++ b/src/plugins/platforms/xcb/qxcbatom.cpp
@@ -9,6 +9,7 @@
#include <string.h>
#include <algorithm>
+#include <cstdlib>
static const char *xcb_atomnames = {
// window-manager <-> client protocols
diff --git a/src/plugins/styles/modernwindows/qwindows11style.cpp b/src/plugins/styles/modernwindows/qwindows11style.cpp
index 27a944a33e2..f79dea194e8 100644
--- a/src/plugins/styles/modernwindows/qwindows11style.cpp
+++ b/src/plugins/styles/modernwindows/qwindows11style.cpp
@@ -107,6 +107,7 @@ inline ControlState calcControlState(const QStyleOption *option)
#define ChromeRestore u"\uE923"_s
#define ChromeClose u"\uE8BB"_s
+#define More u"\uE712"_s
#define Help u"\uE897"_s
template <typename R, typename P, typename B>
@@ -579,21 +580,18 @@ void QWindows11Style::drawComplexControl(ComplexControl control, const QStyleOpt
if (combobox->frame)
drawLineEditFrame(painter, frameRect, combobox, combobox->editable);
- const bool isMouseOver = state & State_MouseOver;
const bool hasFocus = state & State_HasFocus;
- if (isMouseOver && !hasFocus && !highContrastTheme)
- drawRoundedRect(painter, frameRect, Qt::NoPen, winUI3Color(subtleHighlightColor));
+ QStyleOption opt(*option);
+ opt.state.setFlag(QStyle::State_On, false);
+ drawRoundedRect(painter, frameRect, Qt::NoPen, controlFillBrush(&opt, ControlType::Control));
if (sub & SC_ComboBoxArrow) {
QRectF rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget).adjusted(4, 0, -4, 1);
painter->setFont(d->assetFont);
- painter->setPen(combobox->palette.text().color());
+ painter->setPen(controlTextColor(option));
painter->drawText(rect, Qt::AlignCenter, ChevronDownMed);
}
- if (state & State_HasFocus) {
- drawPrimitive(PE_FrameFocusRect, option, painter, widget);
- }
- if (state & State_KeyboardFocusChange && state & State_HasFocus) {
+ if (state & State_KeyboardFocusChange && hasFocus) {
QStyleOptionFocusRect fropt;
fropt.QStyleOption::operator=(*option);
proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
@@ -870,17 +868,13 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
}
break;
case PE_IndicatorCheckBox: {
- const bool isRtl = option->direction == Qt::RightToLeft;
const bool isOn = option->state & State_On;
const bool isPartial = option->state & State_NoChange;
- QRectF rect = isRtl ? option->rect.adjusted(0, 0, -2, 0) : option->rect.adjusted(2, 0, 0, 0);
+ const QRectF rect = option->rect;
const QPointF center = rect.center();
- rect.setWidth(15);
- rect.setHeight(15);
- rect.moveCenter(center);
- drawRoundedRect(painter, rect, borderPenControlAlt(option),
+ drawRoundedRect(painter, option->rect, borderPenControlAlt(option),
controlFillBrush(option, ControlType::ControlAlt));
if (isOn) {
@@ -924,7 +918,6 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
}
break;
case PE_IndicatorRadioButton: {
- const bool isRtl = option->direction == Qt::RightToLeft;
const bool isOn = option->state & State_On;
qreal innerRadius = radioButtonInnerRadius(state);
if (d->transitionsEnabled() && option->styleObject) {
@@ -935,7 +928,7 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
option->styleObject->setProperty("_q_inner_radius", innerRadius);
}
- QRectF rect = isRtl ? option->rect.adjusted(0, 0, -2, 0) : option->rect.adjusted(2, 0, 0, 0);
+ const QRectF rect = option->rect;
const QPointF center = rect.center();
painter->setPen(borderPenControlAlt(option));
@@ -1059,6 +1052,18 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
painter->setBrush(vopt->palette.base());
painter->drawRect(rect);
+ if (option->state & State_Selected && !highContrastTheme) {
+ // keep in sync with CE_ItemViewItem QListView indicator painting
+ const auto col = option->palette.accent().color();
+ painter->setBrush(col);
+ painter->setPen(col);
+ const auto xPos = isRtl ? rect.right() - 4.5f : rect.left() + 3.5f;
+ const auto yOfs = rect.height() / 4.;
+ QRectF r(QPointF(xPos, rect.y() + yOfs),
+ QPointF(xPos + 1, rect.y() + rect.height() - yOfs));
+ painter->drawRoundedRect(r, 1, 1);
+ }
+
const bool isTreeDecoration = vopt->features.testFlag(
QStyleOptionViewItem::IsDecorationForRootColumn);
if (isTreeDecoration && vopt->state.testAnyFlags(State_Selected | State_MouseOver) &&
@@ -1186,11 +1191,14 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op
painter->setRenderHint(QPainter::Antialiasing);
switch (element) {
case QStyle::CE_ComboBoxLabel:
+#if QT_CONFIG(combobox)
if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ painter->setPen(controlTextColor(option));
QStyleOptionComboBox newOption = *cb;
newOption.rect.adjust(4,0,-4,0);
QCommonStyle::drawControl(element, &newOption, painter, widget);
}
+#endif // QT_CONFIG(combobox)
break;
case QStyle::CE_TabBarTabShape:
#if QT_CONFIG(tabbar)
@@ -1433,26 +1441,6 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op
if (!proxy()->styleHint(SH_UnderlineShortcut, btn, widget))
tf |= Qt::TextHideMnemonic;
- if (btn->features & QStyleOptionButton::HasMenu) {
- QPainterStateGuard psg(painter);
-
- 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 = isEnabled ? QIcon::Normal : QIcon::Disabled;
@@ -1479,6 +1467,8 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op
break;
case CE_PushButtonBevel:
if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ using namespace StyleOptionHelper;
+
QRectF rect = btn->rect.marginsRemoved(QMargins(2, 2, 2, 2));
painter->setPen(Qt::NoPen);
if (btn->features.testFlag(QStyleOptionButton::Flat)) {
@@ -1505,6 +1495,29 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op
painter->setPen(defaultButton ? WINUI3Colors[colorSchemeIndex][controlStrokeOnAccentSecondary]
: WINUI3Colors[colorSchemeIndex][controlStrokeSecondary]);
}
+ if (btn->features.testFlag(QStyleOptionButton::HasMenu)) {
+ QPainterStateGuard psg(painter);
+
+ const bool isEnabled = !isDisabled(option);
+ QRect textRect = btn->rect.marginsRemoved(QMargins(contentHMargin, 0, contentHMargin, 0));
+ 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);
+ }
}
break;
case CE_MenuBarItem:
@@ -1856,7 +1869,7 @@ QRect QWindows11Style::subElementRect(QStyle::SubElement element, const QStyleOp
case QStyle::SE_RadioButtonIndicator:
case QStyle::SE_CheckBoxIndicator:
ret = QWindowsVistaStyle::subElementRect(element, option, widget);
- ret = ret.marginsRemoved(QMargins(4,0,0,0));
+ ret.moveLeft(contentItemHMargin);
break;
case QStyle::SE_ComboBoxFocusRect:
case QStyle::SE_CheckBoxFocusRect:
@@ -2061,6 +2074,20 @@ QRect QWindows11Style::subControlRect(ComplexControl control, const QStyleOption
}
break;
}
+ case CC_ComboBox: {
+ if (subControl == SC_ComboBoxArrow) {
+ const auto indicatorWidth =
+ proxy()->pixelMetric(PM_MenuButtonIndicator, option, widget);
+ const int endX = option->rect.right() - contentHMargin - 2;
+ const int startX = endX - indicatorWidth;
+ const QRect rect(QPoint(startX, option->rect.top()),
+ QPoint(endX, option->rect.bottom()));
+ ret = visualRect(option->direction, option->rect, rect);
+ } else {
+ ret = QWindowsVistaStyle::subControlRect(control, option, subControl, widget);
+ }
+ break;
+ }
default:
ret = QWindowsVistaStyle::subControlRect(control, option, subControl, widget);
}
@@ -2151,14 +2178,18 @@ QSize QWindows11Style::sizeFromContents(ContentsType type, const QStyleOption *o
break;
}
#endif
+#if QT_CONFIG(combobox)
case CT_ComboBox:
if (const auto *comboBoxOpt = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
contentSize = QWindowsStyle::sizeFromContents(type, option, size, widget); // don't rely on QWindowsThemeData
contentSize += QSize(4, 4); // default win11 style margins
- if (comboBoxOpt->subControls & SC_ComboBoxArrow)
- contentSize += QSize(8, 0); // arrow margins
+ if (comboBoxOpt->subControls & SC_ComboBoxArrow) {
+ const auto w = proxy()->pixelMetric(PM_MenuButtonIndicator, option, widget);
+ contentSize.rwidth() += w + contentItemHMargin;
+ }
}
break;
+#endif
case CT_HeaderSection:
// windows vista does not honor the indicator (as it was drawn above the text, not on the
// side) so call QWindowsStyle::styleHint directly to get the correct size hint
@@ -2166,6 +2197,27 @@ QSize QWindows11Style::sizeFromContents(ContentsType type, const QStyleOption *o
break;
case CT_RadioButton:
case CT_CheckBox:
+ if (const auto *buttonOpt = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ const auto p = proxy();
+ const bool isRadio = (type == CT_RadioButton);
+
+ const int width = p->pixelMetric(
+ isRadio ? PM_ExclusiveIndicatorWidth : PM_IndicatorWidth, option, widget);
+ const int height = p->pixelMetric(
+ isRadio ? PM_ExclusiveIndicatorHeight : PM_IndicatorHeight, option, widget);
+
+ int margins = 2 * contentItemHMargin;
+ if (!buttonOpt->icon.isNull() || !buttonOpt->text.isEmpty()) {
+ margins += p->pixelMetric(isRadio ? PM_RadioButtonLabelSpacing
+ : PM_CheckBoxLabelSpacing,
+ option, widget);
+ }
+
+ contentSize += QSize(width + margins, 4);
+ contentSize.setHeight(qMax(size.height(), height + 2 * contentItemHMargin));
+ }
+ break;
+
// the indicator needs 2px more in width when there is no text, not needed when
// the style draws the text
contentSize = QWindowsVistaStyle::sizeFromContents(type, option, size, widget);
@@ -2217,12 +2269,24 @@ int QWindows11Style::pixelMetric(PixelMetric metric, const QStyleOption *option,
case PM_SliderLength: // same because handle is a circle with r=8
res += 2 * 8;
break;
+ case PM_RadioButtonLabelSpacing:
+ case PM_CheckBoxLabelSpacing:
+ res = 2 * contentItemHMargin;
+ break;
case QStyle::PM_TitleBarButtonIconSize:
res = 16;
break;
case QStyle::PM_TitleBarButtonSize:
res = 32;
break;
+#if QT_CONFIG(toolbar)
+ case PM_ToolBarExtensionExtent:
+ res = int(QStyleHelper::dpiScaled(32., option));
+ break;
+ case PM_ToolBarHandleExtent:
+ res = int(QStyleHelper::dpiScaled(8., option));
+ break;
+#endif // QT_CONFIG(toolbar)
case QStyle::PM_ScrollBarExtent:
res = 12;
break;
@@ -2233,10 +2297,17 @@ int QWindows11Style::pixelMetric(PixelMetric metric, const QStyleOption *option,
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);
+ auto it = m_fontPoint2ChevronDownMedWidth.find(fontSize);
+ if (it == m_fontPoint2ChevronDownMedWidth.end()) {
+ QFont f(d->assetFont);
+ f.setPointSize(qRound(fontSize * 0.9f)); // a little bit smaller
+ QFontMetrics fm(f);
+ const auto width = fm.horizontalAdvance(ChevronDownMed);
+ m_fontPoint2ChevronDownMedWidth.insert(fontSize, width);
+ res += width;
+ } else {
+ res += it.value();
+ }
} else {
res += 12;
}
@@ -2249,6 +2320,9 @@ int QWindows11Style::pixelMetric(PixelMetric metric, const QStyleOption *option,
case PM_ButtonShiftVertical:
res = 0;
break;
+ case PM_TreeViewIndentation:
+ res = 30;
+ break;
default:
res = QWindowsVistaStyle::pixelMetric(metric, option, widget);
}
@@ -2336,6 +2410,13 @@ void QWindows11Style::unpolish(QWidget *widget)
widget->setProperty("_q_original_menubar_maxheight", QVariant());
}
#endif
+ const auto comboBoxContainer = qobject_cast<const QComboBoxPrivateContainer *>(widget);
+ if (comboBoxContainer) {
+ widget->setAttribute(Qt::WA_OpaquePaintEvent, true);
+ widget->setAttribute(Qt::WA_TranslucentBackground, false);
+ widget->setWindowFlag(Qt::FramelessWindowHint, false);
+ widget->setWindowFlag(Qt::NoDropShadowWindowHint, false);
+ }
if (const auto *scrollarea = qobject_cast<QAbstractScrollArea *>(widget);
scrollarea
@@ -2459,6 +2540,44 @@ void QWindows11Style::polish(QPalette& result)
d->m_titleBarMaxIcon = QIcon();
d->m_titleBarCloseIcon = QIcon();
d->m_titleBarNormalIcon = QIcon();
+ d->m_toolbarExtensionButton = QIcon();
+}
+
+QPixmap QWindows11Style::standardPixmap(StandardPixmap standardPixmap,
+ const QStyleOption *option,
+ const QWidget *widget) const
+{
+ switch (standardPixmap) {
+ case SP_ToolBarHorizontalExtensionButton:
+ case SP_ToolBarVerticalExtensionButton: {
+ const int size = proxy()->pixelMetric(PM_ToolBarExtensionExtent, option, widget);
+ return standardIcon(standardPixmap, option, widget).pixmap(size);
+ }
+ default:
+ break;
+ }
+ return QWindowsVistaStyle::standardPixmap(standardPixmap, option, widget);
+}
+
+QIcon QWindows11Style::standardIcon(StandardPixmap standardIcon,
+ const QStyleOption *option,
+ const QWidget *widget) const
+{
+ auto *d = const_cast<QWindows11StylePrivate*>(d_func());
+ switch (standardIcon) {
+ case SP_ToolBarHorizontalExtensionButton:
+ case SP_ToolBarVerticalExtensionButton: {
+ if (d->m_toolbarExtensionButton.isNull()) {
+ auto e = new WinFontIconEngine(More.at(0), d->assetFont);
+ e->setScale(1.0);
+ d->m_toolbarExtensionButton = QIcon(e);
+ }
+ return d->m_toolbarExtensionButton;
+ }
+ default:
+ break;
+ }
+ return QWindowsVistaStyle::standardIcon(standardIcon, option, widget);
}
QColor QWindows11Style::calculateAccentColor(const QStyleOption *option) const
diff --git a/src/plugins/styles/modernwindows/qwindows11style_p.h b/src/plugins/styles/modernwindows/qwindows11style_p.h
index 130a96430da..736caae956c 100644
--- a/src/plugins/styles/modernwindows/qwindows11style_p.h
+++ b/src/plugins/styles/modernwindows/qwindows11style_p.h
@@ -85,6 +85,10 @@ public:
const QWidget *widget = nullptr) const override;
void polish(QPalette &pal) override;
void unpolish(QWidget *widget) override;
+ QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *option = nullptr,
+ const QWidget *widget = nullptr) const override;
+ QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = nullptr,
+ const QWidget *widget = nullptr) const override;
protected:
QWindows11Style(QWindows11StylePrivate &dd);
@@ -110,10 +114,15 @@ private:
bool highContrastTheme = false;
int colorSchemeIndex = 0;
+
+ mutable QVarLengthFlatMap<int, int, 8> m_fontPoint2ChevronDownMedWidth;
};
class QWindows11StylePrivate : public QWindowsVistaStylePrivate {
Q_DECLARE_PUBLIC(QWindows11Style)
+
+protected:
+ QIcon m_toolbarExtensionButton;
};
QT_END_NAMESPACE
diff --git a/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp b/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp
index 85d55f27bb7..22ca18b10bf 100644
--- a/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp
+++ b/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp
@@ -1626,6 +1626,12 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
break;
case PE_Frame:
+ if (widget && widget->inherits("QComboBoxPrivateContainer")){
+ QStyleOption copy = *option;
+ copy.state |= State_Raised;
+ proxy()->drawPrimitive(PE_PanelMenu, &copy, painter, widget);
+ break;
+ }
#if QT_CONFIG(accessibility)
if (QStyleHelper::isInstanceOf(option->styleObject, QAccessible::EditableText)
|| QStyleHelper::isInstanceOf(option->styleObject, QAccessible::StaticText) ||
@@ -1704,6 +1710,14 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
return;
}
+ case PE_PanelMenu:
+ if (widget && widget->inherits("QComboBoxPrivateContainer")){
+ //fill combobox popup background
+ QWindowsThemeData popupbackgroundTheme(widget, painter, QWindowsVistaStylePrivate::MenuTheme,
+ MENU_POPUPBACKGROUND, stateId, option->rect);
+ d->drawBackground(popupbackgroundTheme);
+ }
+
case PE_PanelMenuBar:
break;
@@ -4968,6 +4982,11 @@ QString WinFontIconEngine::string() const
return m_glyph;
}
+void WinFontIconEngine::setScale(double scale)
+{
+ m_scale = scale;
+}
+
void WinFontIconEngine::paint(QPainter *painter, const QRect &rect, QIcon::Mode mode,
QIcon::State)
{
@@ -4994,7 +5013,7 @@ void WinFontIconEngine::paint(QPainter *painter, const QRect &rect, QIcon::Mode
break;
}
QFont renderFont(m_font);
- renderFont.setPixelSize(rect.height() * 0.7f);
+ renderFont.setPixelSize(rect.height() * m_scale);
painter->save();
painter->setFont(renderFont);
painter->setPen(color);
diff --git a/src/plugins/styles/modernwindows/qwindowsvistastyle_p_p.h b/src/plugins/styles/modernwindows/qwindowsvistastyle_p_p.h
index e8aad528f90..cf982ceb133 100644
--- a/src/plugins/styles/modernwindows/qwindowsvistastyle_p_p.h
+++ b/src/plugins/styles/modernwindows/qwindowsvistastyle_p_p.h
@@ -189,11 +189,13 @@ public:
QString key() const override;
QIconEngine *clone() const override;
QString string() const override;
+ void setScale(double scale);
void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) override;
protected:
QFont m_font;
QChar m_glyph;
+ double m_scale = 0.7;
};
QT_END_NAMESPACE