92 int hmargin = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth,
nullptr, q);
93 QRect result = q->rect();
94 result.adjust(hmargin, 0, -hmargin, 0);
97 if (q->isRightToLeft())
98 result.setLeft(result.left() +
extension->sizeHint().width());
100 result.setWidth(result.width() -
extension->sizeHint().width());
103 if (leftWidget && leftWidget->isVisible()) {
104 QSize sz = leftWidget->sizeHint();
105 if (q->isRightToLeft())
106 result.setRight(result.right() - sz.width());
108 result.setLeft(result.left() + sz.width());
111 if (rightWidget && rightWidget->isVisible()) {
112 QSize sz = rightWidget->sizeHint();
113 if (q->isRightToLeft())
114 result.setLeft(result.left() + sz.width());
116 result.setRight(result.right() - sz.width());
132 int q_width = q->width()-(q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth,
nullptr, q)*2);
134 if (leftWidget || rightWidget) {
135 int vmargin = q->style()->pixelMetric(QStyle::PM_MenuBarVMargin,
nullptr, q)
136 + q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth,
nullptr, q);
137 int hmargin = q->style()->pixelMetric(QStyle::PM_MenuBarHMargin,
nullptr, q)
138 + q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth,
nullptr, q);
139 if (leftWidget && leftWidget->isVisible()) {
140 QSize sz = leftWidget->sizeHint();
141 q_width -= sz.width();
142 q_start = sz.width();
143 QPoint pos(hmargin, (q->height() - leftWidget->height()) / 2);
144 QRect vRect = QStyle::visualRect(q->layoutDirection(), q->rect(), QRect(pos, sz));
145 leftWidget->setGeometry(vRect);
147 if (rightWidget && rightWidget->isVisible()) {
148 QSize sz = rightWidget->sizeHint();
149 q_width -= sz.width();
150 QPoint pos(q->width() - sz.width() - hmargin, vmargin);
151 QRect vRect = QStyle::visualRect(q->layoutDirection(), q->rect(), QRect(pos, sz));
152 rightWidget->setGeometry(vRect);
157 if (q->isNativeMenuBar()) {
163 currentAction =
nullptr;
164#ifndef QT_NO_SHORTCUT
166 for (
const auto shortcutId : std::as_const(shortcutIndexMap))
167 q->releaseShortcut(shortcutId);
168 shortcutIndexMap.clear();
169 shortcutIndexMap.reserve(actions.size());
170 for (
const auto *action : std::as_const(actions))
171 shortcutIndexMap.append(q->grabShortcut(QKeySequence::mnemonic(action->text())));
176 hiddenActions.clear();
178 QRect menuRect =
this->menuRect(
false);
181 bool hasHiddenActions =
false;
182 for (
const auto &rect : std::as_const(actionRects)) {
183 if (rect.isValid() && !menuRect.contains(rect)) {
184 hasHiddenActions =
true;
190 if (hasHiddenActions) {
191 menuRect =
this->menuRect(
true);
192 for (qsizetype i = 0; i < actions.size(); ++i) {
193 const QRect &rect = actionRects.at(i);
194 if (rect.isValid() && !menuRect.contains(rect)) {
195 hiddenActions.append(actions.at(i));
200 if (hiddenActions.size() > 0) {
207 pop->addActions(hiddenActions);
209 int vmargin = q->style()->pixelMetric(QStyle::PM_MenuBarVMargin,
nullptr, q);
210 int x = q->isRightToLeft()
211 ? menuRect.left() - extension->sizeHint().width() + 1
213 extension->setGeometry(x, vmargin,
extension->sizeHint().width(), menuRect.height() - vmargin*2);
248 if (b && !q->style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation,
nullptr, q)) {
254 QWidget *fw = QApplication::focusWidget();
255 if (fw && fw != q && fw->window() != QApplication::activePopupWidget())
256 keyboardFocusWidget = fw;
258 q->setFocus(Qt::MenuBarFocusReason);
262 if (keyboardFocusWidget) {
263 if (QApplication::focusWidget() == q)
264 keyboardFocusWidget->setFocus(Qt::MenuBarFocusReason);
265 keyboardFocusWidget =
nullptr;
274 if (!action || !action->menu() || closePopupMode)
277 if (action->isEnabled() && action->menu()->isEnabled()) {
279 activeMenu = action->menu();
280 auto *activeMenuPriv = activeMenu->d_func();
281 activeMenuPriv->causedPopup.widget = q;
282 activeMenuPriv->causedPopup.action = action;
284 QRect adjustedActionRect = actionRect(action);
285 QPoint popupPos = adjustedActionRect.bottomLeft() + QPoint(0, 1);
288 QScreen *menubarScreen = q->window()->windowHandle()->screen();
289 QPoint screenTestPos = q->mapToGlobal(popupPos + QPoint(adjustedActionRect.width() / 2, 0));
290 QPointer<QScreen> popupScreen = menubarScreen->virtualSiblingAt(screenTestPos);
292 popupScreen = menubarScreen;
293 std::swap(popupScreen, activeMenuPriv->popupScreen);
294 const QSize popup_size = activeMenu->sizeHint();
295 std::swap(popupScreen, activeMenuPriv->popupScreen);
300 QPoint pos(q->mapToGlobal(popupPos).x(), screenTestPos.y());
302 QRect screenRect = popupScreen->geometry();
303 pos = QPoint(qMax(pos.x(), screenRect.x()), qMax(pos.y(), screenRect.y()));
304 const bool fitUp = (pos.y() - popup_size.height() >= screenRect.top());
305 const bool fitDown = (pos.y() + popup_size.height() <= screenRect.bottom());
306 const bool rtl = q->isRightToLeft();
307 const int actionWidth = adjustedActionRect.width();
309 if (!fitUp && !fitDown) {
310 bool shouldShiftToRight = !rtl;
311 if (rtl && popup_size.width() > pos.x())
312 shouldShiftToRight =
true;
313 else if (actionWidth + popup_size.width() + pos.x() > screenRect.right())
314 shouldShiftToRight =
false;
316 if (shouldShiftToRight) {
317 pos.rx() += actionWidth + (rtl ? popup_size.width() : 0);
321 pos.rx() -= popup_size.width();
324 pos.rx() += actionWidth;
327 if (!defaultPopDown || (fitUp && !fitDown))
328 pos.setY(qMax(screenRect.y(), q->mapToGlobal(QPoint(0, adjustedActionRect.top()-popup_size.height())).y()));
329 QMenuPrivate::get(activeMenu)->topData()->initialScreen = popupScreen;
330 activeMenu->popup(pos);
332 activeMenu->d_func()->setFirstActionActive();
334 q->update(actionRect(action));
339 if (currentAction == action && popup == popupState)
342 autoReleaseTimer.stop();
344 doChildEffects = (popup && !activeMenu);
347 if (QMenu *menu = activeMenu) {
348 activeMenu =
nullptr;
349 hoverAction =
nullptr;
351 fw = q->window()->focusWidget();
352 q->setFocus(Qt::NoFocusReason);
358 q->update(actionRect(currentAction));
361#if QT_CONFIG(statustip)
362 QAction *previousAction = currentAction;
364 currentAction = action;
365 if (action && action->isEnabled()) {
366 activateAction(action, QAction::Hover);
369 q->update(actionRect(action));
370#if QT_CONFIG(statustip)
371 }
else if (previousAction) {
373 QStatusTipEvent tip(empty);
374 QCoreApplication::sendEvent(q, &tip);
378 fw->setFocus(Qt::NoFocusReason);
389 actionRects.resize(actions.size());
390 actionRects.fill(QRect());
392 const QStyle *style = q->style();
394 const int itemSpacing = style->pixelMetric(QStyle::PM_MenuBarItemSpacing,
nullptr, q);
395 int max_item_height = 0, separator = -1, separator_start = 0, separator_len = 0;
398 const QFontMetrics fm = q->fontMetrics();
399 const int hmargin = style->pixelMetric(QStyle::PM_MenuBarHMargin,
nullptr, q),
400 vmargin = style->pixelMetric(QStyle::PM_MenuBarVMargin,
nullptr, q),
401 icone = style->pixelMetric(QStyle::PM_SmallIconSize,
nullptr, q);
402 for (qsizetype i = 0; i < actions.size(); ++i) {
403 const QAction *action = actions.at(i);
404 if (!action->isVisible())
410 if (action->isSeparator()) {
411 if (style->styleHint(QStyle::SH_DrawMenuBarSeparator,
nullptr, q))
415 const QString s = action->text();
416 QIcon is = action->icon();
419 sz = sz.expandedTo(QSize(icone, icone));
420 else if (!s.isEmpty())
421 sz = fm.size(Qt::TextShowMnemonic, s);
425 QStyleOptionMenuItemV2 opt;
426 q->initStyleOption(&opt, action);
427 sz = q->style()->sizeFromContents(QStyle::CT_MenuBarItem, &opt, sz, q);
431 int iWidth = sz.width() + itemSpacing;
433 separator_start += iWidth;
435 separator_len += iWidth;
438 max_item_height = qMax(max_item_height, sz.height());
440 actionRects[i] = QRect(0, 0, sz.width(), sz.height());
445 const int fw = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth,
nullptr, q);
446 int x = fw + ((start == -1) ? hmargin : start) + itemSpacing;
447 int y = fw + vmargin;
448 for (qsizetype i = 0; i < actionRects.size(); ++i) {
449 QRect &rect = actionRects[i];
454 rect.setHeight(max_item_height);
457 if (separator != -1 && i >= separator) {
458 int left = (max_width - separator_len - hmargin - itemSpacing) + (x - separator_start - hmargin);
459 if (left < separator_start) {
460 separator_start = x = hmargin;
461 y += max_item_height;
470 x += rect.width() + itemSpacing;
473 rect = QStyle::visualRect(q->layoutDirection(), q->rect(), rect);
504 if (QAction *action = qobject_cast<QAction *>(q->sender())) {
505 emit q->hovered(action);
506#if QT_CONFIG(accessibility)
507 if (QAccessible::isActive()) {
508 int actionIndex = actions.indexOf(action);
509 QAccessibleEvent focusEvent(q, QAccessible::Focus);
510 focusEvent.setChild(actionIndex);
511 QAccessible::updateAccessibility(&focusEvent);
524void QMenuBar::initStyleOption(QStyleOptionMenuItem *option,
const QAction *action)
const
526 if (!option || !action)
529 option->palette = palette();
530 option->state = QStyle::State_None;
531 if (isEnabled() && action->isEnabled())
532 option->state |= QStyle::State_Enabled;
534 option->palette.setCurrentColorGroup(QPalette::Disabled);
535 option->fontMetrics = fontMetrics();
536 if (d->currentAction && d->currentAction == action) {
537 option->state |= QStyle::State_Selected;
538 if (d->popupState && !d->closePopupMode)
539 option->state |= QStyle::State_Sunken;
541 if (hasFocus() || d->currentAction)
542 option->state |= QStyle::State_HasFocus;
543 if (d->hoverAction == action) {
544 if (
auto optionV2 = qstyleoption_cast<QStyleOptionMenuItemV2 *>(option))
545 optionV2->mouseDown = d->mouseDown;
546 option->state |= QStyle::State_MouseOver;
548 option->menuRect = rect();
549 option->menuItemType = QStyleOptionMenuItem::Normal;
550 option->checkType = QStyleOptionMenuItem::NotCheckable;
551 option->text = action->text();
552 option->icon = action->icon();
675 q->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
676 q->setAttribute(Qt::WA_CustomWhatsThis);
678 if (!QCoreApplication::testAttribute(Qt::AA_DontUseNativeMenuBar))
679 platformMenuBar = QGuiApplicationPrivate::platformTheme()->createPlatformMenuBar();
683 q->setBackgroundRole(QPalette::Button);
685 q->setMouseTracking(q->style()->styleHint(QStyle::SH_MenuBar_MouseTracking,
nullptr, q));
687 extension =
new QMenuBarExtension(q);
697 bool allowActiveAndDisabled = q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled,
nullptr, q);
698 const qsizetype start = (_start == -1 && increment == -1) ? actions.size() : _start;
699 const qsizetype end = increment == -1 ? 0 : actions.size() - 1;
701 for (qsizetype i = start; i != end;) {
703 QAction *current = actions.at(i);
704 if (!actionRects.at(i).isNull() && (allowActiveAndDisabled || current->isEnabled()))
709 return getNextAction(-1, increment);
895void QMenuBar::paintEvent(QPaintEvent *e)
899 QRegion emptyArea(rect());
902 for (
int i = 0; i < d->actions.size(); ++i) {
903 QAction *action = d->actions.at(i);
904 QRect adjustedActionRect = d->actionRect(action);
905 if (adjustedActionRect.isEmpty() || !d->isVisible(action))
907 if (!e->rect().intersects(adjustedActionRect))
910 emptyArea -= adjustedActionRect;
911 QStyleOptionMenuItemV2 opt;
912 initStyleOption(&opt, action);
913 opt.rect = adjustedActionRect;
914 p.setClipRect(adjustedActionRect);
915 style()->drawControl(QStyle::CE_MenuBarItem, &opt, &p,
this);
918 if (
int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth,
nullptr,
this)) {
920 borderReg += QRect(0, 0, fw, height());
921 borderReg += QRect(width()-fw, 0, fw, height());
922 borderReg += QRect(0, 0, width(), fw);
923 borderReg += QRect(0, height()-fw, width(), fw);
924 p.setClipRegion(borderReg);
925 emptyArea -= borderReg;
926 QStyleOptionFrame frame;
928 frame.palette = palette();
929 frame.state = QStyle::State_None;
930 frame.lineWidth = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, &frame,
this);
931 frame.midLineWidth = 0;
932 style()->drawPrimitive(QStyle::PE_PanelMenuBar, &frame, &p,
this);
934 p.setClipRegion(emptyArea);
935 QStyleOptionMenuItem menuOpt;
936 menuOpt.palette = palette();
937 menuOpt.state = QStyle::State_None;
938 menuOpt.menuItemType = QStyleOptionMenuItem::EmptyArea;
939 menuOpt.checkType = QStyleOptionMenuItem::NotCheckable;
940 menuOpt.rect = rect();
941 menuOpt.menuRect = rect();
942 style()->drawControl(QStyle::CE_MenuBarEmptyArea, &menuOpt, &p,
this);
961void QMenuBar::mousePressEvent(QMouseEvent *e)
964 if (e->button() != Qt::LeftButton)
969 QAction *action = d->actionAt(e->position().toPoint());
970 if (!action || !d->isVisible(action) || !action->isEnabled()) {
971 d->setCurrentAction(
nullptr);
972#if QT_CONFIG(whatsthis)
973 if (QWhatsThis::inWhatsThisMode())
974 QWhatsThis::showText(e->globalPosition().toPoint(), d->whatsThis,
this);
979 if (d->currentAction == action && d->popupState) {
980 if (QMenu *menu = d->activeMenu) {
981 d->activeMenu =
nullptr;
982 menu->setAttribute(Qt::WA_NoMouseReplay);
987 d->setCurrentAction(action,
true);
989 d->hoverAction = action;
990 update(d->actionRect(d->hoverAction));
996void QMenuBar::mouseReleaseEvent(QMouseEvent *e)
999 if (e->button() != Qt::LeftButton)
1004 d->mouseDown =
false;
1005 QAction *action = d->actionAt(e->position().toPoint());
1008 if (!d->isVisible(action))
1010 if ((d->closePopupMode && action == d->currentAction) || !action || !action->menu()) {
1013 d->setCurrentAction(action,
false);
1015 d->activateAction(action, QAction::Trigger);
1017 d->closePopupMode = 0;
1018 d->hoverAction = action;
1019 update(d->actionRect(d->hoverAction));
1025void QMenuBar::keyPressEvent(QKeyEvent *e)
1028 d->updateGeometries();
1030 if (isRightToLeft()) {
1031 if (key == Qt::Key_Left)
1032 key = Qt::Key_Right;
1033 else if (key == Qt::Key_Right)
1036 if (key == Qt::Key_Tab)
1037 key = Qt::Key_Right;
1038 else if (key == Qt::Key_Backtab)
1041 bool key_consumed =
false;
1047 case Qt::Key_Return: {
1048 if (!style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation,
nullptr,
this) || !d->currentAction)
1050 if (d->currentAction->menu()) {
1051 d->popupAction(d->currentAction,
true);
1052 }
else if (key == Qt::Key_Enter || key == Qt::Key_Return || key == Qt::Key_Space) {
1053 d->activateAction(d->currentAction, QAction::Trigger);
1054 d->setCurrentAction(d->currentAction,
false);
1055 d->setKeyboardMode(
false);
1057 key_consumed =
true;
1061 case Qt::Key_Left: {
1062 if (d->currentAction) {
1063 qsizetype index = d->actions.indexOf(d->currentAction);
1064 if (QAction *nextAction = d->getNextAction(index, key == Qt::Key_Left ? -1 : +1)) {
1065 d->setCurrentAction(nextAction, d->popupState,
true);
1066 key_consumed =
true;
1072 key_consumed =
false;
1075#ifndef QT_NO_SHORTCUT
1076 if (!key_consumed && e->matches(QKeySequence::Cancel)) {
1077 d->setCurrentAction(
nullptr);
1078 d->setKeyboardMode(
false);
1079 key_consumed =
true;
1083 if (!key_consumed &&
1085 (e->modifiers()&(Qt::MetaModifier|Qt::AltModifier))) && e->text().size()==1 && !d->popupState) {
1087 QAction *first =
nullptr, *currentSelected =
nullptr, *firstAfterCurrent =
nullptr;
1089 const QChar c = e->text().at(0).toUpper();
1090 for (qsizetype i = 0; i < d->actions.size(); ++i) {
1091 if (d->actionRects.at(i).isNull())
1093 QAction *act = d->actions.at(i);
1094 QString s = act->text();
1096 qsizetype ampersand = s.indexOf(u'&');
1097 if (ampersand >= 0) {
1098 if (s[ampersand+1].toUpper() == c) {
1102 if (act == d->currentAction)
1103 currentSelected = act;
1104 else if (!firstAfterCurrent && currentSelected)
1105 firstAfterCurrent = act;
1111 QAction *next_action =
nullptr;
1112 if (clashCount >= 1) {
1113 if (clashCount == 1 || !d->currentAction || (currentSelected && !firstAfterCurrent))
1114 next_action = first;
1116 next_action = firstAfterCurrent;
1119 key_consumed =
true;
1120 d->setCurrentAction(next_action,
true,
true);
1132void QMenuBar::mouseMoveEvent(QMouseEvent *e)
1135 if (!(e->buttons() & Qt::LeftButton)) {
1136 d->mouseDown =
false;
1140 if (e->source() != Qt::MouseEventNotSynthesized)
1144 bool popupState = d->popupState || d->mouseDown;
1145 QAction *action = d->actionAt(e->position().toPoint());
1146 QAction *oldHoverAction = d->hoverAction;
1147 if ((action && d->isVisible(action)) || !popupState)
1148 d->setCurrentAction(action, popupState);
1149 if (oldHoverAction != action)
1150 update(d->actionRect(oldHoverAction));
1151 d->hoverAction = action;
1208void QMenuBar::actionEvent(QActionEvent *e)
1211 d->itemsDirty =
true;
1213 if (d->platformMenuBar) {
1214 QPlatformMenuBar *nativeMenuBar = d->platformMenuBar;
1218 auto action =
static_cast<QAction *>(e->action());
1219 if (e->type() == QEvent::ActionAdded) {
1220 QPlatformMenu *menu = d->getPlatformMenu(action);
1222 d->copyActionToPlatformMenu(action, menu);
1224 QPlatformMenu *beforeMenu = d->findInsertionPlatformMenu(action);
1225 d->platformMenuBar->insertMenu(menu, beforeMenu);
1227 }
else if (e->type() == QEvent::ActionRemoved) {
1228 QPlatformMenu *menu = d->getPlatformMenu(action);
1230 d->platformMenuBar->removeMenu(menu);
1231 }
else if (e->type() == QEvent::ActionChanged) {
1232 QPlatformMenu *cur = d->platformMenuBar->menuForTag(
reinterpret_cast<quintptr>(e->action()));
1233 QPlatformMenu *menu = d->getPlatformMenu(action);
1239 d->platformMenuBar->removeMenu(cur);
1241 d->copyActionToPlatformMenu(action, menu);
1243 QPlatformMenu *beforeMenu = d->findInsertionPlatformMenu(action);
1244 d->platformMenuBar->insertMenu(menu, beforeMenu);
1247 d->copyActionToPlatformMenu(action, menu);
1248 d->platformMenuBar->syncMenu(menu);
1253 if (e->type() == QEvent::ActionAdded) {
1254 connect(e->action(), SIGNAL(triggered()),
this, SLOT(_q_actionTriggered()));
1255 connect(e->action(), SIGNAL(hovered()),
this, SLOT(_q_actionHovered()));
1256 }
else if (e->type() == QEvent::ActionRemoved) {
1257 e->action()->disconnect(
this);
1261 if (isVisible() || isNativeMenuBar())
1262 d->updateGeometries();
1306 QWidget *newParent = q->parentWidget();
1311 QWidget *newWindow = newParent ? newParent->window() :
nullptr;
1313 QList<QPointer<QWidget>> newParents;
1320 const auto copy = oldParents;
1321 for (
const QPointer<QWidget> &w : copy) {
1323 if (newParent == w) {
1324 newParents.append(w);
1325 if (newParent != newWindow)
1326 newParent = newParent->parentWidget();
1328 w->removeEventFilter(q);
1334 while (newParent && newParent != newWindow) {
1336 newParents.append(newParent);
1337 newParent->installEventFilter(q);
1338 newParent = newParent->parentWidget();
1341 if (newParent && newWindow) {
1343 newParents.append(newParent);
1344 newParent->installEventFilter(q);
1346 oldParents = newParents;
1353 newWindow->createWinId();
1364void QMenuBar::changeEvent(QEvent *e)
1367 if (e->type() == QEvent::StyleChange) {
1368 d->itemsDirty =
true;
1369 setMouseTracking(style()->styleHint(QStyle::SH_MenuBar_MouseTracking,
nullptr,
this));
1371 resize(parentWidget()->width(), heightForWidth(parentWidget()->width()));
1372 d->updateGeometries();
1373 }
else if (e->type() == QEvent::ParentChange) {
1374 d->handleReparent();
1375 }
else if (e->type() == QEvent::FontChange
1376 || e->type() == QEvent::ApplicationFontChange) {
1377 d->itemsDirty =
true;
1378 d->updateGeometries();
1381 QWidget::changeEvent(e);
1387bool QMenuBar::event(QEvent *e)
1390 switch (e->type()) {
1391 case QEvent::KeyPress: {
1392 QKeyEvent *ke =
static_cast<QKeyEvent *>(e);
1394 if (!d->keyboardState) {
1395 d->setCurrentAction(0);
1399 if (ke->key() == Qt::Key_Tab || ke->key() == Qt::Key_Backtab) {
1405#ifndef QT_NO_SHORTCUT
1406 case QEvent::Shortcut: {
1407 QShortcutEvent *se =
static_cast<QShortcutEvent *>(e);
1408 int shortcutId = se->shortcutId();
1409 for (qsizetype j = 0; j < d->shortcutIndexMap.size(); ++j) {
1410 if (shortcutId == d->shortcutIndexMap.value(j))
1411 d->_q_internalShortcutActivated(j);
1416 d->_q_updateLayout();
1418#ifndef QT_NO_SHORTCUT
1419 case QEvent::ShortcutOverride: {
1420 QKeyEvent *kev =
static_cast<QKeyEvent *>(e);
1422 if (kev->matches(QKeySequence::Cancel) && d->currentAction) {
1429#if QT_CONFIG(whatsthis)
1430 case QEvent::QueryWhatsThis:
1431 e->setAccepted(d->whatsThis.size());
1432 if (QAction *action = d->actionAt(
static_cast<QHelpEvent*>(e)->pos())) {
1433 if (action->whatsThis().size() || action->menu())
1438 case QEvent::LayoutDirectionChange:
1439 d->_q_updateLayout();
1444 return QWidget::event(e);
1450bool QMenuBar::eventFilter(QObject *object, QEvent *event)
1453 if (object && (event->type() == QEvent::ParentChange))
1454 d->handleReparent();
1456 if (object == d->leftWidget || object == d->rightWidget) {
1457 switch (event->type()) {
1458 case QEvent::ShowToParent:
1459 case QEvent::HideToParent:
1460 d->_q_updateLayout();
1467 if (isNativeMenuBar() && event->type() == QEvent::ShowToParent) {
1472 QWidget *widget = qobject_cast<QWidget *>(object);
1473 QWindow *handle = widget ? widget->windowHandle() :
nullptr;
1474 if (handle !=
nullptr)
1475 d->platformMenuBar->handleReparent(handle);
1478 if (style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation,
nullptr,
this)) {
1479 if (d->altPressed) {
1480 switch (event->type()) {
1481 case QEvent::KeyPress:
1482 case QEvent::KeyRelease:
1484 QKeyEvent *kev =
static_cast<QKeyEvent*>(event);
1485 if (kev->key() == Qt::Key_Alt || kev->key() == Qt::Key_Meta) {
1486 if (event->type() == QEvent::KeyPress)
1488 d->setKeyboardMode(!d->keyboardState);
1492 case QEvent::MouseButtonPress:
1493 case QEvent::MouseButtonRelease:
1494 case QEvent::MouseMove:
1495 case QEvent::FocusIn:
1496 case QEvent::FocusOut:
1497 case QEvent::ActivationChange:
1498 case QEvent::Shortcut:
1499 d->altPressed =
false;
1500 qApp->removeEventFilter(
this);
1505 }
else if (isVisible()) {
1506 if (event->type() == QEvent::ShortcutOverride) {
1507 QKeyEvent *kev =
static_cast<QKeyEvent*>(event);
1508 if ((kev->key() == Qt::Key_Alt || kev->key() == Qt::Key_Meta)
1509 && kev->modifiers() == Qt::AltModifier) {
1510 d->altPressed =
true;
1511 qApp->installEventFilter(
this);
1546QSize QMenuBar::minimumSizeHint()
const
1548 Q_D(
const QMenuBar);
1549 const bool as_gui_menubar = !isNativeMenuBar();
1553 const_cast<QMenuBarPrivate*>(d)->updateGeometries();
1554 const int hmargin = style()->pixelMetric(QStyle::PM_MenuBarHMargin,
nullptr,
this);
1555 const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin,
nullptr,
this);
1556 int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth,
nullptr,
this);
1557 int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar,
nullptr,
this);
1558 if (as_gui_menubar) {
1559 int w = parentWidget() ? parentWidget()->width() : QGuiApplication::primaryScreen()->virtualGeometry().width();
1560 d->calcActionRects(w - (2 * fw), 0);
1561 for (qsizetype i = 0; ret.isNull() && i < d->actions.size(); ++i)
1562 ret = d->actionRects.at(i).size();
1563 if (!d->extension->isHidden())
1564 ret += QSize(d->extension->sizeHint().width(), 0);
1565 ret += QSize(2*fw + hmargin, 2*fw + vmargin);
1567 int margin = 2*vmargin + 2*fw + spaceBelowMenuBar;
1568 if (d->leftWidget) {
1569 QSize sz = d->leftWidget->minimumSizeHint();
1570 ret.setWidth(ret.width() + sz.width());
1571 if (sz.height() + margin > ret.height())
1572 ret.setHeight(sz.height() + margin);
1574 if (d->rightWidget) {
1575 QSize sz = d->rightWidget->minimumSizeHint();
1576 ret.setWidth(ret.width() + sz.width());
1577 if (sz.height() + margin > ret.height())
1578 ret.setHeight(sz.height() + margin);
1580 if (as_gui_menubar) {
1581 QStyleOptionMenuItem opt;
1583 opt.menuRect = rect();
1584 opt.state = QStyle::State_None;
1585 opt.menuItemType = QStyleOptionMenuItem::Normal;
1586 opt.checkType = QStyleOptionMenuItem::NotCheckable;
1587 opt.palette = palette();
1588 return style()->sizeFromContents(QStyle::CT_MenuBar, &opt, ret,
this);
1596QSize QMenuBar::sizeHint()
const
1598 Q_D(
const QMenuBar);
1599 const bool as_gui_menubar = !isNativeMenuBar();
1603 const_cast<QMenuBarPrivate*>(d)->updateGeometries();
1604 const int hmargin = style()->pixelMetric(QStyle::PM_MenuBarHMargin,
nullptr,
this);
1605 const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin,
nullptr,
this);
1606 int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth,
nullptr,
this);
1607 int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar,
nullptr,
this);
1608 if (as_gui_menubar) {
1609 const int w = parentWidget() ? parentWidget()->width() : QGuiApplication::primaryScreen()->virtualGeometry().width();
1610 d->calcActionRects(w - (2 * fw), 0);
1611 for (
const auto &actionRect : d->actionRects)
1612 ret = ret.expandedTo(QSize(actionRect.x() + actionRect.width(), actionRect.y() + actionRect.height()));
1615 ret += QSize(fw + hmargin, fw + vmargin);
1617 int margin = 2*vmargin + 2*fw + spaceBelowMenuBar;
1618 if (d->leftWidget) {
1619 QSize sz = d->leftWidget->sizeHint();
1620 sz.rheight() += margin;
1621 ret = ret.expandedTo(sz);
1623 if (d->rightWidget) {
1624 QSize sz = d->rightWidget->sizeHint();
1625 ret.setWidth(ret.width() + sz.width());
1626 if (sz.height() + margin > ret.height())
1627 ret.setHeight(sz.height() + margin);
1629 if (as_gui_menubar) {
1630 QStyleOptionMenuItem opt;
1632 opt.menuRect = rect();
1633 opt.state = QStyle::State_None;
1634 opt.menuItemType = QStyleOptionMenuItem::Normal;
1635 opt.checkType = QStyleOptionMenuItem::NotCheckable;
1636 opt.palette = palette();
1637 return style()->sizeFromContents(QStyle::CT_MenuBar, &opt, ret,
this);
1645int QMenuBar::heightForWidth(
int)
const
1647 Q_D(
const QMenuBar);
1648 const bool as_gui_menubar = !isNativeMenuBar();
1650 const_cast<QMenuBarPrivate*>(d)->updateGeometries();
1652 const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin,
nullptr,
this);
1653 int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth,
nullptr,
this);
1654 int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar,
nullptr,
this);
1655 if (as_gui_menubar) {
1656 for (
const auto &actionRect : d->actionRects)
1657 height = qMax(height, actionRect.height());
1659 height += spaceBelowMenuBar;
1661 height += 2*vmargin;
1663 int margin = 2*vmargin + 2*fw + spaceBelowMenuBar;
1665 height = qMax(d->leftWidget->sizeHint().height() + margin, height);
1667 height = qMax(d->rightWidget->sizeHint().height() + margin, height);
1668 if (as_gui_menubar) {
1669 QStyleOptionMenuItem opt;
1671 opt.menuRect = rect();
1672 opt.state = QStyle::State_None;
1673 opt.menuItemType = QStyleOptionMenuItem::Normal;
1674 opt.checkType = QStyleOptionMenuItem::NotCheckable;
1675 return style()->sizeFromContents(QStyle::CT_MenuBar, &opt, QSize(0, height),
this).height();
1686 QAction *act = actions.at(id);
1687 if (act && act->menu()) {
1688 if (QPlatformMenu *platformMenu = act->menu()->platformMenu()) {
1689 platformMenu->showPopup(q->windowHandle(), actionRects.at(id),
nullptr);
1694 keyboardFocusWidget = QApplication::focusWidget();
1696 if (act && !act->menu()) {
1697 activateAction(act, QAction::Trigger);
1699 autoReleaseTimer.start(100, q);
1700 }
else if (act && q->style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation,
nullptr, q)) {