Skip to content

Commit

Permalink
Added support for proper handling on non client escape key presses on…
Browse files Browse the repository at this point in the history
… Windows
  • Loading branch information
githubuser0xFFFF committed Apr 1, 2020
1 parent 1b6e449 commit 28dc374
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 9 deletions.
2 changes: 1 addition & 1 deletion demo/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ CMainWindow::CMainWindow(QWidget *parent) :

// uncomment the following line if you want to use opaque undocking and
// opaque splitter resizing
//CDockManager::setConfigFlags(CDockManager::DefaultOpaqueConfig);
// CDockManager::setConfigFlags(CDockManager::DefaultOpaqueConfig);

// uncomment the following line if you want a fixed tab width that does
// not change if the visibility of the close button changes
Expand Down
76 changes: 68 additions & 8 deletions src/FloatingDockContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <QDebug>
#include <QAbstractButton>
#include <QElapsedTimer>
#include <QTime>

#include "DockContainerWidget.h"
#include "DockAreaWidget.h"
Expand Down Expand Up @@ -66,6 +67,7 @@ struct FloatingDockContainerPrivate
QPoint DragStartMousePosition;
CDockContainerWidget *DropContainer = nullptr;
CDockAreaWidget *SingleDockArea = nullptr;
QPoint DragStartPos;
#ifdef Q_OS_LINUX
QWidget* MouseEventHandler = nullptr;
CFloatingWidgetTitleBar* TitleBar = nullptr;
Expand Down Expand Up @@ -109,6 +111,10 @@ struct FloatingDockContainerPrivate
#endif
}

/**
* Reflect the current dock widget title in the floating widget windowTitle()
* depending on the CDockManager::FloatingContainerHasWidgetTitle flag
*/
void reflectCurrentWidget(CDockWidget* CurrentWidget)
{
// reflect CurrentWidget's title if configured to do so, otherwise display application name as window title
Expand All @@ -133,6 +139,11 @@ struct FloatingDockContainerPrivate
_this->setWindowIcon(QApplication::windowIcon());
}
}

/**
* Handles escape key press when dragging around the floating widget
*/
void handleEscapeKey();
};
// struct FloatingDockContainerPrivate

Expand Down Expand Up @@ -264,6 +275,17 @@ void FloatingDockContainerPrivate::updateDropOverlays(const QPoint &GlobalPos)
}
}


//============================================================================
void FloatingDockContainerPrivate::handleEscapeKey()
{
ADS_PRINT("FloatingDockContainerPrivate::handleEscapeKey()");
setState(DraggingInactive);
DockManager->containerOverlay()->hideOverlay();
DockManager->dockAreaOverlay()->hideOverlay();
}


//============================================================================
CFloatingDockContainer::CFloatingDockContainer(CDockManager *DockManager) :
tFloatingWidgetBase(DockManager),
Expand Down Expand Up @@ -363,6 +385,7 @@ void CFloatingDockContainer::moveEvent(QMoveEvent *event)
switch (d->DraggingState)
{
case DraggingMousePressed:
qApp->installEventFilter(this);
d->setState(DraggingFloatingWidget);
d->updateDropOverlays(QCursor::pos());
break;
Expand All @@ -380,6 +403,8 @@ void CFloatingDockContainer::moveEvent(QMoveEvent *event)
default:
break;
}


}

//============================================================================
Expand Down Expand Up @@ -443,6 +468,7 @@ void CFloatingDockContainer::showEvent(QShowEvent *event)
Super::showEvent(event);
}


//============================================================================
bool CFloatingDockContainer::event(QEvent *e)
{
Expand All @@ -460,19 +486,16 @@ bool CFloatingDockContainer::event(QEvent *e)
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 2))
if (e->type()
== QEvent::NonClientAreaMouseButtonPress /*&& QGuiApplication::mouseButtons().testFlag(Qt::LeftButton)*/)
{
ADS_PRINT("FloatingWidget::event Event::NonClientAreaMouseButtonPress" << e->type());
d->setState(DraggingMousePressed);
}
#else
if (e->type() == QEvent::NonClientAreaMouseButtonPress && QGuiApplication::mouseButtons().testFlag(Qt::LeftButton))
#endif
{
ADS_PRINT("FloatingWidget::event Event::NonClientAreaMouseButtonPress" << e->type());
ADS_PRINT("FloatingWidget::event Event::NonClientAreaMouseButtonPress" << e->type());
d->DragStartPos = pos();
d->setState(DraggingMousePressed);
}
#endif
}
break;
break;

case DraggingMousePressed:
switch (e->type())
Expand Down Expand Up @@ -515,12 +538,49 @@ bool CFloatingDockContainer::event(QEvent *e)
}

#if (ADS_DEBUG_LEVEL > 0)
qDebug() << "CFloatingDockContainer::event " << e->type();
qDebug() << QTime::currentTime() << "CFloatingDockContainer::event " << e->type();
#endif
return QWidget::event(e);
}


//============================================================================
bool CFloatingDockContainer::eventFilter(QObject *watched, QEvent *e)
{
Q_UNUSED(watched);
// I have not found a way to detect non client area key press events to
// handle escape key presses. On Windows, if the escape key is pressed while
// dragging around a widget, the widget position is reset to its start position
// which in turn generates a QEvent::NonClientAreaMouseButtonRelease event
// if the mouse is outside of the widget after the move to its initial position
// or a QEvent::MouseButtonRelease event, if the mouse is inside of teh widget
// after the position has been reset.
// So we can install an event filter on the application to get these events
// here to properly cancel dragging and hide the overlays.
// If we are in DraggingFloatingWidget state, it means the widget
// has been dragged already but if the position is the same like
// the start position, then this is an indication that the escape
// key has been pressed.
if (e->type() == QEvent::MouseButtonRelease || e->type() == QEvent::NonClientAreaMouseButtonRelease)
{
ADS_PRINT("CFloatingDockContainer::eventFilter QEvent::MouseButtonRelease or"
"QEvent::NonClientAreaMouseButtonRelease" << "d->DragggingState " << d->DraggingState);
qApp->removeEventFilter(this);
if (d->DragStartPos == pos())
{
d->handleEscapeKey();
return true;
}
return false;
}

#if (ADS_DEBUG_LEVEL > 0)
qDebug() << QTime::currentTime() << "CFloatingDockContainer::eventFilter " << e->type();
#endif
return false;
}


//============================================================================
void CFloatingDockContainer::startFloating(const QPoint &DragStartMousePos,
const QSize &Size, eDragState DragState, QWidget *MouseEventHandler)
Expand Down
1 change: 1 addition & 0 deletions src/FloatingDockContainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ private slots:
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;
Expand Down

0 comments on commit 28dc374

Please sign in to comment.