summaryrefslogtreecommitdiffstats
path: root/src/widgets/graphicsview/qgraphicsproxywidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/graphicsview/qgraphicsproxywidget.cpp')
-rw-r--r--src/widgets/graphicsview/qgraphicsproxywidget.cpp253
1 files changed, 132 insertions, 121 deletions
diff --git a/src/widgets/graphicsview/qgraphicsproxywidget.cpp b/src/widgets/graphicsview/qgraphicsproxywidget.cpp
index 513cf9d361..1ff4814142 100644
--- a/src/widgets/graphicsview/qgraphicsproxywidget.cpp
+++ b/src/widgets/graphicsview/qgraphicsproxywidget.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** 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-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qglobal.h"
@@ -183,7 +147,9 @@ QT_BEGIN_NAMESPACE
\warning This class is provided for convenience when bridging
QWidgets and QGraphicsItems, it should not be used for
- high-performance scenarios.
+ high-performance scenarios. In particular, embedding widgets into a scene
+ that is then displayed through a QGraphicsView that uses an OpenGL viewport
+ will not work for all combinations.
\sa QGraphicsScene::addWidget(), QGraphicsWidget
*/
@@ -235,8 +201,9 @@ void QGraphicsProxyWidgetPrivate::sendWidgetMouseEvent(QGraphicsSceneHoverEvent
mouseEvent.setPos(event->pos());
mouseEvent.setScreenPos(event->screenPos());
mouseEvent.setButton(Qt::NoButton);
- mouseEvent.setButtons(0);
+ mouseEvent.setButtons({ });
mouseEvent.setModifiers(event->modifiers());
+ mouseEvent.setTimestamp(event->timestamp());
sendWidgetMouseEvent(&mouseEvent);
event->setAccepted(mouseEvent.isAccepted());
}
@@ -291,7 +258,7 @@ void QGraphicsProxyWidgetPrivate::sendWidgetMouseEvent(QGraphicsSceneMouseEvent
}
if (!lastWidgetUnderMouse) {
- QApplicationPrivate::dispatchEnterLeave(embeddedMouseGrabber ? embeddedMouseGrabber : receiver, 0, event->screenPos());
+ QApplicationPrivate::dispatchEnterLeave(embeddedMouseGrabber ? embeddedMouseGrabber : receiver, nullptr, event->screenPos());
lastWidgetUnderMouse = receiver;
}
@@ -302,6 +269,7 @@ void QGraphicsProxyWidgetPrivate::sendWidgetMouseEvent(QGraphicsSceneMouseEvent
QMouseEvent mouseEvent(type, pos, receiver->mapTo(receiver->topLevelWidget(), pos.toPoint()),
receiver->mapToGlobal(pos.toPoint()),
event->button(), event->buttons(), event->modifiers(), event->source());
+ mouseEvent.setTimestamp(event->timestamp());
QWidget *embeddedMouseGrabberPtr = (QWidget *)embeddedMouseGrabber;
QApplicationPrivate::sendMouseEvent(receiver, &mouseEvent, alienWidget, widget,
@@ -315,10 +283,10 @@ void QGraphicsProxyWidgetPrivate::sendWidgetMouseEvent(QGraphicsSceneMouseEvent
if (q->rect().contains(event->pos()) && q->acceptHoverEvents())
lastWidgetUnderMouse = alienWidget ? alienWidget : widget;
else // released on the frame our outside the item, or doesn't accept hover events.
- lastWidgetUnderMouse = 0;
+ lastWidgetUnderMouse = nullptr;
QApplicationPrivate::dispatchEnterLeave(lastWidgetUnderMouse, embeddedMouseGrabber, event->screenPos());
- embeddedMouseGrabber = 0;
+ embeddedMouseGrabber = nullptr;
#ifndef QT_NO_CURSOR
// ### Restore the cursor, don't override it.
@@ -342,7 +310,7 @@ void QGraphicsProxyWidgetPrivate::sendWidgetKeyEvent(QKeyEvent *event)
Q_ASSERT(receiver);
do {
- bool res = QApplication::sendEvent(receiver, event);
+ bool res = QCoreApplication::sendEvent(receiver, event);
if ((res && event->isAccepted()) || (q->isWindow() && receiver == widget))
break;
receiver = receiver->parentWidget();
@@ -356,9 +324,9 @@ void QGraphicsProxyWidgetPrivate::removeSubFocusHelper(QWidget *widget, Qt::Focu
{
QFocusEvent event(QEvent::FocusOut, reason);
QPointer<QWidget> widgetGuard = widget;
- QApplication::sendEvent(widget, &event);
+ QCoreApplication::sendEvent(widget, &event);
if (widgetGuard && event.isAccepted())
- QApplication::sendEvent(widget->style(), &event);
+ QCoreApplication::sendEvent(widget->style(), &event);
}
/*!
@@ -368,20 +336,20 @@ void QGraphicsProxyWidgetPrivate::removeSubFocusHelper(QWidget *widget, Qt::Focu
QWidget *QGraphicsProxyWidgetPrivate::findFocusChild(QWidget *child, bool next) const
{
if (!widget)
- return 0;
+ return nullptr;
// Run around the focus chain until we find a widget that can take tab focus.
if (!child) {
- child = next ? (QWidget *)widget : widget->d_func()->focus_prev;
+ child = next ? widget.data() : widget->previousInFocusChain();
} else {
- child = next ? child->d_func()->focus_next : child->d_func()->focus_prev;
- if ((next && child == widget) || (!next && child == widget->d_func()->focus_prev)) {
- return 0;
+ child = next ? child->nextInFocusChain() : child->previousInFocusChain();
+ if ((next && child == widget) || (!next && child == widget->previousInFocusChain())) {
+ return nullptr;
}
}
if (!child)
- return 0;
+ return nullptr;
QWidget *oldChild = child;
uint focus_flag = qt_tab_all_widgets() ? Qt::TabFocus : Qt::StrongFocus;
@@ -392,9 +360,9 @@ QWidget *QGraphicsProxyWidgetPrivate::findFocusChild(QWidget *child, bool next)
&& !(child->d_func()->extra && child->d_func()->extra->focus_proxy)) {
return child;
}
- child = next ? child->d_func()->focus_next : child->d_func()->focus_prev;
- } while (child != oldChild && !(next && child == widget) && !(!next && child == widget->d_func()->focus_prev));
- return 0;
+ child = next ? child->nextInFocusChain() : child->previousInFocusChain();
+ } while (child != oldChild && !(next && child == widget) && !(!next && child == widget->previousInFocusChain()));
+ return nullptr;
}
/*!
@@ -404,10 +372,10 @@ void QGraphicsProxyWidgetPrivate::_q_removeWidgetSlot()
{
Q_Q(QGraphicsProxyWidget);
if (!widget.isNull()) {
- if (QWExtra *extra = widget->d_func()->extra)
- extra->proxyWidget = 0;
+ if (const auto &extra = widget->d_func()->extra)
+ extra->proxyWidget = nullptr;
}
- widget = 0;
+ widget = nullptr;
delete q;
}
@@ -430,7 +398,7 @@ void QGraphicsProxyWidgetPrivate::updateProxyGeometryFromWidget()
QRectF widgetGeometry = widget->geometry();
QWidget *parentWidget = widget->parentWidget();
if (widget->isWindow()) {
- QGraphicsProxyWidget *proxyParent = 0;
+ QGraphicsProxyWidget *proxyParent = nullptr;
if (parentWidget && (proxyParent = qobject_cast<QGraphicsProxyWidget *>(q->parentWidget()))) {
// Nested window proxy (e.g., combobox popup), map widget to the
// parent widget's global coordinates, and map that to the parent
@@ -477,8 +445,8 @@ void QGraphicsProxyWidgetPrivate::updateProxyInputMethodAcceptanceFromWidget()
*/
void QGraphicsProxyWidgetPrivate::embedSubWindow(QWidget *subWin)
{
- QWExtra *extra;
- if (!((extra = subWin->d_func()->extra) && extra->proxyWidget)) {
+ const auto &extra = subWin->d_func()->extra;
+ if (!extra || !extra->proxyWidget) {
QGraphicsProxyWidget *subProxy = new QGraphicsProxyWidget(q_func(), subWin->windowFlags());
subProxy->d_func()->setWidget_helper(subWin, false);
}
@@ -493,11 +461,11 @@ void QGraphicsProxyWidgetPrivate::embedSubWindow(QWidget *subWin)
*/
void QGraphicsProxyWidgetPrivate::unembedSubWindow(QWidget *subWin)
{
- foreach (QGraphicsItem *child, children) {
+ for (QGraphicsItem *child : std::as_const(children)) {
if (child->isWidget()) {
if (QGraphicsProxyWidget *proxy = qobject_cast<QGraphicsProxyWidget *>(static_cast<QGraphicsWidget *>(child))) {
if (proxy->widget() == subWin) {
- proxy->setWidget(0);
+ proxy->setWidget(nullptr);
scene->removeItem(proxy);
delete proxy;
return;
@@ -554,9 +522,9 @@ QGraphicsProxyWidget::~QGraphicsProxyWidget()
/*!
Embeds \a widget into this proxy widget. The embedded widget must reside
exclusively either inside or outside of Graphics View. You cannot embed a
- widget as long as it is is visible elsewhere in the UI, at the same time.
+ widget as long as it is visible elsewhere in the UI, at the same time.
- \a widget must be a top-level widget whose parent is 0.
+ \a widget must be a top-level widget whose parent is \nullptr.
When the widget is embedded, its state (e.g., visible, enabled, geometry,
size hints) is copied into the proxy widget. If the embedded widget is
@@ -570,8 +538,8 @@ QGraphicsProxyWidget::~QGraphicsProxyWidget()
After this function returns, QGraphicsProxyWidget will keep its state
synchronized with that of \a widget whenever possible.
- If a widget is already embedded by this proxy when this function is
- called, that widget will first be automatically unembedded. Passing 0 for
+ If a widget is already embedded by this proxy when this function is called,
+ that widget will first be automatically unembedded. Passing \nullptr for
the \a widget argument will only unembed the widget, and the ownership of
the currently embedded widget will be passed on to the caller.
Every child widget that are embedded will also be embedded and their proxy
@@ -579,7 +547,7 @@ QGraphicsProxyWidget::~QGraphicsProxyWidget()
Note that widgets with the Qt::WA_PaintOnScreen widget attribute
set and widgets that wrap an external application or controller
- cannot be embedded. Examples are QGLWidget and QAxWidget.
+ cannot be embedded. Examples are QOpenGLWidget and QAxWidget.
\sa widget()
*/
@@ -598,7 +566,7 @@ void QGraphicsProxyWidgetPrivate::setWidget_helper(QWidget *newWidget, bool auto
QObject::disconnect(widget, SIGNAL(destroyed()), q, SLOT(_q_removeWidgetSlot()));
widget->removeEventFilter(q);
widget->setAttribute(Qt::WA_DontShowOnScreen, false);
- widget->d_func()->extra->proxyWidget = 0;
+ widget->d_func()->extra->proxyWidget = nullptr;
resolveFont(inheritedFontResolveMask);
resolvePalette(inheritedPaletteResolveMask);
widget->update();
@@ -631,7 +599,7 @@ void QGraphicsProxyWidgetPrivate::setWidget_helper(QWidget *newWidget, bool auto
if (!newWidget)
return;
if (!newWidget->isWindow()) {
- QWExtra *extra = newWidget->parentWidget()->d_func()->extra;
+ const auto &extra = newWidget->parentWidget()->d_func()->extra;
if (!extra || !extra->proxyWidget) {
qWarning("QGraphicsProxyWidget::setWidget: cannot embed widget %p "
"which is not a toplevel widget, and is not a child of an embedded widget", newWidget);
@@ -641,10 +609,10 @@ void QGraphicsProxyWidgetPrivate::setWidget_helper(QWidget *newWidget, bool auto
// Register this proxy within the widget's private.
// ### This is a bit backdoorish
- QWExtra *extra = newWidget->d_func()->extra;
+ QWExtra *extra = newWidget->d_func()->extra.get();
if (!extra) {
newWidget->d_func()->createExtra();
- extra = newWidget->d_func()->extra;
+ extra = newWidget->d_func()->extra.get();
}
QGraphicsProxyWidget **proxyWidget = &extra->proxyWidget;
if (*proxyWidget) {
@@ -697,9 +665,7 @@ void QGraphicsProxyWidgetPrivate::setWidget_helper(QWidget *newWidget, bool auto
if (!newWidget->testAttribute(Qt::WA_Resized))
newWidget->adjustSize();
- int left, top, right, bottom;
- newWidget->getContentsMargins(&left, &top, &right, &bottom);
- q->setContentsMargins(left, top, right, bottom);
+ q->setContentsMargins(newWidget->contentsMargins());
q->setWindowTitle(newWidget->windowTitle());
// size policies and constraints..
@@ -739,7 +705,7 @@ QWidget *QGraphicsProxyWidget::widget() const
Returns the rectangle for \a widget, which must be a descendant of
widget(), or widget() itself, in this proxy item's local coordinates.
- If no widget is embedded, \a widget is 0, or \a widget is not a
+ If no widget is embedded, \a widget is \nullptr, or \a widget is not a
descendant of the embedded widget, this function returns an empty QRectF.
\sa widget()
@@ -832,6 +798,10 @@ bool QGraphicsProxyWidget::event(QEvent *event)
return QGraphicsWidget::event(event);
switch (event->type()) {
+ case QEvent::WindowActivate:
+ case QEvent::WindowDeactivate:
+ QCoreApplication::sendEvent(d->widget, event);
+ break;
case QEvent::StyleChange:
// Propagate style changes to the embedded widget.
if (!d->styleChangeMode) {
@@ -843,7 +813,7 @@ bool QGraphicsProxyWidget::event(QEvent *event)
case QEvent::FontChange: {
// Propagate to widget.
QWidgetPrivate *wd = d->widget->d_func();
- int mask = d->font.resolve() | d->inheritedFontResolveMask;
+ int mask = d->font.resolveMask() | d->inheritedFontResolveMask;
wd->inheritedFontResolveMask = mask;
wd->resolveFont();
break;
@@ -851,7 +821,7 @@ bool QGraphicsProxyWidget::event(QEvent *event)
case QEvent::PaletteChange: {
// Propagate to widget.
QWidgetPrivate *wd = d->widget->d_func();
- int mask = d->palette.resolve() | d->inheritedPaletteResolveMask;
+ int mask = d->palette.resolveMask() | d->inheritedPaletteResolveMask;
wd->inheritedPaletteResolveMask = mask;
wd->resolvePalette();
break;
@@ -865,7 +835,7 @@ bool QGraphicsProxyWidget::event(QEvent *event)
case QEvent::ShortcutOverride: {
QWidget *focusWidget = d->widget->focusWidget();
while (focusWidget) {
- QApplication::sendEvent(focusWidget, event);
+ QCoreApplication::sendEvent(focusWidget, event);
if (event->isAccepted())
return true;
focusWidget = focusWidget->parentWidget();
@@ -878,7 +848,7 @@ bool QGraphicsProxyWidget::event(QEvent *event)
if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { //### Add MetaModifier?
QWidget *focusWidget = d->widget->focusWidget();
while (focusWidget) {
- bool res = QApplication::sendEvent(focusWidget, event);
+ const bool res = QCoreApplication::sendEvent(focusWidget, event);
if ((res && event->isAccepted()) || (isWindow() && focusWidget == d->widget)) {
event->accept();
break;
@@ -890,14 +860,14 @@ bool QGraphicsProxyWidget::event(QEvent *event)
}
break;
}
-#ifndef QT_NO_TOOLTIP
+#if QT_CONFIG(tooltip)
case QEvent::GraphicsSceneHelp: {
// Propagate the help event (for tooltip) to the widget under mouse
if (d->lastWidgetUnderMouse) {
QGraphicsSceneHelpEvent *he = static_cast<QGraphicsSceneHelpEvent *>(event);
QPoint pos = d->mapToReceiver(mapFromScene(he->scenePos()), d->lastWidgetUnderMouse).toPoint();
QHelpEvent e(QEvent::ToolTip, pos, he->screenPos());
- QApplication::sendEvent(d->lastWidgetUnderMouse, &e);
+ QCoreApplication::sendEvent(d->lastWidgetUnderMouse, &e);
event->setAccepted(e.isAccepted());
return e.isAccepted();
}
@@ -916,16 +886,13 @@ bool QGraphicsProxyWidget::event(QEvent *event)
case QEvent::TouchBegin:
case QEvent::TouchUpdate:
case QEvent::TouchEnd: {
- if (event->spontaneous())
- qt_sendSpontaneousEvent(d->widget, event);
- else
- QApplication::sendEvent(d->widget, event);
-
- if (event->isAccepted())
+ QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
+ bool res = QApplicationPrivate::translateRawTouchEvent(d->widget, touchEvent);
+ if (res & touchEvent->isAccepted())
return true;
break;
- }
+ }
default:
break;
}
@@ -981,7 +948,7 @@ bool QGraphicsProxyWidget::eventFilter(QObject *object, QEvent *event)
d->styleChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
}
break;
-#ifndef QT_NO_TOOLTIP
+#if QT_CONFIG(tooltip)
case QEvent::ToolTipChange:
// Propagate tooltip change to the proxy.
if (!d->tooltipChangeMode) {
@@ -1044,7 +1011,8 @@ void QGraphicsProxyWidget::contextMenuEvent(QGraphicsSceneContextMenuEvent *even
// Send mouse event. ### Doesn't propagate the event.
QContextMenuEvent contextMenuEvent(QContextMenuEvent::Reason(event->reason()),
pos.toPoint(), globalPos, event->modifiers());
- QApplication::sendEvent(receiver, &contextMenuEvent);
+ contextMenuEvent.setTimestamp(event->timestamp());
+ QCoreApplication::sendEvent(receiver, &contextMenuEvent);
event->setAccepted(contextMenuEvent.isAccepted());
}
@@ -1065,7 +1033,7 @@ void QGraphicsProxyWidget::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
QDragEnterEvent proxyDragEnter(event->pos().toPoint(), event->dropAction(), event->mimeData(), event->buttons(), event->modifiers());
proxyDragEnter.setAccepted(event->isAccepted());
- QApplication::sendEvent(d->widget, &proxyDragEnter);
+ QCoreApplication::sendEvent(d->widget, &proxyDragEnter);
event->setAccepted(proxyDragEnter.isAccepted());
if (proxyDragEnter.isAccepted()) // we discard answerRect
event->setDropAction(proxyDragEnter.dropAction());
@@ -1082,8 +1050,8 @@ void QGraphicsProxyWidget::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
if (!d->widget || !d->dragDropWidget)
return;
QDragLeaveEvent proxyDragLeave;
- QApplication::sendEvent(d->dragDropWidget, &proxyDragLeave);
- d->dragDropWidget = 0;
+ QCoreApplication::sendEvent(d->dragDropWidget, &proxyDragLeave);
+ d->dragDropWidget = nullptr;
#endif
}
@@ -1112,7 +1080,7 @@ void QGraphicsProxyWidget::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
// Try to enter before we leave
QDragEnterEvent dragEnter(receiverPos, event->possibleActions(), event->mimeData(), event->buttons(), event->modifiers());
dragEnter.setDropAction(event->proposedAction());
- QApplication::sendEvent(receiver, &dragEnter);
+ QCoreApplication::sendEvent(receiver, &dragEnter);
event->setAccepted(dragEnter.isAccepted());
event->setDropAction(dragEnter.dropAction());
if (!event->isAccepted()) {
@@ -1124,14 +1092,14 @@ void QGraphicsProxyWidget::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
if (d->dragDropWidget) {
QDragLeaveEvent dragLeave;
- QApplication::sendEvent(d->dragDropWidget, &dragLeave);
+ QCoreApplication::sendEvent(d->dragDropWidget, &dragLeave);
}
d->dragDropWidget = receiver;
}
QDragMoveEvent dragMove(receiverPos, event->possibleActions(), event->mimeData(), event->buttons(), event->modifiers());
event->setDropAction(d->lastDropAction);
- QApplication::sendEvent(receiver, &dragMove);
+ QCoreApplication::sendEvent(receiver, &dragMove);
event->setAccepted(dragMove.isAccepted());
event->setDropAction(dragMove.dropAction());
if (event->isAccepted())
@@ -1144,8 +1112,8 @@ void QGraphicsProxyWidget::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
if (d->dragDropWidget) {
// Leave the last drag drop item
QDragLeaveEvent dragLeave;
- QApplication::sendEvent(d->dragDropWidget, &dragLeave);
- d->dragDropWidget = 0;
+ QCoreApplication::sendEvent(d->dragDropWidget, &dragLeave);
+ d->dragDropWidget = nullptr;
}
// Propagate
event->setDropAction(Qt::IgnoreAction);
@@ -1165,9 +1133,9 @@ void QGraphicsProxyWidget::dropEvent(QGraphicsSceneDragDropEvent *event)
if (d->widget && d->dragDropWidget) {
QPoint widgetPos = d->mapToReceiver(event->pos(), d->dragDropWidget).toPoint();
QDropEvent dropEvent(widgetPos, event->possibleActions(), event->mimeData(), event->buttons(), event->modifiers());
- QApplication::sendEvent(d->dragDropWidget, &dropEvent);
+ QCoreApplication::sendEvent(d->dragDropWidget, &dropEvent);
event->setAccepted(dropEvent.isAccepted());
- d->dragDropWidget = 0;
+ d->dragDropWidget = nullptr;
}
#endif
}
@@ -1190,8 +1158,8 @@ void QGraphicsProxyWidget::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
Q_D(QGraphicsProxyWidget);
// If hoverMove was compressed away, make sure we update properly here.
if (d->lastWidgetUnderMouse) {
- QApplicationPrivate::dispatchEnterLeave(0, d->lastWidgetUnderMouse, event->screenPos());
- d->lastWidgetUnderMouse = 0;
+ QApplicationPrivate::dispatchEnterLeave(nullptr, d->lastWidgetUnderMouse, event->screenPos());
+ d->lastWidgetUnderMouse = nullptr;
}
}
@@ -1207,13 +1175,13 @@ void QGraphicsProxyWidget::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
// Ignore events on the window frame.
if (!d->widget || !rect().contains(event->pos())) {
if (d->lastWidgetUnderMouse) {
- QApplicationPrivate::dispatchEnterLeave(0, d->lastWidgetUnderMouse, event->screenPos());
- d->lastWidgetUnderMouse = 0;
+ QApplicationPrivate::dispatchEnterLeave(nullptr, d->lastWidgetUnderMouse, event->screenPos());
+ d->lastWidgetUnderMouse = nullptr;
}
return;
}
- d->embeddedMouseGrabber = 0;
+ d->embeddedMouseGrabber = nullptr;
d->sendWidgetMouseEvent(event);
}
@@ -1232,7 +1200,7 @@ void QGraphicsProxyWidget::ungrabMouseEvent(QEvent *event)
{
Q_D(QGraphicsProxyWidget);
Q_UNUSED(event);
- d->embeddedMouseGrabber = 0;
+ d->embeddedMouseGrabber = nullptr;
}
/*!
@@ -1289,17 +1257,45 @@ void QGraphicsProxyWidget::wheelEvent(QGraphicsSceneWheelEvent *event)
if (!receiver)
receiver = d->widget;
+ // high precision event streams go to the grabber, which will be the
+ // QGraphicsView's viewport. We need to change that temporarily, otherwise
+ // the event we send to the receiver get grabbed by the viewport, resulting
+ // in infinite recursion
+ QPointer<QWidget> prev_grabber = QApplicationPrivate::wheel_widget;
+ if (event->phase() == Qt::ScrollBegin) {
+ QApplicationPrivate::wheel_widget = receiver;
+ } else if (event->phase() != Qt::NoScrollPhase && QApplicationPrivate::wheel_widget != receiver) {
+ // this event is part of a stream that didn't start here, so ignore
+ event->ignore();
+ return;
+ }
+
// Map event position from us to the receiver
pos = d->mapToReceiver(pos, receiver);
// Send mouse event.
- QWheelEvent wheelEvent(pos.toPoint(), event->screenPos(), event->delta(),
- event->buttons(), event->modifiers(), event->orientation());
+ QPoint angleDelta;
+ if (event->orientation() == Qt::Horizontal)
+ angleDelta.setX(event->delta());
+ else
+ angleDelta.setY(event->delta());
+ // pixelDelta, inverted, scrollPhase and source from the original QWheelEvent
+ // were not preserved in the QGraphicsSceneWheelEvent unfortunately
+ QWheelEvent wheelEvent(pos, event->screenPos(), event->pixelDelta(), angleDelta,
+ event->buttons(), event->modifiers(), event->phase(),
+ event->isInverted(), Qt::MouseEventSynthesizedByQt,
+ QPointingDevice::primaryPointingDevice());
QPointer<QWidget> focusWidget = d->widget->focusWidget();
extern bool qt_sendSpontaneousEvent(QObject *, QEvent *);
qt_sendSpontaneousEvent(receiver, &wheelEvent);
event->setAccepted(wheelEvent.isAccepted());
+ if (event->phase() == Qt::ScrollBegin) {
+ // reset the wheel grabber if the event wasn't accepted
+ if (!wheelEvent.isAccepted())
+ QApplicationPrivate::wheel_widget = prev_grabber;
+ }
+
// ### Remove, this should be done by proper focusIn/focusOut events.
if (focusWidget && !focusWidget->hasFocus()) {
focusWidget->update();
@@ -1367,12 +1363,12 @@ void QGraphicsProxyWidget::focusInEvent(QFocusEvent *event)
switch (event->reason()) {
case Qt::TabFocusReason: {
- if (QWidget *focusChild = d->findFocusChild(0, true))
+ if (QWidget *focusChild = d->findFocusChild(nullptr, true))
focusChild->setFocus(event->reason());
break;
}
case Qt::BacktabFocusReason:
- if (QWidget *focusChild = d->findFocusChild(0, false))
+ if (QWidget *focusChild = d->findFocusChild(nullptr, false))
focusChild->setFocus(event->reason());
break;
default:
@@ -1382,6 +1378,11 @@ void QGraphicsProxyWidget::focusInEvent(QFocusEvent *event)
break;
}
+ // QTBUG-88016
+ if (d->widget && d->widget->focusWidget()
+ && d->widget->focusWidget()->testAttribute(Qt::WA_InputMethodEnabled))
+ QApplication::inputMethod()->reset();
+
d->proxyIsGivingFocus = false;
}
@@ -1397,8 +1398,14 @@ void QGraphicsProxyWidget::focusOutEvent(QFocusEvent *event)
if (d->widget) {
// We need to explicitly remove subfocus from the embedded widget's
// focus widget.
- if (QWidget *focusWidget = d->widget->focusWidget())
+ if (QWidget *focusWidget = d->widget->focusWidget()) {
+ // QTBUG-88016 proxyWidget set QTextEdit(QLineEdit etc.) when input preview text,
+ // inputMethod should be reset when proxyWidget lost focus
+ if (focusWidget->testAttribute(Qt::WA_InputMethodEnabled))
+ QApplication::inputMethod()->reset();
+
d->removeSubFocusHelper(focusWidget, event->reason());
+ }
}
}
@@ -1436,17 +1443,17 @@ QVariant QGraphicsProxyWidget::inputMethodQuery(Qt::InputMethodQuery query) cons
focusWidget = d->widget;
QVariant v = focusWidget->inputMethodQuery(query);
QPointF focusWidgetPos = subWidgetRect(focusWidget).topLeft();
- switch (v.type()) {
- case QVariant::RectF:
+ switch (v.userType()) {
+ case QMetaType::QRectF:
v = v.toRectF().translated(focusWidgetPos);
break;
- case QVariant::PointF:
+ case QMetaType::QPointF:
v = v.toPointF() + focusWidgetPos;
break;
- case QVariant::Rect:
+ case QMetaType::QRect:
v = v.toRect().translated(focusWidgetPos.toPoint());
break;
- case QVariant::Point:
+ case QMetaType::QPoint:
v = v.toPoint() + focusWidgetPos.toPoint();
break;
default:
@@ -1464,7 +1471,7 @@ void QGraphicsProxyWidget::inputMethodEvent(QInputMethodEvent *event)
Q_D(const QGraphicsProxyWidget);
QWidget *focusWidget = d->widget->focusWidget();
if (focusWidget && focusWidget->testAttribute(Qt::WA_InputMethodEnabled))
- QApplication::sendEvent(focusWidget, event);
+ QCoreApplication::sendEvent(focusWidget, event);
}
/*!
@@ -1533,6 +1540,10 @@ void QGraphicsProxyWidget::paint(QPainter *painter, const QStyleOptionGraphicsIt
if (exposedWidgetRect.isEmpty())
return;
+ // When rendering to pdf etc. painting may go outside widget boundaries unless clipped
+ if (painter->device()->devType() != QInternal::Widget && (flags() & ItemClipsChildrenToShape))
+ painter->setClipRect(d->widget->geometry(), Qt::IntersectClip);
+
d->widget->render(painter, exposedWidgetRect.topLeft(), exposedWidgetRect);
}
@@ -1573,16 +1584,16 @@ QGraphicsProxyWidget *QGraphicsProxyWidget::createProxyForChildWidget(QWidget *c
return proxy;
if (!child->parentWidget()) {
qWarning("QGraphicsProxyWidget::createProxyForChildWidget: top-level widget not in a QGraphicsScene");
- return 0;
+ return nullptr;
}
QGraphicsProxyWidget *parentProxy = createProxyForChildWidget(child->parentWidget());
if (!parentProxy)
- return 0;
+ return nullptr;
if (!QMetaObject::invokeMethod(parentProxy, "newProxyWidget", Qt::DirectConnection,
Q_RETURN_ARG(QGraphicsProxyWidget*, proxy), Q_ARG(const QWidget*, child)))
- return 0;
+ return nullptr;
proxy->setParent(parentProxy);
proxy->setWidget(child);
return proxy;