diff --git a/plugins/dde-dock/bluetooth/componments/bluetoothapplet.cpp b/plugins/dde-dock/bluetooth/componments/bluetoothapplet.cpp index ef7be0cf9..4f83ed14c 100644 --- a/plugins/dde-dock/bluetooth/componments/bluetoothapplet.cpp +++ b/plugins/dde-dock/bluetooth/componments/bluetoothapplet.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2016 - 2022 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2016 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later @@ -13,6 +13,7 @@ #include "jumpsettingbutton.h" #include "constants.h" #include "plugins-logging-category.h" +#include "touchscrollfilter.h" #include #include @@ -229,10 +230,7 @@ void BluetoothApplet::initUi() m_scrollArea->setPalette(scrollAreaBackground); // QScroller::grabGesture(m_scrollArea->viewport(), QScroller::LeftMouseButtonGesture); - QScroller *scroller = QScroller::scroller(m_scrollArea); - QScrollerProperties sp; - sp.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff); - scroller->setScrollerProperties(sp); + new TouchScrollFilter(m_scrollArea); m_mainLayout->setSpacing(0); m_mainLayout->setContentsMargins(0, 10, 0, 0); diff --git a/plugins/dde-dock/common/touchscrollfilter.cpp b/plugins/dde-dock/common/touchscrollfilter.cpp new file mode 100644 index 000000000..25e2a9786 --- /dev/null +++ b/plugins/dde-dock/common/touchscrollfilter.cpp @@ -0,0 +1,94 @@ +// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#include "touchscrollfilter.h" + +#include +#include +#include +#include +#include + +TouchScrollFilter::TouchScrollFilter(QAbstractScrollArea *area) + : QObject(area) + , m_area(area) + , m_isDrag(false) +{ + if (m_area) { + m_area->viewport()->setAttribute(Qt::WA_AcceptTouchEvents, true); + m_area->setAttribute(Qt::WA_AcceptTouchEvents, true); + m_area->viewport()->installEventFilter(this); + } +} + +bool TouchScrollFilter::eventFilter(QObject *watched, QEvent *event) +{ + if (!m_area) + return QObject::eventFilter(watched, event); + + const QEvent::Type type = event->type(); + if (type != QEvent::TouchBegin && type != QEvent::TouchUpdate && + type != QEvent::TouchEnd && type != QEvent::TouchCancel) { + return QObject::eventFilter(watched, event); + } + + QTouchEvent *te = static_cast(event); + if (te->points().isEmpty()) { + event->accept(); + return true; + } + + QEventPoint pt = te->points().first(); + + switch (type) { + case QEvent::TouchBegin: { + m_lastPos = pt.globalPosition(); + m_isDrag = false; + break; + } + case QEvent::TouchUpdate: { + qreal deltaY = pt.globalPosition().y() - m_lastPos.y(); + qreal deltaX = pt.globalPosition().x() - m_lastPos.x(); + + if (!m_isDrag && (qAbs(deltaY) >= QApplication::startDragDistance() || qAbs(deltaX) >= QApplication::startDragDistance())) { + m_isDrag = true; + } + + if (m_isDrag) { + if (qAbs(deltaY) > 0 && m_area->verticalScrollBar()) { + m_area->verticalScrollBar()->setValue(m_area->verticalScrollBar()->value() - deltaY); + } + if (qAbs(deltaX) > 0 && m_area->horizontalScrollBar()) { + m_area->horizontalScrollBar()->setValue(m_area->horizontalScrollBar()->value() - deltaX); + } + m_lastPos = pt.globalPosition(); + } + break; + } + case QEvent::TouchEnd: { + if (!m_isDrag) { + // Determine the correct target widget for the click + QWidget *target = m_area->viewport(); + QPoint widgetPos = pt.position().toPoint(); + + // If it's a QScrollArea, the content widget is usually a child of the viewport + if (QWidget *child = target->childAt(widgetPos)) { + target = child; + widgetPos = target->mapFrom(m_area->viewport(), widgetPos); + } + + QMouseEvent press(QEvent::MouseButtonPress, widgetPos, pt.globalPosition(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + QCoreApplication::sendEvent(target, &press); + QMouseEvent release(QEvent::MouseButtonRelease, widgetPos, pt.globalPosition(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + QCoreApplication::sendEvent(target, &release); + } + break; + } + default: + break; + } + + event->accept(); + return true; +} diff --git a/plugins/dde-dock/common/touchscrollfilter.h b/plugins/dde-dock/common/touchscrollfilter.h new file mode 100644 index 000000000..50ba48c36 --- /dev/null +++ b/plugins/dde-dock/common/touchscrollfilter.h @@ -0,0 +1,27 @@ +// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#ifndef TOUCHSCROLLFILTER_H +#define TOUCHSCROLLFILTER_H + +#include +#include +#include + +class TouchScrollFilter : public QObject +{ +public: + explicit TouchScrollFilter(QAbstractScrollArea *area); + ~TouchScrollFilter() override = default; + +protected: + bool eventFilter(QObject *watched, QEvent *event) override; + +private: + QAbstractScrollArea *m_area; + QPointF m_lastPos; + bool m_isDrag; +}; + +#endif // TOUCHSCROLLFILTER_H