diff --git a/examples/dockwidgets/main.cpp b/examples/dockwidgets/main.cpp index 97fc5291..a7c0a7a1 100644 --- a/examples/dockwidgets/main.cpp +++ b/examples/dockwidgets/main.cpp @@ -78,8 +78,11 @@ int main(int argc, char **argv) QCommandLineOption nonDockable("d", QCoreApplication::translate("main", "DockWidget #9 will be non-dockable")); parser.addOption(nonDockable); - QCommandLineOption maximizeButton("b", QCoreApplication::translate("main", "DockWidgets have maximize/restore buttons instead of float/dock button")); - parser.addOption(maximizeButton); + QCommandLineOption maximizeButtonOption("b", QCoreApplication::translate("main", "Floating dockWidgets have maximize/restore buttons instead of float/dock button")); + parser.addOption(maximizeButtonOption); + + QCommandLineOption minimizeButtonOption("k", QCoreApplication::translate("main", "Floating dockWidgets have a minimize button. Implies not being an utility window (~Qt::Tool)")); + parser.addOption(minimizeButtonOption); QCommandLineOption segmentedIndicators("y", QCoreApplication::translate("main", "Use segmented indicators instead of classical")); parser.addOption(segmentedIndicators); @@ -169,9 +172,12 @@ int main(int argc, char **argv) if (parser.isSet(reorderTabsOption)) flags |= KDDockWidgets::Config::Flag_AllowReorderTabs; - if (parser.isSet(maximizeButton)) + if (parser.isSet(maximizeButtonOption)) flags |= KDDockWidgets::Config::Flag_TitleBarHasMaximizeButton; + if (parser.isSet(minimizeButtonOption)) + flags |= KDDockWidgets::Config::Flag_TitleBarHasMinimizeButton; + if (parser.isSet(lazyResizeOption)) flags |= KDDockWidgets::Config::Flag_LazyResize; diff --git a/src/Config.h b/src/Config.h index cd84771a..8717056a 100644 --- a/src/Config.h +++ b/src/Config.h @@ -71,6 +71,7 @@ public: Flag_internal_DontUseParentForFloatingWindows = 0x1000, ///> FloatingWindows won't have a parent top-level. Internal, use Flag_DontUseUtilityFloatingWindows instead. Flag_DontUseUtilityFloatingWindows = Flag_internal_DontUseQtToolWindowsForFloatingWindows | Flag_internal_DontUseParentForFloatingWindows, + Flag_TitleBarHasMinimizeButton = 0x2000 | Flag_DontUseUtilityFloatingWindows, ///> The title bar will have a minimize button when floating. This implies Flag_DontUseUtilityFloatingWindows too, otherwise they wouldn't appear in the task bar. Flag_Default = Flag_AeroSnapWithClientDecos ///> The defaults }; Q_DECLARE_FLAGS(Flags, Flag) diff --git a/src/private/TitleBar.cpp b/src/private/TitleBar.cpp index efe642d2..a7a31889 100644 --- a/src/private/TitleBar.cpp +++ b/src/private/TitleBar.cpp @@ -45,6 +45,7 @@ TitleBar::TitleBar(FloatingWindow *parent) connect(m_floatingWindow, &FloatingWindow::numFramesChanged, this, &TitleBar::updateCloseButton); connect(m_floatingWindow, &FloatingWindow::numFramesChanged, this, &TitleBar::updateFloatButton); connect(m_floatingWindow, &FloatingWindow::numFramesChanged, this, &TitleBar::updateMaximizeButton); + connect(m_floatingWindow, &FloatingWindow::numFramesChanged, this, &TitleBar::updateMinimizeButton); connect(m_floatingWindow, &FloatingWindow::windowStateChanged, this, &TitleBar::updateMaximizeButton); connect(m_floatingWindow, &FloatingWindow::activatedChanged , this, &TitleBar::isFocusedChanged); init(); @@ -190,6 +191,14 @@ bool TitleBar::supportsMaximizeButton() const return m_floatingWindow != nullptr; } +bool TitleBar::supportsMinimizeButton() const +{ + if ((Config::self().flags() & Config::Flag_TitleBarHasMinimizeButton) != Config::Flag_TitleBarHasMinimizeButton) // this specific flag is not base^2 + return false; + + return m_floatingWindow != nullptr; +} + bool TitleBar::hasIcon() const { return !m_icon.isNull(); @@ -293,3 +302,17 @@ void TitleBar::onMaximizeClicked() { toggleMaximized(); } + +void TitleBar::onMinimizeClicked() +{ + if (!m_floatingWindow) + return; + + if (!(Config::self().flags() & Config::Flag_DontUseUtilityFloatingWindows)) { + // Qt::Tool windows don't appear in the task bar. + // Unless someone tells me a good reason to allow this situation. + return; + } + + m_floatingWindow->showMinimized(); +} diff --git a/src/private/TitleBar_p.h b/src/private/TitleBar_p.h index ab75655f..4764f51b 100644 --- a/src/private/TitleBar_p.h +++ b/src/private/TitleBar_p.h @@ -66,6 +66,9 @@ public: ///@brief returns whether this title bar supports a maximize/restore button bool supportsMaximizeButton() const; + ///@brief returns whether this title bar supports a minimize button + bool supportsMinimizeButton() const; + ///@brief returns whether this title bar has an icon bool hasIcon() const; @@ -97,10 +100,12 @@ protected: Q_INVOKABLE void onCloseClicked(); Q_INVOKABLE void onFloatClicked(); Q_INVOKABLE void onMaximizeClicked(); + Q_INVOKABLE void onMinimizeClicked(); Q_INVOKABLE void toggleMaximized(); virtual void updateFloatButton() {} virtual void updateMaximizeButton() {} + virtual void updateMinimizeButton() {} // The following are needed for the unit-tests virtual bool isCloseButtonVisible() const { return true; } diff --git a/src/private/widgets/TitleBarWidget.cpp b/src/private/widgets/TitleBarWidget.cpp index 0cca8579..6b3fefca 100644 --- a/src/private/widgets/TitleBarWidget.cpp +++ b/src/private/widgets/TitleBarWidget.cpp @@ -50,8 +50,11 @@ void TitleBarWidget::init() m_layout->setSpacing(2); m_maximizeButton = TitleBarWidget::createButton(this, style()->standardIcon(QStyle::SP_TitleBarMaxButton)); + m_minimizeButton = TitleBarWidget::createButton(this, style()->standardIcon(QStyle::SP_TitleBarMinButton)); m_floatButton = TitleBarWidget::createButton(this, style()->standardIcon(QStyle::SP_TitleBarNormalButton)); m_closeButton = TitleBarWidget::createButton(this, style()->standardIcon(QStyle::SP_TitleBarCloseButton)); + + m_layout->addWidget(m_minimizeButton); m_layout->addWidget(m_maximizeButton); m_layout->addWidget(m_floatButton); m_layout->addWidget(m_closeButton); @@ -59,10 +62,12 @@ void TitleBarWidget::init() connect(m_floatButton, &QAbstractButton::clicked, this, &TitleBarWidget::onFloatClicked); connect(m_closeButton, &QAbstractButton::clicked, this, &TitleBarWidget::onCloseClicked); connect(m_maximizeButton, &QAbstractButton::clicked, this, &TitleBarWidget::onMaximizeClicked); + connect(m_minimizeButton, &QAbstractButton::clicked, this, &TitleBarWidget::onMinimizeClicked); updateCloseButton(); updateFloatButton(); updateMaximizeButton(); + updateMinimizeButton(); connect(this, &TitleBar::titleChanged, this, [this] { update(); @@ -99,7 +104,7 @@ int TitleBarWidget::buttonAreaWidth() const TitleBarWidget::~TitleBarWidget() { // To avoid a crash - for (auto button : { m_floatButton, m_maximizeButton, m_closeButton }) { + for (auto button : { m_minimizeButton, m_floatButton, m_maximizeButton, m_closeButton }) { button->setParent(nullptr); button->deleteLater(); } @@ -143,6 +148,11 @@ void TitleBarWidget::updateCloseButton() m_closeButton->setEnabled(!anyNonClosable); } +void TitleBarWidget::updateMinimizeButton() +{ + m_minimizeButton->setVisible(supportsMinimizeButton()); +} + void TitleBarWidget::updateMaximizeButton() { if (auto fw = floatingWindow()) { diff --git a/src/private/widgets/TitleBarWidget_p.h b/src/private/widgets/TitleBarWidget_p.h index 85f7a9b0..41375050 100644 --- a/src/private/widgets/TitleBarWidget_p.h +++ b/src/private/widgets/TitleBarWidget_p.h @@ -51,6 +51,7 @@ protected: void updateFloatButton() override; void updateCloseButton() override; void updateMaximizeButton() override; + void updateMinimizeButton() override; // The following are needed for the unit-tests bool isCloseButtonVisible() const override; @@ -68,6 +69,7 @@ private: QAbstractButton *m_closeButton = nullptr; QAbstractButton *m_floatButton = nullptr; QAbstractButton *m_maximizeButton = nullptr; + QAbstractButton *m_minimizeButton = nullptr; QLabel *m_dockWidgetIcon = nullptr; };