Send events as spontaneous in QWindowPrivate::forwardToPopup()
QWindowPrivate::forwardToPopup() sends key events with QCoreApplication::sendEvent(), which sets QEvent::m_spont to false. That makes key and pointer events sent to popups appear synthetic, while they are sponaneous if sent to other widgets. The method has been newly implemented in the course of moving popup handling from QApplication to QGuiApplication. Make current behavior consistent to the behavior prior to e4ef0f03e6f1fddc397980fd7fbf6f6b829f16d9. Since events are always spontaneous, use QCoreApplication::sendSpontaneousEvent() instead. Add a test function to tst_QComboBox to Verify, that key events - are sent directly to the popup - not seen by the window - appear as spontaneous. This amends e4ef0f03e6f1fddc397980fd7fbf6f6b829f16d9. Fixes: QTBUG-129258 Pick-to: 6.8.0 Change-Id: Iff61b98b290f6483948007b5f12b19393759d9db Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> (cherry picked from commit 3fbae61ea245291cb4c34e9126562c307741a600) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
5b697bb08c
commit
c20a382023
@ -238,6 +238,7 @@ private:
|
||||
friend class QWidget;
|
||||
friend class QWidgetWindow;
|
||||
friend class QWidgetPrivate;
|
||||
friend class QWindowPrivate;
|
||||
#ifndef QT_NO_QOBJECT
|
||||
friend class QEventDispatcherUNIXPrivate;
|
||||
friend class QCocoaEventDispatcherPrivate;
|
||||
|
@ -2449,7 +2449,7 @@ const QWindow *QWindowPrivate::forwardToPopup(QEvent *event, const QWindow */*ac
|
||||
/* Popups are expected to be able to directly handle the
|
||||
drag-release sequence after pressing to open, as well as
|
||||
any other mouse events that occur within the popup's bounds. */
|
||||
if (QCoreApplication::sendEvent(popupWindow, pointerEvent.get())) {
|
||||
if (QCoreApplication::sendSpontaneousEvent(popupWindow, pointerEvent.get())) {
|
||||
event->setAccepted(pointerEvent->isAccepted());
|
||||
if (pointerEvent->isAccepted())
|
||||
ret = popupWindow;
|
||||
@ -2458,7 +2458,7 @@ const QWindow *QWindowPrivate::forwardToPopup(QEvent *event, const QWindow */*ac
|
||||
<< "handled?" << (ret != nullptr) << event->isAccepted();
|
||||
return ret;
|
||||
} else if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) {
|
||||
if (QCoreApplication::sendEvent(popupWindow, event))
|
||||
if (QCoreApplication::sendSpontaneousEvent(popupWindow, event))
|
||||
ret = popupWindow;
|
||||
qCDebug(lcPopup) << q << "forwarded" << event->type() << "to popup" << popupWindow
|
||||
<< "handled?" << (ret != nullptr) << event->isAccepted();
|
||||
|
@ -104,6 +104,7 @@ private slots:
|
||||
void mouseWheel();
|
||||
void popupWheelHandling();
|
||||
#endif // QT_CONFIG(wheelevent)
|
||||
void sendKeyEventToPopup();
|
||||
void layoutDirection();
|
||||
void itemListPosition();
|
||||
void separatorItem_data();
|
||||
@ -2185,6 +2186,54 @@ void tst_QComboBox::popupWheelHandling()
|
||||
}
|
||||
#endif // QT_CONFIG(wheelevent)
|
||||
|
||||
void tst_QComboBox::sendKeyEventToPopup()
|
||||
{
|
||||
struct KeyEventFilter : public QObject {
|
||||
uint countWindow = 0;
|
||||
uint countView = 0;
|
||||
bool eventFilter(QObject *obj, QEvent *event) override
|
||||
{
|
||||
if (event->type() != QEvent::KeyPress)
|
||||
return false;
|
||||
|
||||
if (qobject_cast<QWindow *>(obj))
|
||||
++countWindow;
|
||||
|
||||
if (qobject_cast<QAbstractItemView *>(obj) && event->spontaneous())
|
||||
++countView;
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
QScrollArea scrollArea;
|
||||
scrollArea.move(300, 300);
|
||||
QWidget *widget = new QWidget;
|
||||
scrollArea.setWidget(widget);
|
||||
QVBoxLayout *layout = new QVBoxLayout(widget);
|
||||
layout->setSizeConstraint(QLayout::SetMinAndMaxSize);
|
||||
QComboBox *comboBox = new QComboBox;
|
||||
comboBox->addItems(QStringList() << QStringLiteral("Won") << QStringLiteral("Too")
|
||||
<< QStringLiteral("3") << QStringLiteral("fore"));
|
||||
layout->addWidget(comboBox);
|
||||
layout->addSpacing(100);
|
||||
const QPoint sizeP(scrollArea.width(), scrollArea.height());
|
||||
scrollArea.move(QGuiApplication::primaryScreen()->availableGeometry().center() - sizeP / 2);
|
||||
scrollArea.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&scrollArea));
|
||||
comboBox->showPopup();
|
||||
auto *itemView = comboBox->findChild<QAbstractItemView *>();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(itemView));
|
||||
KeyEventFilter filter;
|
||||
itemView->installEventFilter(&filter);
|
||||
comboBox->window()->windowHandle()->installEventFilter(&filter);
|
||||
QWindowSystemInterfacePrivate::KeyEvent ke(comboBox->window()->windowHandle(), 0, QEvent::KeyPress, Qt::Key_End, Qt::KeyboardModifiers());
|
||||
QGuiApplicationPrivate::processKeyEvent(&ke);
|
||||
// Make sure that the key event is directly delivered to the popup
|
||||
QCOMPARE(filter.countWindow, 0);
|
||||
QCOMPARE(filter.countView, 1);
|
||||
}
|
||||
|
||||
void tst_QComboBox::layoutDirection()
|
||||
{
|
||||
QComboBox box;
|
||||
|
Loading…
x
Reference in New Issue
Block a user