3838#include < QDebug>
3939#include < QAbstractButton>
4040#include < QElapsedTimer>
41+ #include < QTime>
4142
4243#include " DockContainerWidget.h"
4344#include " DockAreaWidget.h"
@@ -66,6 +67,7 @@ struct FloatingDockContainerPrivate
6667 QPoint DragStartMousePosition;
6768 CDockContainerWidget *DropContainer = nullptr ;
6869 CDockAreaWidget *SingleDockArea = nullptr ;
70+ QPoint DragStartPos;
6971#ifdef Q_OS_LINUX
7072 QWidget* MouseEventHandler = nullptr ;
7173 CFloatingWidgetTitleBar* TitleBar = nullptr ;
@@ -109,6 +111,10 @@ struct FloatingDockContainerPrivate
109111#endif
110112 }
111113
114+ /* *
115+ * Reflect the current dock widget title in the floating widget windowTitle()
116+ * depending on the CDockManager::FloatingContainerHasWidgetTitle flag
117+ */
112118 void reflectCurrentWidget (CDockWidget* CurrentWidget)
113119 {
114120 // reflect CurrentWidget's title if configured to do so, otherwise display application name as window title
@@ -133,6 +139,11 @@ struct FloatingDockContainerPrivate
133139 _this->setWindowIcon (QApplication::windowIcon ());
134140 }
135141 }
142+
143+ /* *
144+ * Handles escape key press when dragging around the floating widget
145+ */
146+ void handleEscapeKey ();
136147};
137148// struct FloatingDockContainerPrivate
138149
@@ -264,6 +275,17 @@ void FloatingDockContainerPrivate::updateDropOverlays(const QPoint &GlobalPos)
264275 }
265276}
266277
278+
279+ // ============================================================================
280+ void FloatingDockContainerPrivate::handleEscapeKey ()
281+ {
282+ ADS_PRINT (" FloatingDockContainerPrivate::handleEscapeKey()" );
283+ setState (DraggingInactive);
284+ DockManager->containerOverlay ()->hideOverlay ();
285+ DockManager->dockAreaOverlay ()->hideOverlay ();
286+ }
287+
288+
267289// ============================================================================
268290CFloatingDockContainer::CFloatingDockContainer (CDockManager *DockManager) :
269291 tFloatingWidgetBase (DockManager),
@@ -363,6 +385,7 @@ void CFloatingDockContainer::moveEvent(QMoveEvent *event)
363385 switch (d->DraggingState )
364386 {
365387 case DraggingMousePressed:
388+ qApp->installEventFilter (this );
366389 d->setState (DraggingFloatingWidget);
367390 d->updateDropOverlays (QCursor::pos ());
368391 break ;
@@ -380,6 +403,8 @@ void CFloatingDockContainer::moveEvent(QMoveEvent *event)
380403 default :
381404 break ;
382405 }
406+
407+
383408}
384409
385410// ============================================================================
@@ -443,6 +468,7 @@ void CFloatingDockContainer::showEvent(QShowEvent *event)
443468 Super::showEvent (event);
444469}
445470
471+
446472// ============================================================================
447473bool CFloatingDockContainer::event (QEvent *e)
448474{
@@ -460,19 +486,16 @@ bool CFloatingDockContainer::event(QEvent *e)
460486#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 2))
461487 if (e->type ()
462488 == QEvent::NonClientAreaMouseButtonPress /* && QGuiApplication::mouseButtons().testFlag(Qt::LeftButton)*/ )
463- {
464- ADS_PRINT (" FloatingWidget::event Event::NonClientAreaMouseButtonPress" << e->type ());
465- d->setState (DraggingMousePressed);
466- }
467489#else
468490 if (e->type () == QEvent::NonClientAreaMouseButtonPress && QGuiApplication::mouseButtons ().testFlag (Qt::LeftButton))
491+ #endif
469492 {
470- ADS_PRINT (" FloatingWidget::event Event::NonClientAreaMouseButtonPress" << e->type ());
493+ ADS_PRINT (" FloatingWidget::event Event::NonClientAreaMouseButtonPress" << e->type ());
494+ d->DragStartPos = pos ();
471495 d->setState (DraggingMousePressed);
472496 }
473- #endif
474497 }
475- break ;
498+ break ;
476499
477500 case DraggingMousePressed:
478501 switch (e->type ())
@@ -515,12 +538,49 @@ bool CFloatingDockContainer::event(QEvent *e)
515538 }
516539
517540#if (ADS_DEBUG_LEVEL > 0)
518- qDebug () << " CFloatingDockContainer::event " << e->type ();
541+ qDebug () << QTime::currentTime () << " CFloatingDockContainer::event " << e->type ();
519542#endif
520543 return QWidget::event (e);
521544}
522545
523546
547+ // ============================================================================
548+ bool CFloatingDockContainer::eventFilter (QObject *watched, QEvent *e)
549+ {
550+ Q_UNUSED (watched);
551+ // I have not found a way to detect non client area key press events to
552+ // handle escape key presses. On Windows, if the escape key is pressed while
553+ // dragging around a widget, the widget position is reset to its start position
554+ // which in turn generates a QEvent::NonClientAreaMouseButtonRelease event
555+ // if the mouse is outside of the widget after the move to its initial position
556+ // or a QEvent::MouseButtonRelease event, if the mouse is inside of teh widget
557+ // after the position has been reset.
558+ // So we can install an event filter on the application to get these events
559+ // here to properly cancel dragging and hide the overlays.
560+ // If we are in DraggingFloatingWidget state, it means the widget
561+ // has been dragged already but if the position is the same like
562+ // the start position, then this is an indication that the escape
563+ // key has been pressed.
564+ if (e->type () == QEvent::MouseButtonRelease || e->type () == QEvent::NonClientAreaMouseButtonRelease)
565+ {
566+ ADS_PRINT (" CFloatingDockContainer::eventFilter QEvent::MouseButtonRelease or"
567+ " QEvent::NonClientAreaMouseButtonRelease" << " d->DragggingState " << d->DraggingState );
568+ qApp->removeEventFilter (this );
569+ if (d->DragStartPos == pos ())
570+ {
571+ d->handleEscapeKey ();
572+ return true ;
573+ }
574+ return false ;
575+ }
576+
577+ #if (ADS_DEBUG_LEVEL > 0)
578+ qDebug () << QTime::currentTime () << " CFloatingDockContainer::eventFilter " << e->type ();
579+ #endif
580+ return false ;
581+ }
582+
583+
524584// ============================================================================
525585void CFloatingDockContainer::startFloating (const QPoint &DragStartMousePos,
526586 const QSize &Size, eDragState DragState, QWidget *MouseEventHandler)
0 commit comments