Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qdockwidget.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qdockwidget.h"
5
6#include <qaction.h>
7#include <qapplication.h>
8#include <qdrawutil.h>
9#include <qevent.h>
10#include <qfontmetrics.h>
11#include <qproxystyle.h>
12#include <qwindow.h>
13#include <qscreen.h>
14#include <qmainwindow.h>
15#include <qstylepainter.h>
16#include <qtoolbutton.h>
17#include <qdebug.h>
18
19#include <private/qwidgetresizehandler_p.h>
20#include <private/qstylesheetstyle_p.h>
21#include <qpa/qplatformtheme.h>
22
23#include <private/qhighdpiscaling_p.h>
24#include "qdockwidget_p.h"
25#include "qmainwindowlayout_p.h"
26
28
29using namespace Qt::StringLiterals;
30
31extern QString qt_setWindowTitle_helperHelper(const QString&, const QWidget*); // qwidget.cpp
32
33// qmainwindow.cpp
35
37{
38 for (const QWidget *p = dock->parentWidget(); p; p = p->parentWidget()) {
39 if (const QMainWindow *window = qobject_cast<const QMainWindow*>(p))
40 return window;
41 }
42 return nullptr;
43}
44
46{
47 auto mainWindow = mainwindow_from_dock(dock);
48 return mainWindow ? qt_mainwindow_layout(mainWindow) : nullptr;
49}
50
52{ return (priv->features & feature) == feature; }
53
54static inline bool hasFeature(const QDockWidget *dockwidget, QDockWidget::DockWidgetFeature feature)
55{ return (dockwidget->features() & feature) == feature; }
56
57
58/*
59 A Dock Window:
60
61 [+] is the float button
62 [X] is the close button
63
64 +-------------------------------+
65 | Dock Window Title [+][X]|
66 +-------------------------------+
67 | |
68 | place to put the single |
69 | QDockWidget child (this space |
70 | does not yet have a name) |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 +-------------------------------+
81
82*/
83
84/******************************************************************************
85** QDockWidgetTitleButton
86*/
87
89{
91
92public:
94
95 QSize sizeHint() const override;
96 QSize minimumSizeHint() const override
97 { return sizeHint(); }
98
99 void enterEvent(QEnterEvent *event) override;
100 void leaveEvent(QEvent *event) override;
101 void paintEvent(QPaintEvent *event) override;
102
103protected:
104 bool event(QEvent *event) override;
105
106private:
107 QSize dockButtonIconSize() const;
108
109 mutable int m_iconSize = -1;
110};
111
117
119{
120 switch (event->type()) {
123 m_iconSize = -1;
124 break;
125 default:
126 break;
127 }
129}
130
131QSize QDockWidgetTitleButton::dockButtonIconSize() const
132{
133 if (m_iconSize < 0) {
134 m_iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize, nullptr, this);
135 if (style()->styleHint(QStyle::SH_DockWidget_ButtonsHaveFrame, nullptr, this))
136 m_iconSize = (m_iconSize * 5) / 8; // 16 -> 10
137 }
138 return QSize(m_iconSize, m_iconSize);
139}
140
142{
144
146 if (!icon().isNull()) {
147 const QSize sz = icon().actualSize(dockButtonIconSize());
148 size += qMax(sz.width(), sz.height());
149 }
150
151 return QSize(size, size);
152}
153
159
165
167{
168 QStylePainter p(this);
169
171 opt.initFrom(this);
173
174 if (style()->styleHint(QStyle::SH_DockWidget_ButtonsHaveFrame, nullptr, this)) {
175 if (isEnabled() && underMouse() && !isChecked() && !isDown())
177 if (isChecked())
179 if (isDown())
181 p.drawPrimitive(QStyle::PE_PanelButtonTool, opt);
182 } else if (isDown() || isChecked()) {
183 // no frame, but the icon might have explicit pixmaps for QIcon::On
185 }
186
187 opt.icon = icon();
188 opt.subControls = { };
189 opt.activeSubControls = { };
191 opt.arrowType = Qt::NoArrow;
192 opt.iconSize = dockButtonIconSize();
193 p.drawComplexControl(QStyle::CC_ToolButton, opt);
194}
195
196/******************************************************************************
197** QDockWidgetLayout
198*/
199
201 : QLayout(parent), verticalTitleBar(false), item_list(RoleCount, 0)
202{
203}
204
209
215{
216 bool floating = parentWidget()->isWindow();
217#if QT_CONFIG(tabbar)
218 if (auto groupWindow =
219 qobject_cast<const QDockWidgetGroupWindow *>(parentWidget()->parentWidget()))
220 floating = floating || groupWindow->tabLayoutInfo();
221#endif
222 return nativeWindowDeco(floating);
223}
224
230{
231#if defined(Q_OS_ANDROID)
232 return false;
233#else
234 static const bool xcb = !QGuiApplication::platformName().compare("xcb"_L1, Qt::CaseInsensitive);
235 static const bool wayland =
237 return !(xcb || wayland);
238#endif
239}
240
246bool QDockWidgetLayout::nativeWindowDeco(bool floating) const
247{
248 return wmSupportsNativeWindowDeco() && floating && item_list.at(QDockWidgetLayout::TitleBar) == nullptr;
249}
250
251
253{
254 qWarning("QDockWidgetLayout::addItem(): please use QDockWidgetLayout::setWidget()");
255 return;
256}
257
259{
260 int cnt = 0;
261 for (int i = 0; i < item_list.size(); ++i) {
262 QLayoutItem *item = item_list.at(i);
263 if (item == nullptr)
264 continue;
265 if (index == cnt++)
266 return item;
267 }
268 return nullptr;
269}
270
272{
273 int j = 0;
274 for (int i = 0; i < item_list.size(); ++i) {
275 QLayoutItem *item = item_list.at(i);
276 if (item == nullptr)
277 continue;
278 if (index == j) {
279 item_list[i] = 0;
280 invalidate();
281 return item;
282 }
283 ++j;
284 }
285 return nullptr;
286}
287
289{
290 int result = 0;
291 for (int i = 0; i < item_list.size(); ++i) {
292 if (item_list.at(i))
293 ++result;
294 }
295 return result;
296}
297
298QSize QDockWidgetLayout::sizeFromContent(const QSize &content, bool floating) const
299{
300 QSize result = content;
301
302 if (verticalTitleBar) {
304 result.setWidth(qMax(content.width(), 0));
305 } else {
306 result.setHeight(qMax(result.height(), 0));
307 result.setWidth(qMax(content.width(), minimumTitleWidth()));
308 }
309
310 QDockWidget *w = qobject_cast<QDockWidget*>(parentWidget());
311 const bool nativeDeco = nativeWindowDeco(floating);
312
313 int fw = floating && !nativeDeco
314 ? w->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, nullptr, w)
315 : 0;
316
317 const int th = titleHeight();
318 if (!nativeDeco) {
320 result += QSize(th + 2*fw, 2*fw);
321 else
322 result += QSize(2*fw, th + 2*fw);
323 }
324
325 result.setHeight(qMin(result.height(), (int) QWIDGETSIZE_MAX));
326 result.setWidth(qMin(result.width(), (int) QWIDGETSIZE_MAX));
327
328 if (content.width() < 0)
329 result.setWidth(-1);
330 if (content.height() < 0)
331 result.setHeight(-1);
332
333 const QMargins margins = w->contentsMargins();
334 //we need to subtract the contents margin (it will be added by the caller)
335 QSize min = w->minimumSize().shrunkBy(margins);
336 QSize max = w->maximumSize().shrunkBy(margins);
337
338 /* A floating dockwidget will automatically get its minimumSize set to the layout's
339 minimum size + deco. We're *not* interested in this, we only take minimumSize()
340 into account if the user set it herself. Otherwise we end up expanding the result
341 of a calculation for a non-floating dock widget to a floating dock widget's
342 minimum size + window decorations. */
343
344 uint explicitMin = 0;
345 uint explicitMax = 0;
346 if (w->d_func()->extra != nullptr) {
347 explicitMin = w->d_func()->extra->explicitMinSize;
348 explicitMax = w->d_func()->extra->explicitMaxSize;
349 }
350
351 if (!(explicitMin & Qt::Horizontal) || min.width() == 0)
352 min.setWidth(-1);
353 if (!(explicitMin & Qt::Vertical) || min.height() == 0)
354 min.setHeight(-1);
355
356 if (!(explicitMax & Qt::Horizontal))
358 if (!(explicitMax & Qt::Vertical))
360
361 return result.boundedTo(max).expandedTo(min);
362}
363
365{
366 QDockWidget *w = qobject_cast<QDockWidget*>(parentWidget());
367
368 QSize content(-1, -1);
369 if (item_list[Content] != 0)
370 content = item_list[Content]->sizeHint();
371
372 return sizeFromContent(content, w->isFloating());
373}
374
376{
377 if (item_list[Content] != 0) {
378 const QSize content = item_list[Content]->maximumSize();
379 return sizeFromContent(content, parentWidget()->isWindow());
380 } else {
381 return parentWidget()->maximumSize();
382 }
383
384}
385
387{
388 QDockWidget *w = qobject_cast<QDockWidget*>(parentWidget());
389
390 QSize content(0, 0);
391 if (item_list[Content] != 0)
392 content = item_list[Content]->minimumSize();
393
394 return sizeFromContent(content, w->isFloating());
395}
396
398{
399 QLayoutItem *item = item_list.at(r);
400 return item == nullptr ? nullptr : item->widget();
401}
402
404{
405 return item_list.at(r);
406}
407
409{
410 QWidget *old = widgetForRole(r);
411 if (old != nullptr) {
412 old->hide();
413 removeWidget(old);
414 }
415
416 if (w != nullptr) {
418 item_list[r] = new QWidgetItemV2(w);
419 w->show();
420 } else {
421 item_list[r] = 0;
422 }
423
424 invalidate();
425}
426
427static inline int pick(bool vertical, const QSize &size)
428{
429 return vertical ? size.height() : size.width();
430}
431
432static inline int perp(bool vertical, const QSize &size)
433{
434 return vertical ? size.width() : size.height();
435}
436
438{
439 QDockWidget *q = qobject_cast<QDockWidget*>(parentWidget());
440
442 return pick(verticalTitleBar, title->minimumSizeHint());
443
444 QSize closeSize(0, 0);
445 QSize floatSize(0, 0);
447 if (QLayoutItem *item = item_list[CloseButton])
448 closeSize = item->widget()->sizeHint();
449 }
451 if (QLayoutItem *item = item_list[FloatButton])
452 floatSize = item->widget()->sizeHint();
453 }
454
455 int titleHeight = this->titleHeight();
456
457 int mw = q->style()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, nullptr, q);
458 int fw = q->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, nullptr, q);
459
460 return pick(verticalTitleBar, closeSize)
461 + pick(verticalTitleBar, floatSize)
462 + titleHeight + 2*fw + 3*mw;
463}
464
466{
467 QDockWidget *q = qobject_cast<QDockWidget*>(parentWidget());
468
470 return perp(verticalTitleBar, title->sizeHint());
471
472 QSize closeSize(0, 0);
473 QSize floatSize(0, 0);
474 if (QLayoutItem *item = item_list[CloseButton])
475 closeSize = item->widget()->sizeHint();
476 if (QLayoutItem *item = item_list[FloatButton])
477 floatSize = item->widget()->sizeHint();
478
479 int buttonHeight = qMax(perp(verticalTitleBar, closeSize),
480 perp(verticalTitleBar, floatSize));
481
482 QFontMetrics titleFontMetrics = q->fontMetrics();
483 int mw = q->style()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, nullptr, q);
484
485 return qMax(buttonHeight + 2, titleFontMetrics.height() + 2*mw);
486}
487
489{
490 QDockWidget *q = qobject_cast<QDockWidget*>(parentWidget());
491
492 bool nativeDeco = nativeWindowDeco();
493
494 int fw = q->isFloating() && !nativeDeco
495 ? q->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, nullptr, q)
496 : 0;
497
498 if (nativeDeco) {
499 if (QLayoutItem *item = item_list[Content])
500 item->setGeometry(geometry);
501 } else {
502 int titleHeight = this->titleHeight();
503
504 if (verticalTitleBar) {
505 _titleArea = QRect(QPoint(fw, fw),
506 QSize(titleHeight, geometry.height() - (fw * 2)));
507 } else {
508 _titleArea = QRect(QPoint(fw, fw),
509 QSize(geometry.width() - (fw * 2), titleHeight));
510 }
511
512 if (QLayoutItem *item = item_list[TitleBar]) {
513 item->setGeometry(_titleArea);
514 } else {
516 q->initStyleOption(&opt);
517
518 if (QLayoutItem *item = item_list[CloseButton]) {
519 if (!item->isEmpty()) {
520 QRect r = q->style()
521 ->subElementRect(QStyle::SE_DockWidgetCloseButton,
522 &opt, q);
523 if (!r.isNull())
524 item->setGeometry(r);
525 }
526 }
527
528 if (QLayoutItem *item = item_list[FloatButton]) {
529 if (!item->isEmpty()) {
530 QRect r = q->style()
531 ->subElementRect(QStyle::SE_DockWidgetFloatButton,
532 &opt, q);
533 if (!r.isNull())
534 item->setGeometry(r);
535 }
536 }
537 }
538
539 if (QLayoutItem *item = item_list[Content]) {
540 QRect r = geometry;
541 if (verticalTitleBar) {
542 r.setLeft(_titleArea.right() + 1);
543 r.adjust(0, fw, -fw, -fw);
544 } else {
545 r.setTop(_titleArea.bottom() + 1);
546 r.adjust(fw, 0, -fw, -fw);
547 }
548 item->setGeometry(r);
549 }
550 }
551}
552
554{
555 if (b == verticalTitleBar)
556 return;
558 invalidate();
559 parentWidget()->update();
560}
561
562/******************************************************************************
563** QDockWidgetItem
564*/
565
570
572{
573 QSize widgetMin(0, 0);
574 if (QLayoutItem *item = dockWidgetChildItem())
575 widgetMin = item->minimumSize();
576 return dockWidgetLayout()->sizeFromContent(widgetMin, false);
577}
578
580{
581 if (QLayoutItem *item = dockWidgetChildItem()) {
582 return dockWidgetLayout()->sizeFromContent(item->maximumSize(), false);
583 } else {
585 }
586}
587
588
590{
591 if (QLayoutItem *item = dockWidgetChildItem()) {
592 return dockWidgetLayout()->sizeFromContent(item->sizeHint(), false);
593 } else {
594 return QWidgetItem::sizeHint();
595 }
596}
597
598/******************************************************************************
599** QDockWidgetPrivate
600*/
601
634
643{
644 Q_D(const QDockWidget);
645
646 if (!option)
647 return;
648 QDockWidgetLayout *dwlayout = qobject_cast<QDockWidgetLayout*>(layout());
649
650 QDockWidgetGroupWindow *floatingTab = qobject_cast<QDockWidgetGroupWindow*>(parent());
651 // If we are in a floating tab, init from the parent because the attributes and the geometry
652 // of the title bar should be taken from the floating window.
653 option->initFrom(floatingTab && !isFloating() ? parentWidget() : this);
654 option->rect = dwlayout->titleArea();
655 option->title = d->fixedWindowTitle;
659
660 QDockWidgetLayout *l = qobject_cast<QDockWidgetLayout*>(layout());
661 option->verticalTitleBar = l->verticalTitleBar;
662}
663
665{
666 Q_Q(QDockWidget);
667 if (b == q->isHidden()) {
668 if (b)
669 q->show();
670 else
671 q->close();
672 }
673}
674
676{
677 Q_Q(QDockWidget);
678 QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);
679
681 q->initStyleOption(&opt);
682
683 bool customTitleBar = dwLayout->widgetForRole(QDockWidgetLayout::TitleBar) != nullptr;
684 bool nativeDeco = dwLayout->nativeWindowDeco();
685 bool hideButtons = nativeDeco || customTitleBar;
686
687 bool canClose = hasFeature(this, QDockWidget::DockWidgetClosable);
688 bool canFloat = hasFeature(this, QDockWidget::DockWidgetFloatable);
689
691 = qobject_cast<QAbstractButton*>(dwLayout->widgetForRole(QDockWidgetLayout::FloatButton));
692 button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarNormalButton, &opt, q));
693 button->setVisible(canFloat && !hideButtons);
694#if QT_CONFIG(accessibility)
695 //: Accessible name for button undocking a dock widget (floating state)
696 button->setAccessibleName(QDockWidget::tr("Float"));
697 button->setAccessibleDescription(QDockWidget::tr("Undocks and re-attaches the dock widget"));
698#endif
699 button
700 = qobject_cast <QAbstractButton*>(dwLayout->widgetForRole(QDockWidgetLayout::CloseButton));
701 button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarCloseButton, &opt, q));
702 button->setVisible(canClose && !hideButtons);
703#if QT_CONFIG(accessibility)
704 //: Accessible name for button closing a dock widget
705 button->setAccessibleName(QDockWidget::tr("Close"));
706 button->setAccessibleDescription(QDockWidget::tr("Closes the dock widget"));
707#endif
708
710}
711
713{
714 Q_Q(QDockWidget);
715 q->setFloating(!q->isFloating());
716}
717
725{
726 Q_Q(QDockWidget);
727
728 if (state != nullptr)
729 return;
730
732 Q_ASSERT(layout != nullptr);
733 if (layout->pluggingWidget != nullptr) // the main window is animating a docking operation
734 return;
735
736 state = new QDockWidgetPrivate::DragState;
737 state->pressPos = pos;
738 state->globalPressPos = q->mapToGlobal(pos);
739 state->widgetInitialPos = q->isFloating() ? q->pos() : q->mapToGlobal(QPoint(0, 0));
740 state->dragging = false;
741 state->widgetItem = nullptr;
742 state->ownWidgetItem = false;
743 state->nca = nca;
744 state->ctrlDrag = false;
745}
746
754{
755 Q_Q(QDockWidget);
756
757 if (state == nullptr || state->dragging)
758 return;
759
761 Q_ASSERT(layout != nullptr);
762
763#if QT_CONFIG(draganddrop)
764 bool wasFloating = q->isFloating();
765#endif
766
767 state->widgetItem = layout->unplug(q, scope);
768 if (state->widgetItem == nullptr) {
769 /* Dock widget has a QMainWindow parent, but was never inserted with
770 QMainWindow::addDockWidget, so the QMainWindowLayout has no
771 widget item for it. It will be newly created and deleted if it doesn't
772 get dropped into a dock area. */
773 QDockWidgetGroupWindow *floatingTab = qobject_cast<QDockWidgetGroupWindow*>(parent);
774 if (floatingTab && !q->isFloating())
775 state->widgetItem = new QDockWidgetGroupWindowItem(floatingTab);
776 else
777 state->widgetItem = new QDockWidgetItem(q);
778 state->ownWidgetItem = true;
779 }
780
781 if (state->ctrlDrag)
782 layout->restore();
783
784 state->dragging = true;
785
786#if QT_CONFIG(draganddrop)
787 if (QMainWindowLayout::needsPlatformDrag()) {
789 layout->performPlatformWidgetDrag(state->widgetItem, state->pressPos);
790 if (result == Qt::IgnoreAction && !wasFloating) {
791 layout->revert(state->widgetItem);
792 delete state;
793 state = nullptr;
794 } else {
796 }
797 }
798#endif
799}
800
807{
808 Q_Q(QDockWidget);
809 Q_ASSERT(state != nullptr);
810
811 q->releaseMouse();
812
813 if (state->dragging) {
814 const QMainWindow *mainWindow = mainwindow_from_dock(q);
815 Q_ASSERT(mainWindow != nullptr);
816 QMainWindowLayout *mwLayout = qt_mainwindow_layout(mainWindow);
817
818 // if mainWindow is being deleted in an ongoing drag, make it a no-op instead of crashing
819 if (!mwLayout)
820 return;
821
822 if (mode == EndDragMode::Abort || !mwLayout->plug(state->widgetItem)) {
824 // This QDockWidget will now stay in the floating state.
825 if (state->ownWidgetItem) {
826 delete state->widgetItem;
827 state->widgetItem = nullptr;
828 }
829 mwLayout->restore();
830 QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);
831 if (!dwLayout->nativeWindowDeco()) {
832 // get rid of the X11BypassWindowManager window flag and activate the resizer
833 Qt::WindowFlags flags = q->windowFlags();
834 flags &= ~Qt::X11BypassWindowManagerHint;
835 q->setWindowFlags(flags);
836 setResizerActive(q->isFloating());
837 q->show();
838 } else {
839 setResizerActive(false);
840 }
841 if (q->isFloating()) { // Might not be floating when dragging a QDockWidgetGroupWindow
842 undockedGeometry = q->geometry();
843#if QT_CONFIG(tabwidget)
844 // is the widget located within the mainwindow?
845 const Qt::DockWidgetArea area = mainWindow->dockWidgetArea(q);
846 if (area != Qt::NoDockWidgetArea) {
847 tabPosition = mwLayout->tabPosition(area);
848 } else if (auto dwgw = qobject_cast<QDockWidgetGroupWindow *>(q->parent())) {
849 // DockWidget wasn't found in one of the docks within mainwindow
850 // => derive tabPosition from parent
851 tabPosition = mwLayout->tabPosition(toDockWidgetArea(dwgw->layoutInfo()->dockPos));
852 }
853#endif
854 // Reparent, if the drag was out of a dock widget group window
856 if (auto *groupWindow = qobject_cast<QDockWidgetGroupWindow *>(q->parentWidget()))
857 groupWindow->reparent(q);
858 }
859 }
860 q->activateWindow();
861 } else {
862 // The tab was not plugged back in the QMainWindow but the QDockWidget cannot
863 // stay floating, revert to the previous state.
864 mwLayout->revert(state->widgetItem);
865 }
866 }
867 }
868 delete state;
869 state = nullptr;
870}
871
883
885{
886 Q_Q(QDockWidget);
887 const auto *dwLayout = qobject_cast<QDockWidgetLayout *>(layout);
888 if (dwLayout->nativeWindowDeco(q->isFloating()))
889 return;
890
891 if (active && !resizer)
892 resizer = new QWidgetResizeHandler(q);
893 if (resizer)
894 resizer->setEnabled(active);
895}
896
898{
899 Q_Q(const QDockWidget);
900
902 if (mainWinLayout == nullptr)
903 return false;
904
905 return (const void*)mainWinLayout->pluggingWidget == (const void*)q;
906}
907
909{
910#if QT_CONFIG(mainwindow)
911 Q_Q(QDockWidget);
912
913 QDockWidgetLayout *dwLayout
914 = qobject_cast<QDockWidgetLayout*>(layout);
915
916 if (!dwLayout->nativeWindowDeco()) {
917 QRect titleArea = dwLayout->titleArea();
918
919 QDockWidgetGroupWindow *floatingTab = qobject_cast<QDockWidgetGroupWindow*>(parent);
920
921 if (event->button() != Qt::LeftButton ||
922 !titleArea.contains(event->position().toPoint()) ||
923 // check if the tool window is movable... do nothing if it
924 // is not (but allow moving if the window is floating)
925 (!hasFeature(this, QDockWidget::DockWidgetMovable) && !q->isFloating()) ||
926 (qobject_cast<QMainWindow*>(parent) == nullptr && !floatingTab) ||
927 isAnimating() || state != nullptr) {
928 return false;
929 }
930
931 initDrag(event->position().toPoint(), false);
932
933 if (state)
934 state->ctrlDrag = (hasFeature(this, QDockWidget::DockWidgetFloatable) && event->modifiers() & Qt::ControlModifier) ||
935 (!hasFeature(this, QDockWidget::DockWidgetMovable) && q->isFloating());
936
937 return true;
938 }
939
940#endif // QT_CONFIG(mainwindow)
941 return false;
942}
943
945{
946 QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);
947
948 if (!dwLayout->nativeWindowDeco()) {
949 QRect titleArea = dwLayout->titleArea();
950
951 if (event->button() == Qt::LeftButton && titleArea.contains(event->position().toPoint()) &&
954 return true;
955 }
956 }
957 return false;
958}
959
961{
962 Q_Q(const QDockWidget);
963 QDockWidget *that = const_cast<QDockWidget *>(q);
964 auto *mwLayout = qt_mainwindow_layout_from_dock(that);
965 Q_ASSERT(mwLayout);
966 return mwLayout->isDockWidgetTabbed(q);
967}
968
970{
971 bool ret = false;
972#if QT_CONFIG(mainwindow)
973 Q_Q(QDockWidget);
974
975 if (!state)
976 return ret;
977
978 QDockWidgetLayout *dwlayout
979 = qobject_cast<QDockWidgetLayout *>(layout);
981 if (!dwlayout->nativeWindowDeco()) {
982 if (!state->dragging
983 && mwlayout->pluggingWidget == nullptr
984 && (event->position().toPoint() - state->pressPos).manhattanLength()
986
987#ifdef Q_OS_MACOS
988 if (windowHandle() && !q->isFloating()) {
989 // When using native widgets on mac, we have not yet been successful in
990 // starting a drag on an NSView that belongs to one window (QMainWindow),
991 // but continue the drag on another (QDockWidget). This is what happens if
992 // we try to make this widget floating during a drag. So as a fall back
993 // solution, we simply make this widget floating instead, when we would
994 // otherwise start a drag.
995 q->setFloating(true);
996 } else
997#endif
998 {
1000 startDrag(scope);
1001 q->grabMouse();
1002 ret = true;
1003 }
1004 }
1005 }
1006
1007 if (state && state->dragging && !state->nca) {
1008 QMargins windowMargins = q->window()->windowHandle()->frameMargins();
1009 QPoint windowMarginOffset = QPoint(windowMargins.left(), windowMargins.top());
1010
1011 // TODO maybe use QScreen API (if/when available) to simplify the below code.
1012 const QScreen *orgWdgScreen = QGuiApplication::screenAt(state->widgetInitialPos);
1013 const QScreen *screenFrom = QGuiApplication::screenAt(state->globalPressPos);
1014 const QScreen *screenTo = QGuiApplication::screenAt(event->globalPosition().toPoint());
1015 const QScreen *wdgScreen = q->screen();
1016
1017 QPoint pos;
1018 if (Q_LIKELY(screenFrom && screenTo && wdgScreen && orgWdgScreen)) {
1019 const QPoint nativeWdgOrgPos = QHighDpiScaling::mapPositionToNative(
1020 state->widgetInitialPos, orgWdgScreen->handle());
1022 event->globalPosition().toPoint(), screenTo->handle());
1023 const QPoint nativeFrom = QHighDpiScaling::mapPositionToNative(state->globalPressPos,
1024 screenFrom->handle());
1025
1026 // Calculate new nativePos based on startPos + mouse delta move.
1027 const QPoint nativeNewPos = nativeWdgOrgPos + (nativeTo - nativeFrom);
1028 pos = QHighDpiScaling::mapPositionFromNative(nativeNewPos, wdgScreen->handle())
1029 - windowMarginOffset;
1030 } else {
1031 // Fallback in the unlikely case that source and target screens could not be established
1032 qCDebug(lcQpaDockWidgets)
1033 << "QDockWidget failed to find relevant screen info. screenFrom:" << screenFrom
1034 << "screenTo:" << screenTo << " wdgScreen:" << wdgScreen << "orgWdgScreen"
1035 << orgWdgScreen;
1036 pos = event->globalPosition().toPoint() - state->pressPos - windowMarginOffset;
1037 }
1038
1039 // If the newly floating dock widget has got a native title bar,
1040 // offset the position by the native title bar's height or width
1041 const int dx = q->geometry().x() - q->x();
1042 const int dy = q->geometry().y() - q->y();
1043 pos.rx() += dx;
1044 pos.ry() += dy;
1045
1046 QDockWidgetGroupWindow *floatingTab = qobject_cast<QDockWidgetGroupWindow*>(parent);
1047 if (floatingTab && !q->isFloating())
1048 floatingTab->move(pos);
1049 else
1050 q->move(pos);
1051 if (state && !state->ctrlDrag)
1052 mwlayout->hover(state->widgetItem, event->globalPosition().toPoint());
1053
1054 ret = true;
1055 }
1056
1057#endif // QT_CONFIG(mainwindow)
1058 return ret;
1059}
1060
1062{
1063#if QT_CONFIG(mainwindow)
1064#if QT_CONFIG(draganddrop)
1065 // if we are peforming a platform drag ignore the release here and end the drag when the actual
1066 // drag ends.
1067 if (QMainWindowLayout::needsPlatformDrag())
1068 return false;
1069#endif
1070
1071 if (event->button() == Qt::LeftButton && state && !state->nca) {
1073 return true; //filter out the event
1074 }
1075
1076#endif // QT_CONFIG(mainwindow)
1077 return false;
1078}
1079
1081{
1082 Q_Q(QDockWidget);
1083
1084 int fw = q->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, nullptr, q);
1085
1086 QWidget *tl = q->topLevelWidget();
1087 QRect geo = tl->geometry();
1088 QRect titleRect = tl->frameGeometry();
1089 {
1090 titleRect.setLeft(geo.left());
1091 titleRect.setRight(geo.right());
1092 titleRect.setBottom(geo.top() - 1);
1093 titleRect.adjust(0, fw, 0, 0);
1094 }
1095
1096 switch (event->type()) {
1098 if (!titleRect.contains(event->globalPosition().toPoint()))
1099 break;
1100 if (state != nullptr)
1101 break;
1102 if (qobject_cast<QMainWindow*>(parent) == nullptr && qobject_cast<QDockWidgetGroupWindow*>(parent) == nullptr)
1103 break;
1104 if (isAnimating())
1105 break;
1106 initDrag(event->position().toPoint(), true);
1107 if (state == nullptr)
1108 break;
1109 state->ctrlDrag = (event->modifiers() & Qt::ControlModifier) ||
1110 (!hasFeature(this, QDockWidget::DockWidgetMovable) && q->isFloating());
1112 break;
1114 if (state == nullptr || !state->dragging)
1115 break;
1116
1117#if !defined(Q_OS_MAC) && !defined(Q_OS_WASM)
1118 if (state->nca)
1120#endif
1121 break;
1123#if defined(Q_OS_MAC) || defined(Q_OS_WASM)
1124 if (state)
1126#endif
1127 break;
1130 break;
1131 default:
1132 break;
1133 }
1134}
1135
1137{
1138 qreal ratio = event->oldSize().width() / (1.0 * event->size().width());
1139 state->pressPos.setX(state->pressPos.x() / ratio);
1140}
1141
1146{
1147 Q_Q(QDockWidget);
1148
1149 if (state == nullptr || !state->dragging || !state->nca)
1150 return;
1151
1152 if (!q->isWindow() && qobject_cast<QDockWidgetGroupWindow*>(parent) == nullptr)
1153 return;
1154
1155 // When the native window frame is being dragged, all we get is these mouse
1156 // move events.
1157
1158 if (state->ctrlDrag)
1159 return;
1160
1162 Q_ASSERT(layout != nullptr);
1163
1164 QPoint globalMousePos = event->pos() + state->pressPos;
1165 layout->hover(state->widgetItem, globalMousePos);
1166}
1167
1169{
1170 Q_Q(QDockWidget);
1171 QRect r = rect;
1172 r.moveTopLeft(q->mapToGlobal(QPoint(0, 0)));
1173 QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);
1174 if (dwLayout->nativeWindowDeco(true))
1175 r.adjust(0, dwLayout->titleHeight(), 0, 0);
1176 setWindowState(true, true, r);
1177}
1178
1180{
1181 setWindowState(false, false, rect);
1182}
1183
1184void QDockWidgetPrivate::setWindowState(bool floating, bool unplug, const QRect &rect)
1185{
1186 Q_Q(QDockWidget);
1187
1188 if (!floating && parent) {
1190 if (mwlayout && mwlayout->dockWidgetArea(q) == Qt::NoDockWidgetArea
1191 && !qobject_cast<QDockWidgetGroupWindow *>(parent))
1192 return; // this dockwidget can't be redocked
1193 }
1194
1195 const bool wasFloating = q->isFloating();
1196 if (wasFloating) // Prevent repetitive unplugging from nested invocations (QTBUG-42818)
1197 unplug = false;
1198 const bool hidden = q->isHidden();
1199
1200 if (q->isVisible())
1201 q->hide();
1202
1203 Qt::WindowFlags flags = floating ? Qt::Tool : Qt::Widget;
1204
1205 QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);
1206 const bool nativeDeco = dwLayout->nativeWindowDeco(floating);
1207
1208 if (nativeDeco) {
1212 } else {
1214 }
1215
1216#if QT_CONFIG(draganddrop)
1217 // If we are performing a platform drag the flag is not needed and we want to avoid recreating
1218 // the platform window when it would be removed later
1219 if (unplug && !QMainWindowLayout::needsPlatformDrag())
1221#endif
1222
1223 q->setWindowFlags(flags);
1224
1225
1226 if (!rect.isNull())
1227 q->setGeometry(rect);
1228
1229 updateButtons();
1230
1231 if (!hidden)
1232 q->show();
1233
1234 if (floating != wasFloating) {
1235 emit q->topLevelChanged(floating);
1236 if (!floating && parent) {
1238 if (mwlayout)
1239 emit q->dockLocationChanged(mwlayout->dockWidgetArea(q));
1240 } else {
1241 emit q->dockLocationChanged(Qt::NoDockWidgetArea);
1242 }
1243 }
1244
1245 setResizerActive(!unplug && floating && !nativeDeco);
1246}
1247
1332QDockWidget::QDockWidget(QWidget *parent, Qt::WindowFlags flags)
1333 : QWidget(*new QDockWidgetPrivate, parent, flags)
1334{
1335 Q_D(QDockWidget);
1336 d->init();
1337}
1338
1350QDockWidget::QDockWidget(const QString &title, QWidget *parent, Qt::WindowFlags flags)
1351 : QDockWidget(parent, flags)
1352{
1354}
1355
1361
1369{
1370 QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(this->layout());
1372}
1373
1386{
1387 QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(this->layout());
1389}
1390
1401void QDockWidget::setFeatures(QDockWidget::DockWidgetFeatures features)
1402{
1403 Q_D(QDockWidget);
1405 if (d->features == features)
1406 return;
1407 const bool closableChanged = (d->features ^ features) & DockWidgetClosable;
1408 d->features = features;
1410 = qobject_cast<QDockWidgetLayout*>(this->layout());
1412 d->updateButtons();
1413 d->toggleViewAction->setEnabled((d->features & DockWidgetClosable) == DockWidgetClosable);
1414 emit featuresChanged(d->features);
1415 update();
1416 if (closableChanged && layout->nativeWindowDeco()) {
1417 QDockWidgetGroupWindow *floatingTab = qobject_cast<QDockWidgetGroupWindow *>(parent());
1418 if (floatingTab && !isFloating())
1419 floatingTab->adjustFlags();
1420 else
1421 d->setWindowState(true /*floating*/, true /*unplug*/); //this ensures the native decoration is drawn
1422 }
1423}
1424
1425QDockWidget::DockWidgetFeatures QDockWidget::features() const
1426{
1427 Q_D(const QDockWidget);
1428 return d->features;
1429}
1430
1448void QDockWidget::setFloating(bool floating)
1449{
1450 Q_D(QDockWidget);
1451
1452 // the initial click of a double-click may have started a drag...
1453 if (d->state != nullptr)
1455
1456 QRect r = d->undockedGeometry;
1457 // Keep position when undocking for the first time.
1458 if (floating && isVisible() && !r.isValid())
1459 r = QRect(mapToGlobal(QPoint(0, 0)), size());
1460
1461 d->setWindowState(floating, false, floating ? r : QRect());
1462
1463 if (floating && r.isNull()) {
1464 if (x() < 0 || y() < 0) //may happen if we have been hidden
1465 move(QPoint());
1466 setAttribute(Qt::WA_Moved, false); //we want it at the default position
1467 }
1468}
1469
1479void QDockWidget::setAllowedAreas(Qt::DockWidgetAreas areas)
1480{
1481 Q_D(QDockWidget);
1482 areas &= Qt::DockWidgetArea_Mask;
1483 if (areas == d->allowedAreas)
1484 return;
1485 d->allowedAreas = areas;
1486 emit allowedAreasChanged(d->allowedAreas);
1487}
1488
1489Qt::DockWidgetAreas QDockWidget::allowedAreas() const
1490{
1491 Q_D(const QDockWidget);
1492 return d->allowedAreas;
1493}
1494
1504{
1505 Q_D(QDockWidget);
1506 QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(this->layout());
1507
1508 switch (event->type()) {
1510 if (isFloating() && windowHandle() && d->topData() && windowHandle()->isVisible()) {
1511 // From QWidget::setWindowTitle(): Propagate window title without signal emission
1512 d->topData()->caption = windowHandle()->title();
1513 d->setWindowTitle_helper(windowHandle()->title());
1514 }
1515 Q_FALLTHROUGH();
1517 update(layout->titleArea());
1518#ifndef QT_NO_ACTION
1519 d->fixedWindowTitle = qt_setWindowTitle_helperHelper(windowTitle(), this);
1520 d->toggleViewAction->setText(d->fixedWindowTitle);
1521#endif
1522#if QT_CONFIG(tabbar)
1523 {
1524 if (QMainWindowLayout *winLayout = qt_mainwindow_layout_from_dock(this)) {
1525 if (QDockAreaLayoutInfo *info = winLayout->layoutState.dockAreaLayout.info(this))
1526 info->updateTabBar();
1527 }
1528 }
1529#endif // QT_CONFIG(tabbar)
1530 break;
1531 default:
1532 break;
1533 }
1535}
1536
1539{
1540 Q_D(QDockWidget);
1541 if (d->state)
1543
1544 // For non-closable widgets, don't allow closing, except when the mainwindow
1545 // is hidden, as otherwise an application wouldn't be able to be shut down.
1546 const QMainWindow *win = qobject_cast<QMainWindow*>(parentWidget());
1547 const bool canClose = (d->features & DockWidgetClosable)
1548 || (!win || !win->isVisible());
1549 event->setAccepted(canClose);
1550}
1551
1554{
1555 Q_UNUSED(event);
1556 Q_D(QDockWidget);
1557
1559 = qobject_cast<QDockWidgetLayout*>(this->layout());
1560 bool customTitleBar = layout->widgetForRole(QDockWidgetLayout::TitleBar) != nullptr;
1561 bool nativeDeco = layout->nativeWindowDeco();
1562
1563 if (!nativeDeco && !customTitleBar) {
1564 QStylePainter p(this);
1565 // ### Add PixelMetric to change spacers, so style may show border
1566 // when not floating.
1567 if (isFloating()) {
1568 QStyleOptionFrame framOpt;
1569 framOpt.initFrom(this);
1570 p.drawPrimitive(QStyle::PE_FrameDockWidget, framOpt);
1571 }
1572
1573 // Title must be painted after the frame, since the areas overlap, and
1574 // the title may wish to extend out to all sides (eg. Vista style)
1575 QStyleOptionDockWidget titleOpt;
1576 initStyleOption(&titleOpt);
1577 if (font() == QApplication::font("QDockWidget")) {
1578 titleOpt.fontMetrics = QFontMetrics(d->font);
1579 p.setFont(d->font);
1580 }
1581
1582 p.drawControl(QStyle::CE_DockWidgetTitle, titleOpt);
1583 }
1584}
1585
1588{
1589 Q_D(QDockWidget);
1590
1591 QMainWindow *win = qobject_cast<QMainWindow*>(parentWidget());
1593
1594 switch (event->type()) {
1595#ifndef QT_NO_ACTION
1596 case QEvent::Hide:
1597 if (layout != nullptr)
1598 layout->keepSize(this);
1599 d->toggleViewAction->setChecked(false);
1600 emit visibilityChanged(false);
1601 break;
1602 case QEvent::Show: {
1603 d->toggleViewAction->setChecked(true);
1604 QPoint parentTopLeft(0, 0);
1605 if (isWindow()) {
1606 const QScreen *screen = d->associatedScreen();
1607 parentTopLeft = screen
1610 }
1611 emit visibilityChanged(geometry().right() >= parentTopLeft.x() && geometry().bottom() >= parentTopLeft.y());
1612}
1613 break;
1614#endif
1619 d->updateButtons();
1620 break;
1621 case QEvent::ZOrderChange: {
1622 bool onTop = false;
1623 if (win != nullptr) {
1624 const QObjectList &siblings = win->children();
1625 onTop = siblings.size() > 0 && siblings.last() == (QObject*)this;
1626 }
1627#if QT_CONFIG(tabbar)
1628 if (!isFloating() && layout != nullptr && onTop)
1629 layout->raise(this);
1630#endif
1631 break;
1632 }
1635 update(qobject_cast<QDockWidgetLayout *>(this->layout())->titleArea());
1636 break;
1638 if (d->state) {
1639 event->accept();
1640 return true;
1641 }
1642 break;
1643 // return true after calling the handler since we don't want
1644 // them to be passed onto the default handlers
1646 if (d->mousePressEvent(static_cast<QMouseEvent *>(event)))
1647 return true;
1648 break;
1650 if (d->mouseDoubleClickEvent(static_cast<QMouseEvent *>(event)))
1651 return true;
1652 break;
1653 case QEvent::MouseMove:
1654 if (d->mouseMoveEvent(static_cast<QMouseEvent *>(event)))
1655 return true;
1656 break;
1658 if (d->mouseReleaseEvent(static_cast<QMouseEvent *>(event)))
1659 return true;
1660 break;
1665 d->nonClientAreaMouseEvent(static_cast<QMouseEvent*>(event));
1666 return true;
1667 case QEvent::Move:
1668 d->moveEvent(static_cast<QMoveEvent*>(event));
1669 break;
1670 case QEvent::Resize:
1671 // if the mainwindow is plugging us, we don't want to update undocked geometry
1672 if (isFloating() && layout != nullptr && layout->pluggingWidget != this)
1673 d->undockedGeometry = geometry();
1674
1675 // Usually the window won't get resized while it's being moved, but it can happen,
1676 // for example on Windows when moving to a screen with bigger scale factor
1677 // If that happens we should update state->pressPos, otherwise it will be outside
1678 // the window when the window shrinks.
1679 if (d->state && d->state->dragging)
1680 d->recalculatePressPos(static_cast<QResizeEvent*>(event));
1681 break;
1682 default:
1683 break;
1684 }
1685 return QWidget::event(event);
1686}
1687
1688#ifndef QT_NO_ACTION
1701{
1702 Q_D(const QDockWidget);
1703 return d->toggleViewAction;
1704}
1705#endif // QT_NO_ACTION
1706
1797{
1798 Q_D(QDockWidget);
1800 = qobject_cast<QDockWidgetLayout*>(this->layout());
1802 d->updateButtons();
1803 if (isWindow()) {
1804 //this ensures the native decoration is drawn
1805 d->setWindowState(true /*floating*/, true /*unplug*/);
1806 }
1807}
1808
1818{
1820 = qobject_cast<QDockWidgetLayout*>(this->layout());
1822}
1823
1824#ifndef QT_NO_DEBUG_STREAM
1826{
1827 QDebugStateSaver saver(dbg);
1828 dbg.nospace();
1829
1830 if (!dockWidget) {
1831 dbg << "QDockWidget(0x0)";
1832 return dbg;
1833 }
1834
1835 dbg << "QDockWidget(" << static_cast<const void *>(dockWidget);
1836 dbg << "->(ObjectName=" << dockWidget->objectName();
1837 dbg << "; floating=" << dockWidget->isFloating();
1838 dbg << "; features=" << dockWidget->features();
1839 dbg << ";))";
1840 return dbg;
1841}
1842#endif // QT_NO_DEBUG_STREAM
1843
1845
1846#include "qdockwidget.moc"
1847#include "moc_qdockwidget.cpp"
1848#include "moc_qdockwidget_p.cpp"
The QAbstractButton class is the abstract base class of button widgets, providing functionality commo...
QIcon icon
the icon shown on the button
void setIcon(const QIcon &icon)
bool event(QEvent *e) override
\reimp
void clicked(bool checked=false)
This signal is emitted when the button is activated (i.e., pressed down then released while the mouse...
bool isChecked() const
The QAction class provides an abstraction for user commands that can be added to different user inter...
Definition qaction.h:30
void setMenuRole(MenuRole menuRole)
Definition qaction.cpp:1180
@ NoRole
Definition qaction.h:61
void triggered(bool checked=false)
This signal is emitted when an action is activated by the user; for example, when the user clicks a m...
void setText(const QString &text)
Definition qaction.cpp:611
void setCheckable(bool)
Definition qaction.cpp:832
static QFont font()
Returns the default application font.
int startDragDistance
the minimum distance required for a drag and drop operation to start.
The QCloseEvent class contains parameters that describe a close event.
Definition qevent.h:562
\inmodule QtCore
\inmodule QtCore
QDockWidgetItem(QDockWidget *dockWidget)
QSize minimumSize() const override
Implemented in subclasses to return the minimum size of this item.
QSize maximumSize() const override
Implemented in subclasses to return the maximum size of this item.
QSize sizeHint() const override
Implemented in subclasses to return the preferred size of this item.
void setGeometry(const QRect &r) override
\reimp
QSize sizeHint() const override
Implemented in subclasses to return the preferred size of this item.
int count() const override
Must be implemented in subclasses to return the number of items in the layout.
QSize minimumSize() const override
Implemented in subclasses to return the minimum size of this item.
QSize maximumSize() const override
Implemented in subclasses to return the maximum size of this item.
bool nativeWindowDeco() const
QLayoutItem * takeAt(int index) override
Must be implemented in subclasses to remove the layout item at index from the layout,...
QLayoutItem * itemForRole(Role r) const
void setWidgetForRole(Role r, QWidget *w)
QSize sizeFromContent(const QSize &content, bool floating) const
int minimumTitleWidth() const
void addItem(QLayoutItem *item) override
Implemented in subclasses to add an item.
QWidget * widgetForRole(Role r) const
QDockWidgetLayout(QWidget *parent=nullptr)
static bool wmSupportsNativeWindowDeco()
int titleHeight() const
QLayoutItem * itemAt(int index) const override
Must be implemented in subclasses to return the layout item at index.
void setVerticalTitleBar(bool b)
static Qt::DockWidgetArea toDockWidgetArea(QInternal::DockPosition pos)
void plug(const QRect &rect)
bool isAnimating() const
void setResizerActive(bool active)
QAction * toggleViewAction
void setWindowState(bool floating, bool unplug=false, const QRect &rect=QRect())
void startDrag(DragScope scope)
void moveEvent(QMoveEvent *event)
void initDrag(const QPoint &pos, bool nca)
void endDrag(EndDragMode mode)
void nonClientAreaMouseEvent(QMouseEvent *event)
bool mouseDoubleClickEvent(QMouseEvent *event)
bool mousePressEvent(QMouseEvent *event)
void recalculatePressPos(QResizeEvent *event)
bool mouseReleaseEvent(QMouseEvent *event)
bool mouseMoveEvent(QMouseEvent *event)
void unplug(const QRect &rect)
bool isTabbed() const
QSize minimumSizeHint() const override
QSize sizeHint() const override
bool event(QEvent *event) override
\reimp
void leaveEvent(QEvent *event) override
This event handler can be reimplemented in a subclass to receive widget leave events which are passed...
QDockWidgetTitleButton(QDockWidget *dockWidget)
void enterEvent(QEnterEvent *event) override
This event handler can be reimplemented in a subclass to receive widget enter events which are passed...
void paintEvent(QPaintEvent *event) override
\reimp
The QDockWidget class provides a widget that can be docked inside a QMainWindow or floated as a top-l...
Definition qdockwidget.h:20
bool floating
whether the dock widget is floating
Definition qdockwidget.h:23
void paintEvent(QPaintEvent *event) override
\reimp
void setFeatures(DockWidgetFeatures features)
QAction * toggleViewAction() const
Returns a checkable action that can be added to menus and toolbars so that the user can show or close...
Qt::DockWidgetAreas allowedAreas
areas where the dock widget may be placed
Definition qdockwidget.h:26
~QDockWidget()
Destroys the dock widget.
QDockWidget(const QString &title, QWidget *parent=nullptr, Qt::WindowFlags flags=Qt::WindowFlags())
Constructs a QDockWidget with parent parent and window flags flags.
virtual void initStyleOption(QStyleOptionDockWidget *option) const
Initialize option with the values from this QDockWidget.
bool event(QEvent *event) override
\reimp
void featuresChanged(QDockWidget::DockWidgetFeatures features)
This signal is emitted when the \l features property changes.
QWidget * titleBarWidget() const
void setTitleBarWidget(QWidget *widget)
void setAllowedAreas(Qt::DockWidgetAreas areas)
DockWidgetFeature
\value DockWidgetClosable The dock widget can be closed.
Definition qdockwidget.h:38
@ DockWidgetFloatable
Definition qdockwidget.h:41
@ DockWidgetFeatureMask
Definition qdockwidget.h:44
@ DockWidgetVerticalTitleBar
Definition qdockwidget.h:42
void changeEvent(QEvent *event) override
\reimp
void closeEvent(QCloseEvent *event) override
\reimp
void visibilityChanged(bool visible)
bool isFloating() const
Definition qdockwidget.h:56
void setWidget(QWidget *widget)
Sets the widget for the dock widget to widget.
void setFloating(bool floating)
QString windowTitle
the dock widget title (caption)
Definition qdockwidget.h:27
void allowedAreasChanged(Qt::DockWidgetAreas allowedAreas)
This signal is emitted when the \l allowedAreas property changes.
QWidget * widget() const
Returns the widget for the dock widget.
DockWidgetFeatures features
whether the dock widget is movable, closable, and floatable
Definition qdockwidget.h:24
\inmodule QtGui
Definition qevent.h:165
\inmodule QtCore
Definition qcoreevent.h:45
@ NonClientAreaMouseButtonDblClick
Definition qcoreevent.h:215
@ DevicePixelRatioChange
Definition qcoreevent.h:287
@ ParentChange
Definition qcoreevent.h:80
@ ModifiedChange
Definition qcoreevent.h:138
@ LayoutDirectionChange
Definition qcoreevent.h:124
@ ApplicationLayoutDirectionChange
Definition qcoreevent.h:92
@ StyleChange
Definition qcoreevent.h:136
@ MouseMove
Definition qcoreevent.h:63
@ ZOrderChange
Definition qcoreevent.h:173
@ MouseButtonPress
Definition qcoreevent.h:60
@ NonClientAreaMouseMove
Definition qcoreevent.h:212
@ NonClientAreaMouseButtonRelease
Definition qcoreevent.h:214
@ WindowActivate
Definition qcoreevent.h:83
@ MouseButtonDblClick
Definition qcoreevent.h:62
@ WindowTitleChange
Definition qcoreevent.h:88
@ WindowDeactivate
Definition qcoreevent.h:84
@ NonClientAreaMouseButtonPress
Definition qcoreevent.h:213
@ ContextMenu
Definition qcoreevent.h:119
@ MouseButtonRelease
Definition qcoreevent.h:61
Type type() const
Returns the event type.
Definition qcoreevent.h:304
\reentrant \inmodule QtGui
QScreen * primaryScreen
the primary (or default) screen of the application.
QString platformName
The name of the underlying platform plugin.
static QScreen * screenAt(const QPoint &point)
Returns the screen at point, or \nullptr if outside of any screen.
static QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen)
static QPoint mapPositionFromNative(const QPoint &pos, const QPlatformScreen *platformScreen)
QSize actualSize(const QSize &size, Mode mode=Normal, State state=Off) const
Returns the actual size of the icon for the requested size, mode, and state.
Definition qicon.cpp:926
The QLayoutItem class provides an abstract item that a QLayout manipulates.
Definition qlayoutitem.h:25
The QLayout class is the base class of geometry managers.
Definition qlayout.h:26
QRect geometry() const override
\reimp
Definition qlayout.cpp:460
void removeWidget(QWidget *w)
Removes the widget widget from the layout.
Definition qlayout.cpp:1323
void addChildWidget(QWidget *w)
This function is called from addWidget() functions in subclasses to add w as a managed widget of a la...
Definition qlayout.cpp:837
void setSizeConstraint(SizeConstraint)
Definition qlayout.cpp:1241
@ SetMinAndMaxSize
Definition qlayout.h:41
void invalidate() override
\reimp
Definition qlayout.cpp:469
QWidget * parentWidget() const
Returns the parent widget of this layout, or \nullptr if this layout is not installed on any widget.
Definition qlayout.cpp:399
qsizetype size() const noexcept
Definition qlist.h:397
const_reference at(qsizetype i) const noexcept
Definition qlist.h:446
The QMainWindow class provides a main application window.
Definition qmainwindow.h:25
\inmodule QtCore
Definition qmargins.h:24
\inmodule QtGui
Definition qevent.h:196
The QMoveEvent class contains event parameters for move events.
Definition qevent.h:502
QObject * parent
Definition qobject.h:73
static QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer< Func1 >::Object *sender, Func1 signal, const typename QtPrivate::FunctionPointer< Func2 >::Object *receiverPrivate, Func2 slot, Qt::ConnectionType type=Qt::AutoConnection)
Definition qobject_p.h:299
\inmodule QtCore
Definition qobject.h:103
const QObjectList & children() const
Returns a list of child objects.
Definition qobject.h:201
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:346
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
QString objectName
the name of this object
Definition qobject.h:107
Q_WEAK_OVERLOAD void setObjectName(const QString &name)
Sets the object's name to name.
Definition qobject.h:127
The QPaintEvent class contains event parameters for paint events.
Definition qevent.h:486
\inmodule QtCore\reentrant
Definition qpoint.h:25
constexpr int x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:130
constexpr void setX(int x) noexcept
Sets the x coordinate of this point to the given x coordinate.
Definition qpoint.h:140
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr void moveTopLeft(const QPoint &p) noexcept
Moves the rectangle, leaving the top-left corner at the given position.
Definition qrect.h:304
constexpr void adjust(int x1, int y1, int x2, int y2) noexcept
Adds dx1, dy1, dx2 and dy2 respectively to the existing coordinates of the rectangle.
Definition qrect.h:373
constexpr int height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:239
constexpr int bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
Definition qrect.h:182
constexpr void setRight(int pos) noexcept
Sets the right edge of the rectangle to the given x coordinate.
Definition qrect.h:197
constexpr QPoint topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
Definition qrect.h:221
constexpr void setBottom(int pos) noexcept
Sets the bottom edge of the rectangle to the given y coordinate.
Definition qrect.h:200
bool contains(const QRect &r, bool proper=false) const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qrect.cpp:855
constexpr void setLeft(int pos) noexcept
Sets the left edge of the rectangle to the given x coordinate.
Definition qrect.h:191
constexpr int x() const noexcept
Returns the x-coordinate of the rectangle's left edge.
Definition qrect.h:185
constexpr int width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:236
constexpr int y() const noexcept
Returns the y-coordinate of the rectangle's top edge.
Definition qrect.h:188
constexpr int right() const noexcept
Returns the x-coordinate of the rectangle's right edge.
Definition qrect.h:179
The QResizeEvent class contains event parameters for resize events.
Definition qevent.h:548
The QScreen class is used to query screen properties. \inmodule QtGui.
Definition qscreen.h:32
QRect availableVirtualGeometry
the available geometry of the virtual desktop to which this screen belongs
Definition qscreen.h:49
\inmodule QtCore
Definition qsize.h:25
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:133
constexpr QSize shrunkBy(QMargins m) const noexcept
Definition qsize.h:51
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:130
constexpr void setWidth(int w) noexcept
Sets the width to the given width.
Definition qsize.h:136
constexpr void setHeight(int h) noexcept
Sets the height to the given height.
Definition qsize.h:139
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
Definition qstring.cpp:5455
int compare(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
Definition qstring.cpp:6664
ButtonFeatures features
\variable QStyleOptionComplex::subControls
\variable QStyleOptionFocusRect::backgroundColor
\variable QStyleOptionDockWidget::title
QStyle::State state
void initFrom(const QWidget *w)
The QStylePainter class is a convenience class for drawing QStyle elements inside a widget.
@ State_Sunken
Definition qstyle.h:69
@ State_AutoRaise
Definition qstyle.h:79
@ State_On
Definition qstyle.h:72
@ State_Raised
Definition qstyle.h:68
@ SH_DockWidget_ButtonsHaveFrame
Definition qstyle.h:678
@ SP_TitleBarCloseButton
Definition qstyle.h:720
@ SP_TitleBarNormalButton
Definition qstyle.h:721
@ CE_DockWidgetTitle
Definition qstyle.h:210
@ PM_DockWidgetFrameWidth
Definition qstyle.h:437
@ PM_DockWidgetTitleMargin
Definition qstyle.h:505
@ PM_DockWidgetTitleBarButtonMargin
Definition qstyle.h:509
@ PM_SmallIconSize
Definition qstyle.h:495
@ CC_ToolButton
Definition qstyle.h:336
@ PE_PanelButtonTool
Definition qstyle.h:119
@ PE_FrameDockWidget
Definition qstyle.h:105
virtual int pixelMetric(PixelMetric metric, const QStyleOption *option=nullptr, const QWidget *widget=nullptr) const =0
Returns the value of the given pixel metric.
@ SE_DockWidgetFloatButton
Definition qstyle.h:285
@ SE_DockWidgetCloseButton
Definition qstyle.h:284
The QWidgetItem class is a layout item that represents a widget.
Definition qlayoutitem.h:86
QSize sizeHint() const override
\reimp
QLayout * layout
Definition qwidget_p.h:651
QWindow * windowHandle(WindowHandleMode mode=WindowHandleMode::Direct) const
Definition qwidget.cpp:1055
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
void setAttribute(Qt::WidgetAttribute, bool on=true)
Sets the attribute attribute on this widget if on is true; otherwise clears the attribute.
virtual void leaveEvent(QEvent *event)
This event handler can be reimplemented in a subclass to receive widget leave events which are passed...
Definition qwidget.cpp:9731
QWidget * topLevelWidget() const
Definition qwidget.h:312
QSize size
the size of the widget excluding any window frame
Definition qwidget.h:113
QPointF mapToGlobal(const QPointF &) const
Translates the widget coordinate pos to global screen coordinates.
QRect geometry
the geometry of the widget relative to its parent and excluding the window frame
Definition qwidget.h:106
QLayout * layout() const
Returns the layout manager that is installed on this widget, or \nullptr if no layout manager is inst...
QSize maximumSize
the widget's maximum size in pixels
Definition qwidget.h:121
bool close()
Closes this widget.
Definition qwidget.cpp:8562
void move(int x, int y)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qwidget.h:880
void setFocusPolicy(Qt::FocusPolicy policy)
Definition qwidget.cpp:7822
void hide()
Hides the widget.
Definition qwidget.cpp:8135
int y
the y coordinate of the widget relative to its parent and including any window frame
Definition qwidget.h:110
virtual void setVisible(bool visible)
Definition qwidget.cpp:8255
int x
the x coordinate of the widget relative to its parent including any window frame
Definition qwidget.h:109
void ensurePolished() const
Ensures that the widget and its children have been polished by QStyle (i.e., have a proper font and p...
virtual void enterEvent(QEnterEvent *event)
This event handler can be reimplemented in a subclass to receive widget enter events which are passed...
Definition qwidget.cpp:9715
bool isEnabled() const
Definition qwidget.h:814
void update()
Updates the widget unless updates are disabled or the widget is hidden.
QWindow * windowHandle() const
If this is a native widget, return the associated QWindow.
Definition qwidget.cpp:2483
virtual void changeEvent(QEvent *)
This event handler can be reimplemented to handle state changes.
Definition qwidget.cpp:9382
friend class QFontMetrics
Definition qwidget.h:749
void setWindowTitle(const QString &)
Definition qwidget.cpp:6105
bool event(QEvent *event) override
This is the main event handler; it handles event event.
Definition qwidget.cpp:8866
QStyle * style() const
Definition qwidget.cpp:2600
QFont font
the font currently set for the widget
Definition qwidget.h:133
bool underMouse() const
Returns true if the widget is under the mouse cursor; otherwise returns false.
Definition qwidget.h:859
QWidget * parentWidget() const
Returns the parent of this widget, or \nullptr if it does not have any parent widget.
Definition qwidget.h:904
bool isWindow() const
Returns true if the widget is an independent window, otherwise returns false.
Definition qwidget.h:811
QRect frameGeometry
geometry of the widget relative to its parent including any window frame
Definition qwidget.h:107
QScreen * screen() const
Returns the screen the widget is on.
Definition qwidget.cpp:2496
void activateWindow()
Sets the top-level widget containing this widget to be the active window.
bool isVisible() const
Definition qwidget.h:874
QString title
the window's title in the windowing system
Definition qwindow.h:77
QOpenGLWidget * widget
[1]
QPushButton * button
[2]
qDeleteAll(list.begin(), list.end())
rect
[4]
QStyleOptionButton opt
Combined button and popup list for selecting options.
Definition qcompare.h:63
DockWidgetArea
@ BottomDockWidgetArea
@ DockWidgetArea_Mask
@ NoDockWidgetArea
@ RightDockWidgetArea
@ LeftDockWidgetArea
@ TopDockWidgetArea
@ LeftButton
Definition qnamespace.h:58
@ WA_Moved
Definition qnamespace.h:309
@ NoFocus
Definition qnamespace.h:107
@ Horizontal
Definition qnamespace.h:99
@ Vertical
Definition qnamespace.h:100
@ NoArrow
@ ControlModifier
@ CaseInsensitive
DropAction
@ IgnoreAction
@ CustomizeWindowHint
Definition qnamespace.h:239
@ Widget
Definition qnamespace.h:206
@ FramelessWindowHint
Definition qnamespace.h:225
@ Tool
Definition qnamespace.h:212
@ WindowTitleHint
Definition qnamespace.h:226
@ X11BypassWindowManagerHint
Definition qnamespace.h:224
@ WindowCloseButtonHint
Definition qnamespace.h:241
#define Q_FALLTHROUGH()
#define Q_LIKELY(x)
QMainWindowLayout * qt_mainwindow_layout(const QMainWindow *window)
QDebug operator<<(QDebug dbg, const QDockWidget *dockWidget)
static const QMainWindow * mainwindow_from_dock(const QDockWidget *dock)
static int pick(bool vertical, const QSize &size)
static int perp(bool vertical, const QSize &size)
QMainWindowLayout * qt_mainwindow_layout(const QMainWindow *window)
QString qt_setWindowTitle_helperHelper(const QString &, const QWidget *)
Returns a modified window title with the [*] place holder replaced according to the rules described i...
Definition qwidget.cpp:5992
static QMainWindowLayout * qt_mainwindow_layout_from_dock(const QDockWidget *dock)
static bool hasFeature(const QDockWidgetPrivate *priv, QDockWidget::DockWidgetFeature feature)
static int area(const QSize &s)
Definition qicon.cpp:153
#define qWarning
Definition qlogging.h:166
#define qCDebug(category,...)
return ret
static const QMetaObjectPrivate * priv(const uint *data)
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLboolean GLboolean GLboolean b
GLenum mode
GLfloat GLfloat GLfloat w
[0]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLboolean r
[2]
GLdouble GLdouble right
GLint GLint bottom
GLbitfield flags
struct _cl_event * event
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLuint64EXT * result
[6]
GLfloat GLfloat p
[1]
GLuint GLenum option
static bool isWindow(QObject *object)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define Q_OBJECT
#define emit
#define Q_UNUSED(x)
unsigned int uint
Definition qtypes.h:34
double qreal
Definition qtypes.h:187
static bool onTop(QWaylandQuickShellSurfaceItem *surf)
QString qt_setWindowTitle_helperHelper(const QString &title, const QWidget *widget)
Returns a modified window title with the [*] place holder replaced according to the rules described i...
Definition qwidget.cpp:5992
#define QWIDGETSIZE_MAX
Definition qwidget.h:917
QWidget * win
Definition settings.cpp:6
QObject::connect nullptr
QString title
[35]
QGraphicsItem * item
aWidget window() -> setWindowTitle("New Window Title")
[2]
QDockWidget * dockWidget
[0]
QHostInfo info
[0]