1313#include " dplatformintegration.h"
1414
1515#include < QMouseEvent>
16+ #include < QTouchEvent>
1617#include < QTimer>
1718#include < QMetaProperty>
1819#include < QScreen>
@@ -40,6 +41,9 @@ DNoTitlebarWindowHelper::DNoTitlebarWindowHelper(QWindow *window, quint32 window
4041 if (window->flags ().testFlag (Qt::FramelessWindowHint))
4142 window->setFlags (window->flags () & ~Qt::FramelessWindowHint);
4243
44+ // 初始化窗口类型判断结果
45+ m_isQuickWindow = window->inherits (" QQuickWindow" );
46+
4347 mapped[window] = this ;
4448 m_nativeSettingsValid = DPlatformIntegration::buildNativeSettings (this , windowID);
4549 Q_ASSERT (m_nativeSettingsValid);
@@ -524,15 +528,35 @@ bool DNoTitlebarWindowHelper::windowEvent(QEvent *event)
524528 VtableHook::resetVtable (w);
525529 return w->event (event);
526530 }
531+ DNoTitlebarWindowHelper *self = mapped.value (w);
527532
528533 // get touch begin position
529534 static bool isTouchDown = false ;
530535 static QPointF touchBeginPosition;
536+ #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
537+ static QHash<int , QObject*> touchPointGrabbers; // 新增:记录触摸点的grabber状态
538+ const auto isQuickWindow = self->m_isQuickWindow ;
539+ #endif
540+
531541 if (event->type () == QEvent::TouchBegin) {
532542 isTouchDown = true ;
543+ // ========== 新增:记录处理前的grabber状态 ==========
544+ #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
545+ if (isQuickWindow && event->isPointerEvent ()) {
546+ QPointerEvent *pe = static_cast <QPointerEvent*>(event);
547+ touchPointGrabbers.clear ();
548+ for (const auto &point : pe->points ()) {
549+ QObject *grabber = pe->exclusiveGrabber (point);
550+ touchPointGrabbers[point.id ()] = grabber;
551+ }
552+ }
553+ #endif
533554 }
534555 if (event->type () == QEvent::TouchEnd || event->type () == QEvent::MouseButtonRelease) {
535556 isTouchDown = false ;
557+ #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
558+ touchPointGrabbers.clear (); // 清理grabber记录
559+ #endif
536560 }
537561 if (isTouchDown && event->type () == QEvent::MouseButtonPress) {
538562 touchBeginPosition = static_cast <QMouseEvent*>(event)->globalPos ();
@@ -546,7 +570,6 @@ bool DNoTitlebarWindowHelper::windowEvent(QEvent *event)
546570 }
547571 }
548572
549- DNoTitlebarWindowHelper *self = mapped.value (w);
550573 quint32 winId = self->m_windowID ;
551574 bool is_mouse_move = event->type () == QEvent::MouseMove && static_cast <QMouseEvent*>(event)->buttons () == Qt::LeftButton;
552575
@@ -570,10 +593,15 @@ bool DNoTitlebarWindowHelper::windowEvent(QEvent *event)
570593 g_pressPoint[this ] = dynamic_cast <QMouseEvent*>(event)->globalPos ();
571594 }
572595
596+ // ========== 修改:鼠标事件处理保持原有逻辑 ==========
573597 if (is_mouse_move && !event->isAccepted () && g_pressPoint.contains (this )) {
574598 QMouseEvent *me = static_cast <QMouseEvent*>(event);
575599 QRect windowRect = QRect (QPoint (0 , 0 ), w->size ());
576- if (!windowRect.contains (me->windowPos ().toPoint ())) {
600+ #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
601+ if (!windowRect.contains (me->scenePosition ().toPoint ())) {
602+ #else
603+ if (!windowRect.contains (me->localPos ().toPoint ())) {
604+ #endif
577605 return ret;
578606 }
579607
@@ -583,6 +611,7 @@ bool DNoTitlebarWindowHelper::windowEvent(QEvent *event)
583611 }
584612
585613 if (!self->m_windowMoving && self->isEnableSystemMove (winId)) {
614+ qDebug () << " Starting mouse drag for window ID:" << winId;
586615 self->m_windowMoving = true ;
587616
588617 event->accept ();
@@ -594,6 +623,39 @@ bool DNoTitlebarWindowHelper::windowEvent(QEvent *event)
594623 }
595624 }
596625
626+ // ========== 新增:QML窗口触摸事件的特殊处理 ==========
627+ #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
628+ if (isQuickWindow && event->isPointerEvent ()) {
629+ QPointerEvent *pe = static_cast <QPointerEvent*>(event);
630+
631+ // 检查是否是触摸事件
632+ bool isTouchEvent = (event->type () == QEvent::TouchBegin ||
633+ event->type () == QEvent::TouchUpdate ||
634+ event->type () == QEvent::TouchEnd);
635+
636+ if (isTouchEvent) {
637+ // 检查是否有新的grabber产生(说明QML Item处理了触摸事件)
638+ bool wasHandledByQML = false ;
639+ for (const auto &point : pe->points ()) {
640+ QObject *grabberBefore = touchPointGrabbers.value (point.id ());
641+ QObject *grabberAfter = pe->exclusiveGrabber (point);
642+
643+ if (grabberBefore != grabberAfter && grabberAfter != nullptr ) {
644+ wasHandledByQML = true ;
645+ break ;
646+ }
647+ }
648+
649+ // 如果没有QML Item处理触摸事件,尝试窗口拖拽
650+ if (!wasHandledByQML && self->isEnableSystemMove (winId)) {
651+ if (self->handleTouchDragForQML (pe)) {
652+ return ret;
653+ }
654+ }
655+ }
656+ }
657+ #endif
658+
597659 return ret;
598660}
599661
@@ -733,4 +795,105 @@ void DNoTitlebarWindowHelper::updateMoveWindow(quint32 winId)
733795 Utility::updateMousePointForWindowMove (winId);
734796}
735797
798+ #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
799+ bool DNoTitlebarWindowHelper::handleTouchDragForQML (QPointerEvent *touchEvent)
800+ {
801+ QWindow *w = this ->m_window ;
802+ static QHash<int , QPointF> touchStartPositions;
803+ static QHash<int , bool > touchIsMoving;
804+ static QHash<int , QPointF> lastTouchPositions; // 新增:记录最后的触摸位置用于更新
805+
806+ const auto points = touchEvent->points ();
807+ if (points.isEmpty ()) {
808+ return false ;
809+ }
810+
811+ // 只处理第一个触摸点
812+ const auto &point = points.first ();
813+ int touchId = point.id ();
814+
815+ // ========== 新增:多屏幕坐标处理 ==========
816+ QScreen *windowScreen = w->screen ();
817+ QPointF globalPos = point.globalPosition ();
818+ QPointF localPos = point.position ();
819+
820+ switch (touchEvent->type ()) {
821+ case QEvent::TouchBegin: {
822+ touchStartPositions[touchId] = globalPos;
823+ lastTouchPositions[touchId] = globalPos;
824+ touchIsMoving[touchId] = false ;
825+ return false ; // 不消费事件,让QML先处理
826+ }
827+
828+ case QEvent::TouchUpdate: {
829+ if (!touchStartPositions.contains (touchId)) {
830+ return false ;
831+ }
832+
833+ QPointF startPos = touchStartPositions[touchId];
834+ QPointF currentPos = globalPos;
835+ QPointF delta = currentPos - startPos;
836+ qreal distance = delta.manhattanLength ();
837+ qreal threshold = QGuiApplication::styleHints ()->startDragDistance ();
838+
839+ // 更新最后触摸位置
840+ lastTouchPositions[touchId] = currentPos;
841+
842+ // 检查移动距离是否达到拖拽阈值
843+ if (!touchIsMoving[touchId] && distance >= threshold) {
844+
845+ // ========== 修改:多屏幕环境下的窗口边界检查 ==========
846+ QRect windowRect = QRect (QPoint (0 , 0 ), w->size ());
847+ QPoint localTouchPos = localPos.toPoint ();
848+ bool inBounds = windowRect.contains (localTouchPos);
849+
850+ // 使用本地坐标检查(更可靠)
851+ if (!inBounds) {
852+ return false ;
853+ }
854+
855+ // 开始窗口移动
856+ if (isEnableSystemMove (m_windowID)) {
857+ qDebug () << " Starting touch drag for QML window ID:" << m_windowID
858+ << " on screen:" << (windowScreen ? windowScreen->name () : " unknown" );
859+ m_windowMoving = true ;
860+ touchIsMoving[touchId] = true ;
861+
862+ startMoveWindow (m_windowID);
863+ touchEvent->accept ();
864+ return true ;
865+ }
866+ } else if (touchIsMoving[touchId] && m_windowMoving) {
867+ // ========== 修改:使用带坐标参数的updateMousePointForWindowMove ==========
868+ Utility::updateMousePointForWindowMove (m_windowID, currentPos.toPoint ());
869+ touchEvent->accept ();
870+ return true ;
871+ }
872+ break ;
873+ }
874+
875+ case QEvent::TouchEnd: {
876+ if (touchIsMoving.value (touchId, false )) {
877+ m_windowMoving = false ;
878+ // ========== 修改:使用最后的触摸位置结束窗口移动 ==========
879+ QPointF lastPos = lastTouchPositions.value (touchId, globalPos);
880+ Utility::updateMousePointForWindowMove (m_windowID, lastPos.toPoint (), true );
881+ qDebug () << " Finished touch drag for QML window ID:" << m_windowID;
882+ }
883+
884+ // 清理状态
885+ touchStartPositions.remove (touchId);
886+ touchIsMoving.remove (touchId);
887+ lastTouchPositions.remove (touchId);
888+ break ;
889+ }
890+
891+ default :
892+ break ;
893+ }
894+
895+ return false ;
896+ }
897+ #endif
898+
736899DPP_END_NAMESPACE
0 commit comments