Qt 6.x
The Qt SDK
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
114{
116}
117
119{
120 switch (event->type()) {
123 m_iconSize = -1;
124 break;
125 default:
126 break;
127 }
129}
130
131static inline bool isWindowsStyle(const QStyle *style)
132{
133 // Note: QStyleSheetStyle inherits QWindowsStyle
134 const QStyle *effectiveStyle = style;
135
136#if QT_CONFIG(style_stylesheet)
137 if (style->inherits("QStyleSheetStyle"))
138 effectiveStyle = static_cast<const QStyleSheetStyle *>(style)->baseStyle();
139#endif
140#if !defined(QT_NO_STYLE_PROXY)
141 if (style->inherits("QProxyStyle"))
142 effectiveStyle = static_cast<const QProxyStyle *>(style)->baseStyle();
143#endif
144
145 return effectiveStyle->inherits("QWindowsStyle");
146}
147
148QSize QDockWidgetTitleButton::dockButtonIconSize() const
149{
150 if (m_iconSize < 0) {
151 m_iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize, nullptr, this);
152 // Dock Widget title buttons on Windows where historically limited to size 10
153 // (from small icon size 16) since only a 10x10 XPM was provided.
154 // Adding larger pixmaps to the icons thus caused the icons to grow; limit
155 // this to qpiScaled(10) here.
156 if (isWindowsStyle(style()))
157 m_iconSize = qMin((10 * logicalDpiX()) / 96, m_iconSize);
158 }
159 return QSize(m_iconSize, m_iconSize);
160}
161
163{
165
167 if (!icon().isNull()) {
168 const QSize sz = icon().actualSize(dockButtonIconSize());
169 size += qMax(sz.width(), sz.height());
170 }
171
172 return QSize(size, size);
173}
174
176{
177 if (isEnabled()) update();
179}
180
182{
183 if (isEnabled()) update();
185}
186
188{
189 QStylePainter p(this);
190
192 opt.initFrom(this);
194
195 if (style()->styleHint(QStyle::SH_DockWidget_ButtonsHaveFrame, nullptr, this)) {
196 if (isEnabled() && underMouse() && !isChecked() && !isDown())
198 if (isChecked())
200 if (isDown())
202 p.drawPrimitive(QStyle::PE_PanelButtonTool, opt);
203 } else if (isDown() || isChecked()) {
204 // no frame, but the icon might have explicit pixmaps for QIcon::On
206 }
207
208 opt.icon = icon();
209 opt.subControls = { };
210 opt.activeSubControls = { };
212 opt.arrowType = Qt::NoArrow;
213 opt.iconSize = dockButtonIconSize();
214 p.drawComplexControl(QStyle::CC_ToolButton, opt);
215}
216
217/******************************************************************************
218** QDockWidgetLayout
219*/
220
222 : QLayout(parent), verticalTitleBar(false), item_list(RoleCount, 0)
223{
224}
225
227{
228 qDeleteAll(item_list);
229}
230
236{
237 bool floating = parentWidget()->isWindow();
238#if QT_CONFIG(tabbar)
239 if (auto groupWindow =
240 qobject_cast<const QDockWidgetGroupWindow *>(parentWidget()->parentWidget()))
241 floating = floating || groupWindow->tabLayoutInfo();
242#endif
243 return nativeWindowDeco(floating);
244}
245
251{
252#if defined(Q_OS_ANDROID)
253 return false;
254#else
255 static const bool xcb = !QGuiApplication::platformName().compare("xcb"_L1, Qt::CaseInsensitive);
256 static const bool wayland =
258 return !(xcb || wayland);
259#endif
260}
261
267bool QDockWidgetLayout::nativeWindowDeco(bool floating) const
268{
269 return wmSupportsNativeWindowDeco() && floating && item_list.at(QDockWidgetLayout::TitleBar) == nullptr;
270}
271
272
274{
275 qWarning("QDockWidgetLayout::addItem(): please use QDockWidgetLayout::setWidget()");
276 return;
277}
278
280{
281 int cnt = 0;
282 for (int i = 0; i < item_list.size(); ++i) {
283 QLayoutItem *item = item_list.at(i);
284 if (item == nullptr)
285 continue;
286 if (index == cnt++)
287 return item;
288 }
289 return nullptr;
290}
291
293{
294 int j = 0;
295 for (int i = 0; i < item_list.size(); ++i) {
296 QLayoutItem *item = item_list.at(i);
297 if (item == nullptr)
298 continue;
299 if (index == j) {
300 item_list[i] = 0;
301 invalidate();
302 return item;
303 }
304 ++j;
305 }
306 return nullptr;
307}
308
310{
311 int result = 0;
312 for (int i = 0; i < item_list.size(); ++i) {
313 if (item_list.at(i))
314 ++result;
315 }
316 return result;
317}
318
319QSize QDockWidgetLayout::sizeFromContent(const QSize &content, bool floating) const
320{
321 QSize result = content;
322
323 if (verticalTitleBar) {
325 result.setWidth(qMax(content.width(), 0));
326 } else {
327 result.setHeight(qMax(result.height(), 0));
328 result.setWidth(qMax(content.width(), minimumTitleWidth()));
329 }
330
331 QDockWidget *w = qobject_cast<QDockWidget*>(parentWidget());
332 const bool nativeDeco = nativeWindowDeco(floating);
333
334 int fw = floating && !nativeDeco
335 ? w->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, nullptr, w)
336 : 0;
337
338 const int th = titleHeight();
339 if (!nativeDeco) {
341 result += QSize(th + 2*fw, 2*fw);
342 else
343 result += QSize(2*fw, th + 2*fw);
344 }
345
346 result.setHeight(qMin(result.height(), (int) QWIDGETSIZE_MAX));
347 result.setWidth(qMin(result.width(), (int) QWIDGETSIZE_MAX));
348
349 if (content.width() < 0)
350 result.setWidth(-1);
351 if (content.height() < 0)
352 result.setHeight(-1);
353
354 const QMargins margins = w->contentsMargins();
355 //we need to subtract the contents margin (it will be added by the caller)
356 QSize min = w->minimumSize().shrunkBy(margins);
357 QSize max = w->maximumSize().shrunkBy(margins);
358
359 /* A floating dockwidget will automatically get its minimumSize set to the layout's
360 minimum size + deco. We're *not* interested in this, we only take minimumSize()
361 into account if the user set it herself. Otherwise we end up expanding the result
362 of a calculation for a non-floating dock widget to a floating dock widget's
363 minimum size + window decorations. */
364
365 uint explicitMin = 0;
366 uint explicitMax = 0;
367 if (w->d_func()->extra != nullptr) {
368 explicitMin = w->d_func()->extra->explicitMinSize;
369 explicitMax = w->d_func()->extra->explicitMaxSize;
370 }
371
372 if (!(explicitMin & Qt::Horizontal) || min.width() == 0)
373 min.setWidth(-1);
374 if (!(explicitMin & Qt::Vertical) || min.height() == 0)
375 min.setHeight(-1);
376
377 if (!(explicitMax & Qt::Horizontal))
379 if (!(explicitMax & Qt::Vertical))
381
382 return result.boundedTo(max).expandedTo(min);
383}
384
386{
387 QDockWidget *w = qobject_cast<QDockWidget*>(parentWidget());
388
389 QSize content(-1, -1);
390 if (item_list[Content] != 0)
391 content = item_list[Content]->sizeHint();
392
393 return sizeFromContent(content, w->isFloating());
394}
395
397{
398 if (item_list[Content] != 0) {
399 const QSize content = item_list[Content]->maximumSize();
400 return sizeFromContent(content, parentWidget()->isWindow());
401 } else {
402 return parentWidget()->maximumSize();
403 }
404
405}
406
408{
409 QDockWidget *w = qobject_cast<QDockWidget*>(parentWidget());
410
411 QSize content(0, 0);
412 if (item_list[Content] != 0)
413 content = item_list[Content]->minimumSize();
414
415 return sizeFromContent(content, w->isFloating());
416}
417
419{
420 QLayoutItem *item = item_list.at(r);
421 return item == nullptr ? nullptr : item->widget();
422}
423
425{
426 return item_list.at(r);
427}
428
430{
431 QWidget *old = widgetForRole(r);
432 if (old != nullptr) {
433 old->hide();
434 removeWidget(old);
435 }
436
437 if (w != nullptr) {
439 item_list[r] = new QWidgetItemV2(w);
440 w->show();
441 } else {
442 item_list[r] = 0;
443 }
444
445 invalidate();
446}
447
448static inline int pick(bool vertical, const QSize &size)
449{
450 return vertical ? size.height() : size.width();
451}
452
453static inline int perp(bool vertical, const QSize &size)
454{
455 return vertical ? size.width() : size.height();
456}
457
459{
460 QDockWidget *q = qobject_cast<QDockWidget*>(parentWidget());
461
463 return pick(verticalTitleBar, title->minimumSizeHint());
464
465 QSize closeSize(0, 0);
466 QSize floatSize(0, 0);
468 if (QLayoutItem *item = item_list[CloseButton])
469 closeSize = item->widget()->sizeHint();
470 }
472 if (QLayoutItem *item = item_list[FloatButton])
473 floatSize = item->widget()->sizeHint();
474 }
475
476 int titleHeight = this->titleHeight();
477
478 int mw = q->style()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, nullptr, q);
479 int fw = q->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, nullptr, q);
480
481 return pick(verticalTitleBar, closeSize)
482 + pick(verticalTitleBar, floatSize)
483 + titleHeight + 2*fw + 3*mw;
484}
485
487{
488 QDockWidget *q = qobject_cast<QDockWidget*>(parentWidget());
489
491 return perp(verticalTitleBar, title->sizeHint());
492
493 QSize closeSize(0, 0);
494 QSize floatSize(0, 0);
495 if (QLayoutItem *item = item_list[CloseButton])
496 closeSize = item->widget()->sizeHint();
497 if (QLayoutItem *item = item_list[FloatButton])
498 floatSize = item->widget()->sizeHint();
499
500 int buttonHeight = qMax(perp(verticalTitleBar, closeSize),
501 perp(verticalTitleBar, floatSize));
502
503 QFontMetrics titleFontMetrics = q->fontMetrics();
504 int mw = q->style()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, nullptr, q);
505
506 return qMax(buttonHeight + 2, titleFontMetrics.height() + 2*mw);
507}
508
510{
511 QDockWidget *q = qobject_cast<QDockWidget*>(parentWidget());
512
513 bool nativeDeco = nativeWindowDeco();
514
515 int fw = q->isFloating() && !nativeDeco
516 ? q->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, nullptr, q)
517 : 0;
518
519 if (nativeDeco) {
520 if (QLayoutItem *item = item_list[Content])
521 item->setGeometry(geometry);
522 } else {
523 int titleHeight = this->titleHeight();
524
525 if (verticalTitleBar) {
526 _titleArea = QRect(QPoint(fw, fw),
527 QSize(titleHeight, geometry.height() - (fw * 2)));
528 } else {
529 _titleArea = QRect(QPoint(fw, fw),
530 QSize(geometry.width() - (fw * 2), titleHeight));
531 }
532
533 if (QLayoutItem *item = item_list[TitleBar]) {
534 item->setGeometry(_titleArea);
535 } else {
537 q->initStyleOption(&opt);
538
539 if (QLayoutItem *item = item_list[CloseButton]) {
540 if (!item->isEmpty()) {
541 QRect r = q->style()
542 ->subElementRect(QStyle::SE_DockWidgetCloseButton,
543 &opt, q);
544 if (!r.isNull())
545 item->setGeometry(r);
546 }
547 }
548
549 if (QLayoutItem *item = item_list[FloatButton]) {
550 if (!item->isEmpty()) {
551 QRect r = q->style()
552 ->subElementRect(QStyle::SE_DockWidgetFloatButton,
553 &opt, q);
554 if (!r.isNull())
555 item->setGeometry(r);
556 }
557 }
558 }
559
560 if (QLayoutItem *item = item_list[Content]) {
561 QRect r = geometry;
562 if (verticalTitleBar) {
563 r.setLeft(_titleArea.right() + 1);
564 r.adjust(0, fw, -fw, -fw);
565 } else {
566 r.setTop(_titleArea.bottom() + 1);
567 r.adjust(fw, 0, -fw, -fw);
568 }
569 item->setGeometry(r);
570 }
571 }
572}
573
575{
576 if (b == verticalTitleBar)
577 return;
579 invalidate();
580 parentWidget()->update();
581}
582
583/******************************************************************************
584** QDockWidgetItem
585*/
586
589{
590}
591
593{
594 QSize widgetMin(0, 0);
595 if (QLayoutItem *item = dockWidgetChildItem())
596 widgetMin = item->minimumSize();
597 return dockWidgetLayout()->sizeFromContent(widgetMin, false);
598}
599
601{
602 if (QLayoutItem *item = dockWidgetChildItem()) {
603 return dockWidgetLayout()->sizeFromContent(item->maximumSize(), false);
604 } else {
606 }
607}
608
609
611{
612 if (QLayoutItem *item = dockWidgetChildItem()) {
613 return dockWidgetLayout()->sizeFromContent(item->sizeHint(), false);
614 } else {
615 return QWidgetItem::sizeHint();
616 }
617}
618
619/******************************************************************************
620** QDockWidgetPrivate
621*/
622
624{
625 Q_Q(QDockWidget);
626
629
631 button->setObjectName("qt_dockwidget_floatbutton"_L1);
633 layout->setWidgetForRole(QDockWidgetLayout::FloatButton, button);
634
636 button->setObjectName("qt_dockwidget_closebutton"_L1);
637 QObject::connect(button, SIGNAL(clicked()), q, SLOT(close()));
638 layout->setWidgetForRole(QDockWidgetLayout::CloseButton, button);
639
640 font = QApplication::font("QDockWidgetTitle");
641
642#ifndef QT_NO_ACTION
648 QObject::connect(toggleViewAction, SIGNAL(triggered(bool)),
649 q, SLOT(_q_toggleView(bool)));
650#endif
651
653}
654
663{
664 Q_D(const QDockWidget);
665
666 if (!option)
667 return;
668 QDockWidgetLayout *dwlayout = qobject_cast<QDockWidgetLayout*>(layout());
669
670 QDockWidgetGroupWindow *floatingTab = qobject_cast<QDockWidgetGroupWindow*>(parent());
671 // If we are in a floating tab, init from the parent because the attributes and the geometry
672 // of the title bar should be taken from the floating window.
673 option->initFrom(floatingTab && !isFloating() ? parentWidget() : this);
674 option->rect = dwlayout->titleArea();
675 option->title = d->fixedWindowTitle;
679
680 QDockWidgetLayout *l = qobject_cast<QDockWidgetLayout*>(layout());
681 option->verticalTitleBar = l->verticalTitleBar;
682}
683
685{
686 Q_Q(QDockWidget);
687 if (b == q->isHidden()) {
688 if (b)
689 q->show();
690 else
691 q->close();
692 }
693}
694
696{
697 Q_Q(QDockWidget);
698 QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);
699
701 q->initStyleOption(&opt);
702
703 bool customTitleBar = dwLayout->widgetForRole(QDockWidgetLayout::TitleBar) != nullptr;
704 bool nativeDeco = dwLayout->nativeWindowDeco();
705 bool hideButtons = nativeDeco || customTitleBar;
706
707 bool canClose = hasFeature(this, QDockWidget::DockWidgetClosable);
708 bool canFloat = hasFeature(this, QDockWidget::DockWidgetFloatable);
709
711 = qobject_cast<QAbstractButton*>(dwLayout->widgetForRole(QDockWidgetLayout::FloatButton));
712 button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarNormalButton, &opt, q));
713 button->setVisible(canFloat && !hideButtons);
714#if QT_CONFIG(accessibility)
715 //: Accessible name for button undocking a dock widget (floating state)
716 button->setAccessibleName(QDockWidget::tr("Float"));
717 button->setAccessibleDescription(QDockWidget::tr("Undocks and re-attaches the dock widget"));
718#endif
719 button
720 = qobject_cast <QAbstractButton*>(dwLayout->widgetForRole(QDockWidgetLayout::CloseButton));
721 button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarCloseButton, &opt, q));
722 button->setVisible(canClose && !hideButtons);
723#if QT_CONFIG(accessibility)
724 //: Accessible name for button closing a dock widget
725 button->setAccessibleName(QDockWidget::tr("Close"));
726 button->setAccessibleDescription(QDockWidget::tr("Closes the dock widget"));
727#endif
728
730}
731
733{
734 Q_Q(QDockWidget);
735 q->setFloating(!q->isFloating());
736}
737
745{
746 Q_Q(QDockWidget);
747
748 if (state != nullptr)
749 return;
750
752 Q_ASSERT(layout != nullptr);
753 if (layout->pluggingWidget != nullptr) // the main window is animating a docking operation
754 return;
755
756 state = new QDockWidgetPrivate::DragState;
757 state->pressPos = pos;
758 state->globalPressPos = q->mapToGlobal(pos);
759 state->widgetInitialPos = q->isFloating() ? q->pos() : q->mapToGlobal(QPoint(0, 0));
760 state->dragging = false;
761 state->widgetItem = nullptr;
762 state->ownWidgetItem = false;
763 state->nca = nca;
764 state->ctrlDrag = false;
765}
766
774{
775 Q_Q(QDockWidget);
776
777 if (state == nullptr || state->dragging)
778 return;
779
781 Q_ASSERT(layout != nullptr);
782
783 bool wasFloating = q->isFloating();
784
785 state->widgetItem = layout->unplug(q, group);
786 if (state->widgetItem == nullptr) {
787 /* Dock widget has a QMainWindow parent, but was never inserted with
788 QMainWindow::addDockWidget, so the QMainWindowLayout has no
789 widget item for it. It will be newly created and deleted if it doesn't
790 get dropped into a dock area. */
791 QDockWidgetGroupWindow *floatingTab = qobject_cast<QDockWidgetGroupWindow*>(parent);
792 if (floatingTab && !q->isFloating())
793 state->widgetItem = new QDockWidgetGroupWindowItem(floatingTab);
794 else
795 state->widgetItem = new QDockWidgetItem(q);
796 state->ownWidgetItem = true;
797 }
798
799 if (state->ctrlDrag)
800 layout->restore();
801
802 state->dragging = true;
803
804#if QT_CONFIG(draganddrop)
805 if (QMainWindowLayout::needsPlatformDrag()) {
807 layout->performPlatformWidgetDrag(state->widgetItem, state->pressPos);
808 if (result == Qt::IgnoreAction && !wasFloating) {
809 layout->revert(state->widgetItem);
810 delete state;
811 state = nullptr;
812 } else {
813 endDrag();
814 }
815 }
816#endif
817}
818
825{
826 Q_Q(QDockWidget);
827 Q_ASSERT(state != nullptr);
828
829 q->releaseMouse();
830
831 if (state->dragging) {
832 const QMainWindow *mainWindow = mainwindow_from_dock(q);
833 Q_ASSERT(mainWindow != nullptr);
834 QMainWindowLayout *mwLayout = qt_mainwindow_layout(mainWindow);
835
836 if (abort || !mwLayout->plug(state->widgetItem)) {
838 // This QDockWidget will now stay in the floating state.
839 if (state->ownWidgetItem) {
840 delete state->widgetItem;
841 state->widgetItem = nullptr;
842 }
843 mwLayout->restore();
844 QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);
845 if (!dwLayout->nativeWindowDeco()) {
846 // get rid of the X11BypassWindowManager window flag and activate the resizer
847 Qt::WindowFlags flags = q->windowFlags();
848 flags &= ~Qt::X11BypassWindowManagerHint;
849 q->setWindowFlags(flags);
850 setResizerActive(q->isFloating());
851 q->show();
852 } else {
853 setResizerActive(false);
854 }
855 if (q->isFloating()) { // Might not be floating when dragging a QDockWidgetGroupWindow
856 undockedGeometry = q->geometry();
857#if QT_CONFIG(tabwidget)
858 // is the widget located within the mainwindow?
859 const Qt::DockWidgetArea area = mainWindow->dockWidgetArea(q);
860 if (area != Qt::NoDockWidgetArea) {
861 tabPosition = mwLayout->tabPosition(area);
862 } else if (auto dwgw = qobject_cast<QDockWidgetGroupWindow *>(q->parent())) {
863 // DockWidget wasn't found in one of the docks within mainwindow
864 // => derive tabPosition from parent
865 tabPosition = mwLayout->tabPosition(toDockWidgetArea(dwgw->layoutInfo()->dockPos));
866 }
867#endif
868 }
869 q->activateWindow();
870 } else {
871 // The tab was not plugged back in the QMainWindow but the QDockWidget cannot
872 // stay floating, revert to the previous state.
873 mwLayout->revert(state->widgetItem);
874 }
875 }
876 }
877 delete state;
878 state = nullptr;
879}
880
882{
883 switch (pos) {
888 default: break;
889 }
891}
892
894{
895 Q_Q(QDockWidget);
896 if (active && !resizer)
897 resizer = new QWidgetResizeHandler(q);
898 if (resizer)
899 resizer->setEnabled(active);
900}
901
903{
904 Q_Q(const QDockWidget);
905
907 if (mainWinLayout == nullptr)
908 return false;
909
910 return (const void*)mainWinLayout->pluggingWidget == (const void*)q;
911}
912
914{
915#if QT_CONFIG(mainwindow)
916 Q_Q(QDockWidget);
917
918 QDockWidgetLayout *dwLayout
919 = qobject_cast<QDockWidgetLayout*>(layout);
920
921 if (!dwLayout->nativeWindowDeco()) {
922 QRect titleArea = dwLayout->titleArea();
923
924 QDockWidgetGroupWindow *floatingTab = qobject_cast<QDockWidgetGroupWindow*>(parent);
925
926 if (event->button() != Qt::LeftButton ||
927 !titleArea.contains(event->position().toPoint()) ||
928 // check if the tool window is movable... do nothing if it
929 // is not (but allow moving if the window is floating)
930 (!hasFeature(this, QDockWidget::DockWidgetMovable) && !q->isFloating()) ||
931 (qobject_cast<QMainWindow*>(parent) == nullptr && !floatingTab) ||
932 isAnimating() || state != nullptr) {
933 return false;
934 }
935
936 initDrag(event->position().toPoint(), false);
937
938 if (state)
939 state->ctrlDrag = (hasFeature(this, QDockWidget::DockWidgetFloatable) && event->modifiers() & Qt::ControlModifier) ||
940 (!hasFeature(this, QDockWidget::DockWidgetMovable) && q->isFloating());
941
942 return true;
943 }
944
945#endif // QT_CONFIG(mainwindow)
946 return false;
947}
948
950{
951 QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);
952
953 if (!dwLayout->nativeWindowDeco()) {
954 QRect titleArea = dwLayout->titleArea();
955
956 if (event->button() == Qt::LeftButton && titleArea.contains(event->position().toPoint()) &&
959 return true;
960 }
961 }
962 return false;
963}
964
966{
967 bool ret = false;
968#if QT_CONFIG(mainwindow)
969 Q_Q(QDockWidget);
970
971 if (!state)
972 return ret;
973
974 QDockWidgetLayout *dwlayout
975 = qobject_cast<QDockWidgetLayout *>(layout);
977 if (!dwlayout->nativeWindowDeco()) {
978 if (!state->dragging
979 && mwlayout->pluggingWidget == nullptr
980 && (event->position().toPoint() - state->pressPos).manhattanLength()
982
983#ifdef Q_OS_MACOS
984 if (windowHandle() && !q->isFloating()) {
985 // When using native widgets on mac, we have not yet been successful in
986 // starting a drag on an NSView that belongs to one window (QMainWindow),
987 // but continue the drag on another (QDockWidget). This is what happens if
988 // we try to make this widget floating during a drag. So as a fall back
989 // solution, we simply make this widget floating instead, when we would
990 // otherwise start a drag.
991 q->setFloating(true);
992 } else
993#endif
994 {
995 startDrag();
996 q->grabMouse();
997 ret = true;
998 }
999 }
1000 }
1001
1002 if (state && state->dragging && !state->nca) {
1003 QMargins windowMargins = q->window()->windowHandle()->frameMargins();
1004 QPoint windowMarginOffset = QPoint(windowMargins.left(), windowMargins.top());
1005
1006 // TODO maybe use QScreen API (if/when available) to simplify the below code.
1007 const QScreen *orgWdgScreen = QGuiApplication::screenAt(state->widgetInitialPos);
1008 const QScreen *screenFrom = QGuiApplication::screenAt(state->globalPressPos);
1009 const QScreen *screenTo = QGuiApplication::screenAt(event->globalPosition().toPoint());
1010 const QScreen *wdgScreen = q->screen();
1011
1012 QPoint pos;
1013 if (Q_LIKELY(screenFrom && screenTo && wdgScreen && orgWdgScreen)) {
1014 const QPoint nativeWdgOrgPos = QHighDpiScaling::mapPositionToNative(
1015 state->widgetInitialPos, orgWdgScreen->handle());
1017 event->globalPosition().toPoint(), screenTo->handle());
1018 const QPoint nativeFrom = QHighDpiScaling::mapPositionToNative(state->globalPressPos,
1019 screenFrom->handle());
1020
1021 // Calculate new nativePos based on startPos + mouse delta move.
1022 const QPoint nativeNewPos = nativeWdgOrgPos + (nativeTo - nativeFrom);
1023 pos = QHighDpiScaling::mapPositionFromNative(nativeNewPos, wdgScreen->handle())
1024 - windowMarginOffset;
1025 } else {
1026 // Fallback in the unlikely case that source and target screens could not be established
1027 qCDebug(lcQpaDockWidgets)
1028 << "QDockWidget failed to find relevant screen info. screenFrom:" << screenFrom
1029 << "screenTo:" << screenTo << " wdgScreen:" << wdgScreen << "orgWdgScreen"
1030 << orgWdgScreen;
1031 pos = event->globalPosition().toPoint() - state->pressPos - windowMarginOffset;
1032 }
1033
1034 // If the newly floating dock widget has got a native title bar,
1035 // offset the position by the native title bar's height or width
1036 const int dx = q->geometry().x() - q->x();
1037 const int dy = q->geometry().y() - q->y();
1038 pos.rx() += dx;
1039 pos.ry() += dy;
1040
1041 QDockWidgetGroupWindow *floatingTab = qobject_cast<QDockWidgetGroupWindow*>(parent);
1042 if (floatingTab && !q->isFloating())
1043 floatingTab->move(pos);
1044 else
1045 q->move(pos);
1046 if (state && !state->ctrlDrag)
1047 mwlayout->hover(state->widgetItem, event->globalPosition().toPoint());
1048
1049 ret = true;
1050 }
1051
1052#endif // QT_CONFIG(mainwindow)
1053 return ret;
1054}
1055
1057{
1058#if QT_CONFIG(mainwindow)
1059 // if we are peforming a platform drag ignore the release here and end the drag when the actual
1060 // drag ends.
1061 if (QMainWindowLayout::needsPlatformDrag())
1062 return false;
1063
1064 if (event->button() == Qt::LeftButton && state && !state->nca) {
1065 endDrag();
1066 return true; //filter out the event
1067 }
1068
1069#endif // QT_CONFIG(mainwindow)
1070 return false;
1071}
1072
1074{
1075 Q_Q(QDockWidget);
1076
1077 int fw = q->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, nullptr, q);
1078
1079 QWidget *tl = q->topLevelWidget();
1080 QRect geo = tl->geometry();
1081 QRect titleRect = tl->frameGeometry();
1082 {
1083 titleRect.setLeft(geo.left());
1084 titleRect.setRight(geo.right());
1085 titleRect.setBottom(geo.top() - 1);
1086 titleRect.adjust(0, fw, 0, 0);
1087 }
1088
1089 switch (event->type()) {
1091 if (!titleRect.contains(event->globalPosition().toPoint()))
1092 break;
1093 if (state != nullptr)
1094 break;
1095 if (qobject_cast<QMainWindow*>(parent) == nullptr && qobject_cast<QDockWidgetGroupWindow*>(parent) == nullptr)
1096 break;
1097 if (isAnimating())
1098 break;
1099 initDrag(event->position().toPoint(), true);
1100 if (state == nullptr)
1101 break;
1102 state->ctrlDrag = (event->modifiers() & Qt::ControlModifier) ||
1103 (!hasFeature(this, QDockWidget::DockWidgetMovable) && q->isFloating());
1104 startDrag();
1105 break;
1107 if (state == nullptr || !state->dragging)
1108 break;
1109
1110#if !defined(Q_OS_MAC) && !defined(Q_OS_WASM)
1111 if (state->nca) {
1112 endDrag();
1113 }
1114#endif
1115 break;
1117#if defined(Q_OS_MAC) || defined(Q_OS_WASM)
1118 if (state)
1119 endDrag();
1120#endif
1121 break;
1124 break;
1125 default:
1126 break;
1127 }
1128}
1129
1131{
1132 qreal ratio = event->oldSize().width() / (1.0 * event->size().width());
1133 state->pressPos.setX(state->pressPos.x() / ratio);
1134}
1135
1140{
1141 Q_Q(QDockWidget);
1142
1143 if (state == nullptr || !state->dragging || !state->nca)
1144 return;
1145
1146 if (!q->isWindow() && qobject_cast<QDockWidgetGroupWindow*>(parent) == nullptr)
1147 return;
1148
1149 // When the native window frame is being dragged, all we get is these mouse
1150 // move events.
1151
1152 if (state->ctrlDrag)
1153 return;
1154
1156 Q_ASSERT(layout != nullptr);
1157
1158 QPoint globalMousePos = event->pos() + state->pressPos;
1159 layout->hover(state->widgetItem, globalMousePos);
1160}
1161
1163{
1164 Q_Q(QDockWidget);
1165 QRect r = rect;
1166 r.moveTopLeft(q->mapToGlobal(QPoint(0, 0)));
1167 QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);
1168 if (dwLayout->nativeWindowDeco(true))
1169 r.adjust(0, dwLayout->titleHeight(), 0, 0);
1170 setWindowState(true, true, r);
1171}
1172
1174{
1175 setWindowState(false, false, rect);
1176}
1177
1178void QDockWidgetPrivate::setWindowState(bool floating, bool unplug, const QRect &rect)
1179{
1180 Q_Q(QDockWidget);
1181
1182 if (!floating && parent) {
1184 if (mwlayout && mwlayout->dockWidgetArea(q) == Qt::NoDockWidgetArea
1185 && !qobject_cast<QDockWidgetGroupWindow *>(parent))
1186 return; // this dockwidget can't be redocked
1187 }
1188
1189 const bool wasFloating = q->isFloating();
1190 if (wasFloating) // Prevent repetitive unplugging from nested invocations (QTBUG-42818)
1191 unplug = false;
1192 const bool hidden = q->isHidden();
1193
1194 if (q->isVisible())
1195 q->hide();
1196
1197 Qt::WindowFlags flags = floating ? Qt::Tool : Qt::Widget;
1198
1199 QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);
1200 const bool nativeDeco = dwLayout->nativeWindowDeco(floating);
1201
1202 if (nativeDeco) {
1206 } else {
1208 }
1209
1210 // If we are performing a platform drag the flag is not needed and we want to avoid recreating
1211 // the platform window when it would be removed later
1212 if (unplug && !QMainWindowLayout::needsPlatformDrag())
1214
1215 q->setWindowFlags(flags);
1216
1217
1218 if (!rect.isNull())
1219 q->setGeometry(rect);
1220
1221 updateButtons();
1222
1223 if (!hidden)
1224 q->show();
1225
1226 if (floating != wasFloating) {
1227 emit q->topLevelChanged(floating);
1228 if (!floating && parent) {
1230 if (mwlayout)
1231 emit q->dockLocationChanged(mwlayout->dockWidgetArea(q));
1232 } else {
1233 emit q->dockLocationChanged(Qt::NoDockWidgetArea);
1234 }
1235 }
1236
1237 setResizerActive(!unplug && floating && !nativeDeco);
1238}
1239
1328{
1329 Q_D(QDockWidget);
1330 d->init();
1331}
1332
1346{
1348}
1349
1354{ }
1355
1363{
1364 QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(this->layout());
1366}
1367
1380{
1381 QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(this->layout());
1383}
1384
1395void QDockWidget::setFeatures(QDockWidget::DockWidgetFeatures features)
1396{
1397 Q_D(QDockWidget);
1399 if (d->features == features)
1400 return;
1401 const bool closableChanged = (d->features ^ features) & DockWidgetClosable;
1402 d->features = features;
1404 = qobject_cast<QDockWidgetLayout*>(this->layout());
1406 d->updateButtons();
1407 d->toggleViewAction->setEnabled((d->features & DockWidgetClosable) == DockWidgetClosable);
1408 emit featuresChanged(d->features);
1409 update();
1410 if (closableChanged && layout->nativeWindowDeco()) {
1411 QDockWidgetGroupWindow *floatingTab = qobject_cast<QDockWidgetGroupWindow *>(parent());
1412 if (floatingTab && !isFloating())
1413 floatingTab->adjustFlags();
1414 else
1415 d->setWindowState(true /*floating*/, true /*unplug*/); //this ensures the native decoration is drawn
1416 }
1417}
1418
1419QDockWidget::DockWidgetFeatures QDockWidget::features() const
1420{
1421 Q_D(const QDockWidget);
1422 return d->features;
1423}
1424
1439void QDockWidget::setFloating(bool floating)
1440{
1441 Q_D(QDockWidget);
1442
1443 // the initial click of a double-click may have started a drag...
1444 if (d->state != nullptr)
1445 d->endDrag(true);
1446
1447 QRect r = d->undockedGeometry;
1448 // Keep position when undocking for the first time.
1449 if (floating && isVisible() && !r.isValid())
1450 r = QRect(mapToGlobal(QPoint(0, 0)), size());
1451
1452 d->setWindowState(floating, false, floating ? r : QRect());
1453
1454 if (floating && r.isNull()) {
1455 if (x() < 0 || y() < 0) //may happen if we have been hidden
1456 move(QPoint());
1457 setAttribute(Qt::WA_Moved, false); //we want it at the default position
1458 }
1459}
1460
1470void QDockWidget::setAllowedAreas(Qt::DockWidgetAreas areas)
1471{
1472 Q_D(QDockWidget);
1473 areas &= Qt::DockWidgetArea_Mask;
1474 if (areas == d->allowedAreas)
1475 return;
1476 d->allowedAreas = areas;
1477 emit allowedAreasChanged(d->allowedAreas);
1478}
1479
1480Qt::DockWidgetAreas QDockWidget::allowedAreas() const
1481{
1482 Q_D(const QDockWidget);
1483 return d->allowedAreas;
1484}
1485
1495{
1496 Q_D(QDockWidget);
1497 QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(this->layout());
1498
1499 switch (event->type()) {
1501 if (isFloating() && windowHandle() && d->topData()) {
1502 // From QWidget::setWindowTitle(): Propagate window title without signal emission
1503 d->topData()->caption = windowHandle()->title();
1504 d->setWindowTitle_helper(windowHandle()->title());
1505 }
1506 Q_FALLTHROUGH();
1508 update(layout->titleArea());
1509#ifndef QT_NO_ACTION
1510 d->fixedWindowTitle = qt_setWindowTitle_helperHelper(windowTitle(), this);
1511 d->toggleViewAction->setText(d->fixedWindowTitle);
1512#endif
1513#if QT_CONFIG(tabbar)
1514 {
1515 if (QMainWindowLayout *winLayout = qt_mainwindow_layout_from_dock(this)) {
1516 if (QDockAreaLayoutInfo *info = winLayout->layoutState.dockAreaLayout.info(this))
1517 info->updateTabBar();
1518 }
1519 }
1520#endif // QT_CONFIG(tabbar)
1521 break;
1522 default:
1523 break;
1524 }
1526}
1527
1530{
1531 Q_D(QDockWidget);
1532 if (d->state)
1533 d->endDrag(true);
1535}
1536
1539{
1540 Q_UNUSED(event);
1541 Q_D(QDockWidget);
1542
1544 = qobject_cast<QDockWidgetLayout*>(this->layout());
1545 bool customTitleBar = layout->widgetForRole(QDockWidgetLayout::TitleBar) != nullptr;
1546 bool nativeDeco = layout->nativeWindowDeco();
1547
1548 if (!nativeDeco && !customTitleBar) {
1549 QStylePainter p(this);
1550 // ### Add PixelMetric to change spacers, so style may show border
1551 // when not floating.
1552 if (isFloating()) {
1553 QStyleOptionFrame framOpt;
1554 framOpt.initFrom(this);
1555 p.drawPrimitive(QStyle::PE_FrameDockWidget, framOpt);
1556 }
1557
1558 // Title must be painted after the frame, since the areas overlap, and
1559 // the title may wish to extend out to all sides (eg. Vista style)
1560 QStyleOptionDockWidget titleOpt;
1561 initStyleOption(&titleOpt);
1562 if (font() == QApplication::font("QDockWidget")) {
1563 titleOpt.fontMetrics = QFontMetrics(d->font);
1564 p.setFont(d->font);
1565 }
1566
1567 p.drawControl(QStyle::CE_DockWidgetTitle, titleOpt);
1568 }
1569}
1570
1573{
1574 Q_D(QDockWidget);
1575
1576 QMainWindow *win = qobject_cast<QMainWindow*>(parentWidget());
1578
1579 switch (event->type()) {
1580#ifndef QT_NO_ACTION
1581 case QEvent::Hide:
1582 if (layout != nullptr)
1583 layout->keepSize(this);
1584 d->toggleViewAction->setChecked(false);
1585 emit visibilityChanged(false);
1586 break;
1587 case QEvent::Show: {
1588 d->toggleViewAction->setChecked(true);
1589 QPoint parentTopLeft(0, 0);
1590 if (isWindow()) {
1591 const QScreen *screen = d->associatedScreen();
1592 parentTopLeft = screen
1595 }
1596 emit visibilityChanged(geometry().right() >= parentTopLeft.x() && geometry().bottom() >= parentTopLeft.y());
1597}
1598 break;
1599#endif
1604 d->updateButtons();
1605 break;
1606 case QEvent::ZOrderChange: {
1607 bool onTop = false;
1608 if (win != nullptr) {
1609 const QObjectList &siblings = win->children();
1610 onTop = siblings.size() > 0 && siblings.last() == (QObject*)this;
1611 }
1612#if QT_CONFIG(tabbar)
1613 if (!isFloating() && layout != nullptr && onTop)
1614 layout->raise(this);
1615#endif
1616 break;
1617 }
1620 update(qobject_cast<QDockWidgetLayout *>(this->layout())->titleArea());
1621 break;
1623 if (d->state) {
1624 event->accept();
1625 return true;
1626 }
1627 break;
1628 // return true after calling the handler since we don't want
1629 // them to be passed onto the default handlers
1631 if (d->mousePressEvent(static_cast<QMouseEvent *>(event)))
1632 return true;
1633 break;
1635 if (d->mouseDoubleClickEvent(static_cast<QMouseEvent *>(event)))
1636 return true;
1637 break;
1638 case QEvent::MouseMove:
1639 if (d->mouseMoveEvent(static_cast<QMouseEvent *>(event)))
1640 return true;
1641 break;
1643 if (d->mouseReleaseEvent(static_cast<QMouseEvent *>(event)))
1644 return true;
1645 break;
1650 d->nonClientAreaMouseEvent(static_cast<QMouseEvent*>(event));
1651 return true;
1652 case QEvent::Move:
1653 d->moveEvent(static_cast<QMoveEvent*>(event));
1654 break;
1655 case QEvent::Resize:
1656 // if the mainwindow is plugging us, we don't want to update undocked geometry
1657 if (isFloating() && layout != nullptr && layout->pluggingWidget != this)
1658 d->undockedGeometry = geometry();
1659
1660 // Usually the window won't get resized while it's being moved, but it can happen,
1661 // for example on Windows when moving to a screen with bigger scale factor
1662 // If that happens we should update state->pressPos, otherwise it will be outside
1663 // the window when the window shrinks.
1664 if (d->state && d->state->dragging)
1665 d->recalculatePressPos(static_cast<QResizeEvent*>(event));
1666 break;
1667 default:
1668 break;
1669 }
1670 return QWidget::event(event);
1671}
1672
1673#ifndef QT_NO_ACTION
1686{
1687 Q_D(const QDockWidget);
1688 return d->toggleViewAction;
1689}
1690#endif // QT_NO_ACTION
1691
1782{
1783 Q_D(QDockWidget);
1785 = qobject_cast<QDockWidgetLayout*>(this->layout());
1787 d->updateButtons();
1788 if (isWindow()) {
1789 //this ensures the native decoration is drawn
1790 d->setWindowState(true /*floating*/, true /*unplug*/);
1791 }
1792}
1793
1803{
1805 = qobject_cast<QDockWidgetLayout*>(this->layout());
1807}
1808
1810
1811#include "qdockwidget.moc"
1812#include "moc_qdockwidget.cpp"
1813#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
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 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:561
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()
QRect titleArea() const
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)
void startDrag(bool group=true)
bool isAnimating() const
void setResizerActive(bool active)
QAction * toggleViewAction
void setWindowState(bool floating, bool unplug=false, const QRect &rect=QRect())
void moveEvent(QMoveEvent *event)
void initDrag(const QPoint &pos, bool nca)
void _q_toggleView(bool)
void nonClientAreaMouseEvent(QMouseEvent *event)
bool mouseDoubleClickEvent(QMouseEvent *event)
void endDrag(bool abort=false)
bool mousePressEvent(QMouseEvent *event)
void recalculatePressPos(QResizeEvent *event)
bool mouseReleaseEvent(QMouseEvent *event)
bool mouseMoveEvent(QMouseEvent *event)
void unplug(const QRect &rect)
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:164
\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:299
\reentrant \inmodule QtGui
int height() const
Returns the height of the font.
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:880
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:1322
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:836
void setSizeConstraint(SizeConstraint)
Definition qlayout.cpp:1240
@ 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:386
T & last()
Definition qlist.h:631
const_reference at(qsizetype i) const noexcept
Definition qlist.h:429
void hover(QLayoutItem *hoverTarget, const QPoint &mousePos)
void revert(QLayoutItem *widgetItem)
void restore(bool keepSavedState=false)
bool plug(QLayoutItem *widgetItem)
The QMainWindow class provides a main application window.
Definition qmainwindow.h:25
\inmodule QtCore
Definition qmargins.h:23
constexpr int left() const noexcept
Returns the left margin.
Definition qmargins.h:110
constexpr int top() const noexcept
Returns the top margin.
Definition qmargins.h:113
\inmodule QtGui
Definition qevent.h:195
The QMoveEvent class contains event parameters for move events.
Definition qevent.h:501
QObject * parent
Definition qobject.h:61
\inmodule QtCore
Definition qobject.h:90
const QObjectList & children() const
Returns a list of child objects.
Definition qobject.h:171
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:311
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2823
Q_WEAK_OVERLOAD void setObjectName(const QString &name)
Sets the object's name to name.
Definition qobject.h:114
bool inherits(const char *classname) const
Returns true if this object is an instance of a class that inherits className or a QObject subclass t...
Definition qobject.h:313
int logicalDpiX() const
The QPaintEvent class contains event parameters for paint events.
Definition qevent.h:485
\inmodule QtCore\reentrant
Definition qpoint.h:23
constexpr int x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:127
constexpr int y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:132
The QProxyStyle class is a convenience class that simplifies dynamically overriding QStyle elements.
Definition qproxystyle.h:17
QStyle * baseStyle() const
Returns the proxy base style object.
\inmodule QtCore\reentrant
Definition qrect.h:30
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:372
constexpr int height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:238
constexpr int bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
Definition qrect.h:181
constexpr void setRight(int pos) noexcept
Sets the right edge of the rectangle to the given x coordinate.
Definition qrect.h:196
constexpr QPoint topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
Definition qrect.h:220
constexpr int top() const noexcept
Returns the y-coordinate of the rectangle's top edge.
Definition qrect.h:175
constexpr void setBottom(int pos) noexcept
Sets the bottom edge of the rectangle to the given y coordinate.
Definition qrect.h:199
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:851
constexpr void setLeft(int pos) noexcept
Sets the left edge of the rectangle to the given x coordinate.
Definition qrect.h:190
constexpr int left() const noexcept
Returns the x-coordinate of the rectangle's left edge.
Definition qrect.h:172
constexpr int width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:235
constexpr int right() const noexcept
Returns the x-coordinate of the rectangle's right edge.
Definition qrect.h:178
The QResizeEvent class contains event parameters for resize events.
Definition qevent.h:547
The QScreen class is used to query screen properties. \inmodule QtGui.
Definition qscreen.h:32
QPlatformScreen * handle() const
Get the platform screen handle.
Definition qscreen.cpp:83
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:132
constexpr QSize shrunkBy(QMargins m) const noexcept
Definition qsize.h:51
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:129
constexpr void setWidth(int w) noexcept
Sets the width to the given width.
Definition qsize.h:135
constexpr void setHeight(int h) noexcept
Sets the height to the given height.
Definition qsize.h:138
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
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:5299
int compare(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
Definition qstring.cpp:6498
ButtonFeatures features
\variable QStyleOptionComplex::subControls
\variable QStyleOptionFocusRect::backgroundColor
\variable QStyleOptionDockWidget::title
QFontMetrics fontMetrics
QStyle::State state
void initFrom(const QWidget *w)
The QStylePainter class is a convenience class for drawing QStyle elements inside a widget.
The QStyle class is an abstract base class that encapsulates the look and feel of a GUI.
Definition qstyle.h:29
@ 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:676
@ SP_TitleBarCloseButton
Definition qstyle.h:718
@ SP_TitleBarNormalButton
Definition qstyle.h:719
@ CE_DockWidgetTitle
Definition qstyle.h:210
@ PM_DockWidgetFrameWidth
Definition qstyle.h:437
@ PM_DockWidgetTitleMargin
Definition qstyle.h:503
@ PM_DockWidgetTitleBarButtonMargin
Definition qstyle.h:507
@ PM_SmallIconSize
Definition qstyle.h:493
@ 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:643
QWindow * windowHandle(WindowHandleMode mode=WindowHandleMode::Direct) const
Definition qwidget.cpp:1029
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:9777
QWidget * topLevelWidget() const
Definition qwidget.h:312
virtual void closeEvent(QCloseEvent *event)
This event handler is called with the given event when Qt receives a window close request for a top-l...
Definition qwidget.cpp:9902
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
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:7904
void hide()
Hides the widget.
Definition qwidget.cpp:8209
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:8329
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:9761
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:2490
virtual void changeEvent(QEvent *)
This event handler can be reimplemented to handle state changes.
Definition qwidget.cpp:9428
friend class QFontMetrics
Definition qwidget.h:749
void setWindowTitle(const QString &)
Definition qwidget.cpp:6109
bool event(QEvent *event) override
This is the main event handler; it handles event event.
Definition qwidget.cpp:8912
QStyle * style() const
Definition qwidget.cpp:2607
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:2503
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.
DockWidgetArea
@ BottomDockWidgetArea
@ DockWidgetArea_Mask
@ NoDockWidgetArea
@ RightDockWidgetArea
@ LeftDockWidgetArea
@ TopDockWidgetArea
@ LeftButton
Definition qnamespace.h:57
@ WA_Moved
Definition qnamespace.h:308
@ NoFocus
Definition qnamespace.h:106
@ Horizontal
Definition qnamespace.h:98
@ Vertical
Definition qnamespace.h:99
@ NoArrow
@ ControlModifier
@ CaseInsensitive
DropAction
@ IgnoreAction
@ CustomizeWindowHint
Definition qnamespace.h:238
@ Widget
Definition qnamespace.h:205
@ FramelessWindowHint
Definition qnamespace.h:224
@ Tool
Definition qnamespace.h:211
@ WindowTitleHint
Definition qnamespace.h:225
@ X11BypassWindowManagerHint
Definition qnamespace.h:223
@ WindowCloseButtonHint
Definition qnamespace.h:240
#define Q_FALLTHROUGH()
#define Q_LIKELY(x)
QMainWindowLayout * qt_mainwindow_layout(const QMainWindow *window)
static bool isWindowsStyle(const QStyle *style)
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:5996
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:152
#define qWarning
Definition qlogging.h:162
#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
#define SLOT(a)
Definition qobjectdefs.h:51
#define SIGNAL(a)
Definition qobjectdefs.h:52
GLboolean GLboolean GLboolean b
GLfloat GLfloat GLfloat w
[0]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLboolean r
[2]
GLdouble GLdouble right
GLboolean GLuint group
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:29
double qreal
Definition qtypes.h:92
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:5996
#define QWIDGETSIZE_MAX
Definition qwidget.h:930
QWidget * win
Definition settings.cpp:6
QFileInfo info(fileName)
[8]
QObject::connect nullptr
QString title
[35]
QGraphicsItem * item
aWidget window() -> setWindowTitle("New Window Title")
[2]
QDockWidget * dockWidget
[0]
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent