diff --git a/src/DockAreaTabBar.cpp b/src/DockAreaTabBar.cpp index 8ad7283..2f406be 100644 --- a/src/DockAreaTabBar.cpp +++ b/src/DockAreaTabBar.cpp @@ -174,8 +174,13 @@ void CDockAreaTabBar::mouseReleaseEvent(QMouseEvent* ev) { ADS_PRINT("CDockAreaTabBar::mouseReleaseEvent"); ev->accept(); - d->FloatingWidget = nullptr; d->DragStartMousePos = QPoint(); + if (d->FloatingWidget) + { + auto FloatingWidget = d->FloatingWidget; + d->FloatingWidget = nullptr; + FloatingWidget->finishDragging(); + } return; } QScrollArea::mouseReleaseEvent(ev); diff --git a/src/DockManager.cpp b/src/DockManager.cpp index b475ff1..c6d5a2d 100644 --- a/src/DockManager.cpp +++ b/src/DockManager.cpp @@ -205,6 +205,8 @@ bool DockManagerPrivate::checkFormat(const QByteArray &state, int version) bool DockManagerPrivate::restoreStateFromXml(const QByteArray &state, int version, bool Testing) { + Q_UNUSED(version); + if (state.isEmpty()) { return false; diff --git a/src/DockWidgetTab.cpp b/src/DockWidgetTab.cpp index 659fe8d..6ce1faf 100644 --- a/src/DockWidgetTab.cpp +++ b/src/DockWidgetTab.cpp @@ -311,14 +311,27 @@ void CDockWidgetTab::mousePressEvent(QMouseEvent* ev) //============================================================================ void CDockWidgetTab::mouseReleaseEvent(QMouseEvent* ev) { - // End of tab moving, emit signal - if (d->isDraggingState(DraggingTab) && d->DockArea) - { - emit moved(ev->globalPos()); - } - + auto CurrentDragState = d->DragState; d->DragStartMousePosition = QPoint(); d->DragState = DraggingInactive; + + switch (CurrentDragState) + { + case DraggingTab: + // End of tab moving, emit signal + if (d->DockArea) + { + emit moved(ev->globalPos()); + } + break; + + case DraggingFloatingWidget: + d->FloatingWidget->finishDragging(); + break; + + default:; // do nothing + } + Super::mouseReleaseEvent(ev); } diff --git a/src/FloatingDockContainer.cpp b/src/FloatingDockContainer.cpp index 2a38123..01303f4 100644 --- a/src/FloatingDockContainer.cpp +++ b/src/FloatingDockContainer.cpp @@ -260,11 +260,6 @@ CFloatingDockContainer::CFloatingDockContainer(CDockManager *DockManager) : #endif DockManager->registerFloatingWidget(this); - - // We install an event filter to detect mouse release events because we - // do not receive mouse release event if the floating widget is behind - // the drop overlay cross - qApp->installEventFilter(this); } //============================================================================ @@ -493,20 +488,6 @@ bool CFloatingDockContainer::event(QEvent *e) return QWidget::event(e); } -//============================================================================ -bool CFloatingDockContainer::eventFilter(QObject *watched, QEvent *event) -{ - Q_UNUSED(watched); - if (event->type() == QEvent::MouseButtonRelease - && d->isState(DraggingFloatingWidget)) - { - ADS_PRINT("FloatingWidget::eventFilter QEvent::MouseButtonRelease"); - finishDragging(); - d->titleMouseReleaseEvent(); - } - - return false; -} //============================================================================ void CFloatingDockContainer::startFloating(const QPoint &DragStartMousePos, @@ -640,6 +621,7 @@ void CFloatingDockContainer::finishDragging() d->MouseEventHandler = nullptr; } #endif + d->titleMouseReleaseEvent(); } } // namespace ads diff --git a/src/FloatingDockContainer.h b/src/FloatingDockContainer.h index 6c0be1f..61e4c30 100644 --- a/src/FloatingDockContainer.h +++ b/src/FloatingDockContainer.h @@ -74,6 +74,11 @@ public: * startFloating() was called */ virtual void moveFloating() = 0; + + /** + * Tells the widget that to finish dragging if the mouse is released + */ + virtual void finishDragging() = 0; }; @@ -110,8 +115,8 @@ protected: * Use moveToGlobalPos() to move the widget to a new position * depending on the start position given in Pos parameter */ - void startFloating(const QPoint& DragStartMousePos, const QSize& Size, - eDragState DragState, QWidget* MouseEventHandler); + virtual void startFloating(const QPoint& DragStartMousePos, const QSize& Size, + eDragState DragState, QWidget* MouseEventHandler) override; /** * Call this function to start dragging the floating widget @@ -126,7 +131,7 @@ protected: * Call this function if you explicitly want to signal that dragging has * finished */ - void finishDragging(); + virtual void finishDragging() override; /** * Call this function if you just want to initialize the position @@ -164,7 +169,6 @@ protected: // reimplements QWidget virtual void closeEvent(QCloseEvent *event) override; virtual void hideEvent(QHideEvent *event) override; virtual void showEvent(QShowEvent *event) override; - virtual bool eventFilter(QObject *watched, QEvent *event) override; public: using Super = QWidget; diff --git a/src/FloatingOverlay.cpp b/src/FloatingOverlay.cpp index f21ced2..73cd73c 100644 --- a/src/FloatingOverlay.cpp +++ b/src/FloatingOverlay.cpp @@ -39,7 +39,6 @@ struct FloatingOverlayPrivate CDockContainerWidget *DropContainer = nullptr; qreal WindowOpacity; bool Hidden = false; - bool IgnoreMouseEvents = false; QPixmap ContentPreviewPixmap; @@ -184,10 +183,6 @@ CFloatingOverlay::CFloatingOverlay(QWidget* Content, QWidget* parent) : #endif setWindowOpacity(0.6); - // We install an event filter to detect mouse release events because we - // do not receive mouse release event if the floating widget is behind - // the drop overlay cross - qApp->installEventFilter(this); // Create a static image of the widget that should get undocked // This is like some kind preview image like it is uses in drag and drop @@ -265,55 +260,44 @@ void CFloatingOverlay::moveEvent(QMoveEvent *event) //============================================================================ -bool CFloatingOverlay::eventFilter(QObject *watched, QEvent *event) +void CFloatingOverlay::finishDragging() { - Q_UNUSED(watched); - if (event->type() == QEvent::MouseButtonRelease && !d->IgnoreMouseEvents) + ADS_PRINT("CFloatingOverlay::finishDragging"); + auto DockDropArea = d->DockManager->dockAreaOverlay()->dropAreaUnderCursor(); + auto ContainerDropArea = d->DockManager->containerOverlay()->dropAreaUnderCursor(); + bool DropPossible = (DockDropArea != InvalidDockWidgetArea) || (ContainerDropArea != InvalidDockWidgetArea); + if (d->DropContainer && DropPossible) { - ADS_PRINT("FloatingWidget::eventFilter QEvent::MouseButtonRelease"); - - auto DockDropArea = d->DockManager->dockAreaOverlay()->dropAreaUnderCursor(); - auto ContainerDropArea = d->DockManager->containerOverlay()->dropAreaUnderCursor(); - bool DropPossible = (DockDropArea != InvalidDockWidgetArea) || (ContainerDropArea != InvalidDockWidgetArea); - if (d->DropContainer && DropPossible) + d->DropContainer->dropWidget(d->Content, QCursor::pos()); + } + else + { + CDockWidget* DockWidget = qobject_cast(d->Content); + CFloatingDockContainer* FloatingWidget; + if (DockWidget) { - d->DropContainer->dropWidget(d->Content, QCursor::pos()); + FloatingWidget = new CFloatingDockContainer(DockWidget); } else { - CDockWidget* DockWidget = qobject_cast(d->Content); - CFloatingDockContainer* FloatingWidget; - if (DockWidget) - { - FloatingWidget = new CFloatingDockContainer(DockWidget); - } - else - { - CDockAreaWidget* DockArea = qobject_cast(d->Content); - FloatingWidget = new CFloatingDockContainer(DockArea); - } - FloatingWidget->setGeometry(this->geometry()); - FloatingWidget->show(); - if (!CDockManager::configFlags().testFlag(CDockManager::DragPreviewHasWindowFrame)) - { - QApplication::processEvents(); - int FrameHeight = FloatingWidget->frameGeometry().height() - FloatingWidget->geometry().height(); - QRect FixedGeometry = this->geometry(); - FixedGeometry.adjust(0, FrameHeight, 0, 0); - FloatingWidget->setGeometry(FixedGeometry); - } + CDockAreaWidget* DockArea = qobject_cast(d->Content); + FloatingWidget = new CFloatingDockContainer(DockArea); + } + FloatingWidget->setGeometry(this->geometry()); + FloatingWidget->show(); + if (!CDockManager::configFlags().testFlag(CDockManager::DragPreviewHasWindowFrame)) + { + QApplication::processEvents(); + int FrameHeight = FloatingWidget->frameGeometry().height() - FloatingWidget->geometry().height(); + QRect FixedGeometry = this->geometry(); + FixedGeometry.adjust(0, FrameHeight, 0, 0); + FloatingWidget->setGeometry(FixedGeometry); } - - this->close(); - d->DockManager->containerOverlay()->hideOverlay(); - d->DockManager->dockAreaOverlay()->hideOverlay(); - // Because we use the event filter, we receive multiple mouse release - // events. To prevent multiple code execution, we ignore all mouse - // events after the first mouse event - d->IgnoreMouseEvents = true; } - return false; + this->close(); + d->DockManager->containerOverlay()->hideOverlay(); + d->DockManager->dockAreaOverlay()->hideOverlay(); } diff --git a/src/FloatingOverlay.h b/src/FloatingOverlay.h index 7f3f387..6269ed4 100644 --- a/src/FloatingOverlay.h +++ b/src/FloatingOverlay.h @@ -31,7 +31,6 @@ private: protected: virtual void moveEvent(QMoveEvent *event) override; - virtual bool eventFilter(QObject *watched, QEvent *event) override; virtual void paintEvent(QPaintEvent *e) override; /** @@ -57,6 +56,11 @@ public: * startFloating() was called */ virtual void moveFloating() override; + + /** + * Finishes dragging + */ + virtual void finishDragging() override; };