From c210a523e39ca838e7b03070f4d198fd4e9fb6fa Mon Sep 17 00:00:00 2001 From: Sergio Martins Date: Sat, 26 Sep 2020 17:44:30 +0100 Subject: [PATCH] Focus the newly dropped dock widget When we drag a dock widget into a another widget, we should focus it Fixes issue #77 --- src/private/DropArea.cpp | 19 ++++++++++++++++++- src/private/MultiSplitter.cpp | 10 ++++++++++ src/private/MultiSplitter_p.h | 5 ++++- tests/tst_docks.cpp | 3 +-- 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/private/DropArea.cpp b/src/private/DropArea.cpp index a7c53a6a..cdd1392e 100644 --- a/src/private/DropArea.cpp +++ b/src/private/DropArea.cpp @@ -225,6 +225,9 @@ bool DropArea::drop(FloatingWindow *droppedWindow, QPoint globalPos) } bool result = true; + const bool needToFocusNewlyDroppedWidgets = Config::self().flags() & Config::Flag_TitleBarIsFocusable; + const DockWidgetBase::List droppedDockWidgets = needToFocusNewlyDroppedWidgets ? droppedWindow->multiSplitter()->dockWidgets() + : DockWidgetBase::List(); // just so save some memory allocations for the case where this variable isn't used auto droploc = m_dropIndicatorOverlay->currentDropLocation(); switch (droploc) { @@ -253,9 +256,23 @@ bool DropArea::drop(FloatingWindow *droppedWindow, QPoint globalPos) break; } - if (result) + if (result) { + // Window receiving the drop gets raised: raiseAndActivate(); + if (needToFocusNewlyDroppedWidgets) { + // Let's also focus the newly dropped dock widget + if (droppedDockWidgets.size() > 0) { + // If more than 1 was dropped, we only focus the first one + Frame *frame = droppedDockWidgets.first()->frame(); + frame->FocusScope::focus(Qt::MouseFocusReason); + } else { + // Doesn't happen. + qWarning() << Q_FUNC_INFO << "Nothing was dropped?"; + } + } + } + return result; } diff --git a/src/private/MultiSplitter.cpp b/src/private/MultiSplitter.cpp index 3c0b020d..73be2916 100644 --- a/src/private/MultiSplitter.cpp +++ b/src/private/MultiSplitter.cpp @@ -288,6 +288,16 @@ Layouting::Item *MultiSplitter::itemForFrame(const Frame *frame) const return m_rootItem->itemForWidget(frame); } +DockWidgetBase::List MultiSplitter::dockWidgets() const +{ + DockWidgetBase::List dockWidgets; + const Frame::List frames = this->frames(); + for (Frame *frame : frames) + dockWidgets << frame->dockWidgets(); + + return dockWidgets; +} + Frame::List MultiSplitter::framesFrom(QWidgetOrQuick *frameOrMultiSplitter) const { if (auto frame = qobject_cast(frameOrMultiSplitter)) diff --git a/src/private/MultiSplitter_p.h b/src/private/MultiSplitter_p.h index 9184e42d..da19bbff 100644 --- a/src/private/MultiSplitter_p.h +++ b/src/private/MultiSplitter_p.h @@ -188,10 +188,13 @@ public: Layouting::Item *itemForFrame(const Frame *frame) const; /** - * @brief Returns a list of Frame objects contained in this layout + * @brief Returns this list of Frame objects contained in this layout */ QList frames() const; + /// @brief Returns the list of dock widgets contained in this layout + QVector dockWidgets() const; + /// @brief restores the dockwidget @p dw to its previous position void restorePlaceholder(DockWidgetBase *dw, Layouting::Item *, int tabIndex); diff --git a/tests/tst_docks.cpp b/tests/tst_docks.cpp index 1d8071e5..91e66de1 100644 --- a/tests/tst_docks.cpp +++ b/tests/tst_docks.cpp @@ -6105,9 +6105,8 @@ void TestDocks::tst_dockWidgetGetsFocusWhenDocked() /// We dropped into floating window 1, it should still be active QVERIFY(fw1->isActiveWindow()); - QEXPECT_FAIL("", "To be fixed", Continue); + // DockWidget 2 was dropped, it should now be focused QVERIFY(!dw1->isFocused()); - QEXPECT_FAIL("", "To be fixed", Continue); QVERIFY(dw2->isFocused()); delete fw1;