12 #include "TitleBar_p.h"
14 #include "FloatingWindow_p.h"
15 #include "Logging_p.h"
16 #include "WindowBeingDragged_p.h"
21 #include "MDILayoutWidget_p.h"
22 #include "TabWidget_p.h"
23 #include "DockWidgetBase_p.h"
26 #include <QWindowStateChangeEvent>
30 TitleBar::TitleBar(Frame *parent)
31 : QWidgetAdapter(parent)
34 , m_floatingWindow(nullptr)
35 , m_genericWidget(nullptr)
36 , m_supportsAutoHide(
Config::self().flags() &
Config::Flag_AutoHideSupport)
38 connect(m_frame, &Frame::numDockWidgetsChanged,
this, &TitleBar::updateCloseButton);
39 connect(m_frame, &Frame::isFocusedChanged,
this, &TitleBar::isFocusedChanged);
40 connect(m_frame, &Frame::isInMainWindowChanged,
this, &TitleBar::updateAutoHideButton);
44 if (Config::self().flags() & Config::Flag_TitleBarIsFocusable)
48 TitleBar::TitleBar(FloatingWindow *parent)
49 : QWidgetAdapter(parent)
52 , m_floatingWindow(parent)
53 , m_genericWidget(nullptr)
54 , m_supportsAutoHide(
Config::self().flags() &
Config::Flag_AutoHideSupport)
56 connect(m_floatingWindow, &FloatingWindow::numFramesChanged,
this, &TitleBar::updateButtons);
57 connect(m_floatingWindow, &FloatingWindow::windowStateChanged,
this, &TitleBar::updateMaximizeButton);
58 connect(m_floatingWindow, &FloatingWindow::activatedChanged,
this, &TitleBar::isFocusedChanged);
63 : QWidgetAdapter(parent)
66 , m_floatingWindow(nullptr)
67 , m_genericWidget(parent)
68 , m_supportsAutoHide(false)
77 connect(
this, &TitleBar::isFocusedChanged,
this, [
this] {
91 bool TitleBar::onDoubleClicked()
93 if ((Config::self().flags() & Config::Flag_DoubleClickMaximizes) && m_floatingWindow) {
97 }
else if (supportsFloatingButton()) {
107 if (m_floatingWindow || m_genericWidget)
111 return m_frame->mainWindow();
113 qWarning() << Q_FUNC_INFO <<
"null frame and null floating window";
117 bool TitleBar::isMDI()
const
119 QObject *p =
const_cast<TitleBar *
>(
this);
121 if (qobject_cast<const QWindow *>(p)) {
126 if (qobject_cast<MDILayoutWidget *>(p))
129 if (qobject_cast<DropArea *>(p)) {
141 void TitleBar::updateButtons()
145 updateMaximizeButton();
146 updateMinimizeButton();
147 updateAutoHideButton();
150 void TitleBar::updateCloseButton()
153 const bool anyNonClosable = frame() ? frame()->anyNonClosable()
154 : (floatingWindow() ? floatingWindow()->anyNonClosable()
157 setCloseButtonEnabled(!anyNonClosable);
160 void TitleBar::toggleMaximized()
162 if (!m_floatingWindow)
165 if (m_floatingWindow->isMaximizedOverride())
166 m_floatingWindow->showNormal();
168 m_floatingWindow->showMaximized();
173 QWidgetAdapter::focusInEvent(ev);
175 if (!m_frame || !(Config::self().flags() & Config::Flag_TitleBarIsFocusable))
179 m_frame->FocusScope::focus(ev->
reason());
182 bool TitleBar::isOverlayed()
const
184 return m_frame && m_frame->isOverlayed();
187 void TitleBar::setCloseButtonEnabled(
bool enabled)
189 if (enabled != m_closeButtonEnabled) {
190 m_closeButtonEnabled = enabled;
191 Q_EMIT closeButtonEnabledChanged(enabled);
195 void TitleBar::setFloatButtonVisible(
bool visible)
197 if (visible != m_floatButtonVisible) {
198 m_floatButtonVisible = visible;
199 Q_EMIT floatButtonVisibleChanged(visible);
203 void TitleBar::setFloatButtonToolTip(
const QString &tip)
205 if (tip != m_floatButtonToolTip) {
206 m_floatButtonToolTip = tip;
207 Q_EMIT floatButtonToolTipChanged(tip);
211 void TitleBar::setTitle(
const QString &title)
213 if (title != m_title) {
216 Q_EMIT titleChanged();
220 void TitleBar::setIcon(
const QIcon &icon)
223 Q_EMIT iconChanged();
226 std::unique_ptr<WindowBeingDragged> TitleBar::makeWindow()
231 if (!isVisible() && window()->isVisible() && !(Config::self().flags() & Config::Flag_ShowButtonsOnTabBarIfTitleBarHidden)) {
236 qWarning() <<
"TitleBar::makeWindow shouldn't be called on invisible title bar"
237 <<
this << window()->isVisible();
239 qWarning() <<
"this=" <<
this <<
"; actual=" << m_frame->actualTitleBar();
240 }
else if (m_floatingWindow) {
241 qWarning() <<
"Has floating window with titlebar=" << m_floatingWindow->titleBar()
242 <<
"; fw->isVisible=" << m_floatingWindow->isVisible();
249 if (m_floatingWindow) {
251 return std::unique_ptr<WindowBeingDragged>(
new WindowBeingDragged(m_floatingWindow,
this));
254 if (FloatingWindow *fw = QWidgetAdapter::floatingWindow()) {
255 if (m_frame->isTheOnlyFrame()) {
256 qCDebug(hovering) <<
"TitleBar::makeWindow no detach needed";
257 return std::unique_ptr<WindowBeingDragged>(
new WindowBeingDragged(fw,
this));
261 QRect r = m_frame->QWidgetAdapter::geometry();
264 auto floatingWindow = Config::self().frameworkWidgetFactory()->createFloatingWindow(m_frame);
266 floatingWindow->show();
268 auto draggable = KDDockWidgets::usesNativeTitleBar() ?
static_cast<Draggable *
>(floatingWindow)
270 return std::unique_ptr<WindowBeingDragged>(
new WindowBeingDragged(floatingWindow, draggable));
276 return dockWidgets.
isEmpty() ? nullptr : dockWidgets.
first();
279 bool TitleBar::supportsFloatingButton()
const
284 if (Config::self().flags() & Config::Flag_TitleBarHasMaximizeButton) {
291 if (Config::self().flags() & Config::Flag_TitleBarNoFloatButton) {
298 if (dw->options() & DockWidgetBase::Option_NotDockable)
304 return !m_floatingWindow || m_floatingWindow->hasSingleFrame();
307 bool TitleBar::supportsMaximizeButton()
const
309 if (!(Config::self().flags() & Config::Flag_TitleBarHasMaximizeButton))
312 return m_floatingWindow !=
nullptr;
315 bool TitleBar::supportsMinimizeButton()
const
317 if ((Config::self().flags() & Config::Flag_TitleBarHasMinimizeButton) != Config::Flag_TitleBarHasMinimizeButton)
320 return m_floatingWindow !=
nullptr;
323 bool TitleBar::supportsAutoHideButton()
const
326 return m_supportsAutoHide && m_frame && (m_frame->isInMainWindow() || m_frame->isOverlayed());
329 bool TitleBar::hasIcon()
const
331 return !m_icon.isNull();
334 bool TitleBar::isFocused()
const
337 return m_frame->isFocused();
338 else if (m_floatingWindow)
339 return m_floatingWindow->isActiveWindow();
340 #ifdef KDDOCKWIDGETS_QTWIDGETS
342 else if (m_genericWidget)
343 return m_genericWidget->isActiveWindow();
348 QIcon TitleBar::icon()
const
353 void TitleBar::onCloseClicked()
355 const bool closeOnlyCurrentTab = Config::self().flags() & Config::Flag_CloseOnlyCurrentTab;
358 if (closeOnlyCurrentTab) {
363 qWarning() << Q_FUNC_INFO <<
"Frame with no dock widgets";
366 if (m_frame->isTheOnlyFrame() && m_frame->isInFloatingWindow()) {
367 m_frame->window()->close();
372 }
else if (m_floatingWindow) {
374 if (closeOnlyCurrentTab) {
375 if (Frame *f = m_floatingWindow->singleFrame()) {
380 qWarning() << Q_FUNC_INFO <<
"Frame with no dock widgets";
383 m_floatingWindow->close();
386 m_floatingWindow->close();
388 }
else if (m_genericWidget) {
389 if (
auto window = m_genericWidget->window())
394 bool TitleBar::isFloating()
const
396 if (m_floatingWindow)
400 return m_frame->isFloating();
405 qWarning() <<
"TitleBar::isFloating: shouldn't happen";
411 if (m_floatingWindow) {
413 for (Frame *f : m_floatingWindow->frames()) {
414 result << f->dockWidgets();
420 return m_frame->dockWidgets();
425 qWarning() <<
"TitleBar::dockWidget: shouldn't happen";
429 void TitleBar::onFloatClicked()
436 qWarning() <<
"TitleBar::onFloatClicked: empty list. Shouldn't happen";
440 if (dockWidgets.
size() == 1) {
442 dockWidgets[0]->setFloating(
false);
448 if (!dockWidgets.
constFirst()->hasPreviousDockedLocation()) {
455 for (
auto dock : qAsConst(dockWidgets)) {
457 if (!current && dock->isCurrentTab())
461 dock->dptr()->m_lastPosition->m_tabIndex = i;
462 dock->setFloating(
false);
473 if (dockWidgets.
size() == 1) {
476 dockWidgets[0]->setFloating(
true);
483 void TitleBar::onMaximizeClicked()
488 void TitleBar::onMinimizeClicked()
490 if (!m_floatingWindow)
493 if (KDDockWidgets::usesUtilityWindows()) {
499 m_floatingWindow->showMinimized();
502 void TitleBar::onAutoHideClicked()
506 qWarning() << Q_FUNC_INFO <<
"Minimize not supported on floating windows";
510 const auto &dockwidgets = m_frame->dockWidgets();
512 if (dw->isOverlayed()) {
522 bool TitleBar::closeButtonEnabled()
const
524 return m_closeButtonEnabled;
527 bool TitleBar::floatButtonVisible()
const
529 return m_floatButtonVisible;
532 QString TitleBar::floatButtonToolTip()
const
534 return m_floatButtonToolTip;
537 void TitleBar::updateFloatButton()
539 setFloatButtonToolTip(floatingWindow() ? tr(
"Dock window") : tr(
"Undock window"));
540 setFloatButtonVisible(supportsFloatingButton());
543 bool TitleBar::isWindow()
const
545 return m_floatingWindow !=
nullptr;
548 TabBar *TitleBar::tabBar()
const
550 if (m_floatingWindow && m_floatingWindow->hasSingleFrame()) {
551 if (Frame *frame = m_floatingWindow->singleFrame()) {
552 return frame->tabWidget()->tabBar();
555 qWarning() << Q_FUNC_INFO <<
"Expected a frame";
558 }
else if (m_frame) {
559 return m_frame->tabWidget()->tabBar();