/**************************************************************************** ** ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the manual tests of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 as published by the Free Software ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "inputinspector.h" #include #include #include #include static const int timerInterval = 100; InputInspector::InputInspector(QObject *parent) : QObject(parent) { } InputInspector::~InputInspector() { m_window = nullptr; killTimer(m_timerId); } QString InputInspector::mouseGrabber() const { QString name; if (m_window) { if (QQuickItem *grabber = m_window->mouseGrabberItem()) { name = objectIdentifier(grabber); } else { name = QLatin1String("no grabber"); } } else { name = "ERROR: need a source window"; } return name; } QString InputInspector::passiveGrabbers() const { return vectorStringJoin(passiveGrabbers_helper()); } QString InputInspector::exclusiveGrabbers() const { return vectorStringJoin(exclusiveGrabbers_helper()); } QString InputInspector::vectorStringJoin(const QVector &arr) const { QString res; for (QObject* obj: arr) { if (!res.isEmpty()) res += QLatin1String(" , "); res += objectIdentifier(obj); } res.prepend(QLatin1String("[")); res += QLatin1String("]"); return res; } QQuickWindow *InputInspector::source() const { return m_window; } void InputInspector::setSource(QQuickWindow *window) { m_window = window; if (m_window && !m_timerId) m_timerId = startTimer(timerInterval); emit sourceChanged(); } void InputInspector::update() { const QString mouseGrabberName = mouseGrabber(); if (lastState.mouseGrabber != mouseGrabberName) { emit mouseGrabberChanged(); lastState.mouseGrabber = mouseGrabberName; } const QString tempPassiveGrabbers = passiveGrabbers(); if (lastState.passiveGrabbers != tempPassiveGrabbers) { emit passiveGrabbersChanged(); lastState.passiveGrabbers = tempPassiveGrabbers; } const QString tempExclusiveGrabbers = exclusiveGrabbers(); if (lastState.exclusiveGrabbers != tempExclusiveGrabbers) { emit exclusiveGrabbersChanged(); lastState.exclusiveGrabbers = tempExclusiveGrabbers; } } void InputInspector::timerEvent(QTimerEvent *event) { if (event->timerId() == m_timerId) update(); } QQuickPointerDevice *InputInspector::pointerDevice() const { QQuickPointerDevice *device = QQuickPointerDevice::touchDevices().value(0); if (!device) device = QQuickPointerDevice::genericMouseDevice(); return device; } QVector InputInspector::passiveGrabbers_helper(int pointId /*= 0*/) const { QVector result; QSet visited; QQuickPointerDevice *device = pointerDevice(); if (device && source()) { QQuickWindowPrivate *winPriv = QQuickWindowPrivate::get(source()); QQuickPointerEvent *pointerEvent = winPriv->pointerEventInstance(device); if (pointerEvent) { for (int i = 0; i < pointerEvent->pointCount(); ++i) { QQuickEventPoint *eventPoint = pointerEvent->point(i); QVector > passives = eventPoint->passiveGrabbers(); if (!pointId || eventPoint->pointId() == pointId) { for (auto it = passives.constBegin(); it != passives.constEnd(); ++it) { QObject *handler = it->data(); if (!visited.contains(handler)) { result << it->data(); visited << handler; } } } } } } return result; } QVector InputInspector::exclusiveGrabbers_helper(int pointId /*= 0*/) const { QVector result; QSet visited; QQuickPointerDevice *device = pointerDevice(); if (device && source()) { QQuickWindowPrivate *winPriv = QQuickWindowPrivate::get(source()); QQuickPointerEvent *pointerEvent = winPriv->pointerEventInstance(device); if (pointerEvent) { for (int i = 0; i < pointerEvent->pointCount(); ++i) { QQuickEventPoint *eventPoint = pointerEvent->point(i); if (!pointId || eventPoint->pointId() == pointId) { if (QObject *exclusiveGrabber = eventPoint->exclusiveGrabber()) { if (!visited.contains(exclusiveGrabber)) { result << exclusiveGrabber; visited << exclusiveGrabber; } } } } } } return result; } QString InputInspector::objectIdentifier(QObject *o) { QString name; name = o->objectName(); if (name.isEmpty()) name = o->property("text").toString(); if (name.isEmpty()) name = o->metaObject()->className(); if (name.isEmpty()) name = QLatin1String("unknown"); return name; }