Skip to content

Commit

Permalink
Deliver tablet events to the toplevel widget if there is no child
Browse files Browse the repository at this point in the history
QWidgetWindow dispatched only tablet presses to the toplevel widget if
no child was found at the position; other events, such as hover events,
were discarded. The tabletTracking test case even documented that
shortcoming in a comment.

Fix that by falling back to the toplevel widget for any event. As
before, only press events initialize the tablet grabbing target widget.

Remove the now unneeded parent widget from the test case, and move the
test class into the only test function that uses it.

Amends ea615b4 and
8fd6cef.

Pick-to: 6.4
Fixes: QTBUG-108747
Change-Id: I79050f1e063931e439945f64b50712dcc1ecb18c
Reviewed-by: Shawn Rutledge <[email protected]>
  • Loading branch information
vohi authored and ec1oud committed Dec 2, 2022
1 parent f6b137b commit 7956d9e
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 48 deletions.
7 changes: 3 additions & 4 deletions src/widgets/kernel/qwidgetwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1053,11 +1053,10 @@ void QWidgetWindow::handleTabletEvent(QTabletEvent *event)

if (!widget) {
widget = m_widget->childAt(event->position().toPoint());
if (event->type() == QEvent::TabletPress) {
if (!widget)
widget = m_widget;
if (!widget)
widget = m_widget;
if (event->type() == QEvent::TabletPress)
qt_tablet_target = widget;
}
}

if (widget) {
Expand Down
82 changes: 38 additions & 44 deletions tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12500,60 +12500,54 @@ void tst_QWidget::testForOutsideWSRangeFlag()
}
}

class TabletWidget : public QWidget
void tst_QWidget::tabletTracking()
{
public:
TabletWidget(QWidget *parent) : QWidget(parent) { }
class TabletWidget : public QWidget
{
public:
using QWidget::QWidget;

int tabletEventCount = 0;
int pressEventCount = 0;
int moveEventCount = 0;
int releaseEventCount = 0;
int trackingChangeEventCount = 0;
qint64 uid = -1;
int tabletEventCount = 0;
int pressEventCount = 0;
int moveEventCount = 0;
int releaseEventCount = 0;
int trackingChangeEventCount = 0;
qint64 uid = -1;

protected:
void tabletEvent(QTabletEvent *event) override {
++tabletEventCount;
uid = event->pointingDevice()->uniqueId().numericId();
switch (event->type()) {
case QEvent::TabletMove:
++moveEventCount;
break;
case QEvent::TabletPress:
++pressEventCount;
break;
case QEvent::TabletRelease:
++releaseEventCount;
break;
default:
break;
protected:
void tabletEvent(QTabletEvent *event) override {
++tabletEventCount;
uid = event->pointingDevice()->uniqueId().numericId();
switch (event->type()) {
case QEvent::TabletMove:
++moveEventCount;
break;
case QEvent::TabletPress:
++pressEventCount;
break;
case QEvent::TabletRelease:
++releaseEventCount;
break;
default:
break;
}
}
}

bool event(QEvent *ev) override {
if (ev->type() == QEvent::TabletTrackingChange)
++trackingChangeEventCount;
return QWidget::event(ev);
}
};

void tst_QWidget::tabletTracking()
{
QWidget parent;
parent.setWindowTitle(QLatin1String(QTest::currentTestFunction()));
parent.resize(200,200);
// QWidgetWindow::handleTabletEvent doesn't deliver tablet events to the window's widget, only to a child.
// So it doesn't do any good to show a TabletWidget directly: it needs a parent.
TabletWidget widget(&parent);
bool event(QEvent *ev) override {
if (ev->type() == QEvent::TabletTrackingChange)
++trackingChangeEventCount;
return QWidget::event(ev);
}
} widget;
widget.setWindowTitle(QLatin1String(QTest::currentTestFunction()));
widget.resize(200,200);
parent.showNormal();
QVERIFY(QTest::qWaitForWindowExposed(&parent));
widget.showNormal();
QVERIFY(QTest::qWaitForWindowExposed(&widget));
widget.setAttribute(Qt::WA_TabletTracking);
QTRY_COMPARE(widget.trackingChangeEventCount, 1);
QVERIFY(widget.hasTabletTracking());

QWindow *window = parent.windowHandle();
QWindow *window = widget.windowHandle();
QPointF local(10, 10);
QPointF global = window->mapToGlobal(local.toPoint());
QPointF deviceLocal = QHighDpi::toNativeLocalPosition(local, window);
Expand Down

0 comments on commit 7956d9e

Please sign in to comment.