Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquickwindowinspector.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 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// Qt-Security score:significant
4
6#include "inspecttool.h"
7
8#include <private/qquickitem_p.h>
9
11
12namespace QmlJSDebugger {
13
14/*
15 * Returns the first visible item at the given position, or 0 when no such
16 * child exists.
17 */
18static QQuickItem *itemAt(QQuickItem *item, const QPointF &pos,
19 QQuickItem *overlay)
20{
21 if (item == overlay)
22 return nullptr;
23
24 if (!item->isVisible() || item->opacity() == 0.0)
25 return nullptr;
26
27 if (item->flags() & QQuickItem::ItemClipsChildrenToShape) {
28 if (!QRectF(0, 0, item->width(), item->height()).contains(pos))
29 return nullptr;
30 }
31
32 QList<QQuickItem *> children = QQuickItemPrivate::get(item)->paintOrderChildItems();
33 for (int i = children.size() - 1; i >= 0; --i) {
34 QQuickItem *child = children.at(i);
35 if (QQuickItem *betterCandidate = itemAt(child, item->mapToItem(child, pos),
36 overlay))
37 return betterCandidate;
38 }
39
40 if (!(item->flags() & QQuickItem::ItemHasContents))
41 return nullptr;
42
43 if (!QRectF(0, 0, item->width(), item->height()).contains(pos))
44 return nullptr;
45
46 return item;
47}
48
49/*
50 * Collects all the items at the given position, from top to bottom.
51 */
52static void collectItemsAt(QQuickItem *item, const QPointF &pos,
53 QQuickItem *overlay, QList<QQuickItem *> &resultList)
54{
55 if (item == overlay)
56 return;
57
58 if (item->flags() & QQuickItem::ItemClipsChildrenToShape) {
59 if (!QRectF(0, 0, item->width(), item->height()).contains(pos))
60 return;
61 }
62
63 QList<QQuickItem *> children = QQuickItemPrivate::get(item)->paintOrderChildItems();
64 for (int i = children.size() - 1; i >= 0; --i) {
65 QQuickItem *child = children.at(i);
66 collectItemsAt(child, item->mapToItem(child, pos), overlay, resultList);
67 }
68
69 if (!QRectF(0, 0, item->width(), item->height()).contains(pos))
70 return;
71
72 resultList.append(item);
73}
74
75QQuickWindowInspector::QQuickWindowInspector(QQuickWindow *quickWindow, QObject *parent) :
76 QObject(parent),
77 m_overlay(new QQuickItem),
78 m_window(quickWindow),
79 m_parentWindow(nullptr),
80 m_tool(nullptr)
81{
82 setParentWindow(quickWindow);
83
84 // Try to make sure the overlay is always on top
85 m_overlay->setZ(FLT_MAX);
86
87 if (QQuickItem *root = m_window->contentItem())
88 m_overlay->setParentItem(root);
89
90 m_window->installEventFilter(this);
91}
92
93bool QQuickWindowInspector::eventFilter(QObject *obj, QEvent *event)
94{
95 if (!m_tool || obj != m_window)
96 return QObject::eventFilter(obj, event);
97
98 switch (event->type()) {
99 case QEvent::Enter:
100 m_tool->enterEvent(static_cast<QEnterEvent*>(event));
101 return true;
102 case QEvent::Leave:
103 m_tool->leaveEvent(event);
104 return true;
105 case QEvent::MouseButtonPress:
106 m_tool->mousePressEvent(static_cast<QMouseEvent*>(event));
107 return true;
108 case QEvent::MouseMove:
109 m_tool->mouseMoveEvent(static_cast<QMouseEvent*>(event));
110 return true;
111 case QEvent::MouseButtonRelease:
112 return true;
113 case QEvent::KeyPress:
114 m_tool->keyPressEvent(static_cast<QKeyEvent*>(event));
115 return true;
116 case QEvent::KeyRelease:
117 return true;
118 case QEvent::MouseButtonDblClick:
119 m_tool->mouseDoubleClickEvent(static_cast<QMouseEvent*>(event));
120 return true;
121#if QT_CONFIG(wheelevent)
122 case QEvent::Wheel:
123 return true;
124#endif
125 case QEvent::TouchBegin:
126 case QEvent::TouchUpdate:
127 case QEvent::TouchEnd:
128 m_tool->touchEvent(static_cast<QTouchEvent*>(event));
129 return true;
130 default:
131 break;
132 }
133
134 return QObject::eventFilter(obj, event);
135}
136
137static Qt::WindowFlags fixFlags(Qt::WindowFlags flags)
138{
139 // If only the type flag is given, some other window flags are automatically assumed. When we
140 // add a flag, we need to make those explicit.
141 switch (flags) {
142 case Qt::Window:
143 return flags | Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint
144 | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint;
145 case Qt::Dialog:
146 case Qt::Tool:
147 return flags | Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;
148 default:
149 return flags;
150 }
151}
152
154{
155 if (!m_parentWindow)
156 return;
157
158 Qt::WindowFlags flags = m_parentWindow->flags();
159 Qt::WindowFlags newFlags = appOnTop ? (fixFlags(flags) | Qt::WindowStaysOnTopHint) :
160 (flags & ~Qt::WindowStaysOnTopHint);
161 if (newFlags != flags)
162 m_parentWindow->setFlags(newFlags);
163}
164
166{
167 return m_tool != nullptr;
168}
169
171{
172 if (enabled) {
173 m_tool = new InspectTool(this, m_window);
174 } else {
175 delete m_tool;
176 m_tool = nullptr;
177 }
178}
179
180QQuickWindow *QQuickWindowInspector::quickWindow() const
181{
182 return m_window;
183}
184
185void QQuickWindowInspector::setParentWindow(QWindow *parentWindow)
186{
187 if (parentWindow) {
188 while (QWindow *w = parentWindow->parent())
189 parentWindow = w;
190 }
191
192 m_parentWindow = parentWindow;
193}
194
195QList<QQuickItem *> QQuickWindowInspector::itemsAt(const QPointF &pos) const
196{
197 QList<QQuickItem *> resultList;
198 QQuickItem *root = m_window->contentItem();
199 collectItemsAt(root, root->mapFromScene(pos), m_overlay,
200 resultList);
201 return resultList;
202}
203
204QQuickItem *QQuickWindowInspector::topVisibleItemAt(const QPointF &pos) const
205{
206 QQuickItem *root = m_window->contentItem();
207 return itemAt(root, root->mapFromScene(pos), m_overlay);
208}
209
210
211} // namespace QmlJSDebugger
212
213QT_END_NAMESPACE
214
215#include "moc_qquickwindowinspector.cpp"
void mouseDoubleClickEvent(QMouseEvent *)
void touchEvent(QTouchEvent *event)
void mousePressEvent(QMouseEvent *)
void enterEvent(QEnterEvent *)
void mouseMoveEvent(QMouseEvent *)
void keyPressEvent(QKeyEvent *)
Definition inspecttool.h:39
QQuickItem * topVisibleItemAt(const QPointF &pos) const
QList< QQuickItem * > itemsAt(const QPointF &pos) const
bool eventFilter(QObject *, QEvent *) override
Filters events if this object has been installed as an event filter for the watched object.
Combined button and popup list for selecting options.
static void collectItemsAt(QQuickItem *item, const QPointF &pos, QQuickItem *overlay, QList< QQuickItem * > &resultList)
static QQuickItem * itemAt(QQuickItem *item, const QPointF &pos, QQuickItem *overlay)
static Qt::WindowFlags fixFlags(Qt::WindowFlags flags)