Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qwindowsuiautils.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <QtGui/qtguiglobal.h>
5#if QT_CONFIG(accessibility)
6
7#include "qwindowsuiautils.h"
8#include "qwindowscontext.h"
9#include "qwindowswindow.h"
10
11#include <QtGui/qwindow.h>
12#include <QtGui/private/qhighdpiscaling_p.h>
13#include <cmath>
14
16
17namespace QWindowsUiAutomation {
18
19// Returns the window containing the element (usually the top window),
20QWindow *windowForAccessible(const QAccessibleInterface *accessible)
21{
22 QWindow *window = accessible->window();
23 if (!window) {
24 const QAccessibleInterface *acc = accessible;
25 const QAccessibleInterface *par = accessible->parent();
26 while (par && par->isValid() && !window) {
27 window = par->window();
28 acc = par;
29 par = par->parent();
30 }
31 if (!window) {
32 // Workaround for WebEngineView not knowing its parent.
33 const auto appWindows = QGuiApplication::topLevelWindows();
34 for (QWindow *w : appWindows) {
35 if (QAccessibleInterface *root = w->accessibleRoot()) {
36 int count = root->childCount();
37 for (int i = 0; i < count; ++i) {
38 if (root->child(i) == acc)
39 return w;
40 }
41 }
42 }
43 }
44 }
45 return window;
46}
47
48// Returns the native window handle associated with the element, if any.
49// Usually it will be NULL, as Qt5 by default uses alien widgets with no native windows.
50HWND hwndForAccessible(const QAccessibleInterface *accessible)
51{
52 if (QWindow *window = accessible->window()) {
53 if (!accessible->parent() || (accessible->parent()->window() != window)) {
55 }
56 }
57 return nullptr;
58}
59
60void clearVariant(VARIANT *variant)
61{
62 variant->vt = VT_EMPTY;
63 variant->punkVal = nullptr;
64}
65
66void setVariantI4(int value, VARIANT *variant)
67{
68 variant->vt = VT_I4;
69 variant->lVal = value;
70}
71
72void setVariantBool(bool value, VARIANT *variant)
73{
74 variant->vt = VT_BOOL;
75 variant->boolVal = value ? -1 : 0;
76}
77
78void setVariantDouble(double value, VARIANT *variant)
79{
80 variant->vt = VT_R8;
81 variant->dblVal = value;
82}
83
84BSTR bStrFromQString(const QString &value)
85{
86 return SysAllocString(reinterpret_cast<const wchar_t *>(value.utf16()));
87}
88
89void setVariantString(const QString &value, VARIANT *variant)
90{
91 variant->vt = VT_BSTR;
92 variant->bstrVal = bStrFromQString(value);
93}
94
95// Scales a rect to native coordinates, according to high dpi settings.
96void rectToNativeUiaRect(const QRect &rect, const QWindow *w, UiaRect *uiaRect)
97{
98 if (w && uiaRect) {
100 uiaRect->left =r.x();
101 uiaRect->top = r.y();
102 uiaRect->width = r.width();
103 uiaRect->height = r.height();
104 }
105}
106
107// Scales a point from native coordinates, according to high dpi settings.
108void nativeUiaPointToPoint(const UiaPoint &uiaPoint, const QWindow *w, QPoint *point)
109{
110 if (w && point)
111 *point = QHighDpi::fromNativePixels(QPoint(uiaPoint.x, uiaPoint.y), w);
112}
113
114// Maps an accessibility role ID to an UI Automation control type ID.
115long roleToControlTypeId(QAccessible::Role role)
116{
117 static const QHash<QAccessible::Role, long> mapping {
118 {QAccessible::TitleBar, UIA_TitleBarControlTypeId},
119 {QAccessible::MenuBar, UIA_MenuBarControlTypeId},
120 {QAccessible::ScrollBar, UIA_ScrollBarControlTypeId},
121 {QAccessible::Grip, UIA_ThumbControlTypeId},
122 {QAccessible::Sound, UIA_CustomControlTypeId},
123 {QAccessible::Cursor, UIA_CustomControlTypeId},
124 {QAccessible::Caret, UIA_CustomControlTypeId},
125 {QAccessible::AlertMessage, UIA_WindowControlTypeId},
126 {QAccessible::Window, UIA_WindowControlTypeId},
127 {QAccessible::Client, UIA_GroupControlTypeId},
128 {QAccessible::PopupMenu, UIA_MenuControlTypeId},
129 {QAccessible::MenuItem, UIA_MenuItemControlTypeId},
130 {QAccessible::ToolTip, UIA_ToolTipControlTypeId},
131 {QAccessible::Application, UIA_CustomControlTypeId},
132 {QAccessible::Document, UIA_DocumentControlTypeId},
133 {QAccessible::Pane, UIA_PaneControlTypeId},
134 {QAccessible::Chart, UIA_CustomControlTypeId},
135 {QAccessible::Dialog, UIA_WindowControlTypeId},
136 {QAccessible::Border, UIA_CustomControlTypeId},
137 {QAccessible::Grouping, UIA_GroupControlTypeId},
138 {QAccessible::Separator, UIA_SeparatorControlTypeId},
139 {QAccessible::ToolBar, UIA_ToolBarControlTypeId},
140 {QAccessible::StatusBar, UIA_StatusBarControlTypeId},
141 {QAccessible::Table, UIA_TableControlTypeId},
142 {QAccessible::ColumnHeader, UIA_HeaderControlTypeId},
143 {QAccessible::RowHeader, UIA_HeaderControlTypeId},
144 {QAccessible::Column, UIA_HeaderItemControlTypeId},
145 {QAccessible::Row, UIA_HeaderItemControlTypeId},
146 {QAccessible::Cell, UIA_DataItemControlTypeId},
147 {QAccessible::Link, UIA_HyperlinkControlTypeId},
148 {QAccessible::HelpBalloon, UIA_ToolTipControlTypeId},
149 {QAccessible::Assistant, UIA_CustomControlTypeId},
150 {QAccessible::List, UIA_ListControlTypeId},
151 {QAccessible::ListItem, UIA_ListItemControlTypeId},
152 {QAccessible::Tree, UIA_TreeControlTypeId},
153 {QAccessible::TreeItem, UIA_TreeItemControlTypeId},
154 {QAccessible::PageTab, UIA_TabItemControlTypeId},
155 {QAccessible::PropertyPage, UIA_CustomControlTypeId},
156 {QAccessible::Indicator, UIA_CustomControlTypeId},
157 {QAccessible::Graphic, UIA_ImageControlTypeId},
158 {QAccessible::StaticText, UIA_TextControlTypeId},
159 {QAccessible::EditableText, UIA_EditControlTypeId},
160 {QAccessible::Button, UIA_ButtonControlTypeId},
161 {QAccessible::CheckBox, UIA_CheckBoxControlTypeId},
162 {QAccessible::RadioButton, UIA_RadioButtonControlTypeId},
163 {QAccessible::ComboBox, UIA_ComboBoxControlTypeId},
164 {QAccessible::ProgressBar, UIA_ProgressBarControlTypeId},
165 {QAccessible::Dial, UIA_CustomControlTypeId},
166 {QAccessible::HotkeyField, UIA_CustomControlTypeId},
167 {QAccessible::Slider, UIA_SliderControlTypeId},
168 {QAccessible::SpinBox, UIA_SpinnerControlTypeId},
169 {QAccessible::Canvas, UIA_CustomControlTypeId},
170 {QAccessible::Animation, UIA_CustomControlTypeId},
171 {QAccessible::Equation, UIA_CustomControlTypeId},
172 {QAccessible::ButtonDropDown, UIA_ButtonControlTypeId},
173 {QAccessible::ButtonMenu, UIA_ButtonControlTypeId},
174 {QAccessible::ButtonDropGrid, UIA_ButtonControlTypeId},
175 {QAccessible::Whitespace, UIA_CustomControlTypeId},
176 {QAccessible::PageTabList, UIA_TabControlTypeId},
177 {QAccessible::Clock, UIA_CustomControlTypeId},
178 {QAccessible::Splitter, UIA_CustomControlTypeId},
179 {QAccessible::Paragraph, UIA_TextControlTypeId},
180 {QAccessible::WebDocument, UIA_DocumentControlTypeId},
181 {QAccessible::Heading, UIA_TextControlTypeId},
182 };
183
184 return mapping.value(role, UIA_CustomControlTypeId);
185}
186
187// True if a character can be a separator for a text unit.
188bool isTextUnitSeparator(TextUnit unit, const QChar &ch)
189{
190 return (((unit == TextUnit_Word) || (unit == TextUnit_Format)) && ch.isSpace())
191 || ((unit == TextUnit_Line) && (ch.toLatin1() == '\n'));
192}
193
194} // namespace QWindowsUiAutomation
195
196
198
199#endif // QT_CONFIG(accessibility)
\inmodule QtCore
static QWindowList topLevelWindows()
Returns a list of the top-level windows in the application.
\inmodule QtCore\reentrant
Definition qpoint.h:25
\inmodule QtCore\reentrant
Definition qrect.h:484
\inmodule QtCore\reentrant
Definition qrect.h:30
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
\inmodule QtGui
Definition qwindow.h:63
static HWND handleOf(const QWindow *w)
rect
[4]
T toNativePixels(const T &value, const C *context)
T fromNativePixels(const T &value, const C *context)
Combined button and popup list for selecting options.
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
GLfloat GLfloat GLfloat w
[0]
GLboolean r
[2]
GLenum GLenum GLsizei count
GLenum GLenum GLenum GLenum mapping
QVariant variant
[1]
aWidget window() -> setWindowTitle("New Window Title")
[2]