5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
94
95
96
97
98
99
102
103
104
105
106
107
108
109
110
114#include <QApplication>
115#include <QStylePainter>
116#include <QVBoxLayout>
117#include <QMouseEvent>
118#if QT_CONFIG(whatsthis)
121#if QT_CONFIG(tooltip)
124#if QT_CONFIG(mainwindow)
125#include <QMainWindow>
130#include <QScopedValueRollback>
137#include <QProxyStyle>
141using namespace Qt::StringLiterals;
142using namespace std::chrono_literals;
148 QStyle::SC_TitleBarLabel,
149 QStyle::SC_TitleBarSysMenu,
150 QStyle::SC_TitleBarMinButton,
151 QStyle::SC_TitleBarMaxButton,
152 QStyle::SC_TitleBarShadeButton,
153 QStyle::SC_TitleBarCloseButton,
154 QStyle::SC_TitleBarNormalButton,
155 QStyle::SC_TitleBarUnshadeButton,
156 QStyle::SC_TitleBarContextHelpButton
161 Qt::FramelessWindowHint
162 | Qt::CustomizeWindowHint
163 | Qt::WindowTitleHint
164 | Qt::WindowSystemMenuHint
165 | Qt::WindowMinimizeButtonHint
166 | Qt::WindowMaximizeButtonHint
167 | Qt::WindowMinMaxButtonsHint;
174 auto proxyStyle = qobject_cast<QProxyStyle *>(style);
175 auto styleToCheck = proxyStyle ? proxyStyle->baseStyle() : style;
176 return styleToCheck->inherits(
"QMacStyle");
180 int delta,
int maxDelta,
int minDelta)
182 if (cflags & moveFlag) {
184 return (cflags & resizeFlag) ? qMin(delta, maxDelta) : delta;
185 return (cflags & resizeFlag) ? qMax(delta, minDelta) : delta;
191 uint resizeReverseFlag,
int delta)
193 if (cflags & resizeFlag) {
194 if (cflags & resizeReverseFlag)
204 QWidget *parent = child->parentWidget();
206 if (qobject_cast<QMdiSubWindow *>(parent))
208 parent = parent->parentWidget();
216 if (QMdiArea *mdiArea = child->mdiArea()) {
217 if (mdiArea->viewMode() == QMdiArea::TabbedView)
226 if (widget && widget->qt_metacast(
"ControlElement")
227 && strcmp(widget->metaObject()->className(), T::staticMetaObject.className()) == 0) {
233QString QMdiSubWindowPrivate::originalWindowTitleHelper()
const
235 Q_Q(
const QMdiSubWindow);
238 if (
auto *mdiArea = q->mdiArea()) {
239 const auto &subWindows = mdiArea->subWindowList();
240 for (
auto *subWindow : subWindows) {
241 if (subWindow != q && subWindow->isMaximized()) {
242 auto *subWindowD =
static_cast<QMdiSubWindowPrivate *>(qt_widget_private(subWindow));
243 if (!subWindowD->originalTitle.isNull())
244 return subWindowD->originalTitle;
248 return q->window()->windowTitle();
251QString QMdiSubWindowPrivate::originalWindowTitle()
253 if (originalTitle.isNull()) {
254 originalTitle = originalWindowTitleHelper();
255 if (originalTitle.isNull())
256 originalTitle =
""_L1;
258 return originalTitle;
261void QMdiSubWindowPrivate::setNewWindowTitle()
264 QString childTitle = q->windowTitle();
265 if (childTitle.isEmpty())
267 QString original = originalWindowTitle();
268 if (!original.isEmpty()) {
269 if (!original.contains(QMdiSubWindow::tr(
"- [%1]").arg(childTitle))) {
270 auto title = QMdiSubWindow::tr(
"%1 - [%2]").arg(original, childTitle);
271 ignoreWindowTitleChange =
true;
272 q->window()->setWindowTitle(title);
273 ignoreWindowTitleChange =
false;
277 ignoreWindowTitleChange =
true;
278 q->window()->setWindowTitle(childTitle);
279 ignoreWindowTitleChange =
false;
285 return control != QStyle::SC_None && control != QStyle::SC_TitleBarLabel;
288#if QT_CONFIG(tooltip)
289static void showToolTip(QHelpEvent *helpEvent, QWidget *widget,
const QStyleOptionComplex &opt,
290 QStyle::ComplexControl complexControl, QStyle::SubControl subControl)
293 Q_ASSERT(helpEvent->type() == QEvent::ToolTip);
296 if (widget->style()->styleHint(QStyle::SH_TitleBar_ShowToolTipsOnButtons, &opt, widget))
301 if (complexControl == QStyle::CC_MdiControls) {
302 if (subControl == QStyle::SC_MdiMinButton)
303 subControl = QStyle::SC_TitleBarMinButton;
304 else if (subControl == QStyle::SC_MdiCloseButton)
305 subControl = QStyle::SC_TitleBarCloseButton;
306 else if (subControl == QStyle::SC_MdiNormalButton)
307 subControl = QStyle::SC_TitleBarNormalButton;
309 subControl = QStyle::SC_None;
313 if (subControl == QStyle::SC_None)
318 switch (subControl) {
319 case QStyle::SC_TitleBarMinButton:
320 toolTip = QMdiSubWindow::tr(
"Minimize");
322 case QStyle::SC_TitleBarMaxButton:
323 toolTip = QMdiSubWindow::tr(
"Maximize");
325 case QStyle::SC_TitleBarUnshadeButton:
326 toolTip = QMdiSubWindow::tr(
"Unshade");
328 case QStyle::SC_TitleBarShadeButton:
329 toolTip = QMdiSubWindow::tr(
"Shade");
331 case QStyle::SC_TitleBarNormalButton:
332 if (widget->isMaximized() || !qobject_cast<QMdiSubWindow *>(widget))
333 toolTip = QMdiSubWindow::tr(
"Restore Down");
335 toolTip = QMdiSubWindow::tr(
"Restore");
337 case QStyle::SC_TitleBarCloseButton:
338 toolTip = QMdiSubWindow::tr(
"Close");
340 case QStyle::SC_TitleBarContextHelpButton:
341 toolTip = QMdiSubWindow::tr(
"Help");
343 case QStyle::SC_TitleBarSysMenu:
344 toolTip = QMdiSubWindow::tr(
"Menu");
350 const QRect rect = widget->style()->subControlRect(complexControl, &opt, subControl, widget);
351 QToolTip::showText(helpEvent->globalPos(), toolTip, widget, rect);
357
358
359
382 void updateWindowIcon();
387 : QWidget(parent), isPressed(
false)
389 setFocusPolicy(Qt::NoFocus);
391 setFixedSize(label.deviceIndependentSize().toSize());
395
396
399 return label.deviceIndependentSize().toSize();
403
404
407 if (event->type() == QEvent::WindowIconChange)
409 else if (event->type() == QEvent::StyleChange) {
411 setFixedSize(label.size());
413#if QT_CONFIG(tooltip)
414 else if (event->type() == QEvent::ToolTip) {
415 QStyleOptionTitleBar options;
416 options.initFrom(
this);
417 showToolTip(
static_cast<QHelpEvent *>(event),
this, options,
418 QStyle::CC_TitleBar, QStyle::SC_TitleBarSysMenu);
421 return QWidget::event(event);
425
426
429 QPainter painter(
this);
430 painter.drawPixmap(0, 0, label);
434
435
438 if (mouseEvent->button() != Qt::LeftButton) {
439 mouseEvent->ignore();
446
447
450 if (mouseEvent->button() != Qt::LeftButton) {
451 mouseEvent->ignore();
455 emit _q_doubleClicked();
459
460
463 if (mouseEvent->button() != Qt::LeftButton) {
464 mouseEvent->ignore();
474
475
478 QIcon menuIcon = windowIcon();
479 if (menuIcon.isNull())
480 menuIcon = style()->standardIcon(QStyle::SP_TitleBarMenuButton,
nullptr, parentWidget());
481 const int iconSize = style()->pixelMetric(QStyle::PM_TitleBarButtonIconSize,
nullptr, parentWidget());
482 label = menuIcon.pixmap(iconSize);
488
489
490
500 return (visibleControls & QStyle::SC_MdiMinButton)
501 || (visibleControls & QStyle::SC_MdiNormalButton)
502 || (visibleControls & QStyle::SC_MdiCloseButton);
519 QStyle::SubControl activeControl;
520 QStyle::SubControl hoverControl;
521 QStyle::SubControls visibleControls;
522 void initStyleOption(QStyleOptionComplex *option)
const;
523 inline QStyle::SubControl getSubControl(
const QPoint &pos)
const
525 QStyleOptionComplex opt;
526 initStyleOption(&opt);
527 return style()->hitTestComplexControl(QStyle::CC_MdiControls, &opt, pos,
this);
533
534
537 activeControl(QStyle::SC_None),
538 hoverControl(QStyle::SC_None),
539 visibleControls(QStyle::SC_None)
541 setFocusPolicy(Qt::NoFocus);
542 setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
543 setMouseTracking(
true);
547
548
552 QStyleOptionComplex opt;
553 initStyleOption(&opt);
554 const int buttonSize = style()->pixelMetric(QStyle::PM_TitleBarButtonSize, &opt,
this);
555 QSize size(3 * buttonSize, buttonSize);
556 return style()->sizeFromContents(QStyle::CT_MdiControls, &opt, size,
this);
561 QStyle::SubControl subControl = QStyle::SC_None;
564 if (action == QMdiSubWindowPrivate::MaximizeAction)
565 subControl = QStyle::SC_MdiNormalButton;
566 else if (action == QMdiSubWindowPrivate::CloseAction)
567 subControl = QStyle::SC_MdiCloseButton;
568 else if (action == QMdiSubWindowPrivate::MinimizeAction)
569 subControl = QStyle::SC_MdiMinButton;
571 if (subControl == QStyle::SC_None)
574 visibleControls.setFlag(subControl, visible && !(visibleControls & subControl));
578
579
582 QStyleOptionComplex opt;
583 initStyleOption(&opt);
584 if (activeControl == hoverControl) {
585 opt.activeSubControls = activeControl;
586 opt.state |= QStyle::State_Sunken;
587 }
else if (hoverControl != QStyle::SC_None && (activeControl == QStyle::SC_None)) {
588 opt.activeSubControls = hoverControl;
589 opt.state |= QStyle::State_MouseOver;
591 QPainter painter(
this);
592 style()->drawComplexControl(QStyle::CC_MdiControls, &opt, &painter,
this);
596
597
600 if (event->button() != Qt::LeftButton) {
604 activeControl = getSubControl(event->position().toPoint());
609
610
613 if (event->button() != Qt::LeftButton) {
618 QStyle::SubControl under_mouse = getSubControl(event->position().toPoint());
619 if (under_mouse == activeControl) {
620 switch (activeControl) {
621 case QStyle::SC_MdiCloseButton:
624 case QStyle::SC_MdiNormalButton:
627 case QStyle::SC_MdiMinButton:
635 activeControl = QStyle::SC_None;
640
641
644 QStyle::SubControl under_mouse = getSubControl(event->position().toPoint());
646 if (hoverControl != under_mouse) {
647 hoverControl = under_mouse;
653
654
657 hoverControl = QStyle::SC_None;
662
663
666#if QT_CONFIG(tooltip)
667 if (event->type() == QEvent::ToolTip) {
668 QStyleOptionComplex opt;
669 initStyleOption(&opt);
670 QHelpEvent *helpEvent =
static_cast<QHelpEvent *>(event);
671 showToolTip(helpEvent,
this, opt, QStyle::CC_MdiControls, getSubControl(helpEvent->pos()));
674 return QWidget::event(event);
678
679
682 option->initFrom(
this);
683 option->subControls = visibleControls;
684 option->activeSubControls = QStyle::SC_None;
688
689
694#if QT_CONFIG(menubar)
701 m_controllerWidget =
new ControlElement<ControllerWidget>(mdiChild);
702 connect(m_controllerWidget, SIGNAL(_q_close()), mdiChild, SLOT(close()));
703 connect(m_controllerWidget, SIGNAL(_q_restore()), mdiChild, SLOT(showNormal()));
704 connect(m_controllerWidget, SIGNAL(_q_minimize()), mdiChild, SLOT(showMinimized()));
706 m_menuLabel =
new ControlElement<ControlLabel>(mdiChild);
707 m_menuLabel->setWindowIcon(mdiChild->windowIcon());
709 connect(m_menuLabel, SIGNAL(_q_clicked()), mdiChild, SLOT(showSystemMenu()));
711 connect(m_menuLabel, SIGNAL(_q_doubleClicked()), mdiChild, SLOT(close()));
716#if QT_CONFIG(menubar)
717 removeButtonsFromMenuBar();
720 m_menuLabel =
nullptr;
721 delete m_controllerWidget;
722 m_controllerWidget =
nullptr;
725#if QT_CONFIG(menubar)
727
728
729QMenuBar *QMdiSubWindowPrivate::menuBar()
const
731#if !QT_CONFIG(mainwindow)
734 Q_Q(
const QMdiSubWindow);
735 if (!q->isMaximized() || drawTitleBarWhenMaximized() || isChildOfTabbedQMdiArea(q))
738 if (QMainWindow *mainWindow = qobject_cast<QMainWindow *>(q->window()))
739 return mainWindow->menuBar();
746
747
748void ControlContainer::showButtonsInMenuBar(QMenuBar *menuBar)
750 if (!menuBar || !mdiChild || mdiChild->windowFlags() & Qt::FramelessWindowHint)
754 if (m_menuLabel && mdiChild->windowFlags() & Qt::WindowSystemMenuHint) {
755 QWidget *currentLeft = menuBar->cornerWidget(Qt::TopLeftCorner);
758 if (currentLeft != m_menuLabel) {
759 menuBar->setCornerWidget(m_menuLabel, Qt::TopLeftCorner);
760 previousLeft = currentLeft;
764 ControllerWidget *controllerWidget = qobject_cast<ControllerWidget *>(m_controllerWidget);
765 if (controllerWidget && controllerWidget->hasVisibleControls()) {
766 QWidget *currentRight = menuBar->cornerWidget(Qt::TopRightCorner);
768 currentRight->hide();
769 if (currentRight != m_controllerWidget) {
770 menuBar->setCornerWidget(m_controllerWidget, Qt::TopRightCorner);
771 previousRight = currentRight;
773 m_controllerWidget->show();
775 mdiChild->d_func()->setNewWindowTitle();
779
780
781void ControlContainer::removeButtonsFromMenuBar(QMenuBar *menuBar)
783 if (menuBar && menuBar != m_menuBar) {
785 previousRight =
nullptr;
786 previousLeft =
nullptr;
790 if (!m_menuBar || !mdiChild || qt_widget_private(mdiChild->window())->data.in_destructor)
793 QMdiSubWindow *child =
nullptr;
794 if (m_controllerWidget) {
795 QWidget *currentRight = m_menuBar->cornerWidget(Qt::TopRightCorner);
796 if (currentRight == m_controllerWidget) {
797 if (ControlElement<ControllerWidget> *ce = ptr<ControllerWidget>(previousRight)) {
798 if (!ce->mdiChild || !ce->mdiChild->isMaximized())
799 previousRight =
nullptr;
801 child = ce->mdiChild;
803 m_menuBar->setCornerWidget(previousRight, Qt::TopRightCorner);
805 previousRight->show();
806 previousRight =
nullptr;
809 m_controllerWidget->hide();
810 m_controllerWidget->setParent(
nullptr);
813 QWidget *currentLeft = m_menuBar->cornerWidget(Qt::TopLeftCorner);
814 if (currentLeft == m_menuLabel) {
815 if (ControlElement<ControlLabel> *ce = ptr<ControlLabel>(previousLeft)) {
816 if (!ce->mdiChild || !ce->mdiChild->isMaximized())
817 previousLeft =
nullptr;
821 m_menuBar->setCornerWidget(previousLeft, Qt::TopLeftCorner);
823 previousLeft->show();
824 previousLeft =
nullptr;
828 m_menuLabel->setParent(
nullptr);
832 child->d_func()->setNewWindowTitle();
834 mdiChild->window()->setWindowTitle(mdiChild->d_func()->originalWindowTitle());
842 m_menuLabel->setWindowIcon(windowIcon);
846
847
848QMdiSubWindowPrivate::QMdiSubWindowPrivate()
849 : baseWidget(
nullptr),
850 restoreFocusWidget(
nullptr),
851 controlContainer(
nullptr),
852#if QT_CONFIG(sizegrip)
855#if QT_CONFIG(rubberband)
858 userMinimumSize(0,0),
861 isInInteractiveMode(
false),
862#if QT_CONFIG(rubberband)
863 isInRubberBandMode(
false),
866 ignoreWindowTitleChange(
false),
867 ignoreNextActivationEvent(
false),
868 activationEnabled(
true),
869 isShadeRequestFromMinimizeMode(
false),
870 isMaximizeMode(
false),
871 isWidgetHiddenByUs(
false),
873 isExplicitlyDeactivated(
false),
874 keyboardSingleStep(5),
875 keyboardPageStep(20),
876 currentOperation(None),
877 hoveredSubControl(QStyle::SC_None),
878 activeSubControl(QStyle::SC_None),
879 focusInReason(Qt::ActiveWindowFocusReason)
885
886
887void QMdiSubWindowPrivate::_q_updateStaysOnTopHint()
891 if (QAction *senderAction = qobject_cast<QAction *>(q->sender())) {
892 if (senderAction->isChecked()) {
893 q->setWindowFlags(q->windowFlags() | Qt::WindowStaysOnTopHint);
896 q->setWindowFlags(q->windowFlags() & ~Qt::WindowStaysOnTopHint);
904
905
906void QMdiSubWindowPrivate::_q_enterInteractiveMode()
910 QAction *action = qobject_cast<QAction *>(q->sender());
915 if (actions[MoveAction] && actions[MoveAction] == action) {
916 currentOperation = Move;
917 pressPos = QPoint(q->width() / 2, titleBarHeight() - 1);
918 }
else if (actions[ResizeAction] && actions[ResizeAction] == action) {
919 currentOperation = q->isLeftToRight() ? BottomRightResize : BottomLeftResize;
920 int offset = q->style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth,
nullptr, q) / 2;
921 int x = q->isLeftToRight() ? q->width() - offset : offset;
922 pressPos = QPoint(x, q->height() - offset);
929 q->cursor().setPos(q->mapToGlobal(pressPos));
931 mousePressPosition = q->mapToParent(pressPos);
932 oldGeometry = q->geometry();
933 isInInteractiveMode =
true;
935#if QT_CONFIG(rubberband)
936 if ((q->testOption(QMdiSubWindow::RubberBandResize)
937 && (currentOperation == BottomRightResize || currentOperation == BottomLeftResize))
938 || (q->testOption(QMdiSubWindow::RubberBandMove) && currentOperation == Move)) {
939 enterRubberBandMode();
949
950
951void QMdiSubWindowPrivate::_q_processFocusChanged(QWidget *old, QWidget *now)
955 if (now && (now == q || q->isAncestorOf(now))) {
956 if (now == q && !isInInteractiveMode)
963
964
965void QMdiSubWindowPrivate::leaveInteractiveMode()
968#if QT_CONFIG(rubberband)
969 if (isInRubberBandMode)
970 leaveRubberBandMode();
974 isInInteractiveMode =
false;
975 currentOperation = None;
976 updateDirtyRegions();
978 if (baseWidget && baseWidget->focusWidget())
979 baseWidget->focusWidget()->setFocus();
983
984
985void QMdiSubWindowPrivate::removeBaseWidget()
991 baseWidget->removeEventFilter(q);
993 layout->removeWidget(baseWidget);
994 if (baseWidget->windowTitle() == q->windowTitle()) {
995 ignoreWindowTitleChange =
true;
996 q->setWindowTitle(QString());
997 ignoreWindowTitleChange =
false;
998 q->setWindowModified(
false);
1000 lastChildWindowTitle.clear();
1002 if (baseWidget->parentWidget() == q)
1003 baseWidget->setParent(
nullptr);
1004 baseWidget =
nullptr;
1005 isWidgetHiddenByUs =
false;
1009
1010
1011void QMdiSubWindowPrivate::initOperationMap()
1013 operationMap.insert(Move, OperationInfo(HMove | VMove, Qt::ArrowCursor,
false));
1014 operationMap.insert(TopResize, OperationInfo(VMove | VResize | VResizeReverse, Qt::SizeVerCursor));
1015 operationMap.insert(BottomResize, OperationInfo(VResize, Qt::SizeVerCursor));
1016 operationMap.insert(LeftResize, OperationInfo(HMove | HResize | HResizeReverse, Qt::SizeHorCursor));
1017 operationMap.insert(RightResize, OperationInfo(HResize, Qt::SizeHorCursor));
1018 operationMap.insert(TopLeftResize, OperationInfo(HMove | VMove | HResize | VResize | VResizeReverse
1019 | HResizeReverse, Qt::SizeFDiagCursor));
1020 operationMap.insert(TopRightResize, OperationInfo(VMove | HResize | VResize
1021 | VResizeReverse, Qt::SizeBDiagCursor));
1022 operationMap.insert(BottomLeftResize, OperationInfo(HMove | HResize | VResize | HResizeReverse,
1023 Qt::SizeBDiagCursor));
1024 operationMap.insert(BottomRightResize, OperationInfo(HResize | VResize, Qt::SizeFDiagCursor));
1030
1031
1032void QMdiSubWindowPrivate::createSystemMenu()
1035 Q_ASSERT_X(q,
"QMdiSubWindowPrivate::createSystemMenu",
1036 "You can NOT call this function before QMdiSubWindow's ctor");
1037 systemMenu =
new QMenu(q);
1038 systemMenu->installEventFilter(q);
1039 const QStyle *style = q->style();
1040 addToSystemMenu(RestoreAction, QMdiSubWindow::tr(
"&Restore"), SLOT(showNormal()));
1041 actions[RestoreAction]->setIcon(style->standardIcon(QStyle::SP_TitleBarNormalButton,
nullptr, q));
1042 actions[RestoreAction]->setEnabled(
false);
1043 addToSystemMenu(MoveAction, QMdiSubWindow::tr(
"&Move"), SLOT(_q_enterInteractiveMode()));
1044 addToSystemMenu(ResizeAction, QMdiSubWindow::tr(
"&Size"), SLOT(_q_enterInteractiveMode()));
1045 addToSystemMenu(MinimizeAction, QMdiSubWindow::tr(
"Mi&nimize"), SLOT(showMinimized()));
1046 actions[MinimizeAction]->setIcon(style->standardIcon(QStyle::SP_TitleBarMinButton,
nullptr, q));
1047 addToSystemMenu(MaximizeAction, QMdiSubWindow::tr(
"Ma&ximize"), SLOT(showMaximized()));
1048 actions[MaximizeAction]->setIcon(style->standardIcon(QStyle::SP_TitleBarMaxButton,
nullptr, q));
1049 addToSystemMenu(StayOnTopAction, QMdiSubWindow::tr(
"Stay on &Top"), SLOT(_q_updateStaysOnTopHint()));
1050 actions[StayOnTopAction]->setCheckable(
true);
1051 systemMenu->addSeparator();
1052 addToSystemMenu(CloseAction, QMdiSubWindow::tr(
"&Close"), SLOT(close()));
1053 actions[CloseAction]->setIcon(style->standardIcon(QStyle::SP_TitleBarCloseButton,
nullptr, q));
1054#if !defined(QT_NO_SHORTCUT)
1055 actions[CloseAction]->setShortcuts(QKeySequence::Close);
1062
1063
1064void QMdiSubWindowPrivate::updateCursor()
1068 if (isMacStyle(q->style()))
1071 if (currentOperation == None) {
1076 if (currentOperation == Move || operationMap.find(currentOperation).value().hover) {
1077 q->setCursor(operationMap.find(currentOperation).value().cursorShape);
1084
1085
1086void QMdiSubWindowPrivate::updateDirtyRegions()
1092 for (OperationInfoMap::iterator it = operationMap.begin(), end = operationMap.end(); it != end; ++it)
1093 it.value().region = getRegion(it.key());
1097
1098
1099void QMdiSubWindowPrivate::updateGeometryConstraints()
1105 internalMinimumSize = (!q->isMinimized() && !q->minimumSize().isNull())
1106 ? q->minimumSize() : q->minimumSizeHint();
1107 int margin, minWidth;
1108 sizeParameters(&margin, &minWidth);
1109 q->setContentsMargins(margin, titleBarHeight(), margin, margin);
1110 if (q->isMaximized() || (q->isMinimized() && !q->isShaded())) {
1111 moveEnabled =
false;
1112 resizeEnabled =
false;
1115 if ((q->windowFlags() & Qt::MSWindowsFixedSizeDialogHint) || q->isShaded())
1116 resizeEnabled =
false;
1118 resizeEnabled =
true;
1120 updateDirtyRegions();
1124
1125
1126void QMdiSubWindowPrivate::updateMask()
1129 if (!q->mask().isEmpty())
1135 if ((q->isMaximized() && !drawTitleBarWhenMaximized())
1136 || q->windowFlags() & Qt::FramelessWindowHint)
1139 if (!resizeTimer.isActive())
1140 cachedStyleOptions = titleBarOptions();
1141 cachedStyleOptions.rect = q->rect();
1142 QStyleHintReturnMask frameMask;
1143 q->style()->styleHint(QStyle::SH_WindowFrame_Mask, &cachedStyleOptions, q, &frameMask);
1144 if (!frameMask.region.isEmpty())
1145 q->setMask(frameMask.region);
1149
1150
1151void QMdiSubWindowPrivate::setNewGeometry(
const QPoint &pos)
1154 Q_ASSERT(currentOperation != None);
1157 uint cflags = operationMap.find(currentOperation).value().changeFlags;
1161 const bool restrictHorizontal = !q->testOption(QMdiSubWindow::AllowOutsideAreaHorizontally);
1162 const bool restrictVertical = !q->testOption(QMdiSubWindow::AllowOutsideAreaVertically);
1164 if (restrictHorizontal || restrictVertical) {
1165 QRect parentRect = q->parentWidget()->rect();
1166 if (restrictVertical && (cflags & VResizeReverse || currentOperation == Move)) {
1167 posY = qMin(qMax(mousePressPosition.y() - oldGeometry.y(), posY),
1168 parentRect.height() - BoundaryMargin);
1170 if (currentOperation == Move) {
1171 if (restrictHorizontal)
1172 posX = qMin(qMax(BoundaryMargin, posX), parentRect.width() - BoundaryMargin);
1173 if (restrictVertical)
1174 posY = qMin(posY, parentRect.height() - BoundaryMargin);
1176 if (restrictHorizontal) {
1177 if (cflags & HResizeReverse)
1178 posX = qMax(mousePressPosition.x() - oldGeometry.x(), posX);
1180 posX = qMin(parentRect.width() - (oldGeometry.x() + oldGeometry.width()
1181 - mousePressPosition.x()), posX);
1183 if (restrictVertical && !(cflags & VResizeReverse)) {
1184 posY = qMin(parentRect.height() - (oldGeometry.y() + oldGeometry.height()
1185 - mousePressPosition.y()), posY);
1191 if (cflags & (HMove | VMove)) {
1192 int dx = getMoveDeltaComponent(cflags, HMove, HResize, posX - mousePressPosition.x(),
1193 oldGeometry.width() - internalMinimumSize.width(),
1194 oldGeometry.width() - q->maximumWidth());
1195 int dy = getMoveDeltaComponent(cflags, VMove, VResize, posY - mousePressPosition.y(),
1196 oldGeometry.height() - internalMinimumSize.height(),
1197 oldGeometry.height() - q->maximumHeight());
1198 geometry.setTopLeft(oldGeometry.topLeft() + QPoint(dx, dy));
1200 geometry.setTopLeft(q->geometry().topLeft());
1203 if (cflags & (HResize | VResize)) {
1204 int dx = getResizeDeltaComponent(cflags, HResize, HResizeReverse,
1205 posX - mousePressPosition.x());
1206 int dy = getResizeDeltaComponent(cflags, VResize, VResizeReverse,
1207 posY - mousePressPosition.y());
1208 geometry.setSize(oldGeometry.size() + QSize(dx, dy));
1210 geometry.setSize(q->geometry().size());
1213 setNewGeometry(&geometry);
1217
1218
1219void QMdiSubWindowPrivate::setMinimizeMode()
1224 ensureWindowState(Qt::WindowMinimized);
1225 isShadeRequestFromMinimizeMode =
true;
1227 isShadeRequestFromMinimizeMode =
false;
1229 moveEnabled =
false;
1231 setEnabled(MoveAction, moveEnabled);
1234 Q_ASSERT(q->windowState() & Qt::WindowMinimized);
1235 Q_ASSERT(!(q->windowState() & Qt::WindowMaximized));
1245
1246
1247void QMdiSubWindowPrivate::setNormalMode()
1252 isShadeMode =
false;
1253 isMaximizeMode =
false;
1255 ensureWindowState(Qt::WindowNoState);
1256#if QT_CONFIG(menubar)
1257 removeButtonsFromMenuBar();
1262 const bool wasVisible = q->isVisible();
1264 q->setVisible(
false);
1267 if (!userMinimumSize.isNull()) {
1268 q->setMinimumSize(userMinimumSize);
1269 userMinimumSize = QSize(0, 0);
1273 if (baseWidget && isWidgetHiddenByUs) {
1275 isWidgetHiddenByUs =
false;
1278 updateGeometryConstraints();
1279 QRect newGeometry = oldGeometry;
1280 newGeometry.setSize(restoreSize.expandedTo(internalMinimumSize));
1281 q->setGeometry(newGeometry);
1284 q->setVisible(
true);
1287 restoreSize.setWidth(-1);
1288 restoreSize.setHeight(-1);
1290#if QT_CONFIG(sizegrip)
1291 setSizeGripVisible(
true);
1295 setEnabled(MoveAction,
true);
1296 setEnabled(MaximizeAction,
true);
1297 setEnabled(MinimizeAction,
true);
1298 setEnabled(RestoreAction,
false);
1299 setEnabled(ResizeAction, resizeEnabled);
1302 Q_ASSERT(!(q_func()->windowState() & Qt::WindowMinimized));
1306 Q_ASSERT((isMaximizeMode && q_func()->windowState() & Qt::WindowMaximized)
1307 || (!isMaximizeMode && !(q_func()->windowState() & Qt::WindowMaximized)));
1308 Q_ASSERT(!isShadeMode);
1315inline void QMdiSubWindowPrivate::storeFocusWidget()
1317 if (QWidget *focus = QApplication::focusWidget()) {
1318 if (!restoreFocusWidget && q_func()->isAncestorOf(focus))
1319 restoreFocusWidget = focus;
1324
1325
1326void QMdiSubWindowPrivate::setMaximizeMode()
1331 ensureWindowState(Qt::WindowMaximized);
1332 isShadeMode =
false;
1333 isMaximizeMode =
true;
1337#if QT_CONFIG(sizegrip)
1338 setSizeGripVisible(
false);
1342 if (!restoreSize.isValid()) {
1343 oldGeometry = q->geometry();
1344 restoreSize.setWidth(oldGeometry.width());
1345 restoreSize.setHeight(oldGeometry.height());
1350 const bool wasVisible = q->isVisible();
1352 q->setVisible(
false);
1355 if (baseWidget && isWidgetHiddenByUs) {
1357 isWidgetHiddenByUs =
false;
1360 updateGeometryConstraints();
1363#if QT_CONFIG(menubar)
1364 if (QMenuBar *mBar = menuBar())
1365 showButtonsInMenuBar(mBar);
1368 if (!controlContainer)
1369 controlContainer =
new ControlContainer(q);
1372 QWidget *parent = q->parentWidget();
1373 QRect availableRect = parent->contentsRect();
1376 QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(parent->parentWidget());
1377 if (scrollArea && scrollArea->viewport() == parent) {
1378 QScrollBar *hbar = scrollArea->horizontalScrollBar();
1379 QScrollBar *vbar = scrollArea->verticalScrollBar();
1380 const int xOffset = hbar ? hbar->value() : 0;
1381 const int yOffset = vbar ? vbar->value() : 0;
1382 availableRect.adjust(-xOffset, -yOffset, -xOffset, -yOffset);
1383 oldGeometry.adjust(xOffset, yOffset, xOffset, yOffset);
1386 setNewGeometry(&availableRect);
1388 ensureWindowState(Qt::WindowMaximized);
1391 q->setVisible(
true);
1393 resizeEnabled =
false;
1394 moveEnabled =
false;
1397 setEnabled(MoveAction, moveEnabled);
1398 setEnabled(MaximizeAction,
false);
1399 setEnabled(MinimizeAction,
true);
1400 setEnabled(RestoreAction,
true);
1401 setEnabled(ResizeAction, resizeEnabled);
1404 Q_ASSERT(q->windowState() & Qt::WindowMaximized);
1405 Q_ASSERT(!(q->windowState() & Qt::WindowMinimized));
1412
1413
1414void QMdiSubWindowPrivate::setActive(
bool activate,
bool changeFocus)
1417 if (!parent || !activationEnabled)
1420 if (activate && !isActive && q->isEnabled()) {
1422 isExplicitlyDeactivated =
false;
1423 Qt::WindowStates oldWindowState = q->windowState();
1424 ensureWindowState(Qt::WindowActive);
1425 emit q->aboutToActivate();
1426#if QT_CONFIG(menubar)
1427 if (QMenuBar *mBar = menuBar())
1428 showButtonsInMenuBar(mBar);
1431 emit q->windowStateChanged(oldWindowState, q->windowState());
1432 }
else if (!activate && isActive) {
1434 Qt::WindowStates oldWindowState = q->windowState();
1435 q->overrideWindowState(q->windowState() & ~Qt::WindowActive);
1438 QWidget *focusWidget = QApplication::focusWidget();
1439 if (focusWidget && (focusWidget == q || q->isAncestorOf(focusWidget)))
1440 focusWidget->clearFocus();
1443 baseWidget->overrideWindowState(baseWidget->windowState() & ~Qt::WindowActive);
1444 Q_ASSERT(!isActive);
1445 emit q->windowStateChanged(oldWindowState, q->windowState());
1448 if (activate && isActive && q->isEnabled() && !q->hasFocus()
1449 && !q->isAncestorOf(QApplication::focusWidget())) {
1452 ensureWindowState(Qt::WindowActive);
1455 int frameWidth = q->style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth,
nullptr, q);
1456 int titleBarHeight =
this->titleBarHeight();
1457 QRegion windowDecoration = QRegion(0, 0, q->width(), q->height());
1458 windowDecoration -= QRegion(frameWidth, titleBarHeight, q->width() - 2 * frameWidth,
1459 q->height() - titleBarHeight - frameWidth);
1463 if (resizeTimer.isActive()) {
1465 updateDirtyRegions();
1468 q->update(windowDecoration);
1472
1473
1474void QMdiSubWindowPrivate::processClickedSubControl()
1477 switch (activeSubControl) {
1478 case QStyle::SC_TitleBarContextHelpButton:
1479#if QT_CONFIG(whatsthis)
1480 QWhatsThis::enterWhatsThisMode();
1483 case QStyle::SC_TitleBarShadeButton:
1485 hoveredSubControl = QStyle::SC_TitleBarUnshadeButton;
1487 case QStyle::SC_TitleBarUnshadeButton:
1489 hoveredSubControl = QStyle::SC_TitleBarShadeButton;
1492 case QStyle::SC_TitleBarMinButton:
1493 if (isMacStyle(q->style())) {
1494 if (q->isMinimized())
1503 case QStyle::SC_TitleBarNormalButton:
1505 hoveredSubControl = QStyle::SC_TitleBarMinButton;
1508 case QStyle::SC_TitleBarMaxButton:
1509 if (isMacStyle(q->style())) {
1510 if (q->isMaximized())
1519 case QStyle::SC_TitleBarCloseButton:
1528
1529
1530QRegion QMdiSubWindowPrivate::getRegion(Operation operation)
const
1532 Q_Q(
const QMdiSubWindow);
1533 int width = q->width();
1534 int height = q->height();
1535 int titleBarHeight =
this->titleBarHeight();
1536 int frameWidth = q->style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth,
nullptr, q);
1537 int cornerConst = titleBarHeight - frameWidth;
1538 int titleBarConst = 2 * titleBarHeight;
1540 if (operation == Move) {
1541 QStyleOptionTitleBar titleBarOptions =
this->titleBarOptions();
1542 QRegion move(frameWidth, frameWidth, width - 2 * frameWidth, cornerConst);
1545 for (
int i = 0; i < NumSubControls; ++i) {
1546 if (SubControls[i] == QStyle::SC_TitleBarLabel)
1548 move -= QRegion(q->style()->subControlRect(QStyle::CC_TitleBar, &titleBarOptions,
1555 if (isMacStyle(q->style()))
1558 switch (operation) {
1560 region = QRegion(titleBarHeight, 0, width - titleBarConst, frameWidth);
1563 region = QRegion(titleBarHeight, height - frameWidth, width - titleBarConst, frameWidth);
1566 region = QRegion(0, titleBarHeight, frameWidth, height - titleBarConst);
1569 region = QRegion(width - frameWidth, titleBarHeight, frameWidth, height - titleBarConst);
1572 region = QRegion(0, 0, titleBarHeight, titleBarHeight)
1573 - QRegion(frameWidth, frameWidth, cornerConst, cornerConst);
1575 case TopRightResize:
1576 region = QRegion(width - titleBarHeight, 0, titleBarHeight, titleBarHeight)
1577 - QRegion(width - titleBarHeight, frameWidth, cornerConst, cornerConst);
1579 case BottomLeftResize:
1580 region = QRegion(0, height - titleBarHeight, titleBarHeight, titleBarHeight)
1581 - QRegion(frameWidth, height - titleBarHeight, cornerConst, cornerConst);
1583 case BottomRightResize:
1584 region = QRegion(width - titleBarHeight, height - titleBarHeight, titleBarHeight, titleBarHeight)
1585 - QRegion(width - titleBarHeight, height - titleBarHeight, cornerConst, cornerConst);
1595
1596
1597QMdiSubWindowPrivate::Operation QMdiSubWindowPrivate::getOperation(
const QPoint &pos)
const
1599 OperationInfoMap::const_iterator it;
1600 for (it = operationMap.constBegin(); it != operationMap.constEnd(); ++it)
1601 if (it.value().region.contains(pos))
1609
1610
1611QStyleOptionTitleBar QMdiSubWindowPrivate::titleBarOptions()
const
1613 Q_Q(
const QMdiSubWindow);
1614 QStyleOptionTitleBar titleBarOptions;
1615 titleBarOptions.initFrom(q);
1616 if (activeSubControl != QStyle::SC_None) {
1617 if (hoveredSubControl == activeSubControl) {
1618 titleBarOptions.state |= QStyle::State_Sunken;
1619 titleBarOptions.activeSubControls = activeSubControl;
1621 }
else if (autoRaise() && hoveredSubControl != QStyle::SC_None
1622 && hoveredSubControl != QStyle::SC_TitleBarLabel) {
1623 titleBarOptions.state |= QStyle::State_MouseOver;
1624 titleBarOptions.activeSubControls = hoveredSubControl;
1626 titleBarOptions.state &= ~QStyle::State_MouseOver;
1627 titleBarOptions.activeSubControls = QStyle::SC_None;
1630 titleBarOptions.subControls = QStyle::SC_All;
1631 titleBarOptions.titleBarFlags = q->windowFlags();
1632 titleBarOptions.titleBarState = q->windowState();
1633 titleBarOptions.palette = titleBarPalette;
1634 titleBarOptions.icon = menuIcon;
1637 titleBarOptions.state |= QStyle::State_Active;
1638 titleBarOptions.titleBarState |= QStyle::State_Active;
1639 titleBarOptions.palette.setCurrentColorGroup(QPalette::Active);
1641 titleBarOptions.state &= ~QStyle::State_Active;
1642 titleBarOptions.palette.setCurrentColorGroup(QPalette::Inactive);
1645 int border = hasBorder(titleBarOptions) ? 4 : 0;
1646 int paintHeight = titleBarHeight(titleBarOptions);
1647 paintHeight -= q->isMinimized() ? 2 * border : border;
1648 titleBarOptions.rect = QRect(border, border, q->width() - 2 * border, paintHeight);
1650 if (!windowTitle.isEmpty()) {
1653 titleBarOptions.text = windowTitle;
1654 titleBarOptions.fontMetrics = QFontMetrics(font);
1655 int width = q->style()->subControlRect(QStyle::CC_TitleBar, &titleBarOptions,
1656 QStyle::SC_TitleBarLabel, q).width();
1658 titleBarOptions.text = titleBarOptions.fontMetrics.elidedText(windowTitle, Qt::ElideRight, width);
1660 return titleBarOptions;
1664
1665
1666void QMdiSubWindowPrivate::ensureWindowState(Qt::WindowState state)
1669 Qt::WindowStates windowStates = q->windowState() | state;
1671 case Qt::WindowMinimized:
1672 windowStates &= ~Qt::WindowMaximized;
1673 windowStates &= ~Qt::WindowFullScreen;
1674 windowStates &= ~Qt::WindowNoState;
1676 case Qt::WindowMaximized:
1677 windowStates &= ~Qt::WindowMinimized;
1678 windowStates &= ~Qt::WindowFullScreen;
1679 windowStates &= ~Qt::WindowNoState;
1681 case Qt::WindowNoState:
1682 windowStates &= ~Qt::WindowMinimized;
1683 windowStates &= ~Qt::WindowMaximized;
1684 windowStates &= ~Qt::WindowFullScreen;
1690 if (!(baseWidget->windowState() & Qt::WindowActive) && windowStates & Qt::WindowActive)
1691 baseWidget->overrideWindowState(windowStates & ~Qt::WindowActive);
1693 baseWidget->overrideWindowState(windowStates);
1695 q->overrideWindowState(windowStates);
1699
1700
1701int QMdiSubWindowPrivate::titleBarHeight(
const QStyleOptionTitleBar &options)
const
1703 Q_Q(
const QMdiSubWindow);
1704 if (!parent || q->windowFlags() & Qt::FramelessWindowHint
1705 || (q->isMaximized() && !drawTitleBarWhenMaximized())) {
1709 int height = q->style()->pixelMetric(QStyle::PM_TitleBarHeight, &options, q);
1710 if (hasBorder(options))
1711 height += q->isMinimized() ? 8 : 4;
1716
1717
1718void QMdiSubWindowPrivate::sizeParameters(
int *margin,
int *minWidth)
const
1720 Q_Q(
const QMdiSubWindow);
1721 Qt::WindowFlags flags = q->windowFlags();
1722 if (!parent || flags & Qt::FramelessWindowHint) {
1728 if (q->isMaximized() && !drawTitleBarWhenMaximized())
1731 *margin = q->style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth,
nullptr, q);
1733 QStyleOptionTitleBar opt =
this->titleBarOptions();
1735 for (
int i = 0; i < NumSubControls; ++i) {
1736 if (SubControls[i] == QStyle::SC_TitleBarLabel) {
1740 QRect rect = q->style()->subControlRect(QStyle::CC_TitleBar, &opt, SubControls[i], q);
1741 if (!rect.isValid())
1743 tempWidth += rect.width();
1745 *minWidth = tempWidth;
1749
1750
1751bool QMdiSubWindowPrivate::drawTitleBarWhenMaximized()
const
1753 Q_Q(
const QMdiSubWindow);
1754 if (q->window()->testAttribute(Qt::WA_CanHostQMdiSubWindowTitleBar))
1757 if (isChildOfTabbedQMdiArea(q))
1760 if (q->style()->styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize,
nullptr, q))
1762#if !QT_CONFIG(menubar) || !QT_CONFIG(mainwindow)
1763 Q_UNUSED(isChildOfQMdiSubWindow);
1766 QMainWindow *mainWindow = qobject_cast<QMainWindow *>(q->window());
1767 if (!mainWindow || !qobject_cast<QMenuBar *>(mainWindow->menuWidget())
1768 || mainWindow->menuWidget()->isHidden())
1771 return isChildOfQMdiSubWindow(q);
1775#if QT_CONFIG(menubar)
1778
1779
1780void QMdiSubWindowPrivate::showButtonsInMenuBar(QMenuBar *menuBar)
1783 Q_ASSERT(q->isMaximized() && !drawTitleBarWhenMaximized());
1785 if (isChildOfTabbedQMdiArea(q))
1788 removeButtonsFromMenuBar();
1789 if (!controlContainer)
1790 controlContainer =
new ControlContainer(q);
1792 ignoreWindowTitleChange =
true;
1793 controlContainer->showButtonsInMenuBar(menuBar);
1794 ignoreWindowTitleChange =
false;
1796 QWidget *topLevelWindow = q->window();
1797 topLevelWindow->setWindowModified(q->isWindowModified());
1798 topLevelWindow->installEventFilter(q);
1800 int buttonHeight = 0;
1801 if (controlContainer->controllerWidget())
1802 buttonHeight = controlContainer->controllerWidget()->height();
1803 else if (controlContainer->systemMenuLabel())
1804 buttonHeight = controlContainer->systemMenuLabel()->height();
1807 if (menuBar && menuBar->height() < buttonHeight
1808 && topLevelWindow->layout()) {
1811 QEvent event(QEvent::LayoutRequest);
1812 QCoreApplication::sendEvent(topLevelWindow, &event);
1817
1818
1819void QMdiSubWindowPrivate::removeButtonsFromMenuBar()
1823 if (!controlContainer || isChildOfTabbedQMdiArea(q))
1826 QMenuBar *currentMenuBar =
nullptr;
1827#if QT_CONFIG(mainwindow)
1828 if (QMainWindow *mainWindow = qobject_cast<QMainWindow *>(q->window())) {
1831 currentMenuBar = qobject_cast<QMenuBar *>(mainWindow->menuWidget());
1835 ignoreWindowTitleChange =
true;
1836 controlContainer->removeButtonsFromMenuBar(currentMenuBar);
1837 ignoreWindowTitleChange =
false;
1839 QWidget *topLevelWindow = q->window();
1840 topLevelWindow->removeEventFilter(q);
1841 if (baseWidget && !drawTitleBarWhenMaximized())
1842 topLevelWindow->setWindowModified(
false);
1843 originalTitle.clear();
1848void QMdiSubWindowPrivate::updateWindowTitle(
bool isRequestFromChild)
1851 if (isRequestFromChild && !q->windowTitle().isEmpty() && !lastChildWindowTitle.isEmpty()
1852 && lastChildWindowTitle != q->windowTitle()) {
1856 QWidget *titleWidget =
nullptr;
1857 if (isRequestFromChild)
1858 titleWidget = baseWidget;
1861 if (!titleWidget || titleWidget->windowTitle().isEmpty())
1864 ignoreWindowTitleChange =
true;
1865 q->setWindowTitle(titleWidget->windowTitle());
1866 if (q->maximizedButtonsWidget())
1867 setNewWindowTitle();
1868 ignoreWindowTitleChange =
false;
1871#if QT_CONFIG(rubberband)
1872void QMdiSubWindowPrivate::enterRubberBandMode()
1875 if (q->isMaximized())
1877 Q_ASSERT(oldGeometry.isValid());
1880 rubberBand =
new QRubberBand(QRubberBand::Rectangle, q->parentWidget());
1882 rubberBand->setObjectName(
"qt_rubberband"_L1);
1884 QPoint rubberBandPos = q->mapToParent(QPoint(0, 0));
1885 rubberBand->setGeometry(rubberBandPos.x(), rubberBandPos.y(),
1886 oldGeometry.width(), oldGeometry.height());
1888 isInRubberBandMode =
true;
1892void QMdiSubWindowPrivate::leaveRubberBandMode()
1895 Q_ASSERT(rubberBand);
1896 Q_ASSERT(isInRubberBandMode);
1898 isInRubberBandMode =
false;
1899 q->setGeometry(rubberBand->geometry());
1901 currentOperation = None;
1906QPalette QMdiSubWindowPrivate::desktopPalette()
const
1908 Q_Q(
const QMdiSubWindow);
1909 QPalette newPalette = q->palette();
1911 newPalette.setColor(QPalette::Active, QPalette::Highlight,
1912 newPalette.color(QPalette::Active, QPalette::Highlight));
1913 newPalette.setColor(QPalette::Active, QPalette::Base,
1914 newPalette.color(QPalette::Active, QPalette::Highlight));
1915 newPalette.setColor(QPalette::Inactive, QPalette::Highlight,
1916 newPalette.color(QPalette::Inactive, QPalette::Dark));
1917 newPalette.setColor(QPalette::Inactive, QPalette::Base,
1918 newPalette.color(QPalette::Inactive, QPalette::Dark));
1919 newPalette.setColor(QPalette::Inactive, QPalette::HighlightedText,
1920 newPalette.color(QPalette::Inactive, QPalette::Window));
1925void QMdiSubWindowPrivate::updateActions()
1927 Qt::WindowFlags windowFlags = q_func()->windowFlags();
1929 for (
int i = 0; i < NumWindowStateActions; ++i)
1930 setVisible(WindowStateAction(i),
false);
1932#if defined(Q_OS_MACOS) && QT_CONFIG(action)
1933 if (q_func()->style()->inherits(
"QMacStyle"))
1934 for (
int i = 0; i < NumWindowStateActions; ++i)
1935 if (QAction *action = actions[i])
1936 action->setIconVisibleInMenu(
false);
1939 if (windowFlags & Qt::FramelessWindowHint)
1942 setVisible(StayOnTopAction,
true);
1943 setVisible(MoveAction, moveEnabled);
1944 setVisible(ResizeAction, resizeEnabled);
1947 if (windowFlags & Qt::WindowSystemMenuHint)
1948 setVisible(CloseAction,
true);
1951 if (windowFlags & (Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint))
1952 setVisible(RestoreAction,
true);
1955 if (windowFlags & Qt::WindowMinimizeButtonHint)
1956 setVisible(MinimizeAction,
true);
1959 if (windowFlags & Qt::WindowMaximizeButtonHint)
1960 setVisible(MaximizeAction,
true);
1963void QMdiSubWindowPrivate::setFocusWidget()
1974 if (focusInReason == Qt::TabFocusReason) {
1975 q->focusNextChild();
1980 if (focusInReason == Qt::BacktabFocusReason) {
1981 q->focusPreviousChild();
1985 if (!(q->windowState() & Qt::WindowMinimized) && restoreFocus())
1988 if (QWidget *focusWidget = baseWidget->focusWidget()) {
1989 if (!focusWidget->hasFocus() && q->isAncestorOf(focusWidget)
1990 && focusWidget->isVisible() && !q->isMinimized()
1991 && focusWidget->focusPolicy() != Qt::NoFocus) {
1992 focusWidget->setFocus();
1999 QWidget *focusWidget = q->nextInFocusChain();
2000 while (focusWidget && focusWidget != q && focusWidget->focusPolicy() == Qt::NoFocus)
2001 focusWidget = focusWidget->nextInFocusChain();
2002 if (focusWidget && q->isAncestorOf(focusWidget))
2003 focusWidget->setFocus();
2004 else if (baseWidget->focusPolicy() != Qt::NoFocus)
2005 baseWidget->setFocus();
2006 else if (!q->hasFocus())
2010bool QMdiSubWindowPrivate::restoreFocus()
2012 if (restoreFocusWidget.isNull())
2014 QWidget *candidate = restoreFocusWidget;
2015 restoreFocusWidget.clear();
2016 if (!candidate->hasFocus() && q_func()->isAncestorOf(candidate)
2017 && candidate->isVisible()
2018 && candidate->focusPolicy() != Qt::NoFocus) {
2019 candidate->setFocus();
2022 return candidate->hasFocus();
2026
2027
2028void QMdiSubWindowPrivate::setWindowFlags(Qt::WindowFlags windowFlags)
2033 QWidgetPrivate::setWindowFlags(windowFlags);
2037 Qt::WindowFlags windowType = windowFlags & Qt::WindowType_Mask;
2038 if (windowType == Qt::Dialog || windowFlags & Qt::MSWindowsFixedSizeDialogHint)
2039 windowFlags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint;
2042 if (!(windowFlags & CustomizeWindowFlags))
2043 windowFlags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint;
2044 else if (windowFlags & Qt::FramelessWindowHint && windowFlags & Qt::WindowStaysOnTopHint)
2045 windowFlags = Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint;
2046 else if (windowFlags & Qt::FramelessWindowHint)
2047 windowFlags = Qt::FramelessWindowHint;
2049 windowFlags &= ~windowType;
2050 windowFlags &= ~Qt::WindowFullscreenButtonHint;
2051 windowFlags |= Qt::SubWindow;
2054 if (QAction *stayOnTopAction = actions[QMdiSubWindowPrivate::StayOnTopAction]) {
2055 if (windowFlags & Qt::WindowStaysOnTopHint)
2056 stayOnTopAction->setChecked(
true);
2058 stayOnTopAction->setChecked(
false);
2062#if QT_CONFIG(sizegrip)
2063 if ((windowFlags & Qt::FramelessWindowHint) && sizeGrip)
2067 QWidgetPrivate::setWindowFlags(windowFlags);
2068 updateGeometryConstraints();
2070 QSize currentSize = q->size();
2071 if (q->isVisible() && (currentSize.width() < internalMinimumSize.width()
2072 || currentSize.height() < internalMinimumSize.height())) {
2073 q->resize(currentSize.expandedTo(internalMinimumSize));
2077void QMdiSubWindowPrivate::setVisible(WindowStateAction action,
bool visible)
2080 if (actions[action])
2081 actions[action]->setVisible(visible);
2085 if (!controlContainer)
2086 controlContainer =
new ControlContainer(q);
2088 if (ControllerWidget *ctrlWidget = qobject_cast<ControllerWidget *>
2089 (controlContainer->controllerWidget())) {
2090 ctrlWidget->setControlVisible(action, visible);
2096void QMdiSubWindowPrivate::setEnabled(WindowStateAction action,
bool enable)
2098 if (actions[action])
2099 actions[action]->setEnabled(enable);
2103void QMdiSubWindowPrivate::addToSystemMenu(WindowStateAction action,
const QString &text,
2108 actions[action] = systemMenu->addAction(text, q_func(), slot);
2114
2115
2116QSize QMdiSubWindowPrivate::iconSize()
const
2118 Q_Q(
const QMdiSubWindow);
2119 if (!parent || q->windowFlags() & Qt::FramelessWindowHint)
2120 return QSize(-1, -1);
2121 return QSize(q->style()->pixelMetric(QStyle::PM_MdiSubWindowMinimizedWidth,
nullptr, q), titleBarHeight());
2124#if QT_CONFIG(sizegrip)
2127
2128
2129void QMdiSubWindowPrivate::setSizeGrip(QSizeGrip *newSizeGrip)
2132 if (!newSizeGrip || sizeGrip || q->windowFlags() & Qt::FramelessWindowHint)
2135 if (layout && layout->indexOf(newSizeGrip) != -1)
2137 newSizeGrip->setFixedSize(newSizeGrip->sizeHint());
2138 bool putSizeGripInLayout = layout ?
true :
false;
2139 if (isMacStyle(q->style()))
2140 putSizeGripInLayout =
false;
2141 if (putSizeGripInLayout) {
2142 layout->addWidget(newSizeGrip);
2143 layout->setAlignment(newSizeGrip, Qt::AlignBottom | Qt::AlignRight);
2145 newSizeGrip->setParent(q);
2146 newSizeGrip->move(q->isLeftToRight() ? q->width() - newSizeGrip->width() : 0,
2147 q->height() - newSizeGrip->height());
2148 sizeGrip = newSizeGrip;
2150 newSizeGrip->raise();
2151 updateGeometryConstraints();
2152 newSizeGrip->installEventFilter(q);
2156
2157
2158void QMdiSubWindowPrivate::setSizeGripVisible(
bool visible)
const
2161 const QList<QSizeGrip *> sizeGrips = q_func()->findChildren<QSizeGrip *>();
2162 for (QSizeGrip *grip : sizeGrips)
2163 grip->setVisible(visible);
2169
2170
2171void QMdiSubWindowPrivate::updateInternalWindowTitle()
2174 if (q->isWindowModified()) {
2175 windowTitle = q->windowTitle();
2176 windowTitle.replace(
"[*]"_L1,
"*"_L1);
2178 windowTitle = qt_setWindowTitle_helperHelper(q->windowTitle(), q);
2180 q->update(0, 0, q->width(), titleBarHeight());
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201QMdiSubWindow::QMdiSubWindow(QWidget *parent, Qt::WindowFlags flags)
2202 : QWidget(*
new QMdiSubWindowPrivate, parent, { })
2206 d->createSystemMenu();
2207 addActions(d->systemMenu->actions());
2209 d->setWindowFlags(flags);
2210 setBackgroundRole(QPalette::Window);
2211 setAutoFillBackground(
true);
2212 setMouseTracking(
true);
2213 setLayout(
new QVBoxLayout);
2214 setFocusPolicy(Qt::StrongFocus);
2215 layout()->setContentsMargins(QMargins());
2216 d->updateGeometryConstraints();
2217 setAttribute(Qt::WA_Resized,
false);
2218 d->titleBarPalette = d->desktopPalette();
2219 d->font = QApplication::font(
"QMdiSubWindowTitleBar");
2222 if (windowIcon().isNull())
2223 d->menuIcon = style()->standardIcon(QStyle::SP_TitleBarMenuButton,
nullptr,
this);
2225 d->menuIcon = windowIcon();
2227 connect(qApp, SIGNAL(focusChanged(QWidget*,QWidget*)),
2228 this, SLOT(_q_processFocusChanged(QWidget*,QWidget*)));
2232
2233
2234
2235
2236QMdiSubWindow::~QMdiSubWindow()
2239#if QT_CONFIG(menubar)
2240 d->removeButtonsFromMenuBar();
2242 d->setActive(
false);
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256void QMdiSubWindow::setWidget(QWidget *widget)
2260 d->removeBaseWidget();
2264 if (Q_UNLIKELY(widget == d->baseWidget)) {
2265 qWarning(
"QMdiSubWindow::setWidget: widget is already set");
2269 bool wasResized = testAttribute(Qt::WA_Resized);
2270 d->removeBaseWidget();
2272 if (QLayout *layout =
this->layout())
2273 layout->addWidget(widget);
2275 widget->setParent(
this);
2277#if QT_CONFIG(sizegrip)
2278 QSizeGrip *sizeGrip = widget->findChild<QSizeGrip *>();
2280 sizeGrip->installEventFilter(
this);
2282 d->sizeGrip->raise();
2285 d->baseWidget = widget;
2286 d->baseWidget->installEventFilter(
this);
2288 d->ignoreWindowTitleChange =
true;
2289 bool isWindowModified =
this->isWindowModified();
2290 if (windowTitle().isEmpty()) {
2291 d->updateWindowTitle(
true);
2292 isWindowModified = d->baseWidget->isWindowModified();
2294 if (!
this->isWindowModified() && isWindowModified && windowTitle().contains(
"[*]"_L1))
2295 setWindowModified(isWindowModified);
2296 d->lastChildWindowTitle = d->baseWidget->windowTitle();
2297 d->ignoreWindowTitleChange =
false;
2299 if (windowIcon().isNull() && !d->baseWidget->windowIcon().isNull())
2300 setWindowIcon(d->baseWidget->windowIcon());
2302 d->updateGeometryConstraints();
2303 if (!wasResized && testAttribute(Qt::WA_Resized))
2304 setAttribute(Qt::WA_Resized,
false);
2308
2309
2310
2311
2312QWidget *QMdiSubWindow::widget()
const
2314 return d_func()->baseWidget;
2319
2320
2321QWidget *QMdiSubWindow::maximizedButtonsWidget()
const
2323 Q_D(
const QMdiSubWindow);
2324 if (isVisible() && d->controlContainer && isMaximized() && !d->drawTitleBarWhenMaximized()
2325 && !isChildOfTabbedQMdiArea(
this)) {
2326 return d->controlContainer->controllerWidget();
2332
2333
2334QWidget *QMdiSubWindow::maximizedSystemMenuIconWidget()
const
2336 Q_D(
const QMdiSubWindow);
2337 if (isVisible() && d->controlContainer && isMaximized() && !d->drawTitleBarWhenMaximized()
2338 && !isChildOfTabbedQMdiArea(
this)) {
2339 return d->controlContainer->systemMenuLabel();
2345
2346
2347
2348
2349
2350bool QMdiSubWindow::isShaded()
const
2352 return d_func()->isShadeMode;
2356
2357
2358
2359
2360
2361void QMdiSubWindow::setOption(SubWindowOption option,
bool on)
2364 d->options.setFlag(option, on);
2366#if QT_CONFIG(rubberband)
2367 if ((option & (RubberBandResize | RubberBandMove)) && !on && d->isInRubberBandMode)
2368 d->leaveRubberBandMode();
2373
2374
2375
2376
2377bool QMdiSubWindow::testOption(SubWindowOption option)
const
2379 return d_func()->options & option;
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396int QMdiSubWindow::keyboardSingleStep()
const
2398 return d_func()->keyboardSingleStep;
2401void QMdiSubWindow::setKeyboardSingleStep(
int step)
2406 d_func()->keyboardSingleStep = step;
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423int QMdiSubWindow::keyboardPageStep()
const
2425 return d_func()->keyboardPageStep;
2428void QMdiSubWindow::setKeyboardPageStep(
int step)
2433 d_func()->keyboardPageStep = step;
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454void QMdiSubWindow::setSystemMenu(QMenu *systemMenu)
2457 if (Q_UNLIKELY(systemMenu && systemMenu == d->systemMenu)) {
2458 qWarning(
"QMdiSubWindow::setSystemMenu: system menu is already set");
2462 if (d->systemMenu) {
2463 delete d->systemMenu;
2464 d->systemMenu =
nullptr;
2470 if (systemMenu->parent() !=
this)
2471 systemMenu->setParent(
this);
2472 d->systemMenu = systemMenu;
2476
2477
2478
2479
2480
2481
2482QMenu *QMdiSubWindow::systemMenu()
const
2484 return d_func()->systemMenu;
2488
2489
2490
2491
2492void QMdiSubWindow::showSystemMenu()
2498 QPoint globalPopupPos;
2499 if (QWidget *icon = maximizedSystemMenuIconWidget()) {
2500 if (isLeftToRight())
2501 globalPopupPos = icon->mapToGlobal(QPoint(0, icon->y() + icon->height()));
2503 globalPopupPos = icon->mapToGlobal(QPoint(icon->width(), icon->y() + icon->height()));
2505 if (isLeftToRight())
2506 globalPopupPos = mapToGlobal(contentsRect().topLeft());
2508 globalPopupPos = mapToGlobal(contentsRect().topRight()) + QPoint(1, 0);
2512 if (isRightToLeft())
2513 globalPopupPos -= QPoint(d->systemMenu->sizeHint().width(), 0);
2514 d->systemMenu->popup(globalPopupPos);
2519
2520
2521
2522
2523
2524
2525
2526QMdiArea *QMdiSubWindow::mdiArea()
const
2528 QWidget *parent = parentWidget();
2530 if (QMdiArea *area = qobject_cast<QMdiArea *>(parent)) {
2531 if (area->viewport() == parentWidget())
2534 parent = parent->parentWidget();
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552void QMdiSubWindow::showShaded()
2559 if (!d->isShadeRequestFromMinimizeMode && isShaded())
2562 d->isMaximizeMode =
false;
2564 d->storeFocusWidget();
2566 if (!d->isShadeRequestFromMinimizeMode) {
2567 d->isShadeMode =
true;
2568 d->ensureWindowState(Qt::WindowMinimized);
2571#if QT_CONFIG(menubar)
2572 d->removeButtonsFromMenuBar();
2578 if (hasFocus() || isAncestorOf(QApplication::focusWidget()))
2579 d->ensureWindowState(Qt::WindowActive);
2581#if QT_CONFIG(sizegrip)
2582 d->setSizeGripVisible(
false);
2585 if (!d->restoreSize.isValid() || d->isShadeMode) {
2586 d->oldGeometry = geometry();
2587 d->restoreSize.setWidth(d->oldGeometry.width());
2588 d->restoreSize.setHeight(d->oldGeometry.height());
2593 const bool wasVisible = isVisible();
2597 d->updateGeometryConstraints();
2599 if (!minimumSize().isNull()) {
2600 d->userMinimumSize = minimumSize();
2601 setMinimumSize(d->internalMinimumSize);
2603 resize(d->internalMinimumSize);
2606 if (d->baseWidget && !d->baseWidget->isHidden() && !(windowFlags() & Qt::FramelessWindowHint)) {
2607 d->baseWidget->hide();
2608 d->isWidgetHiddenByUs =
true;
2614 d->setFocusWidget();
2615 d->resizeEnabled =
false;
2616 d->moveEnabled =
true;
2617 d->updateDirtyRegions();
2621 d->setEnabled(QMdiSubWindowPrivate::MinimizeAction,
false);
2622 d->setEnabled(QMdiSubWindowPrivate::ResizeAction, d->resizeEnabled);
2623 d->setEnabled(QMdiSubWindowPrivate::MaximizeAction,
true);
2624 d->setEnabled(QMdiSubWindowPrivate::RestoreAction,
true);
2625 d->setEnabled(QMdiSubWindowPrivate::MoveAction, d->moveEnabled);
2630
2631
2632bool QMdiSubWindow::eventFilter(QObject *object, QEvent *event)
2636 return QWidget::eventFilter(object, event);
2640 if (d->systemMenu && d->systemMenu == object) {
2641 if (event->type() == QEvent::MouseButtonDblClick) {
2642 const QMouseEvent *mouseEvent =
static_cast<
const QMouseEvent *>(event);
2643 const QAction *action = d->systemMenu->actionAt(mouseEvent->position().toPoint());
2644 if (!action || action->isEnabled())
2646 }
else if (event->type() == QEvent::MouseMove) {
2647 QMouseEvent *mouseEvent =
static_cast<QMouseEvent *>(event);
2648 d->hoveredSubControl = d->getSubControl(mapFromGlobal(mouseEvent->globalPosition().toPoint()));
2649 }
else if (event->type() == QEvent::Hide) {
2650 d->activeSubControl = QStyle::SC_None;
2651 update(QRegion(0, 0, width(), d->titleBarHeight()));
2653 return QWidget::eventFilter(object, event);
2657#if QT_CONFIG(sizegrip)
2658 if (object != d->baseWidget && parent() && qobject_cast<QSizeGrip *>(object)) {
2659 if (event->type() != QEvent::MouseButtonPress || !testOption(QMdiSubWindow::RubberBandResize))
2660 return QWidget::eventFilter(object, event);
2661 const QMouseEvent *mouseEvent =
static_cast<QMouseEvent *>(event);
2662 d->mousePressPosition = parentWidget()->mapFromGlobal(mouseEvent->globalPosition().toPoint());
2663 d->oldGeometry = geometry();
2664 d->currentOperation = isLeftToRight() ? QMdiSubWindowPrivate::BottomRightResize
2665 : QMdiSubWindowPrivate::BottomLeftResize;
2666#if QT_CONFIG(rubberband)
2667 d->enterRubberBandMode();
2673 if (object != d->baseWidget && event->type() != QEvent::WindowTitleChange)
2674 return QWidget::eventFilter(object, event);
2676 switch (event->type()) {
2680 case QEvent::ShowToParent:
2681 if (!d->isWidgetHiddenByUs)
2684 case QEvent::WindowStateChange: {
2685 QWindowStateChangeEvent *changeEvent =
static_cast<QWindowStateChangeEvent*>(event);
2686 if (changeEvent->isOverride())
2688 Qt::WindowStates oldState = changeEvent->oldState();
2689 Qt::WindowStates newState = d->baseWidget->windowState();
2690 if (!(oldState & Qt::WindowMinimized) && (newState & Qt::WindowMinimized))
2692 else if (!(oldState & Qt::WindowMaximized) && (newState & Qt::WindowMaximized))
2694 else if (!(newState & (Qt::WindowMaximized | Qt::WindowMinimized | Qt::WindowFullScreen)))
2699 d->currentOperation = QMdiSubWindowPrivate::None;
2702 case QEvent::LayoutRequest:
2703 d->updateGeometryConstraints();
2705 case QEvent::WindowTitleChange:
2706 if (d->ignoreWindowTitleChange)
2708 if (object == d->baseWidget) {
2709 d->updateWindowTitle(
true);
2710 d->lastChildWindowTitle = d->baseWidget->windowTitle();
2711#if QT_CONFIG(menubar)
2712 }
else if (maximizedButtonsWidget() && d->controlContainer->menuBar() && d->controlContainer->menuBar()
2713 ->cornerWidget(Qt::TopRightCorner) == maximizedButtonsWidget()) {
2714 d->originalTitle.clear();
2715 if (d->baseWidget && d->baseWidget->windowTitle() == windowTitle())
2716 d->updateWindowTitle(
true);
2718 d->updateWindowTitle(
false);
2722 case QEvent::ModifiedChange: {
2723 if (object != d->baseWidget)
2725 bool windowModified = d->baseWidget->isWindowModified();
2726 if (!windowModified && d->baseWidget->windowTitle() != windowTitle())
2728 if (windowTitle().contains(
"[*]"_L1))
2729 setWindowModified(windowModified);
2735 return QWidget::eventFilter(object, event);
2739
2740
2741bool QMdiSubWindow::event(QEvent *event)
2744 switch (event->type()) {
2745 case QEvent::StyleChange: {
2746 bool wasShaded = isShaded();
2747 bool wasMinimized = isMinimized();
2748 bool wasMaximized = isMaximized();
2750 const QScopedValueRollback<
bool> activationEnabledSaver(d->activationEnabled);
2751 d->activationEnabled =
false;
2754 setContentsMargins(0, 0, 0, 0);
2755 if (wasMinimized || wasMaximized || wasShaded)
2757 d->updateGeometryConstraints();
2758 resize(d->internalMinimumSize.expandedTo(size()));
2760 d->updateDirtyRegions();
2763 else if (wasMinimized)
2765 else if (wasMaximized)
2769 case QEvent::ParentAboutToChange:
2770 d->setActive(
false);
2772 case QEvent::ParentChange: {
2773 bool wasResized = testAttribute(Qt::WA_Resized);
2774#if QT_CONFIG(menubar)
2775 d->removeButtonsFromMenuBar();
2777 d->currentOperation = QMdiSubWindowPrivate::None;
2778 d->activeSubControl = QStyle::SC_None;
2779 d->hoveredSubControl = QStyle::SC_None;
2780#if QT_CONFIG(rubberband)
2781 if (d->isInRubberBandMode)
2782 d->leaveRubberBandMode();
2784 d->isShadeMode =
false;
2785 d->isMaximizeMode =
false;
2786 d->isWidgetHiddenByUs =
false;
2788#if QT_CONFIG(sizegrip)
2789 if (isMacStyle(style()))
2792 setOption(RubberBandResize,
false);
2793 setOption(RubberBandMove,
false);
2795 d->setWindowFlags(windowFlags());
2797 setContentsMargins(0, 0, 0, 0);
2798 d->updateGeometryConstraints();
2801 d->updateDirtyRegions();
2803 if (!wasResized && testAttribute(Qt::WA_Resized))
2804 setAttribute(Qt::WA_Resized,
false);
2807 case QEvent::WindowActivate:
2808 if (d->ignoreNextActivationEvent) {
2809 d->ignoreNextActivationEvent =
false;
2812 d->isExplicitlyDeactivated =
false;
2815 case QEvent::WindowDeactivate:
2816 if (d->ignoreNextActivationEvent) {
2817 d->ignoreNextActivationEvent =
false;
2820 d->isExplicitlyDeactivated =
true;
2821 d->setActive(
false);
2823 case QEvent::WindowTitleChange:
2824 if (!d->ignoreWindowTitleChange)
2825 d->updateWindowTitle(
false);
2826 d->updateInternalWindowTitle();
2828 case QEvent::ModifiedChange:
2829 if (!windowTitle().contains(
"[*]"_L1))
2831#if QT_CONFIG(menubar)
2832 if (maximizedButtonsWidget() && d->controlContainer->menuBar() && d->controlContainer->menuBar()
2833 ->cornerWidget(Qt::TopRightCorner) == maximizedButtonsWidget()) {
2834 window()->setWindowModified(isWindowModified());
2837 d->updateInternalWindowTitle();
2839 case QEvent::LayoutDirectionChange:
2840 d->updateDirtyRegions();
2842 case QEvent::LayoutRequest:
2843 d->updateGeometryConstraints();
2845 case QEvent::WindowIconChange:
2846 d->menuIcon = windowIcon();
2847 if (d->menuIcon.isNull())
2848 d->menuIcon = style()->standardIcon(QStyle::SP_TitleBarMenuButton,
nullptr,
this);
2849 if (d->controlContainer)
2850 d->controlContainer->updateWindowIcon(d->menuIcon);
2851 if (!maximizedSystemMenuIconWidget())
2852 update(0, 0, width(), d->titleBarHeight());
2854 case QEvent::PaletteChange:
2855 d->titleBarPalette = d->desktopPalette();
2857 case QEvent::FontChange:
2860#if QT_CONFIG(tooltip)
2861 case QEvent::ToolTip:
2862 showToolTip(
static_cast<QHelpEvent *>(event),
this, d->titleBarOptions(),
2863 QStyle::CC_TitleBar, d->hoveredSubControl);
2867 case QEvent::ActionAdded:
2868 case QEvent::ActionChanged:
2869 case QEvent::ActionRemoved:
2876 return QWidget::event(event);
2880
2881
2882void QMdiSubWindow::showEvent(QShowEvent *showEvent)
2886 QWidget::showEvent(showEvent);
2890#if QT_CONFIG(sizegrip)
2891 if (isMacStyle(style()) && !d->sizeGrip
2892 && !(windowFlags() & Qt::FramelessWindowHint)) {
2893 d->setSizeGrip(
new QSizeGrip(
this));
2894 Q_ASSERT(d->sizeGrip);
2896 d->setSizeGripVisible(
false);
2898 d->setSizeGripVisible(
true);
2899 resize(size().expandedTo(d->internalMinimumSize));
2903 d->updateDirtyRegions();
2906#if QT_CONFIG(menubar)
2907 if (d->controlContainer) {
2908 if (QMenuBar *menuBar = d->menuBar()) {
2909 if (menuBar->cornerWidget(Qt::TopRightCorner) != maximizedButtonsWidget())
2910 d->showButtonsInMenuBar(menuBar);
2918
2919
2920void QMdiSubWindow::hideEvent(QHideEvent * )
2922#if QT_CONFIG(menubar)
2923 d_func()->removeButtonsFromMenuBar();
2928
2929
2930void QMdiSubWindow::changeEvent(QEvent *changeEvent)
2933 QWidget::changeEvent(changeEvent);
2937 if (changeEvent->type() != QEvent::WindowStateChange) {
2938 QWidget::changeEvent(changeEvent);
2942 QWindowStateChangeEvent *event =
static_cast<QWindowStateChangeEvent *>(changeEvent);
2943 if (event->isOverride()) {
2948 Qt::WindowStates oldState = event->oldState();
2949 Qt::WindowStates newState = windowState();
2950 if (oldState == newState) {
2951 changeEvent->ignore();
2960 d->ensureWindowState(Qt::WindowNoState);
2964 if (!d->oldGeometry.isValid())
2965 d->oldGeometry = geometry();
2967 if ((oldState & Qt::WindowActive) && (newState & Qt::WindowActive))
2968 d->currentOperation = QMdiSubWindowPrivate::None;
2970 if (!(oldState & Qt::WindowMinimized) && (newState & Qt::WindowMinimized))
2971 d->setMinimizeMode();
2972 else if (!(oldState & Qt::WindowMaximized) && (newState & Qt::WindowMaximized))
2973 d->setMaximizeMode();
2974 else if (!(newState & (Qt::WindowMaximized | Qt::WindowMinimized | Qt::WindowFullScreen)))
2978 d->ensureWindowState(Qt::WindowActive);
2979 if (d->activationEnabled)
2980 emit windowStateChanged(oldState, windowState());
2984
2985
2986void QMdiSubWindow::closeEvent(QCloseEvent *closeEvent)
2989 bool acceptClose =
true;
2991 acceptClose = d->baseWidget->close();
2993 closeEvent->ignore();
2996#if QT_CONFIG(menubar)
2997 d->removeButtonsFromMenuBar();
2999 d->setActive(
false);
3000 if (parentWidget() && testAttribute(Qt::WA_DeleteOnClose)) {
3001 QChildEvent childRemoved(QEvent::ChildRemoved,
this);
3002 QCoreApplication::sendEvent(parentWidget(), &childRemoved);
3004 closeEvent->accept();
3008
3009
3010void QMdiSubWindow::leaveEvent(QEvent * )
3013 if (d->hoveredSubControl != QStyle::SC_None) {
3014 d->hoveredSubControl = QStyle::SC_None;
3015 update(QRegion(0, 0, width(), d->titleBarHeight()));
3020
3021
3022
3023
3024
3025void QMdiSubWindow::resizeEvent(QResizeEvent *resizeEvent)
3028#if QT_CONFIG(sizegrip)
3030 d->sizeGrip->move(isLeftToRight() ? width() - d->sizeGrip->width() : 0,
3031 height() - d->sizeGrip->height());
3036 QWidget::resizeEvent(resizeEvent);
3040 if (d->isMaximizeMode)
3041 d->ensureWindowState(Qt::WindowMaximized);
3047 if (!d->resizeTimer.isActive())
3048 d->cachedStyleOptions = d->titleBarOptions();
3049 d->resizeTimer.start(200ms,
this);
3053
3054
3055void QMdiSubWindow::timerEvent(QTimerEvent *timerEvent)
3058 if (timerEvent->id() == d->resizeTimer.id()) {
3059 d->resizeTimer.stop();
3060 d->updateDirtyRegions();
3065
3066
3067void QMdiSubWindow::moveEvent(QMoveEvent *moveEvent)
3070 QWidget::moveEvent(moveEvent);
3075 if (d->isMaximizeMode)
3076 d->ensureWindowState(Qt::WindowMaximized);
3080
3081
3082void QMdiSubWindow::paintEvent(QPaintEvent *paintEvent)
3084 if (!parent() || (windowFlags() & Qt::FramelessWindowHint)) {
3085 QWidget::paintEvent(paintEvent);
3091 if (d->resizeTimer.isActive()) {
3093 int border = d->hasBorder(d->cachedStyleOptions) ? 4 : 0;
3094 int titleBarHeight = d->titleBarHeight(d->cachedStyleOptions);
3095 titleBarHeight -= isMinimized() ? 2 * border : border;
3096 d->cachedStyleOptions.rect = QRect(border, border, width() - 2 * border, titleBarHeight);
3097 if (!d->windowTitle.isEmpty()) {
3098 int width = style()->subControlRect(QStyle::CC_TitleBar, &d->cachedStyleOptions,
3099 QStyle::SC_TitleBarLabel,
this).width();
3100 d->cachedStyleOptions.text = d->cachedStyleOptions.fontMetrics
3101 .elidedText(d->windowTitle, Qt::ElideRight, width);
3105 d->cachedStyleOptions = d->titleBarOptions();
3108 QStylePainter painter(
this);
3109 QStyleOptionFrame frameOptions;
3110 frameOptions.initFrom(
this);
3111 frameOptions.state.setFlag(QStyle::State_Active, d->isActive);
3112 if (isMaximized() && !d->drawTitleBarWhenMaximized()) {
3113 if (!autoFillBackground() && (!widget() || !qt_widget_private(widget())->isOpaque)) {
3115 painter.drawPrimitive(QStyle::PE_FrameWindow, frameOptions);
3120 if (!d->windowTitle.isEmpty())
3121 painter.setFont(d->font);
3122 painter.drawComplexControl(QStyle::CC_TitleBar, d->cachedStyleOptions);
3124 if (isMinimized() && !d->hasBorder(d->cachedStyleOptions))
3127 frameOptions.lineWidth = style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth,
nullptr,
this);
3130 if (!isMinimized() && !d->hasBorder(d->cachedStyleOptions))
3131 painter.setClipRect(rect().adjusted(0, d->titleBarHeight(d->cachedStyleOptions), 0, 0));
3132 if (!isMinimized() || d->hasBorder(d->cachedStyleOptions))
3133 painter.drawPrimitive(QStyle::PE_FrameWindow, frameOptions);
3137
3138
3139void QMdiSubWindow::mousePressEvent(QMouseEvent *mouseEvent)
3142 QWidget::mousePressEvent(mouseEvent);
3147 if (d->isInInteractiveMode)
3148 d->leaveInteractiveMode();
3149#if QT_CONFIG(rubberband)
3150 if (d->isInRubberBandMode)
3151 d->leaveRubberBandMode();
3154 if (mouseEvent->button() != Qt::LeftButton) {
3155 mouseEvent->ignore();
3159 if (d->currentOperation != QMdiSubWindowPrivate::None) {
3161 d->mousePressPosition = mapToParent(mouseEvent->position().toPoint());
3162 if (d->resizeEnabled || d->moveEnabled)
3163 d->oldGeometry = geometry();
3164#if QT_CONFIG(rubberband)
3165 if ((testOption(QMdiSubWindow::RubberBandResize) && d->isResizeOperation())
3166 || (testOption(QMdiSubWindow::RubberBandMove) && d->isMoveOperation())) {
3167 d->enterRubberBandMode();
3173 d->activeSubControl = d->hoveredSubControl;
3175 if (d->activeSubControl == QStyle::SC_TitleBarSysMenu)
3179 update(QRegion(0, 0, width(), d->titleBarHeight()));
3183
3184
3185void QMdiSubWindow::mouseDoubleClickEvent(QMouseEvent *mouseEvent)
3188 QWidget::mouseDoubleClickEvent(mouseEvent);
3192 if (mouseEvent->button() != Qt::LeftButton) {
3193 mouseEvent->ignore();
3198 if (!d->isMoveOperation()) {
3200 if (d->hoveredSubControl == QStyle::SC_TitleBarSysMenu)
3206 Qt::WindowFlags flags = windowFlags();
3207 if (isMinimized()) {
3208 if ((isShaded() && (flags & Qt::WindowShadeButtonHint))
3209 || (flags & Qt::WindowMinimizeButtonHint)) {
3215 if (isMaximized()) {
3216 if (flags & Qt::WindowMaximizeButtonHint)
3221 if (flags & Qt::WindowShadeButtonHint)
3223 else if (flags & Qt::WindowMaximizeButtonHint)
3228
3229
3230void QMdiSubWindow::mouseReleaseEvent(QMouseEvent *mouseEvent)
3233 QWidget::mouseReleaseEvent(mouseEvent);
3237 if (mouseEvent->button() != Qt::LeftButton) {
3238 mouseEvent->ignore();
3243 if (d->currentOperation != QMdiSubWindowPrivate::None) {
3244#if QT_CONFIG(rubberband)
3245 if (d->isInRubberBandMode && !d->isInInteractiveMode)
3246 d->leaveRubberBandMode();
3248 if (d->resizeEnabled || d->moveEnabled)
3249 d->oldGeometry = geometry();
3252 d->currentOperation = d->getOperation(mouseEvent->position().toPoint());
3255 d->hoveredSubControl = d->getSubControl(mouseEvent->position().toPoint());
3256 if (d->activeSubControl != QStyle::SC_None
3257 && d->activeSubControl == d->hoveredSubControl) {
3258 d->processClickedSubControl();
3260 d->activeSubControl = QStyle::SC_None;
3261 update(QRegion(0, 0, width(), d->titleBarHeight()));
3265
3266
3267void QMdiSubWindow::mouseMoveEvent(QMouseEvent *mouseEvent)
3270 QWidget::mouseMoveEvent(mouseEvent);
3276 if (!d->isMoveOperation() && !d->isResizeOperation()) {
3278 const QStyleOptionTitleBar options = d->titleBarOptions();
3279 QStyle::SubControl oldHover = d->hoveredSubControl;
3280 d->hoveredSubControl = d->getSubControl(mouseEvent->position().toPoint());
3281 QRegion hoverRegion;
3282 if (isHoverControl(oldHover) && oldHover != d->hoveredSubControl)
3283 hoverRegion += style()->subControlRect(QStyle::CC_TitleBar, &options, oldHover,
this);
3284 if (isHoverControl(d->hoveredSubControl) && d->hoveredSubControl != oldHover) {
3285 hoverRegion += style()->subControlRect(QStyle::CC_TitleBar, &options,
3286 d->hoveredSubControl,
this);
3289 if (isMacStyle(style()) && !hoverRegion.isEmpty())
3290 hoverRegion += QRegion(0, 0, width(), d->titleBarHeight(options));
3292 if (!hoverRegion.isEmpty())
3293 update(hoverRegion);
3296 if ((mouseEvent->buttons() & Qt::LeftButton) || d->isInInteractiveMode) {
3297 if ((d->isResizeOperation() && d->resizeEnabled) || (d->isMoveOperation() && d->moveEnabled)) {
3300 d->setNewGeometry(parentWidget()->mapFromGlobal(mouseEvent->globalPosition().toPoint()));
3306 d->currentOperation = d->getOperation(mouseEvent->position().toPoint());
3307 if ((d->isResizeOperation() && !d->resizeEnabled) || (d->isMoveOperation() && !d->moveEnabled))
3308 d->currentOperation = QMdiSubWindowPrivate::None;
3313
3314
3315void QMdiSubWindow::keyPressEvent(QKeyEvent *keyEvent)
3318 if (!d->isInInteractiveMode || !parent()) {
3324 switch (keyEvent->key()) {
3326 if (keyEvent->modifiers() & Qt::ShiftModifier)
3327 delta = QPoint(d->keyboardPageStep, 0);
3329 delta = QPoint(d->keyboardSingleStep, 0);
3332 if (keyEvent->modifiers() & Qt::ShiftModifier)
3333 delta = QPoint(0, -d->keyboardPageStep);
3335 delta = QPoint(0, -d->keyboardSingleStep);
3338 if (keyEvent->modifiers() & Qt::ShiftModifier)
3339 delta = QPoint(-d->keyboardPageStep, 0);
3341 delta = QPoint(-d->keyboardSingleStep, 0);
3344 if (keyEvent->modifiers() & Qt::ShiftModifier)
3345 delta = QPoint(0, d->keyboardPageStep);
3347 delta = QPoint(0, d->keyboardSingleStep);
3349 case Qt::Key_Escape:
3350 case Qt::Key_Return:
3352 d->leaveInteractiveMode();
3360 QPoint newPosition = parentWidget()->mapFromGlobal(cursor().pos() + delta);
3362#if QT_CONFIG(rubberband)
3363 d->isInRubberBandMode ? d->rubberBand->geometry() :
3366 d->setNewGeometry(newPosition);
3367 QRect currentGeometry =
3368#if QT_CONFIG(rubberband)
3369 d->isInRubberBandMode ? d->rubberBand->geometry() :
3372 if (currentGeometry == oldGeometry)
3378 if (d->isMoveOperation()) {
3379 actualDelta = QPoint(currentGeometry.x() - oldGeometry.x(),
3380 currentGeometry.y() - oldGeometry.y());
3382 int dx = isLeftToRight() ? currentGeometry.width() - oldGeometry.width()
3383 : currentGeometry.x() - oldGeometry.x();
3384 actualDelta = QPoint(dx, currentGeometry.height() - oldGeometry.height());
3388 if (actualDelta != delta)
3389 newPosition += (actualDelta - delta);
3390 cursor().setPos(parentWidget()->mapToGlobal(newPosition));
3394#ifndef QT_NO_CONTEXTMENU
3396
3397
3398void QMdiSubWindow::contextMenuEvent(QContextMenuEvent *contextMenuEvent)
3401 if (!d->systemMenu) {
3402 contextMenuEvent->ignore();
3406 if (d->hoveredSubControl == QStyle::SC_TitleBarSysMenu
3407 || d->getRegion(QMdiSubWindowPrivate::Move).contains(contextMenuEvent->pos())) {
3408 d->systemMenu->exec(contextMenuEvent->globalPos());
3410 contextMenuEvent->ignore();
3416
3417
3418void QMdiSubWindow::focusInEvent(QFocusEvent *focusInEvent)
3420 d_func()->focusInReason = focusInEvent->reason();
3424
3425
3426void QMdiSubWindow::focusOutEvent(QFocusEvent * )
3432
3433
3434void QMdiSubWindow::childEvent(QChildEvent *childEvent)
3436 if (childEvent->type() != QEvent::ChildPolished)
3438#if QT_CONFIG(sizegrip)
3439 if (QSizeGrip *sizeGrip = qobject_cast<QSizeGrip *>(childEvent->child()))
3440 d_func()->setSizeGrip(sizeGrip);
3445
3446
3447QSize QMdiSubWindow::sizeHint()
const
3449 Q_D(
const QMdiSubWindow);
3450 int margin, minWidth;
3451 d->sizeParameters(&margin, &minWidth);
3452 QSize size(2 * margin, d->titleBarHeight() + margin);
3453 if (d->baseWidget && d->baseWidget->sizeHint().isValid())
3454 size += d->baseWidget->sizeHint();
3455 return size.expandedTo(minimumSizeHint());
3459
3460
3461QSize QMdiSubWindow::minimumSizeHint()
const
3463 Q_D(
const QMdiSubWindow);
3468 if (parent() && isMinimized() && !isShaded())
3469 return d->iconSize();
3472 int margin, minWidth;
3473 d->sizeParameters(&margin, &minWidth);
3474 int decorationHeight = margin + d->titleBarHeight();
3475 int minHeight = decorationHeight;
3478 if (parent() && isShaded())
3479 return QSize(qMax(minWidth, width()), d->titleBarHeight());
3483 QSize minLayoutSize = layout()->minimumSize();
3484 if (minLayoutSize.isValid()) {
3485 minWidth = qMax(minWidth, minLayoutSize.width() + 2 * margin);
3486 minHeight += minLayoutSize.height();
3488 }
else if (d->baseWidget && d->baseWidget->isVisible()) {
3489 QSize minBaseWidgetSize = d->baseWidget->minimumSizeHint();
3490 if (minBaseWidgetSize.isValid()) {
3491 minWidth = qMax(minWidth, minBaseWidgetSize.width() + 2 * margin);
3492 minHeight += minBaseWidgetSize.height();
3496#if QT_CONFIG(sizegrip)
3498 int sizeGripHeight = 0;
3499 if (d->sizeGrip && d->sizeGrip->isVisibleTo(
const_cast<QMdiSubWindow *>(
this)))
3500 sizeGripHeight = d->sizeGrip->height();
3501 else if (parent() && isMacStyle(style()) && !d->sizeGrip)
3502 sizeGripHeight = style()->pixelMetric(QStyle::PM_SizeGripSize,
nullptr,
this);
3503 minHeight = qMax(minHeight, decorationHeight + sizeGripHeight);
3506 return QSize(minWidth, minHeight);
3511#include "moc_qmdisubwindow.cpp"
3512#include "qmdisubwindow.moc"
void updateWindowIcon(const QIcon &windowIcon)
ControlContainer(QMdiSubWindow *mdiChild)
QSize sizeHint() const override
bool event(QEvent *event) override
This virtual function receives events to an object and should return true if the event e was recogniz...
void mousePressEvent(QMouseEvent *mouseEvent) override
This event handler, for event event, can be reimplemented in a subclass to receive mouse press events...
void mouseReleaseEvent(QMouseEvent *mouseEvent) override
This event handler, for event event, can be reimplemented in a subclass to receive mouse release even...
void mouseDoubleClickEvent(QMouseEvent *mouseEvent) override
This event handler, for event event, can be reimplemented in a subclass to receive mouse double click...
void paintEvent(QPaintEvent *paintEvent) override
This event handler can be reimplemented in a subclass to receive paint events passed in event.
Combined button and popup list for selecting options.
static const int BoundaryMargin
static bool isChildOfQMdiSubWindow(const QWidget *child)
static const int NumSubControls
static const QStyle::SubControl SubControls[]
static int getMoveDeltaComponent(uint cflags, uint moveFlag, uint resizeFlag, int delta, int maxDelta, int minDelta)
static bool isHoverControl(QStyle::SubControl control)
static const Qt::WindowFlags CustomizeWindowFlags
static int getResizeDeltaComponent(uint cflags, uint resizeFlag, uint resizeReverseFlag, int delta)
static bool isMacStyle(QStyle *style)
QString qt_setWindowTitle_helperHelper(const QString &, const QWidget *)
Returns a modified window title with the [*] place holder replaced according to the rules described i...
static ControlElement< T > * ptr(QWidget *widget)
static bool isChildOfTabbedQMdiArea(const QMdiSubWindow *child)