diff --git a/src/DockAreaTitleBar.cpp b/src/DockAreaTitleBar.cpp index 7fbb01a..8651d29 100644 --- a/src/DockAreaTitleBar.cpp +++ b/src/DockAreaTitleBar.cpp @@ -51,6 +51,7 @@ #include "DockAreaTabBar.h" #include "IconProvider.h" #include "DockComponentsFactory.h" +#include "DockFocusController.h" #include @@ -471,7 +472,8 @@ void CDockAreaTitleBar::mousePressEvent(QMouseEvent* ev) if (CDockManager::testConfigFlag(CDockManager::FocusHighlighting)) { - d->TabBar->currentTab()->setFocus(Qt::OtherFocusReason); + //d->TabBar->currentTab()->setFocus(Qt::OtherFocusReason); + d->dockManager()->dockFocusController()->setDockWidgetTabFocused(d->TabBar->currentTab()); } return; } diff --git a/src/DockFocusController.cpp b/src/DockFocusController.cpp index c36f91b..831561f 100644 --- a/src/DockFocusController.cpp +++ b/src/DockFocusController.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include "DockWidget.h" #include "DockAreaWidget.h" @@ -115,6 +116,11 @@ void DockFocusControllerPrivate::updateDockWidgetFocus(CDockWidget* DockWidget) return; } + auto Window = DockWidget->dockContainer()->window()->windowHandle(); + if (Window) + { + Window->setProperty("FocusedDockWidget", QVariant::fromValue(DockWidget)); + } CDockAreaWidget* NewFocusedDockArea = nullptr; if (FocusedDockWidget) { @@ -206,6 +212,8 @@ CDockFocusController::CDockFocusController(CDockManager* DockManager) : d->DockManager = DockManager; connect(QApplication::instance(), SIGNAL(focusChanged(QWidget*, QWidget*)), this, SLOT(onApplicationFocusChanged(QWidget*, QWidget*))); + connect(QApplication::instance(), SIGNAL(focusWindowChanged(QWindow*)), + this, SLOT(onFocusWindowChanged(QWindow*))); connect(d->DockManager, SIGNAL(stateRestored()), SLOT(onStateRestored())); } @@ -216,9 +224,35 @@ CDockFocusController::~CDockFocusController() } +//============================================================================ +void CDockFocusController::onFocusWindowChanged(QWindow *focusWindow) +{ + if (!focusWindow) + { + return; + } + + auto vDockWidget = focusWindow->property("FocusedDockWidget"); + if (!vDockWidget.isValid()) + { + return; + } + + auto DockWidget = vDockWidget.value(); + if (!DockWidget) + { + return; + } + + d->updateDockWidgetFocus(DockWidget); +} + + //=========================================================================== void CDockFocusController::onApplicationFocusChanged(QWidget* focusedOld, QWidget* focusedNow) { + Q_UNUSED(focusedOld); + if (d->DockManager->isRestoringState()) { return; @@ -231,47 +265,7 @@ void CDockFocusController::onApplicationFocusChanged(QWidget* focusedOld, QWidge return; } - // If the close button in another tab steals the focus from the current - // active dock widget content, i.e. if the user clicks its close button, - // then we immediately give the focus back to the previous focused widget - // focusedOld - if (CDockManager::testConfigFlag(CDockManager::AllTabsHaveCloseButton)) - { - auto OtherDockWidgetTab = internal::findParent(focusedNow); - if (OtherDockWidgetTab && focusedOld) - { - auto OldFocusedDockWidget = internal::findParent(focusedOld); - if (OldFocusedDockWidget) - { - focusedOld->setFocus(); - } - return; - } - } - - CDockWidget* DockWidget = nullptr; - auto DockWidgetTab = qobject_cast(focusedNow); - if (DockWidgetTab) - { - DockWidget = DockWidgetTab->dockWidget(); - // If the DockWidgetTab "steals" the focus from a widget in the same - // DockWidget, then we immediately give the focus back to the previous - // focused widget focusedOld - if (focusedOld) - { - auto OldFocusedDockWidget = internal::findParent(focusedOld); - if (OldFocusedDockWidget && OldFocusedDockWidget == DockWidget) - { - focusedOld->setFocus(); - } - } - } - - if (!DockWidget) - { - DockWidget = qobject_cast(focusedNow); - } - + CDockWidget* DockWidget = qobject_cast(focusedNow); if (!DockWidget) { DockWidget = internal::findParent(focusedNow); @@ -293,6 +287,17 @@ void CDockFocusController::onApplicationFocusChanged(QWidget* focusedOld, QWidge } +//=========================================================================== +void CDockFocusController::setDockWidgetTabFocused(CDockWidgetTab* Tab) +{ + auto DockWidget = Tab->dockWidget(); + if (DockWidget) + { + d->updateDockWidgetFocus(DockWidget); + } +} + + //=========================================================================== void CDockFocusController::setDockWidgetFocused(CDockWidget* focusedNow) { @@ -320,7 +325,7 @@ void CDockFocusController::onFocusedDockAreaViewToggled(bool Open) return; } - CDockManager::setWidgetFocus(OpenedDockAreas[0]->currentDockWidget()->tabWidget()); + d->updateDockWidgetFocus(OpenedDockAreas[0]->currentDockWidget()); } @@ -348,7 +353,7 @@ void CDockFocusController::notifyWidgetOrAreaRelocation(QWidget* DroppedWidget) } d->ForceFocusChangedSignal = true; - CDockManager::setWidgetFocus(DockWidget->tabWidget()); + CDockManager::setWidgetFocus(DockWidget); } @@ -369,9 +374,8 @@ void CDockFocusController::notifyFloatingWidgetDrop(CFloatingDockContainer* Floa auto DockWidget = vDockWidget.value(); if (DockWidget) { - d->FocusedDockWidget = nullptr; DockWidget->dockAreaWidget()->setCurrentDockWidget(DockWidget); - CDockManager::setWidgetFocus(DockWidget->tabWidget()); + CDockManager::setWidgetFocus(DockWidget); } } diff --git a/src/DockFocusController.h b/src/DockFocusController.h index 0a354ef..b080f3b 100644 --- a/src/DockFocusController.h +++ b/src/DockFocusController.h @@ -32,6 +32,7 @@ private: private Q_SLOTS: void onApplicationFocusChanged(QWidget *old, QWidget *now); + void onFocusWindowChanged(QWindow *focusWindow); void onFocusedDockAreaViewToggled(bool Open); void onStateRestored(); void onDockWidgetVisibilityChanged(bool Visible); @@ -48,21 +49,6 @@ public: */ virtual ~CDockFocusController(); - /** - * Helper function to set focus depending on the configuration of the - * FocusStyling flag - */ - template - static void setWidgetFocus(QWidgetPtr widget) - { - if (!CDockManager::testConfigFlag(CDockManager::FocusHighlighting)) - { - return; - } - - widget->setFocus(Qt::OtherFocusReason); - } - /** * A container needs to call this function if a widget has been dropped * into it @@ -83,6 +69,12 @@ public: */ CDockWidget* focusedDockWidget() const; + /** + * Request focus highlighting for the given dock widget assigned to the tab + * given in Tab parameter + */ + void setDockWidgetTabFocused(CDockWidgetTab* Tab); + public Q_SLOTS: /** * Request a focus change to the given dock widget diff --git a/src/DockManager.cpp b/src/DockManager.cpp index 42f61b8..9df3a5a 100644 --- a/src/DockManager.cpp +++ b/src/DockManager.cpp @@ -1140,6 +1140,13 @@ void CDockManager::setSplitterSizes(CDockAreaWidget *ContainedArea, const QList< } } + +//=========================================================================== +CDockFocusController* CDockManager::dockFocusController() const +{ + return d->FocusController; +} + } // namespace ads //--------------------------------------------------------------------------- diff --git a/src/DockManager.h b/src/DockManager.h index 390e283..5941ea7 100644 --- a/src/DockManager.h +++ b/src/DockManager.h @@ -53,6 +53,7 @@ struct DockWidgetTabPrivate; struct DockAreaWidgetPrivate; class CIconProvider; class CDockComponentsFactory; +class CDockFocusController; /** * The central dock manager that maintains the complete docking system. @@ -134,12 +135,18 @@ protected: */ void notifyFloatingWidgetDrop(CFloatingDockContainer* FloatingWidget); - /** * Show the floating widgets that has been created floating */ virtual void showEvent(QShowEvent *event) override; + /** + * Acces for the internal dock focus controller. + * This function only returns a valid object, if the FocusHighlighting + * flag is set. + */ + CDockFocusController* dockFocusController() const; + public: using Super = CDockContainerWidget; diff --git a/src/DockWidgetTab.cpp b/src/DockWidgetTab.cpp index a43ba03..9eaa911 100644 --- a/src/DockWidgetTab.cpp +++ b/src/DockWidgetTab.cpp @@ -50,6 +50,7 @@ #include "DockOverlay.h" #include "DockManager.h" #include "IconProvider.h" +#include "DockFocusController.h" namespace ads @@ -207,6 +208,14 @@ struct DockWidgetTabPrivate IconLabel->setVisible(true); } + /** + * Convenience function for access to the dock manager dock focus controller + */ + CDockFocusController* focusController() const + { + return DockWidget->dockManager()->dockFocusController(); + } + }; // struct DockWidgetTabPrivate @@ -234,6 +243,7 @@ void DockWidgetTabPrivate::createLayout() CloseButton->setObjectName("tabCloseButton"); internal::setButtonIcon(CloseButton, QStyle::SP_TitleBarCloseButton, TabCloseIcon); CloseButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + CloseButton->setFocusPolicy(Qt::NoFocus); updateCloseButtonSizePolicy(); internal::setToolTip(CloseButton, QObject::tr("Close Tab")); _this->connect(CloseButton, SIGNAL(clicked()), SIGNAL(closeRequested())); @@ -331,10 +341,11 @@ CDockWidgetTab::CDockWidgetTab(CDockWidget* DockWidget, QWidget *parent) : setAttribute(Qt::WA_NoMousePropagation, true); d->DockWidget = DockWidget; d->createLayout(); - if (CDockManager::testConfigFlag(CDockManager::FocusHighlighting)) + setFocusPolicy(Qt::NoFocus); + /*if (CDockManager::testConfigFlag(CDockManager::FocusHighlighting)) { setFocusPolicy(Qt::ClickFocus); - } + }*/ } //============================================================================ @@ -353,6 +364,10 @@ void CDockWidgetTab::mousePressEvent(QMouseEvent* ev) ev->accept(); d->saveDragStartMousePosition(internal::globalPositionOf(ev)); d->DragState = DraggingMousePressed; + if (CDockManager::testConfigFlag(CDockManager::FocusHighlighting)) + { + d->focusController()->setDockWidgetTabFocused(this); + } Q_EMIT clicked(); return; } @@ -515,7 +530,8 @@ void CDockWidgetTab::setActiveTab(bool active) bool UpdateFocusStyle = false; if (active && !hasFocus()) { - setFocus(Qt::OtherFocusReason); + //setFocus(Qt::OtherFocusReason); + d->focusController()->setDockWidgetTabFocused(this); UpdateFocusStyle = true; }