12 #include "TitleBar_p.h"
14 #include "FloatingWindow_p.h"
15 #include "Logging_p.h"
16 #include "WindowBeingDragged_p.h"
23 #include <QWindowStateChangeEvent>
27 TitleBar::TitleBar(Frame *parent)
28 : QWidgetAdapter(parent)
31 , m_floatingWindow(nullptr)
32 , m_supportsAutoHide(
Config::self().flags() &
Config::Flag_AutoHideSupport)
34 connect(m_frame, &Frame::numDockWidgetsChanged,
this, &TitleBar::updateCloseButton);
35 connect(m_frame, &Frame::isFocusedChanged,
this, &TitleBar::isFocusedChanged);
36 connect(m_frame, &Frame::isInMainWindowChanged,
this, &TitleBar::updateAutoHideButton);
40 if (Config::self().flags() & Config::Flag_TitleBarIsFocusable)
44 TitleBar::TitleBar(FloatingWindow *parent)
45 : QWidgetAdapter(parent)
48 , m_floatingWindow(parent)
49 , m_supportsAutoHide(
Config::self().flags() &
Config::Flag_AutoHideSupport)
51 connect(m_floatingWindow, &FloatingWindow::numFramesChanged,
this, &TitleBar::updateButtons);
52 connect(m_floatingWindow, &FloatingWindow::windowStateChanged,
this, &TitleBar::updateMaximizeButton);
53 connect(m_floatingWindow, &FloatingWindow::activatedChanged,
this, &TitleBar::isFocusedChanged);
61 connect(
this, &TitleBar::isFocusedChanged,
this, [
this] {
75 bool TitleBar::onDoubleClicked()
77 if ((Config::self().flags() & Config::Flag_DoubleClickMaximizes) && m_floatingWindow) {
81 }
else if (supportsFloatingButton()) {
95 return m_frame->mainWindow();
97 qWarning() << Q_FUNC_INFO <<
"null frame and null floating window";
101 bool TitleBar::isMDI()
const
103 if (
auto mw = mainWindow())
109 void TitleBar::updateButtons()
113 updateMaximizeButton();
114 updateMinimizeButton();
115 updateAutoHideButton();
118 void TitleBar::updateCloseButton()
121 const bool anyNonClosable = frame() ? frame()->anyNonClosable()
122 : (floatingWindow() ? floatingWindow()->anyNonClosable()
125 setCloseButtonEnabled(!anyNonClosable);
128 void TitleBar::toggleMaximized()
130 if (!m_floatingWindow)
133 if (m_floatingWindow->isMaximizedOverride())
134 m_floatingWindow->showNormal();
136 m_floatingWindow->showMaximized();
141 QWidgetAdapter::focusInEvent(ev);
143 if (!m_frame || !(Config::self().flags() & Config::Flag_TitleBarIsFocusable))
147 m_frame->FocusScope::focus(ev->
reason());
150 bool TitleBar::isOverlayed()
const
152 return m_frame && m_frame->isOverlayed();
155 void TitleBar::setCloseButtonEnabled(
bool enabled)
157 if (enabled != m_closeButtonEnabled) {
158 m_closeButtonEnabled = enabled;
159 Q_EMIT closeButtonEnabledChanged(enabled);
163 void TitleBar::setFloatButtonVisible(
bool visible)
165 if (visible != m_floatButtonVisible) {
166 m_floatButtonVisible = visible;
167 Q_EMIT floatButtonVisibleChanged(visible);
171 void TitleBar::setFloatButtonToolTip(
const QString &tip)
173 if (tip != m_floatButtonToolTip) {
174 m_floatButtonToolTip = tip;
175 Q_EMIT floatButtonToolTipChanged(tip);
179 void TitleBar::setTitle(
const QString &title)
181 if (title != m_title) {
184 Q_EMIT titleChanged();
188 void TitleBar::setIcon(
const QIcon &icon)
191 Q_EMIT iconChanged();
194 std::unique_ptr<WindowBeingDragged> TitleBar::makeWindow()
196 if (!isVisible() && window()->isVisible() && !(Config::self().flags() & Config::Flag_ShowButtonsOnTabBarIfTitleBarHidden)) {
201 qWarning() <<
"TitleBar::makeWindow shouldn't be called on invisible title bar"
202 <<
this << window()->isVisible();
204 qWarning() <<
"this=" <<
this <<
"; actual=" << m_frame->actualTitleBar();
205 }
else if (m_floatingWindow) {
206 qWarning() <<
"Has floating window with titlebar=" << m_floatingWindow->titleBar()
207 <<
"; fw->isVisible=" << m_floatingWindow->isVisible();
214 if (m_floatingWindow) {
216 return std::unique_ptr<WindowBeingDragged>(
new WindowBeingDragged(m_floatingWindow,
this));
219 if (FloatingWindow *fw = QWidgetAdapter::floatingWindow()) {
220 if (m_frame->isTheOnlyFrame()) {
221 qCDebug(hovering) <<
"TitleBar::makeWindow no detach needed";
222 return std::unique_ptr<WindowBeingDragged>(
new WindowBeingDragged(fw,
this));
226 QRect r = m_frame->QWidgetAdapter::geometry();
229 auto floatingWindow = Config::self().frameworkWidgetFactory()->createFloatingWindow(m_frame);
231 floatingWindow->show();
233 auto draggable = KDDockWidgets::usesNativeTitleBar() ?
static_cast<Draggable *
>(floatingWindow)
235 return std::unique_ptr<WindowBeingDragged>(
new WindowBeingDragged(floatingWindow, draggable));
241 return dockWidgets.
isEmpty() ? nullptr : dockWidgets.
first();
244 bool TitleBar::supportsFloatingButton()
const
246 if (Config::self().flags() & Config::Flag_TitleBarHasMaximizeButton) {
253 if (Config::self().flags() & Config::Flag_TitleBarNoFloatButton) {
260 if (dw->options() & DockWidgetBase::Option_NotDockable)
266 return !m_floatingWindow || m_floatingWindow->hasSingleFrame();
269 bool TitleBar::supportsMaximizeButton()
const
271 if (!(Config::self().flags() & Config::Flag_TitleBarHasMaximizeButton))
274 return m_floatingWindow !=
nullptr;
277 bool TitleBar::supportsMinimizeButton()
const
279 if ((Config::self().flags() & Config::Flag_TitleBarHasMinimizeButton) != Config::Flag_TitleBarHasMinimizeButton)
282 return m_floatingWindow !=
nullptr;
285 bool TitleBar::supportsAutoHideButton()
const
288 return m_supportsAutoHide && m_frame && (m_frame->isInMainWindow() || m_frame->isOverlayed());
291 bool TitleBar::hasIcon()
const
293 return !m_icon.isNull();
296 bool TitleBar::isFocused()
const
299 return m_frame->isFocused();
300 else if (m_floatingWindow)
301 return m_floatingWindow->isActiveWindow();
306 QIcon TitleBar::icon()
const
311 void TitleBar::onCloseClicked()
313 const bool closeOnlyCurrentTab = Config::self().flags() & Config::Flag_CloseOnlyCurrentTab;
316 if (closeOnlyCurrentTab) {
321 qWarning() << Q_FUNC_INFO <<
"Frame with no dock widgets";
324 if (m_frame->isTheOnlyFrame() && !m_frame->isInMainWindow()) {
325 m_frame->window()->close();
330 }
else if (m_floatingWindow) {
332 if (closeOnlyCurrentTab) {
333 if (Frame *f = m_floatingWindow->singleFrame()) {
338 qWarning() << Q_FUNC_INFO <<
"Frame with no dock widgets";
341 m_floatingWindow->close();
344 m_floatingWindow->close();
349 bool TitleBar::isFloating()
const
351 if (m_floatingWindow)
352 return m_floatingWindow->hasSingleDockWidget();
355 return m_frame->isFloating();
357 qWarning() <<
"TitleBar::isFloating: shouldn't happen";
363 if (m_floatingWindow) {
365 for (Frame *f : m_floatingWindow->frames()) {
366 result << f->dockWidgets();
372 return m_frame->dockWidgets();
374 qWarning() <<
"TitleBar::dockWidget: shouldn't happen";
378 void TitleBar::onFloatClicked()
385 qWarning() <<
"TitleBar::onFloatClicked: empty list. Shouldn't happen";
389 if (dockWidgets.
size() == 1) {
391 dockWidgets[0]->setFloating(
false);
396 for (
auto dock : qAsConst(dockWidgets)) {
397 dock->setFloating(
true);
398 dock->setFloating(
false);
403 if (dockWidgets.
size() == 1) {
406 dockWidgets[0]->setFloating(
true);
413 void TitleBar::onMaximizeClicked()
418 void TitleBar::onMinimizeClicked()
420 if (!m_floatingWindow)
423 if (KDDockWidgets::usesUtilityWindows()) {
429 m_floatingWindow->showMinimized();
432 void TitleBar::onAutoHideClicked()
436 qWarning() << Q_FUNC_INFO <<
"Minimize not supported on floating windows";
440 const auto &dockwidgets = m_frame->dockWidgets();
442 if (dw->isOverlayed()) {
452 bool TitleBar::closeButtonEnabled()
const
454 return m_closeButtonEnabled;
457 bool TitleBar::floatButtonVisible()
const
459 return m_floatButtonVisible;
462 QString TitleBar::floatButtonToolTip()
const
464 return m_floatButtonToolTip;
467 void TitleBar::updateFloatButton()
469 setFloatButtonToolTip(floatingWindow() ? tr(
"Dock window") : tr(
"Undock window"));
470 setFloatButtonVisible(supportsFloatingButton());
473 bool TitleBar::isWindow()
const
475 return m_floatingWindow !=
nullptr;