Skip to content

Commit

Permalink
ENH: Support dragging of the splashwindow just after clicking on it (#…
Browse files Browse the repository at this point in the history
…7532)

Follow-up of edfbdb4 (ENH: Allow dragging of splashwindow), this commit
further improve the `DraggableWidgetEventFilter` to support dragging the
Splashwindow without having to release the mouse button and re-pressing it.

To address potential issues arising from widget reparenting due to changes
in window hints, the commit removes the Qt::WindowStaysOnTopHint flag after
releasing the mouse button.

Co-authored-by: Andras Lasso <lasso@queensu.ca>
  • Loading branch information
jcfr and lassoan committed Jan 25, 2024
1 parent 5199545 commit 48c7e16
Showing 1 changed file with 27 additions and 14 deletions.
41 changes: 27 additions & 14 deletions Base/QTApp/qSlicerApplicationHelper.txx
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,16 @@
namespace
{

/// Event filter that allows to move a widget by clicking anywhere on it.
/// It also removes the WindowStaysOnTopHint so that the window is not forced to
/// appear above all other applications.
/// \brief Event filter for enabling draggable behavior on a widget.
///
/// This event filter allows the user to move a widget by clicking anywhere on it.
/// It also removes the WindowStaysOnTopHint, preventing the window from staying
/// above all other applications. The filter should be installed on and uninstalled
/// from the application.
class DraggableWidgetEventFilter : public QObject
{
public:
/// Set the widget that will become draggable.
void setWidget(QWidget* w)
{
this->Widget = w;
Expand All @@ -64,33 +68,37 @@ protected:
{
if (event->type() == QEvent::MouseButtonPress && this->Widget)
{
// Record the mouse press position for later reference during dragging.
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
this->PressPosition = mouseEvent->pos();
this->Dragging = true;
if (this->DisableTopMost)
{
this->Widget->setWindowFlags(this->Widget->windowFlags() & ~Qt::WindowStaysOnTopHint);
// After removing the WindowStaysOnTopHint hint, we need to show the window again
this->Widget->show();
this->DisableTopMost = false;
}
return true; // do not process the event further
}
else if (event->type() == QEvent::MouseMove && this->Dragging && this->Widget)
{
// Move the widget
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
this->Widget->move(this->Widget->pos() + mouseEvent->pos() - this->PressPosition);
return true; // do not process the event further
}
else if (event->type() == QEvent::MouseButtonRelease)
{
// End the dragging process.
this->Dragging = false;
// Disable the WindowStaysOnTop hint to allow other windows to be shown above it.
// Do it after the mouse button is released, because the widget may be reparented
// as a result of changing the window hint, and during reparenting some events
// might not arrive to the widget.
if (this->DisableTopMost)
{
this->DisableTopMost = false;
this->Widget->setWindowFlags(this->Widget->windowFlags() & ~Qt::WindowStaysOnTopHint);
// After removing the WindowStaysOnTopHint hint, we need to show the window again
this->Widget->show();
}
return true; // do not process the event further
}
else if (event->type() == QEvent::Leave)
{
this->Dragging = false;
}
// If the event is not one of the specified types, pass it to the base class.
return QObject::eventFilter(obj, event);
}
private:
Expand Down Expand Up @@ -239,6 +247,11 @@ int qSlicerApplicationHelper::postInitializeApplication(
moduleFactoryManager->instantiateModules();
QObject::disconnect(moduleAboutToBeInstantiatedConnection);

if (splashScreen)
{
splashScreen->removeEventFilter(&draggable);
}

if (app.commandOptions()->verboseModuleDiscovery())
{
qDebug() << "Number of instantiated modules:"
Expand Down

0 comments on commit 48c7e16

Please sign in to comment.