From 9fda86a511011c84e7faa69029e1a77f6586fd8a Mon Sep 17 00:00:00 2001 From: Sergio Martins Date: Sun, 19 Jun 2022 12:13:50 +0100 Subject: [PATCH] Linux: Fix dragging of maximized floating windows They should restore their normal size when the drag starts (cherry-picked from commit 1305dee08182ebbfdcbfcc7d3b06c65f5cda2d07) --- src/controllers/TitleBar.cpp | 13 +++++++++++++ src/private/DragController.cpp | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/controllers/TitleBar.cpp b/src/controllers/TitleBar.cpp index b888cd66..fff372ad 100644 --- a/src/controllers/TitleBar.cpp +++ b/src/controllers/TitleBar.cpp @@ -19,6 +19,7 @@ #include "views/TitleBarViewInterface.h" #include "ViewWrapper.h" +#include "controllers/DockWidget_p.h" #include "controllers/FloatingWindow.h" #include "controllers/TabBar.h" #include "controllers/MainWindow.h" @@ -371,10 +372,22 @@ void TitleBar::onFloatClicked() return; } + int i = 0; + DockWidget *current = nullptr; for (auto dock : qAsConst(dockWidgets)) { + + if (!current && dock->isCurrentTab()) + current = dock; + dock->setFloating(true); + dock->dptr()->m_lastPosition->m_tabIndex = i; dock->setFloating(false); + ++i; } + + // Restore the current tab + if (current) + current->setAsCurrentTab(); } } } else { diff --git a/src/private/DragController.cpp b/src/private/DragController.cpp index f7a8be2f..99d8512a 100644 --- a/src/private/DragController.cpp +++ b/src/private/DragController.cpp @@ -317,7 +317,38 @@ void StateDragging::onEntry() << "; m_windowBeingDragged=" << q->m_windowBeingDragged->floatingWindow(); auto fw = q->m_windowBeingDragged->floatingWindow(); - if (!fw->geometry().contains(q->m_pressPos)) { +#ifdef Q_OS_LINUX + if (fw->view()->isMaximized()) { + // When dragging a maximized window on linux we need to restore its normal size + // On Windows this works already. On macOS I don't see this feature at all + + const QRect normalGeometry = fw->normalGeometry(); + + // distance to the left edge of the window: + const int leftOffset = q->m_offset.x(); + + // distance to the right edge of the window: + const int rightOffset = fw->width() - q->m_offset.x(); + + const bool leftEdgeIsNearest = leftOffset <= rightOffset; + + fw->showNormal(); + + if (!normalGeometry.contains(q->m_pressPos)) { + if ((leftEdgeIsNearest && leftOffset > normalGeometry.width()) || (!leftEdgeIsNearest && rightOffset > normalGeometry.width())) { + // Case #1: The window isn't under the cursor anymore + // Let's just put its middle under the cursor + q->m_offset.setX(normalGeometry.width() / 2); + } else if (!leftEdgeIsNearest) { + // Case #2: The new geometry is still under the cursor, but instead of moving its right edge left + // we'll move the left edge right, since initially the press position was closer to the right edge + q->m_offset.setX(normalGeometry.width() - rightOffset); + } + } + } else +#endif + + if (!fw->geometry().contains(q->m_pressPos)) { // The window shrunk when the drag started, this can happen if it has max-size constraints // we make the floating window smaller. Has the downside that it might not be under the mouse // cursor anymore, so make the change