Skip to content

Commit 59aa275

Browse files
committed
fix(touch): enable manual touch scrolling for network plugin in Wayland
Under Wayland, Qt's gesture manager fails to find correct target widgets for touch events inside QTreeView and QScrollArea, leading to unresponsive touch scrolling. Direct interception of Touch events on the viewport, translation into scrollbar value updates, and generation of precise mouse button events for item interaction without drag. Log: Fix touch scrolling for NetView Pms: BUG-351259
1 parent 7bf893c commit 59aa275

File tree

3 files changed

+80
-14
lines changed

3 files changed

+80
-14
lines changed

common-plugin/networkdialog/networkpanel.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd.
1+
// SPDX-FileCopyrightText: 2018 - 2026 UnionTech Software Technology Co., Ltd.
22
//
33
// SPDX-License-Identifier: LGPL-3.0-or-later
44

@@ -111,6 +111,7 @@ void NetworkPanel::initUi()
111111
m_netListView->setMouseTracking(true);
112112
m_netListView->setItemMargins(QMargins(10, 0, 10, 0));
113113
m_netListView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
114+
m_netListView->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
114115
m_netListView->setItemRadius(0);
115116

116117
NetworkDelegate *delegate = new NetworkDelegate(m_netListView);
@@ -163,11 +164,8 @@ void NetworkPanel::initUi()
163164
setControlBackground();
164165

165166
// 支持在触摸屏上滚动
166-
QScroller::grabGesture(m_netListView->viewport(), QScroller::LeftMouseButtonGesture);
167-
QScroller *scroller = QScroller::scroller(m_netListView->window());
168-
QScrollerProperties sp;
169-
sp.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff);
170-
scroller->setScrollerProperties(sp);
167+
m_netListView->setAttribute(Qt::WA_AcceptTouchEvents, true);
168+
m_netListView->viewport()->setAttribute(Qt::WA_AcceptTouchEvents, true);
171169
}
172170

173171
void NetworkPanel::initConnection()

net-view/window/netview.cpp

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <QEvent>
1616
#include <QHoverEvent>
1717
#include <QScrollBar>
18+
#include <QCoreApplication>
1819
#include <QScroller>
1920
#include <QScrollerProperties>
2021
#include <QSortFilterProxyModel>
@@ -66,6 +67,8 @@ NetView::NetView(NetManager *manager)
6667
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
6768
setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
6869
setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
70+
setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
71+
setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
6972

7073
setSelectionMode(QAbstractItemView::NoSelection);
7174
setRootIsDecorated(false);
@@ -83,13 +86,8 @@ NetView::NetView(NetManager *manager)
8386
connect(this, &NetView::activated, this, &NetView::onActivated);
8487

8588
// 支持在触摸屏上滚动
86-
QScroller::grabGesture(viewport(), QScroller::TouchGesture);
87-
QScrollerProperties sp = QScroller::scroller(viewport())->scrollerProperties();
88-
sp.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff);
89-
sp.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff);
90-
sp.setScrollMetric(QScrollerProperties::DecelerationFactor, 0.5);
91-
sp.setScrollMetric(QScrollerProperties::MaximumVelocity, 0.5);
92-
QScroller::scroller(viewport())->setScrollerProperties(sp);
89+
setAttribute(Qt::WA_AcceptTouchEvents, true);
90+
viewport()->setAttribute(Qt::WA_AcceptTouchEvents, true);
9391
}
9492

9593
NetView::~NetView() = default;
@@ -183,6 +181,74 @@ void NetView::rowsInserted(const QModelIndex &parent, int start, int end)
183181

184182
bool NetView::viewportEvent(QEvent *event)
185183
{
184+
const QEvent::Type type = event->type();
185+
if (type == QEvent::TouchBegin || type == QEvent::TouchUpdate ||
186+
type == QEvent::TouchEnd || type == QEvent::TouchCancel) {
187+
188+
QTouchEvent *te = static_cast<QTouchEvent *>(event);
189+
if (te->points().isEmpty()) {
190+
event->accept();
191+
return true;
192+
}
193+
194+
QEventPoint pt = te->points().first();
195+
196+
switch (type) {
197+
case QEvent::TouchBegin: {
198+
m_touchPressPos = pt.globalPosition();
199+
m_isDrag = false;
200+
break;
201+
}
202+
case QEvent::TouchUpdate: {
203+
QPointF delta = pt.globalPosition() - m_touchPressPos;
204+
205+
if (!m_isDrag && (qAbs(delta.y()) >= QApplication::startDragDistance() || qAbs(delta.x()) >= QApplication::startDragDistance())) {
206+
m_isDrag = true;
207+
}
208+
209+
if (m_isDrag) {
210+
if (qAbs(delta.y()) > 0 && verticalScrollBar()) {
211+
verticalScrollBar()->setValue(verticalScrollBar()->value() - delta.y());
212+
}
213+
if (qAbs(delta.x()) > 0 && horizontalScrollBar()) {
214+
horizontalScrollBar()->setValue(horizontalScrollBar()->value() - delta.x());
215+
}
216+
m_touchPressPos = pt.globalPosition();
217+
}
218+
break;
219+
}
220+
case QEvent::TouchEnd: {
221+
if (!m_isDrag) {
222+
// Determine the correct target widget for the click
223+
QWidget *target = viewport();
224+
QPoint widgetPos = pt.position().toPoint();
225+
226+
if (QWidget *child = target->childAt(widgetPos)) {
227+
target = child;
228+
if (target) {
229+
widgetPos = target->mapFrom(viewport(), widgetPos);
230+
}
231+
}
232+
233+
QMouseEvent press(QEvent::MouseButtonPress, widgetPos, pt.globalPosition(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
234+
QCoreApplication::sendEvent(target, &press);
235+
QMouseEvent release(QEvent::MouseButtonRelease, widgetPos, pt.globalPosition(), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
236+
QCoreApplication::sendEvent(target, &release);
237+
}
238+
break;
239+
}
240+
case QEvent::TouchCancel: {
241+
m_isDrag = false;
242+
break;
243+
}
244+
default:
245+
break;
246+
}
247+
248+
event->accept();
249+
return true;
250+
}
251+
186252
switch (event->type()) {
187253
case QEvent::HoverLeave: {
188254
setCurrentIndex(QModelIndex());

net-view/window/netview.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd.
1+
// SPDX-FileCopyrightText: 2019 - 2026 UnionTech Software Technology Co., Ltd.
22
//
33
// SPDX-License-Identifier: LGPL-3.0-or-later
44
#ifndef NETVIEW_H
@@ -74,6 +74,8 @@ protected Q_SLOTS:
7474
NetDelegate *m_delegate;
7575
bool m_closeOnClear;
7676
int m_maxHeight;
77+
QPointF m_touchPressPos;
78+
bool m_isDrag = false;
7779
};
7880

7981
} // namespace network

0 commit comments

Comments
 (0)