diff options
Diffstat (limited to 'src/quick/items/qquickwindow.cpp')
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 117 |
1 files changed, 92 insertions, 25 deletions
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 2eee98a738..39f238e4ed 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -78,8 +78,11 @@ #include <private/qqmldebugserviceinterfaces_p.h> #include <private/qqmldebugconnector_p.h> #if QT_CONFIG(opengl) -# include <private/qopenglvertexarrayobject_p.h> -# include <private/qsgdefaultrendercontext_p.h> +#include <private/qopenglvertexarrayobject_p.h> +#include <private/qsgdefaultrendercontext_p.h> +#include <private/qopengl_p.h> +#include <QOpenGLContext> +#include <QOpenGLFramebufferObject> #endif #ifndef QT_NO_DEBUG_STREAM #include <private/qdebug_p.h> @@ -93,6 +96,7 @@ Q_LOGGING_CATEGORY(DBG_TOUCH, "qt.quick.touch") Q_LOGGING_CATEGORY(DBG_TOUCH_TARGET, "qt.quick.touch.target") Q_LOGGING_CATEGORY(DBG_MOUSE, "qt.quick.mouse") Q_LOGGING_CATEGORY(DBG_MOUSE_TARGET, "qt.quick.mouse.target") +Q_LOGGING_CATEGORY(lcTablet, "qt.quick.tablet") Q_LOGGING_CATEGORY(lcWheelTarget, "qt.quick.wheel.target") Q_LOGGING_CATEGORY(lcGestureTarget, "qt.quick.gesture.target") Q_LOGGING_CATEGORY(DBG_HOVER_TRACE, "qt.quick.hover.trace") @@ -547,7 +551,7 @@ void QQuickWindowPrivate::renderSceneGraph(const QSize &size, const QSize &surfa else context->endNextFrame(renderer); - if (renderer->hasCustomRenderModeWithContinuousUpdate()) { + if (renderer && renderer->hasCustomRenderModeWithContinuousUpdate()) { // For the overdraw visualizer. This update is not urgent so avoid a // direct update() call, this is only here to keep the overdraw // visualization box rotating even when the scene is static. @@ -560,6 +564,7 @@ QQuickWindowPrivate::QQuickWindowPrivate() , activeFocusItem(nullptr) #if QT_CONFIG(cursor) , cursorItem(nullptr) + , cursorHandler(nullptr) #endif #if QT_CONFIG(quick_draganddrop) , dragGrabber(nullptr) @@ -681,10 +686,13 @@ void QQuickWindow::handleApplicationStateChanged(Qt::ApplicationState state) QQmlListProperty<QObject> QQuickWindowPrivate::data() { - return QQmlListProperty<QObject>(q_func(), nullptr, QQuickWindowPrivate::data_append, - QQuickWindowPrivate::data_count, - QQuickWindowPrivate::data_at, - QQuickWindowPrivate::data_clear); + return QQmlListProperty<QObject>(q_func(), nullptr, + QQuickWindowPrivate::data_append, + QQuickWindowPrivate::data_count, + QQuickWindowPrivate::data_at, + QQuickWindowPrivate::data_clear, + QQuickWindowPrivate::data_replace, + QQuickWindowPrivate::data_removeLast); } static QMouseEvent *touchToMouseEvent(QEvent::Type type, const QTouchEvent::TouchPoint &p, QTouchEvent *event, QQuickItem *item, bool transformNeeded = true) @@ -1762,6 +1770,10 @@ bool QQuickWindow::event(QEvent *e) if (d->activeFocusItem) QCoreApplication::sendEvent(d->activeFocusItem, e); return true; + case QEvent::LanguageChange: + if (d->contentItem) + QCoreApplication::sendEvent(d->contentItem, e); + break; default: break; } @@ -2118,6 +2130,17 @@ void QQuickWindow::wheelEvent(QWheelEvent *event) } #endif // wheelevent +#if QT_CONFIG(tabletevent) +/*! \reimp */ +void QQuickWindow::tabletEvent(QTabletEvent *event) +{ + Q_D(QQuickWindow); + qCDebug(lcTablet) << event; + // TODO Qt 6: make sure TabletEnterProximity and TabletLeaveProximity are delivered here + d->deliverPointerEvent(d->pointerEventInstance(event)); +} +#endif // tabletevent + bool QQuickWindowPrivate::deliverTouchCancelEvent(QTouchEvent *event) { qCDebug(DBG_TOUCH) << event; @@ -2396,8 +2419,14 @@ QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QQuickPointerDevic #endif ev = new QQuickPointerTouchEvent(q, device); break; +#if QT_CONFIG(tabletevent) + case QQuickPointerDevice::Stylus: + case QQuickPointerDevice::Airbrush: + case QQuickPointerDevice::Puck: + ev = new QQuickPointerTabletEvent(q, device); + break; +#endif default: - // TODO tablet event types break; } pointerEventInstances << ev; @@ -2428,7 +2457,15 @@ QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QEvent *event) con case QEvent::TouchCancel: dev = QQuickPointerDevice::touchDevice(static_cast<QTouchEvent *>(event)->device()); break; - // TODO tablet event types +#if QT_CONFIG(tabletevent) + case QEvent::TabletPress: + case QEvent::TabletMove: + case QEvent::TabletRelease: + case QEvent::TabletEnterProximity: + case QEvent::TabletLeaveProximity: + dev = QQuickPointerDevice::tabletDevice(static_cast<QTabletEvent *>(event)); + break; +#endif #if QT_CONFIG(gestures) case QEvent::NativeGesture: dev = QQuickPointerDevice::touchDevice(static_cast<QNativeGestureEvent *>(event)->device()); @@ -2463,6 +2500,11 @@ void QQuickWindowPrivate::deliverPointerEvent(QQuickPointerEvent *event) deliverTouchEvent(event->asPointerTouchEvent()); } else { deliverSinglePointEventUntilAccepted(event); + // If any handler got interested in the tablet event, we don't want to receive a synth-mouse event from QtGui + // TODO Qt 6: QTabletEvent will be accepted by default, like other events + if (event->asPointerTabletEvent() && + (!event->point(0)->passiveGrabbers().isEmpty() || event->point(0)->exclusiveGrabber())) + event->setAccepted(true); } event->reset(nullptr); @@ -2967,26 +3009,27 @@ void QQuickWindowPrivate::updateCursor(const QPointF &scenePos) { Q_Q(QQuickWindow); - QQuickItem *oldCursorItem = cursorItem; - cursorItem = findCursorItem(contentItem, scenePos); + auto cursorItemAndHandler = findCursorItemAndHandler(contentItem, scenePos); - if (cursorItem != oldCursorItem) { + if (cursorItem != cursorItemAndHandler.first || cursorHandler != cursorItemAndHandler.second) { QWindow *renderWindow = QQuickRenderControl::renderWindowFor(q); QWindow *window = renderWindow ? renderWindow : q; + cursorItem = cursorItemAndHandler.first; + cursorHandler = cursorItemAndHandler.second; if (cursorItem) - window->setCursor(cursorItem->cursor()); + window->setCursor(QQuickItemPrivate::get(cursorItem)->effectiveCursor(cursorHandler)); else window->unsetCursor(); } } -QQuickItem *QQuickWindowPrivate::findCursorItem(QQuickItem *item, const QPointF &scenePos) +QPair<QQuickItem*, QQuickPointerHandler*> QQuickWindowPrivate::findCursorItemAndHandler(QQuickItem *item, const QPointF &scenePos) const { QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) { QPointF p = item->mapFromScene(scenePos); if (!item->contains(p)) - return nullptr; + return {nullptr, nullptr}; } if (itemPrivate->subtreeCursorEnabled) { @@ -2995,17 +3038,24 @@ QQuickItem *QQuickWindowPrivate::findCursorItem(QQuickItem *item, const QPointF QQuickItem *child = children.at(ii); if (!child->isVisible() || !child->isEnabled() || QQuickItemPrivate::get(child)->culled) continue; - if (QQuickItem *cursorItem = findCursorItem(child, scenePos)) - return cursorItem; + auto ret = findCursorItemAndHandler(child, scenePos); + if (ret.first) + return ret; + } + if (itemPrivate->hasCursor || itemPrivate->hasCursorHandler) { + QPointF p = item->mapFromScene(scenePos); + if (!item->contains(p)) + return {nullptr, nullptr}; + if (itemPrivate->hasCursorHandler) { + if (auto handler = itemPrivate->effectiveCursorHandler()) + return {item, handler}; + } + if (itemPrivate->hasCursor) + return {item, nullptr}; } } - if (itemPrivate->hasCursor) { - QPointF p = item->mapFromScene(scenePos); - if (item->contains(p)) - return item; - } - return nullptr; + return {nullptr, nullptr}; } #endif @@ -3248,6 +3298,20 @@ void QQuickWindowPrivate::data_clear(QQmlListProperty<QObject> *property) itemProperty.clear(&itemProperty); } +void QQuickWindowPrivate::data_replace(QQmlListProperty<QObject> *property, int i, QObject *o) +{ + QQuickWindow *win = static_cast<QQuickWindow*>(property->object); + QQmlListProperty<QObject> itemProperty = QQuickItemPrivate::get(win->contentItem())->data(); + itemProperty.replace(&itemProperty, i, o); +} + +void QQuickWindowPrivate::data_removeLast(QQmlListProperty<QObject> *property) +{ + QQuickWindow *win = static_cast<QQuickWindow*>(property->object); + QQmlListProperty<QObject> itemProperty = QQuickItemPrivate::get(win->contentItem())->data(); + itemProperty.removeLast(&itemProperty); +} + bool QQuickWindowPrivate::isRenderable() const { Q_Q(const QQuickWindow); @@ -4377,7 +4441,7 @@ QQmlIncubationController *QQuickWindow::incubationController() const OpenGL context is actually created. QQuickWindow::openglContext() will still return 0 for this window - until after the QQuickWindow::sceneGraphInitialize() has been + until after the QQuickWindow::sceneGraphInitialized() has been emitted. \note @@ -4513,7 +4577,7 @@ QSGTexture *QQuickWindow::createTextureFromImage(const QImage &image, CreateText } - +#if QT_DEPRECATED_SINCE(5, 15) /*! Creates a new QSGTexture object from an existing OpenGL texture \a id and \a size. @@ -4535,6 +4599,8 @@ QSGTexture *QQuickWindow::createTextureFromImage(const QImage &image, CreateText \note This function has no effect when running on the RHI graphics abstraction. Use createTextureFromNativeObject() instead. + \obsolete + \sa sceneGraphInitialized(), QSGTexture */ QSGTexture *QQuickWindow::createTextureFromId(uint id, const QSize &size, CreateTextureOptions options) const @@ -4561,6 +4627,7 @@ QSGTexture *QQuickWindow::createTextureFromId(uint id, const QSize &size, Create #endif return nullptr; } +#endif /*! \enum QQuickWindow::NativeObjectType |