93 int hmargin = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth,
nullptr, q);
94 QRect result = q->rect();
95 result.adjust(hmargin, 0, -hmargin, 0);
98 if (q->isRightToLeft())
99 result.setLeft(result.left() +
extension->sizeHint().width());
101 result.setWidth(result.width() -
extension->sizeHint().width());
104 if (leftWidget && leftWidget->isVisible()) {
105 QSize sz = leftWidget->sizeHint();
106 if (q->isRightToLeft())
107 result.setRight(result.right() - sz.width());
109 result.setLeft(result.left() + sz.width());
112 if (rightWidget && rightWidget->isVisible()) {
113 QSize sz = rightWidget->sizeHint();
114 if (q->isRightToLeft())
115 result.setLeft(result.left() + sz.width());
117 result.setRight(result.right() - sz.width());
133 int q_width = q->width()-(q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth,
nullptr, q)*2);
135 if (leftWidget || rightWidget) {
136 int vmargin = q->style()->pixelMetric(QStyle::PM_MenuBarVMargin,
nullptr, q)
137 + q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth,
nullptr, q);
138 int hmargin = q->style()->pixelMetric(QStyle::PM_MenuBarHMargin,
nullptr, q)
139 + q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth,
nullptr, q);
140 if (leftWidget && leftWidget->isVisible()) {
141 QSize sz = leftWidget->sizeHint();
142 q_width -= sz.width();
143 q_start = sz.width();
144 QPoint pos(hmargin, (q->height() - leftWidget->height()) / 2);
145 QRect vRect = QStyle::visualRect(q->layoutDirection(), q->rect(), QRect(pos, sz));
146 leftWidget->setGeometry(vRect);
148 if (rightWidget && rightWidget->isVisible()) {
149 QSize sz = rightWidget->sizeHint();
150 q_width -= sz.width();
151 QPoint pos(q->width() - sz.width() - hmargin, vmargin);
152 QRect vRect = QStyle::visualRect(q->layoutDirection(), q->rect(), QRect(pos, sz));
153 rightWidget->setGeometry(vRect);
158 if (q->isNativeMenuBar()) {
164 currentAction =
nullptr;
165#ifndef QT_NO_SHORTCUT
167 for (
const auto shortcutId : std::as_const(shortcutIndexMap))
168 q->releaseShortcut(shortcutId);
169 shortcutIndexMap.clear();
170 shortcutIndexMap.reserve(actions.size());
171 for (
const auto *action : std::as_const(actions))
172 shortcutIndexMap.append(q->grabShortcut(QKeySequence::mnemonic(action->text())));
177 hiddenActions.clear();
179 QRect menuRect =
this->menuRect(
false);
182 bool hasHiddenActions =
false;
183 for (
const auto &rect : std::as_const(actionRects)) {
184 if (rect.isValid() && !menuRect.contains(rect)) {
185 hasHiddenActions =
true;
191 if (hasHiddenActions) {
192 menuRect =
this->menuRect(
true);
193 for (qsizetype i = 0; i < actions.size(); ++i) {
194 const QRect &rect = actionRects.at(i);
195 if (rect.isValid() && !menuRect.contains(rect)) {
196 hiddenActions.append(actions.at(i));
201 if (hiddenActions.size() > 0) {
208 pop->addActions(hiddenActions);
210 int vmargin = q->style()->pixelMetric(QStyle::PM_MenuBarVMargin,
nullptr, q);
211 int x = q->isRightToLeft()
212 ? menuRect.left() - extension->sizeHint().width() + 1
214 extension->setGeometry(x, vmargin,
extension->sizeHint().width(), menuRect.height() - vmargin*2);
249 if (b && !q->style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation,
nullptr, q)) {
255 QWidget *fw = QApplication::focusWidget();
256 if (fw && fw != q && fw->window() != QApplication::activePopupWidget())
257 keyboardFocusWidget = fw;
259 q->setFocus(Qt::MenuBarFocusReason);
263 if (keyboardFocusWidget) {
264 if (QApplication::focusWidget() == q)
265 keyboardFocusWidget->setFocus(Qt::MenuBarFocusReason);
266 keyboardFocusWidget =
nullptr;
275 if (!action || !action->menu() || closePopupMode)
278 if (action->isEnabled() && action->menu()->isEnabled()) {
280 activeMenu = action->menu();
281 auto *activeMenuPriv = activeMenu->d_func();
282 activeMenuPriv->causedPopup.widget = q;
283 activeMenuPriv->causedPopup.action = action;
285 QRect adjustedActionRect = actionRect(action);
286 QPoint popupPos = adjustedActionRect.bottomLeft() + QPoint(0, 1);
289 QScreen *menubarScreen = q->window()->windowHandle()->screen();
290 QPoint screenTestPos = q->mapToGlobal(popupPos + QPoint(adjustedActionRect.width() / 2, 0));
291 QPointer<QScreen> popupScreen = menubarScreen->virtualSiblingAt(screenTestPos);
293 popupScreen = menubarScreen;
294 std::swap(popupScreen, activeMenuPriv->popupScreen);
295 const QSize popup_size = activeMenu->sizeHint();
296 std::swap(popupScreen, activeMenuPriv->popupScreen);
301 QPoint pos(q->mapToGlobal(popupPos).x(), screenTestPos.y());
303 QRect screenRect = QStylePrivate::useFullScreenForPopup()
304 ? popupScreen->geometry()
305 : popupScreen->availableGeometry();
306 pos = QPoint(qMax(pos.x(), screenRect.x()), qMax(pos.y(), screenRect.y()));
307 const bool fitUp = (pos.y() - popup_size.height() >= screenRect.top());
308 const bool fitDown = (pos.y() + popup_size.height() <= screenRect.bottom());
309 const bool rtl = q->isRightToLeft();
310 const int actionWidth = adjustedActionRect.width();
312 if (!fitUp && !fitDown) {
313 bool shouldShiftToRight = !rtl;
314 if (rtl && popup_size.width() > pos.x())
315 shouldShiftToRight =
true;
316 else if (actionWidth + popup_size.width() + pos.x() > screenRect.right())
317 shouldShiftToRight =
false;
319 if (shouldShiftToRight) {
320 pos.rx() += actionWidth + (rtl ? popup_size.width() : 0);
324 pos.rx() -= popup_size.width();
327 pos.rx() += actionWidth;
330 if (!defaultPopDown || (fitUp && !fitDown))
331 pos.setY(qMax(screenRect.y(), q->mapToGlobal(QPoint(0, adjustedActionRect.top()-popup_size.height())).y()));
332 QMenuPrivate::get(activeMenu)->topData()->initialScreen = popupScreen;
333 activeMenu->popup(pos);
335 activeMenu->d_func()->setFirstActionActive();
337 q->update(actionRect(action));
342 if (currentAction == action && popup == popupState)
345 autoReleaseTimer.stop();
347 doChildEffects = (popup && !activeMenu);
350 if (QMenu *menu = activeMenu) {
351 activeMenu =
nullptr;
352 hoverAction =
nullptr;
354 fw = q->window()->focusWidget();
355 q->setFocus(Qt::NoFocusReason);
361 q->update(actionRect(currentAction));
364#if QT_CONFIG(statustip)
365 QAction *previousAction = currentAction;
367 currentAction = action;
368 if (action && action->isEnabled()) {
369 activateAction(action, QAction::Hover);
372 q->update(actionRect(action));
373#if QT_CONFIG(statustip)
374 }
else if (previousAction) {
376 QStatusTipEvent tip(empty);
377 QCoreApplication::sendEvent(q, &tip);
381 fw->setFocus(Qt::NoFocusReason);
392 actionRects.resize(actions.size());
393 actionRects.fill(QRect());
395 const QStyle *style = q->style();
397 const int itemSpacing = style->pixelMetric(QStyle::PM_MenuBarItemSpacing,
nullptr, q);
398 int max_item_height = 0, separator = -1, separator_start = 0, separator_len = 0;
401 const QFontMetrics fm = q->fontMetrics();
402 const int hmargin = style->pixelMetric(QStyle::PM_MenuBarHMargin,
nullptr, q),
403 vmargin = style->pixelMetric(QStyle::PM_MenuBarVMargin,
nullptr, q),
404 icone = style->pixelMetric(QStyle::PM_SmallIconSize,
nullptr, q);
405 for (qsizetype i = 0; i < actions.size(); ++i) {
406 const QAction *action = actions.at(i);
407 if (!action->isVisible())
413 if (action->isSeparator()) {
414 if (style->styleHint(QStyle::SH_DrawMenuBarSeparator,
nullptr, q))
418 const QString s = action->text();
419 QIcon is = action->icon();
422 sz = sz.expandedTo(QSize(icone, icone));
423 else if (!s.isEmpty())
424 sz = fm.size(Qt::TextShowMnemonic, s);
428 QStyleOptionMenuItemV2 opt;
429 q->initStyleOption(&opt, action);
430 sz = q->style()->sizeFromContents(QStyle::CT_MenuBarItem, &opt, sz, q);
434 int iWidth = sz.width() + itemSpacing;
436 separator_start += iWidth;
438 separator_len += iWidth;
441 max_item_height = qMax(max_item_height, sz.height());
443 actionRects[i] = QRect(0, 0, sz.width(), sz.height());
448 const int fw = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth,
nullptr, q);
449 int x = fw + ((start == -1) ? hmargin : start) + itemSpacing;
450 int y = fw + vmargin;
451 for (qsizetype i = 0; i < actionRects.size(); ++i) {
452 QRect &rect = actionRects[i];
457 rect.setHeight(max_item_height);
460 if (separator != -1 && i >= separator) {
461 int left = (max_width - separator_len - hmargin - itemSpacing) + (x - separator_start - hmargin);
462 if (left < separator_start) {
463 separator_start = x = hmargin;
464 y += max_item_height;
473 x += rect.width() + itemSpacing;
476 rect = QStyle::visualRect(q->layoutDirection(), q->rect(), rect);
507 if (QAction *action = qobject_cast<QAction *>(q->sender())) {
508 emit q->hovered(action);
509#if QT_CONFIG(accessibility)
510 if (QAccessible::isActive()) {
511 int actionIndex = actions.indexOf(action);
512 QAccessibleEvent focusEvent(q, QAccessible::Focus);
513 focusEvent.setChild(actionIndex);
514 QAccessible::updateAccessibility(&focusEvent);
527void QMenuBar::initStyleOption(QStyleOptionMenuItem *option,
const QAction *action)
const
529 if (!option || !action)
532 option->palette = palette();
533 option->state = QStyle::State_None;
534 if (isEnabled() && action->isEnabled())
535 option->state |= QStyle::State_Enabled;
537 option->palette.setCurrentColorGroup(QPalette::Disabled);
538 option->fontMetrics = fontMetrics();
539 if (d->currentAction && d->currentAction == action) {
540 option->state |= QStyle::State_Selected;
541 if (d->popupState && !d->closePopupMode)
542 option->state |= QStyle::State_Sunken;
544 if (hasFocus() || d->currentAction)
545 option->state |= QStyle::State_HasFocus;
546 if (d->hoverAction == action) {
547 if (
auto optionV2 = qstyleoption_cast<QStyleOptionMenuItemV2 *>(option))
548 optionV2->mouseDown = d->mouseDown;
549 option->state |= QStyle::State_MouseOver;
551 option->menuRect = rect();
552 option->menuItemType = QStyleOptionMenuItem::Normal;
553 option->checkType = QStyleOptionMenuItem::NotCheckable;
554 option->text = action->text();
555 option->icon = action->icon();
678 q->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
679 q->setAttribute(Qt::WA_CustomWhatsThis);
681 if (!QCoreApplication::testAttribute(Qt::AA_DontUseNativeMenuBar))
682 platformMenuBar = QGuiApplicationPrivate::platformTheme()->createPlatformMenuBar();
686 q->setBackgroundRole(QPalette::Button);
688 q->setMouseTracking(q->style()->styleHint(QStyle::SH_MenuBar_MouseTracking,
nullptr, q));
690 extension =
new QMenuBarExtension(q);
700 bool allowActiveAndDisabled = q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled,
nullptr, q);
701 const qsizetype start = (_start == -1 && increment == -1) ? actions.size() : _start;
702 const qsizetype end = increment == -1 ? 0 : actions.size() - 1;
704 for (qsizetype i = start; i != end;) {
706 QAction *current = actions.at(i);
707 if (!actionRects.at(i).isNull() && (allowActiveAndDisabled || current->isEnabled()))
712 return getNextAction(-1, increment);
898void QMenuBar::paintEvent(QPaintEvent *e)
902 QRegion emptyArea(rect());
905 for (
int i = 0; i < d->actions.size(); ++i) {
906 QAction *action = d->actions.at(i);
907 QRect adjustedActionRect = d->actionRect(action);
908 if (adjustedActionRect.isEmpty() || !d->isVisible(action))
910 if (!e->rect().intersects(adjustedActionRect))
913 emptyArea -= adjustedActionRect;
914 QStyleOptionMenuItemV2 opt;
915 initStyleOption(&opt, action);
916 opt.rect = adjustedActionRect;
917 p.setClipRect(adjustedActionRect);
918 style()->drawControl(QStyle::CE_MenuBarItem, &opt, &p,
this);
921 if (
int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth,
nullptr,
this)) {
923 borderReg += QRect(0, 0, fw, height());
924 borderReg += QRect(width()-fw, 0, fw, height());
925 borderReg += QRect(0, 0, width(), fw);
926 borderReg += QRect(0, height()-fw, width(), fw);
927 p.setClipRegion(borderReg);
928 emptyArea -= borderReg;
929 QStyleOptionFrame frame;
931 frame.palette = palette();
932 frame.state = QStyle::State_None;
933 frame.lineWidth = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, &frame,
this);
934 frame.midLineWidth = 0;
935 style()->drawPrimitive(QStyle::PE_PanelMenuBar, &frame, &p,
this);
937 p.setClipRegion(emptyArea);
938 QStyleOptionMenuItem menuOpt;
939 menuOpt.palette = palette();
940 menuOpt.state = QStyle::State_None;
941 menuOpt.menuItemType = QStyleOptionMenuItem::EmptyArea;
942 menuOpt.checkType = QStyleOptionMenuItem::NotCheckable;
943 menuOpt.rect = rect();
944 menuOpt.menuRect = rect();
945 style()->drawControl(QStyle::CE_MenuBarEmptyArea, &menuOpt, &p,
this);
964void QMenuBar::mousePressEvent(QMouseEvent *e)
967 if (e->button() != Qt::LeftButton)
972 QAction *action = d->actionAt(e->position().toPoint());
973 if (!action || !d->isVisible(action) || !action->isEnabled()) {
974 d->setCurrentAction(
nullptr);
975#if QT_CONFIG(whatsthis)
976 if (QWhatsThis::inWhatsThisMode())
977 QWhatsThis::showText(e->globalPosition().toPoint(), d->whatsThis,
this);
982 if (d->currentAction == action && d->popupState) {
983 if (QMenu *menu = d->activeMenu) {
984 d->activeMenu =
nullptr;
985 menu->setAttribute(Qt::WA_NoMouseReplay);
990 d->setCurrentAction(action,
true);
992 d->hoverAction = action;
993 update(d->actionRect(d->hoverAction));
999void QMenuBar::mouseReleaseEvent(QMouseEvent *e)
1002 if (e->button() != Qt::LeftButton)
1007 d->mouseDown =
false;
1008 QAction *action = d->actionAt(e->position().toPoint());
1011 if (!d->isVisible(action))
1013 if ((d->closePopupMode && action == d->currentAction) || !action || !action->menu()) {
1016 d->setCurrentAction(action,
false);
1018 d->activateAction(action, QAction::Trigger);
1020 d->closePopupMode = 0;
1021 d->hoverAction = action;
1022 update(d->actionRect(d->hoverAction));
1028void QMenuBar::keyPressEvent(QKeyEvent *e)
1031 d->updateGeometries();
1033 if (isRightToLeft()) {
1034 if (key == Qt::Key_Left)
1035 key = Qt::Key_Right;
1036 else if (key == Qt::Key_Right)
1039 if (key == Qt::Key_Tab)
1040 key = Qt::Key_Right;
1041 else if (key == Qt::Key_Backtab)
1044 bool key_consumed =
false;
1050 case Qt::Key_Return: {
1051 if (!style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation,
nullptr,
this) || !d->currentAction)
1053 if (d->currentAction->menu()) {
1054 d->popupAction(d->currentAction,
true);
1055 }
else if (key == Qt::Key_Enter || key == Qt::Key_Return || key == Qt::Key_Space) {
1056 d->activateAction(d->currentAction, QAction::Trigger);
1057 d->setCurrentAction(d->currentAction,
false);
1058 d->setKeyboardMode(
false);
1060 key_consumed =
true;
1064 case Qt::Key_Left: {
1065 if (d->currentAction) {
1066 qsizetype index = d->actions.indexOf(d->currentAction);
1067 if (QAction *nextAction = d->getNextAction(index, key == Qt::Key_Left ? -1 : +1)) {
1068 d->setCurrentAction(nextAction, d->popupState,
true);
1069 key_consumed =
true;
1075 key_consumed =
false;
1078#ifndef QT_NO_SHORTCUT
1079 if (!key_consumed && e->matches(QKeySequence::Cancel)) {
1080 d->setCurrentAction(
nullptr);
1081 d->setKeyboardMode(
false);
1082 key_consumed =
true;
1086 if (!key_consumed &&
1088 (e->modifiers()&(Qt::MetaModifier|Qt::AltModifier))) && e->text().size()==1 && !d->popupState) {
1090 QAction *first =
nullptr, *currentSelected =
nullptr, *firstAfterCurrent =
nullptr;
1092 const QChar c = e->text().at(0).toUpper();
1093 for (qsizetype i = 0; i < d->actions.size(); ++i) {
1094 if (d->actionRects.at(i).isNull())
1096 QAction *act = d->actions.at(i);
1097 QString s = act->text();
1099 qsizetype ampersand = s.indexOf(u'&');
1100 if (ampersand >= 0) {
1101 if (s[ampersand+1].toUpper() == c) {
1105 if (act == d->currentAction)
1106 currentSelected = act;
1107 else if (!firstAfterCurrent && currentSelected)
1108 firstAfterCurrent = act;
1114 QAction *next_action =
nullptr;
1115 if (clashCount >= 1) {
1116 if (clashCount == 1 || !d->currentAction || (currentSelected && !firstAfterCurrent))
1117 next_action = first;
1119 next_action = firstAfterCurrent;
1122 key_consumed =
true;
1123 d->setCurrentAction(next_action,
true,
true);
1135void QMenuBar::mouseMoveEvent(QMouseEvent *e)
1138 if (!(e->buttons() & Qt::LeftButton)) {
1139 d->mouseDown =
false;
1143 if (e->source() != Qt::MouseEventNotSynthesized)
1147 bool popupState = d->popupState || d->mouseDown;
1148 QAction *action = d->actionAt(e->position().toPoint());
1149 QAction *oldHoverAction = d->hoverAction;
1150 if ((action && d->isVisible(action)) || !popupState)
1151 d->setCurrentAction(action, popupState);
1152 if (oldHoverAction != action)
1153 update(d->actionRect(oldHoverAction));
1154 d->hoverAction = action;
1211void QMenuBar::actionEvent(QActionEvent *e)
1214 d->itemsDirty =
true;
1216 if (d->platformMenuBar) {
1217 QPlatformMenuBar *nativeMenuBar = d->platformMenuBar;
1221 auto action =
static_cast<QAction *>(e->action());
1222 if (e->type() == QEvent::ActionAdded) {
1223 QPlatformMenu *menu = d->getPlatformMenu(action);
1225 d->copyActionToPlatformMenu(action, menu);
1227 QPlatformMenu *beforeMenu = d->findInsertionPlatformMenu(action);
1228 d->platformMenuBar->insertMenu(menu, beforeMenu);
1230 }
else if (e->type() == QEvent::ActionRemoved) {
1231 QPlatformMenu *menu = d->getPlatformMenu(action);
1233 d->platformMenuBar->removeMenu(menu);
1234 }
else if (e->type() == QEvent::ActionChanged) {
1235 QPlatformMenu *cur = d->platformMenuBar->menuForTag(
reinterpret_cast<quintptr>(e->action()));
1236 QPlatformMenu *menu = d->getPlatformMenu(action);
1242 d->platformMenuBar->removeMenu(cur);
1244 d->copyActionToPlatformMenu(action, menu);
1246 QPlatformMenu *beforeMenu = d->findInsertionPlatformMenu(action);
1247 d->platformMenuBar->insertMenu(menu, beforeMenu);
1250 d->copyActionToPlatformMenu(action, menu);
1251 d->platformMenuBar->syncMenu(menu);
1256 if (e->type() == QEvent::ActionAdded) {
1257 connect(e->action(), SIGNAL(triggered()),
this, SLOT(_q_actionTriggered()));
1258 connect(e->action(), SIGNAL(hovered()),
this, SLOT(_q_actionHovered()));
1259 }
else if (e->type() == QEvent::ActionRemoved) {
1260 e->action()->disconnect(
this);
1264 if (isVisible() || isNativeMenuBar())
1265 d->updateGeometries();
1309 QWidget *newParent = q->parentWidget();
1314 QWidget *newWindow = newParent ? newParent->window() :
nullptr;
1316 QList<QPointer<QWidget>> newParents;
1323 const auto copy = oldParents;
1324 for (
const QPointer<QWidget> &w : copy) {
1326 if (newParent == w) {
1327 newParents.append(w);
1328 if (newParent != newWindow)
1329 newParent = newParent->parentWidget();
1331 w->removeEventFilter(q);
1337 while (newParent && newParent != newWindow) {
1339 newParents.append(newParent);
1340 newParent->installEventFilter(q);
1341 newParent = newParent->parentWidget();
1344 if (newParent && newWindow) {
1346 newParents.append(newParent);
1347 newParent->installEventFilter(q);
1349 oldParents = newParents;
1356 newWindow->createWinId();
1367void QMenuBar::changeEvent(QEvent *e)
1370 if (e->type() == QEvent::StyleChange) {
1371 d->itemsDirty =
true;
1372 setMouseTracking(style()->styleHint(QStyle::SH_MenuBar_MouseTracking,
nullptr,
this));
1374 resize(parentWidget()->width(), heightForWidth(parentWidget()->width()));
1375 d->updateGeometries();
1376 }
else if (e->type() == QEvent::ParentChange) {
1377 d->handleReparent();
1378 }
else if (e->type() == QEvent::FontChange
1379 || e->type() == QEvent::ApplicationFontChange) {
1380 d->itemsDirty =
true;
1381 d->updateGeometries();
1384 QWidget::changeEvent(e);
1390bool QMenuBar::event(QEvent *e)
1393 switch (e->type()) {
1394 case QEvent::KeyPress: {
1395 QKeyEvent *ke =
static_cast<QKeyEvent *>(e);
1397 if (!d->keyboardState) {
1398 d->setCurrentAction(0);
1402 if (ke->key() == Qt::Key_Tab || ke->key() == Qt::Key_Backtab) {
1408#ifndef QT_NO_SHORTCUT
1409 case QEvent::Shortcut: {
1410 QShortcutEvent *se =
static_cast<QShortcutEvent *>(e);
1411 int shortcutId = se->shortcutId();
1412 for (qsizetype j = 0; j < d->shortcutIndexMap.size(); ++j) {
1413 if (shortcutId == d->shortcutIndexMap.value(j))
1414 d->_q_internalShortcutActivated(j);
1419 d->_q_updateLayout();
1421#ifndef QT_NO_SHORTCUT
1422 case QEvent::ShortcutOverride: {
1423 QKeyEvent *kev =
static_cast<QKeyEvent *>(e);
1425 if (kev->matches(QKeySequence::Cancel) && d->currentAction) {
1432#if QT_CONFIG(whatsthis)
1433 case QEvent::QueryWhatsThis:
1434 e->setAccepted(d->whatsThis.size());
1435 if (QAction *action = d->actionAt(
static_cast<QHelpEvent*>(e)->pos())) {
1436 if (action->whatsThis().size() || action->menu())
1441 case QEvent::LayoutDirectionChange:
1442 d->_q_updateLayout();
1447 return QWidget::event(e);
1453bool QMenuBar::eventFilter(QObject *object, QEvent *event)
1456 if (object && (event->type() == QEvent::ParentChange))
1457 d->handleReparent();
1459 if (object == d->leftWidget || object == d->rightWidget) {
1460 switch (event->type()) {
1461 case QEvent::ShowToParent:
1462 case QEvent::HideToParent:
1463 d->_q_updateLayout();
1470 if (isNativeMenuBar() && event->type() == QEvent::ShowToParent) {
1475 QWidget *widget = qobject_cast<QWidget *>(object);
1476 QWindow *handle = widget ? widget->windowHandle() :
nullptr;
1477 if (handle !=
nullptr)
1478 d->platformMenuBar->handleReparent(handle);
1481 if (style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation,
nullptr,
this)) {
1482 if (d->altPressed) {
1483 switch (event->type()) {
1484 case QEvent::KeyPress:
1485 case QEvent::KeyRelease:
1487 QKeyEvent *kev =
static_cast<QKeyEvent*>(event);
1488 if (kev->key() == Qt::Key_Alt || kev->key() == Qt::Key_Meta) {
1489 if (event->type() == QEvent::KeyPress)
1491 d->setKeyboardMode(!d->keyboardState);
1495 case QEvent::MouseButtonPress:
1496 case QEvent::MouseButtonRelease:
1497 case QEvent::MouseMove:
1498 case QEvent::FocusIn:
1499 case QEvent::FocusOut:
1500 case QEvent::ActivationChange:
1501 case QEvent::Shortcut:
1502 d->altPressed =
false;
1503 qApp->removeEventFilter(
this);
1508 }
else if (isVisible()) {
1509 if (event->type() == QEvent::ShortcutOverride) {
1510 QKeyEvent *kev =
static_cast<QKeyEvent*>(event);
1511 if ((kev->key() == Qt::Key_Alt || kev->key() == Qt::Key_Meta)
1512 && kev->modifiers() == Qt::AltModifier) {
1513 d->altPressed =
true;
1514 qApp->installEventFilter(
this);
1549QSize QMenuBar::minimumSizeHint()
const
1551 Q_D(
const QMenuBar);
1552 const bool as_gui_menubar = !isNativeMenuBar();
1556 const_cast<QMenuBarPrivate*>(d)->updateGeometries();
1557 const int hmargin = style()->pixelMetric(QStyle::PM_MenuBarHMargin,
nullptr,
this);
1558 const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin,
nullptr,
this);
1559 int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth,
nullptr,
this);
1560 int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar,
nullptr,
this);
1561 if (as_gui_menubar) {
1562 int w = parentWidget() ? parentWidget()->width() : QGuiApplication::primaryScreen()->virtualGeometry().width();
1563 d->calcActionRects(w - (2 * fw), 0);
1564 for (qsizetype i = 0; ret.isNull() && i < d->actions.size(); ++i)
1565 ret = d->actionRects.at(i).size();
1566 if (!d->extension->isHidden())
1567 ret += QSize(d->extension->sizeHint().width(), 0);
1568 ret += QSize(2*fw + hmargin, 2*fw + vmargin);
1570 int margin = 2*vmargin + 2*fw + spaceBelowMenuBar;
1571 if (d->leftWidget) {
1572 QSize sz = d->leftWidget->minimumSizeHint();
1573 ret.setWidth(ret.width() + sz.width());
1574 if (sz.height() + margin > ret.height())
1575 ret.setHeight(sz.height() + margin);
1577 if (d->rightWidget) {
1578 QSize sz = d->rightWidget->minimumSizeHint();
1579 ret.setWidth(ret.width() + sz.width());
1580 if (sz.height() + margin > ret.height())
1581 ret.setHeight(sz.height() + margin);
1583 if (as_gui_menubar) {
1584 QStyleOptionMenuItem opt;
1586 opt.menuRect = rect();
1587 opt.state = QStyle::State_None;
1588 opt.menuItemType = QStyleOptionMenuItem::Normal;
1589 opt.checkType = QStyleOptionMenuItem::NotCheckable;
1590 opt.palette = palette();
1591 return style()->sizeFromContents(QStyle::CT_MenuBar, &opt, ret,
this);
1599QSize QMenuBar::sizeHint()
const
1601 Q_D(
const QMenuBar);
1602 const bool as_gui_menubar = !isNativeMenuBar();
1606 const_cast<QMenuBarPrivate*>(d)->updateGeometries();
1607 const int hmargin = style()->pixelMetric(QStyle::PM_MenuBarHMargin,
nullptr,
this);
1608 const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin,
nullptr,
this);
1609 int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth,
nullptr,
this);
1610 int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar,
nullptr,
this);
1611 if (as_gui_menubar) {
1612 const int w = parentWidget() ? parentWidget()->width() : QGuiApplication::primaryScreen()->virtualGeometry().width();
1613 d->calcActionRects(w - (2 * fw), 0);
1614 for (
const auto &actionRect : d->actionRects)
1615 ret = ret.expandedTo(QSize(actionRect.x() + actionRect.width(), actionRect.y() + actionRect.height()));
1618 ret += QSize(fw + hmargin, fw + vmargin);
1620 int margin = 2*vmargin + 2*fw + spaceBelowMenuBar;
1621 if (d->leftWidget) {
1622 QSize sz = d->leftWidget->sizeHint();
1623 sz.rheight() += margin;
1624 ret = ret.expandedTo(sz);
1626 if (d->rightWidget) {
1627 QSize sz = d->rightWidget->sizeHint();
1628 ret.setWidth(ret.width() + sz.width());
1629 if (sz.height() + margin > ret.height())
1630 ret.setHeight(sz.height() + margin);
1632 if (as_gui_menubar) {
1633 QStyleOptionMenuItem opt;
1635 opt.menuRect = rect();
1636 opt.state = QStyle::State_None;
1637 opt.menuItemType = QStyleOptionMenuItem::Normal;
1638 opt.checkType = QStyleOptionMenuItem::NotCheckable;
1639 opt.palette = palette();
1640 return style()->sizeFromContents(QStyle::CT_MenuBar, &opt, ret,
this);
1648int QMenuBar::heightForWidth(
int)
const
1650 Q_D(
const QMenuBar);
1651 const bool as_gui_menubar = !isNativeMenuBar();
1653 const_cast<QMenuBarPrivate*>(d)->updateGeometries();
1655 const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin,
nullptr,
this);
1656 int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth,
nullptr,
this);
1657 int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar,
nullptr,
this);
1658 if (as_gui_menubar) {
1659 for (
const auto &actionRect : d->actionRects)
1660 height = qMax(height, actionRect.height());
1662 height += spaceBelowMenuBar;
1664 height += 2*vmargin;
1666 int margin = 2*vmargin + 2*fw + spaceBelowMenuBar;
1668 height = qMax(d->leftWidget->sizeHint().height() + margin, height);
1670 height = qMax(d->rightWidget->sizeHint().height() + margin, height);
1671 if (as_gui_menubar) {
1672 QStyleOptionMenuItem opt;
1674 opt.menuRect = rect();
1675 opt.state = QStyle::State_None;
1676 opt.menuItemType = QStyleOptionMenuItem::Normal;
1677 opt.checkType = QStyleOptionMenuItem::NotCheckable;
1678 return style()->sizeFromContents(QStyle::CT_MenuBar, &opt, QSize(0, height),
this).height();
1689 QAction *act = actions.at(id);
1690 if (act && act->menu()) {
1691 if (QPlatformMenu *platformMenu = act->menu()->platformMenu()) {
1692 platformMenu->showPopup(q->windowHandle(), actionRects.at(id),
nullptr);
1697 keyboardFocusWidget = QApplication::focusWidget();
1699 if (act && !act->menu()) {
1700 activateAction(act, QAction::Trigger);
1702 autoReleaseTimer.start(100, q);
1703 }
else if (act && q->style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation,
nullptr, q)) {