summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/CMakeLists.txt4
-rw-r--r--src/plugins/platforms/android/CMakeLists.txt5
-rw-r--r--src/plugins/platforms/android/androidjniaccessibility.cpp130
-rw-r--r--src/plugins/styles/modernwindows/qwindows11style.cpp213
4 files changed, 241 insertions, 111 deletions
diff --git a/src/plugins/platforms/CMakeLists.txt b/src/plugins/platforms/CMakeLists.txt
index f30c27c24be..498a0772bc9 100644
--- a/src/plugins/platforms/CMakeLists.txt
+++ b/src/plugins/platforms/CMakeLists.txt
@@ -4,10 +4,10 @@
if(ANDROID)
add_subdirectory(android)
endif()
-if(NOT ANDROID AND NOT WASM)
+if(NOT WASM)
add_subdirectory(minimal)
endif()
-if(QT_FEATURE_freetype AND NOT ANDROID AND NOT WASM)
+if(QT_FEATURE_freetype AND NOT WASM)
add_subdirectory(offscreen)
endif()
if(QT_FEATURE_xcb)
diff --git a/src/plugins/platforms/android/CMakeLists.txt b/src/plugins/platforms/android/CMakeLists.txt
index 0160e12c26c..0d2a048abde 100644
--- a/src/plugins/platforms/android/CMakeLists.txt
+++ b/src/plugins/platforms/android/CMakeLists.txt
@@ -51,7 +51,12 @@ qt_internal_add_plugin(QAndroidIntegrationPlugin
qandroidplatformdialoghelpers.cpp
# Conflicting JNI classes, and types
androidcontentfileengine.cpp
+ qandroidplatformforeignwindow.cpp
qandroidplatformintegration.cpp
+ qandroidplatformscreen.cpp
+ qandroidplatformservices.cpp
+ qandroidplatformwindow.cpp
+ qandroidsystemlocale.cpp
INCLUDE_DIRECTORIES
${CMAKE_CURRENT_SOURCE_DIR}
${QtBase_SOURCE_DIR}/src/3rdparty/android
diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp
index 200c2f7a47b..b3ff0a4f06e 100644
--- a/src/plugins/platforms/android/androidjniaccessibility.cpp
+++ b/src/plugins/platforms/android/androidjniaccessibility.cpp
@@ -28,6 +28,7 @@ using namespace Qt::StringLiterals;
namespace QtAndroidAccessibility
{
+ static jmethodID m_setClassNameMethodID = 0;
static jmethodID m_addActionMethodID = 0;
static jmethodID m_setCheckableMethodID = 0;
static jmethodID m_setCheckedMethodID = 0;
@@ -421,6 +422,130 @@ namespace QtAndroidAccessibility
return jstr;
}
+ static QString classNameForRole(QAccessible::Role role, QAccessible::State state) {
+ switch (role) {
+ case QAccessible::Role::Button:
+ case QAccessible::Role::Link:
+ {
+ if (state.checkable)
+ // There is also a android.widget.Switch for which we have no match.
+ return QStringLiteral("android.widget.ToggleButton");
+ return QStringLiteral("android.widget.Button");
+ }
+ case QAccessible::Role::CheckBox:
+ // As of android/accessibility/utils/Role.java::getRole a CheckBox
+ // is NOT android.widget.CheckBox
+ return QStringLiteral("android.widget.CompoundButton");
+ case QAccessible::Role::Clock:
+ return QStringLiteral("android.widget.TextClock");
+ case QAccessible::Role::ComboBox:
+ return QStringLiteral("android.widget.Spinner");
+ case QAccessible::Role::Graphic:
+ // QQuickImage does not provide this role it inherits Client from QQuickItem
+ return QStringLiteral("android.widget.ImageView");
+ case QAccessible::Role::Grouping:
+ return QStringLiteral("android.view.ViewGroup");
+ case QAccessible::Role::List:
+ // As of android/accessibility/utils/Role.java::getRole a List
+ // is NOT android.widget.ListView
+ return QStringLiteral("android.widget.AbsListView");
+ case QAccessible::Role::MenuItem:
+ return QStringLiteral("android.view.MenuItem");
+ case QAccessible::Role::PopupMenu:
+ return QStringLiteral("android.widget.PopupMenu");
+ case QAccessible::Role::Separator:
+ return QStringLiteral("android.widget.Space");
+ case QAccessible::Role::ToolBar:
+ return QStringLiteral("android.view.Toolbar");
+ case QAccessible::Role::Heading: [[fallthrough]];
+ case QAccessible::Role::StaticText:
+ // Heading vs. regular Text is finally determined by AccessibilityNodeInfo.isHeading()
+ return QStringLiteral("android.widget.TextView");
+ case QAccessible::Role::EditableText:
+ return QStringLiteral("android.widget.EditText");
+ case QAccessible::Role::RadioButton:
+ return QStringLiteral("android.widget.RadioButton");
+ case QAccessible::Role::ProgressBar:
+ return QStringLiteral("android.widget.ProgressBar");
+ // Range information need to be filled to announce percentages
+ case QAccessible::Role::SpinBox:
+ return QStringLiteral("android.widget.NumberPicker");
+ case QAccessible::Role::WebDocument:
+ return QStringLiteral("android.webkit.WebView");
+ case QAccessible::Role::Dialog:
+ return QStringLiteral("android.app.AlertDialog");
+ case QAccessible::Role::PageTab:
+ return QStringLiteral("android.app.ActionBar.Tab");
+ case QAccessible::Role::PageTabList:
+ return QStringLiteral("android.widget.TabWidget");
+ case QAccessible::Role::ScrollBar: [[fallthrough]];
+ case QAccessible::Role::Slider:
+ return QStringLiteral("android.widget.SeekBar");
+ case QAccessible::Role::Table:
+ // #TODO Evaluate the usage of AccessibleNodeInfo.setCollectionItemInfo() to provide
+ // infos about colums, rows und items.
+ return QStringLiteral("android.widget.GridView");
+ case QAccessible::Role::Pane:
+ // #TODO QQuickScrollView, QQuickListView (see QTBUG-137806)
+ return QStringLiteral("android.view.ViewGroup");
+ case QAccessible::Role::AlertMessage:
+ case QAccessible::Role::Animation:
+ case QAccessible::Role::Application:
+ case QAccessible::Role::Assistant:
+ case QAccessible::Role::BlockQuote:
+ case QAccessible::Role::Border:
+ case QAccessible::Role::ButtonDropGrid:
+ case QAccessible::Role::ButtonDropDown:
+ case QAccessible::Role::ButtonMenu:
+ case QAccessible::Role::Canvas:
+ case QAccessible::Role::Caret:
+ case QAccessible::Role::Cell:
+ case QAccessible::Role::Chart:
+ case QAccessible::Role::Client:
+ case QAccessible::Role::ColorChooser:
+ case QAccessible::Role::Column:
+ case QAccessible::Role::ColumnHeader:
+ case QAccessible::Role::ComplementaryContent:
+ case QAccessible::Role::Cursor:
+ case QAccessible::Role::Desktop:
+ case QAccessible::Role::Dial:
+ case QAccessible::Role::Document:
+ case QAccessible::Role::Equation:
+ case QAccessible::Role::Footer:
+ case QAccessible::Role::Form:
+ case QAccessible::Role::Grip:
+ case QAccessible::Role::HelpBalloon:
+ case QAccessible::Role::HotkeyField:
+ case QAccessible::Role::Indicator:
+ case QAccessible::Role::LayeredPane:
+ case QAccessible::Role::ListItem:
+ case QAccessible::Role::MenuBar:
+ case QAccessible::Role::NoRole:
+ case QAccessible::Role::Note:
+ case QAccessible::Role::Notification:
+ case QAccessible::Role::Paragraph:
+ case QAccessible::Role::PropertyPage:
+ case QAccessible::Role::Row:
+ case QAccessible::Role::RowHeader:
+ case QAccessible::Role::Section:
+ case QAccessible::Role::Sound:
+ case QAccessible::Role::Splitter:
+ case QAccessible::Role::StatusBar:
+ case QAccessible::Role::Terminal:
+ case QAccessible::Role::TitleBar:
+ case QAccessible::Role::ToolTip:
+ case QAccessible::Role::Tree:
+ case QAccessible::Role::TreeItem:
+ case QAccessible::Role::UserRole:
+ case QAccessible::Role::Whitespace:
+ case QAccessible::Role::Window:
+ // If unsure, every visible or interactive element in Android
+ // inherits android.view.View and by many extends also TextView.
+ // Android itself does a similar thing e.g. in its Settings-App.
+ return QStringLiteral("android.view.TextView");
+ }
+ }
+
static QString descriptionForInterface(QAccessibleInterface *iface)
{
QString desc;
@@ -513,6 +638,10 @@ namespace QtAndroidAccessibility
return false;
}
+ const QString role = classNameForRole(info.role, info.state);
+ jstring jrole = env->NewString((jchar*)role.constData(), (jsize)role.size());
+ env->CallVoidMethod(node, m_setClassNameMethodID, jrole);
+
const bool hasClickableAction =
info.actions.contains(QAccessibleActionInterface::pressAction()) ||
info.actions.contains(QAccessibleActionInterface::toggleAction());
@@ -590,6 +719,7 @@ namespace QtAndroidAccessibility
}
jclass nodeInfoClass = env->FindClass("android/view/accessibility/AccessibilityNodeInfo");
+ GET_AND_CHECK_STATIC_METHOD(m_setClassNameMethodID, nodeInfoClass, "setClassName", "(Ljava/lang/CharSequence;)V");
GET_AND_CHECK_STATIC_METHOD(m_addActionMethodID, nodeInfoClass, "addAction", "(I)V");
GET_AND_CHECK_STATIC_METHOD(m_setCheckableMethodID, nodeInfoClass, "setCheckable", "(Z)V");
GET_AND_CHECK_STATIC_METHOD(m_setCheckedMethodID, nodeInfoClass, "setChecked", "(Z)V");
diff --git a/src/plugins/styles/modernwindows/qwindows11style.cpp b/src/plugins/styles/modernwindows/qwindows11style.cpp
index 3f40dea5eb9..82e978862f8 100644
--- a/src/plugins/styles/modernwindows/qwindows11style.cpp
+++ b/src/plugins/styles/modernwindows/qwindows11style.cpp
@@ -1662,128 +1662,123 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op
}
case CE_ItemViewItem: {
if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(option)) {
- if (qobject_cast<const QAbstractItemView *>(widget)) {
- QRect checkRect = proxy()->subElementRect(SE_ItemViewItemCheckIndicator, vopt, widget);
- QRect iconRect = proxy()->subElementRect(SE_ItemViewItemDecoration, vopt, widget);
- QRect textRect = proxy()->subElementRect(SE_ItemViewItemText, vopt, widget);
+ QRect checkRect = proxy()->subElementRect(SE_ItemViewItemCheckIndicator, vopt, widget);
+ QRect iconRect = proxy()->subElementRect(SE_ItemViewItemDecoration, vopt, widget);
+ QRect textRect = proxy()->subElementRect(SE_ItemViewItemText, vopt, widget);
- // draw the background
- proxy()->drawPrimitive(PE_PanelItemViewItem, option, painter, widget);
+ // draw the background
+ proxy()->drawPrimitive(PE_PanelItemViewItem, option, painter, widget);
- const QRect &rect = vopt->rect;
- const bool isRtl = option->direction == Qt::RightToLeft;
- bool onlyOne = vopt->viewItemPosition == QStyleOptionViewItem::OnlyOne ||
- vopt->viewItemPosition == QStyleOptionViewItem::Invalid;
- bool isFirst = vopt->viewItemPosition == QStyleOptionViewItem::Beginning;
- bool isLast = vopt->viewItemPosition == QStyleOptionViewItem::End;
+ const QRect &rect = vopt->rect;
+ const bool isRtl = option->direction == Qt::RightToLeft;
+ bool onlyOne = vopt->viewItemPosition == QStyleOptionViewItem::OnlyOne ||
+ vopt->viewItemPosition == QStyleOptionViewItem::Invalid;
+ bool isFirst = vopt->viewItemPosition == QStyleOptionViewItem::Beginning;
+ bool isLast = vopt->viewItemPosition == QStyleOptionViewItem::End;
- // the tree decoration already painted the left side of the rounded rect
- if (vopt->features.testFlag(QStyleOptionViewItem::IsDecoratedRootColumn) &&
- vopt->showDecorationSelected) {
- isFirst = false;
- if (onlyOne) {
- onlyOne = false;
- isLast = true;
- }
+ // the tree decoration already painted the left side of the rounded rect
+ if (vopt->features.testFlag(QStyleOptionViewItem::IsDecoratedRootColumn) &&
+ vopt->showDecorationSelected) {
+ isFirst = false;
+ if (onlyOne) {
+ onlyOne = false;
+ isLast = true;
}
+ }
- if (isRtl) {
- if (isFirst) {
- isFirst = false;
- isLast = true;
- } else if (isLast) {
- isFirst = true;
- isLast = false;
- }
+ if (isRtl) {
+ if (isFirst) {
+ isFirst = false;
+ isLast = true;
+ } else if (isLast) {
+ isFirst = true;
+ isLast = false;
}
- const bool highlightCurrent = vopt->state.testAnyFlags(State_Selected | State_MouseOver);
- if (highlightCurrent) {
- const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget);
- if (highContrastTheme)
- painter->setBrush(vopt->palette.highlight());
- else
- painter->setBrush(view->alternatingRowColors() ? vopt->palette.highlight() : WINUI3Colors[colorSchemeIndex][subtleHighlightColor]);
- QWidget *editorWidget = view ? view->indexWidget(view->currentIndex()) : nullptr;
- if (editorWidget) {
- QPalette pal = editorWidget->palette();
- QColor editorBgColor = vopt->backgroundBrush == Qt::NoBrush ? vopt->palette.color(widget->backgroundRole()) : vopt->backgroundBrush.color();
- editorBgColor.setAlpha(255);
- pal.setColor(editorWidget->backgroundRole(), editorBgColor);
- editorWidget->setPalette(pal);
- }
- } else {
- painter->setBrush(vopt->backgroundBrush);
+ }
+ const bool highlightCurrent = vopt->state.testAnyFlags(State_Selected | State_MouseOver);
+ if (highlightCurrent) {
+ const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget);
+ if (highContrastTheme)
+ painter->setBrush(vopt->palette.highlight());
+ else
+ painter->setBrush(view->alternatingRowColors() ? vopt->palette.highlight() : WINUI3Colors[colorSchemeIndex][subtleHighlightColor]);
+ QWidget *editorWidget = view ? view->indexWidget(view->currentIndex()) : nullptr;
+ if (editorWidget) {
+ QPalette pal = editorWidget->palette();
+ QColor editorBgColor = vopt->backgroundBrush == Qt::NoBrush ? vopt->palette.color(widget->backgroundRole()) : vopt->backgroundBrush.color();
+ editorBgColor.setAlpha(255);
+ pal.setColor(editorWidget->backgroundRole(), editorBgColor);
+ editorWidget->setPalette(pal);
}
- painter->setPen(Qt::NoPen);
+ } else {
+ painter->setBrush(vopt->backgroundBrush);
+ }
+ painter->setPen(Qt::NoPen);
- if (onlyOne) {
- painter->drawRoundedRect(rect.marginsRemoved(QMargins(2, 2, 2, 2)),
- secondLevelRoundingRadius, secondLevelRoundingRadius);
- } else if (isFirst) {
- painter->save();
- painter->setClipRect(rect);
- painter->drawRoundedRect(rect.marginsRemoved(QMargins(2, 2, -secondLevelRoundingRadius, 2)),
- secondLevelRoundingRadius, secondLevelRoundingRadius);
- painter->restore();
- } else if (isLast) {
- painter->save();
- painter->setClipRect(rect);
- painter->drawRoundedRect(rect.marginsRemoved(QMargins(-secondLevelRoundingRadius, 2, 2, 2)),
- secondLevelRoundingRadius, secondLevelRoundingRadius);
- painter->restore();
- } else {
- painter->drawRect(rect.marginsRemoved(QMargins(0, 2, 0, 2)));
- }
+ if (onlyOne) {
+ painter->drawRoundedRect(rect.marginsRemoved(QMargins(2, 2, 2, 2)),
+ secondLevelRoundingRadius, secondLevelRoundingRadius);
+ } else if (isFirst) {
+ painter->save();
+ painter->setClipRect(rect);
+ painter->drawRoundedRect(rect.marginsRemoved(QMargins(2, 2, -secondLevelRoundingRadius, 2)),
+ secondLevelRoundingRadius, secondLevelRoundingRadius);
+ painter->restore();
+ } else if (isLast) {
+ painter->save();
+ painter->setClipRect(rect);
+ painter->drawRoundedRect(rect.marginsRemoved(QMargins(-secondLevelRoundingRadius, 2, 2, 2)),
+ secondLevelRoundingRadius, secondLevelRoundingRadius);
+ painter->restore();
+ } else {
+ painter->drawRect(rect.marginsRemoved(QMargins(0, 2, 0, 2)));
+ }
- // draw the check mark
- if (vopt->features & QStyleOptionViewItem::HasCheckIndicator) {
- QStyleOptionViewItem option(*vopt);
- option.rect = checkRect;
- option.state = option.state & ~QStyle::State_HasFocus;
+ // draw the check mark
+ if (vopt->features & QStyleOptionViewItem::HasCheckIndicator) {
+ QStyleOptionViewItem option(*vopt);
+ option.rect = checkRect;
+ option.state = option.state & ~QStyle::State_HasFocus;
- switch (vopt->checkState) {
- case Qt::Unchecked:
- option.state |= QStyle::State_Off;
- break;
- case Qt::PartiallyChecked:
- option.state |= QStyle::State_NoChange;
- break;
- case Qt::Checked:
- option.state |= QStyle::State_On;
- break;
- }
- proxy()->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &option, painter, widget);
+ switch (vopt->checkState) {
+ case Qt::Unchecked:
+ option.state |= QStyle::State_Off;
+ break;
+ case Qt::PartiallyChecked:
+ option.state |= QStyle::State_NoChange;
+ break;
+ case Qt::Checked:
+ option.state |= QStyle::State_On;
+ break;
}
+ proxy()->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &option, painter, widget);
+ }
- // draw the icon
- QIcon::Mode mode = QIcon::Normal;
- if (!(vopt->state & QStyle::State_Enabled))
- mode = QIcon::Disabled;
- else if (vopt->state & QStyle::State_Selected)
- mode = QIcon::Selected;
- QIcon::State state = vopt->state & QStyle::State_Open ? QIcon::On : QIcon::Off;
- vopt->icon.paint(painter, iconRect, vopt->decorationAlignment, mode, state);
-
- painter->setPen(highlightCurrent && highContrastTheme ? vopt->palette.base().color()
- : vopt->palette.text().color());
- d->viewItemDrawText(painter, vopt, textRect);
-
- // paint a vertical marker for QListView
- if (vopt->state & State_Selected) {
- if (const QListView *lv = qobject_cast<const QListView *>(widget);
- lv && lv->viewMode() != QListView::IconMode && !highContrastTheme) {
- painter->setPen(vopt->palette.accent().color());
- const auto xPos = isRtl ? rect.right() - 1 : rect.left();
- const QLineF lines[2] = {
- QLineF(xPos, rect.y() + 2, xPos, rect.y() + rect.height() - 2),
- QLineF(xPos + 1, rect.y() + 2, xPos + 1, rect.y() + rect.height() - 2),
- };
- painter->drawLines(lines, 2);
- }
+ // draw the icon
+ QIcon::Mode mode = QIcon::Normal;
+ if (!(vopt->state & QStyle::State_Enabled))
+ mode = QIcon::Disabled;
+ else if (vopt->state & QStyle::State_Selected)
+ mode = QIcon::Selected;
+ QIcon::State state = vopt->state & QStyle::State_Open ? QIcon::On : QIcon::Off;
+ vopt->icon.paint(painter, iconRect, vopt->decorationAlignment, mode, state);
+
+ painter->setPen(highlightCurrent && highContrastTheme ? vopt->palette.base().color()
+ : vopt->palette.text().color());
+ d->viewItemDrawText(painter, vopt, textRect);
+
+ // paint a vertical marker for QListView
+ if (vopt->state & State_Selected) {
+ if (const QListView *lv = qobject_cast<const QListView *>(widget);
+ lv && lv->viewMode() != QListView::IconMode && !highContrastTheme) {
+ painter->setPen(vopt->palette.accent().color());
+ const auto xPos = isRtl ? rect.right() - 1 : rect.left();
+ const QLineF lines[2] = {
+ QLineF(xPos, rect.y() + 2, xPos, rect.y() + rect.height() - 2),
+ QLineF(xPos + 1, rect.y() + 2, xPos + 1, rect.y() + rect.height() - 2),
+ };
+ painter->drawLines(lines, 2);
}
- } else {
- QRect textRect = proxy()->subElementRect(SE_ItemViewItemText, vopt, widget);
- d->viewItemDrawText(painter, vopt, textRect);
}
}
break;