summaryrefslogtreecommitdiffstats
path: root/src/widgets/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/widgets')
-rw-r--r--src/widgets/widgets/qabstractbutton.cpp3
-rw-r--r--src/widgets/widgets/qmainwindow.cpp1
-rw-r--r--src/widgets/widgets/qmenu.cpp114
-rw-r--r--src/widgets/widgets/qmenu_p.h151
-rw-r--r--src/widgets/widgets/qmenubar.cpp54
-rw-r--r--src/widgets/widgets/qmenubar_p.h4
6 files changed, 174 insertions, 153 deletions
diff --git a/src/widgets/widgets/qabstractbutton.cpp b/src/widgets/widgets/qabstractbutton.cpp
index dbd94e890d..5854472ff0 100644
--- a/src/widgets/widgets/qabstractbutton.cpp
+++ b/src/widgets/widgets/qabstractbutton.cpp
@@ -991,13 +991,14 @@ void QAbstractButton::mousePressEvent(QMouseEvent *e)
void QAbstractButton::mouseReleaseEvent(QMouseEvent *e)
{
Q_D(QAbstractButton);
- d->pressed = false;
if (e->button() != Qt::LeftButton) {
e->ignore();
return;
}
+ d->pressed = false;
+
if (!d->down) {
// refresh is required by QMacStyle to resume the default button animation
d->refresh();
diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp
index d97fedadab..00ee0a9d10 100644
--- a/src/widgets/widgets/qmainwindow.cpp
+++ b/src/widgets/widgets/qmainwindow.cpp
@@ -545,6 +545,7 @@ void QMainWindow::setMenuBar(QMenuBar *menuBar)
menuBar->setCornerWidget(cornerWidget, Qt::TopRightCorner);
}
oldMenuBar->hide();
+ oldMenuBar->setParent(nullptr);
oldMenuBar->deleteLater();
}
topLayout->setMenuBar(menuBar);
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index cf6167bace..c4bb02fd5b 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -234,9 +234,6 @@ void QMenuPrivate::setPlatformMenu(QPlatformMenu *menu)
}
}
-// forward declare function
-static void copyActionToPlatformItem(const QAction *action, QPlatformMenuItem *item, QPlatformMenu *itemsMenu);
-
void QMenuPrivate::syncPlatformMenu()
{
Q_Q(QMenu);
@@ -246,19 +243,64 @@ void QMenuPrivate::syncPlatformMenu()
QPlatformMenuItem *beforeItem = nullptr;
const QList<QAction*> actions = q->actions();
for (QList<QAction*>::const_reverse_iterator it = actions.rbegin(), end = actions.rend(); it != end; ++it) {
- QPlatformMenuItem *menuItem = platformMenu->createMenuItem();
- QAction *action = *it;
- menuItem->setTag(reinterpret_cast<quintptr>(action));
- QObject::connect(menuItem, SIGNAL(activated()), action, SLOT(trigger()), Qt::QueuedConnection);
- QObject::connect(menuItem, SIGNAL(hovered()), action, SIGNAL(hovered()), Qt::QueuedConnection);
- copyActionToPlatformItem(action, menuItem, platformMenu.data());
- platformMenu->insertMenuItem(menuItem, beforeItem);
+ QPlatformMenuItem *menuItem = insertActionInPlatformMenu(*it, beforeItem);
beforeItem = menuItem;
}
platformMenu->syncSeparatorsCollapsible(collapsibleSeparators);
platformMenu->setEnabled(q->isEnabled());
}
+void QMenuPrivate::copyActionToPlatformItem(const QAction *action, QPlatformMenuItem *item)
+{
+ item->setText(action->text());
+ item->setIsSeparator(action->isSeparator());
+ if (action->isIconVisibleInMenu()) {
+ item->setIcon(action->icon());
+ if (QWidget *w = action->parentWidget()) {
+ QStyleOption opt;
+ opt.init(w);
+ item->setIconSize(w->style()->pixelMetric(QStyle::PM_SmallIconSize, &opt, w));
+ } else {
+ QStyleOption opt;
+ item->setIconSize(qApp->style()->pixelMetric(QStyle::PM_SmallIconSize, &opt, 0));
+ }
+ } else {
+ item->setIcon(QIcon());
+ }
+ item->setVisible(action->isVisible());
+#if QT_CONFIG(shortcut)
+ item->setShortcut(action->shortcut());
+#endif
+ item->setCheckable(action->isCheckable());
+ item->setChecked(action->isChecked());
+ item->setHasExclusiveGroup(action->actionGroup() && action->actionGroup()->isExclusive());
+ item->setFont(action->font());
+ item->setRole((QPlatformMenuItem::MenuRole) action->menuRole());
+ item->setEnabled(action->isEnabled());
+
+ if (action->menu()) {
+ if (!action->menu()->platformMenu())
+ action->menu()->setPlatformMenu(platformMenu->createSubMenu());
+ item->setMenu(action->menu()->platformMenu());
+ } else {
+ item->setMenu(0);
+ }
+}
+
+QPlatformMenuItem * QMenuPrivate::insertActionInPlatformMenu(const QAction *action, QPlatformMenuItem *beforeItem)
+{
+ QPlatformMenuItem *menuItem = platformMenu->createMenuItem();
+ Q_ASSERT(menuItem);
+
+ menuItem->setTag(reinterpret_cast<quintptr>(action));
+ QObject::connect(menuItem, &QPlatformMenuItem::activated, action, &QAction::trigger, Qt::QueuedConnection);
+ QObject::connect(menuItem, &QPlatformMenuItem::hovered, action, &QAction::hovered, Qt::QueuedConnection);
+ copyActionToPlatformItem(action, menuItem);
+ platformMenu->insertMenuItem(menuItem, beforeItem);
+
+ return menuItem;
+}
+
int QMenuPrivate::scrollerHeight() const
{
Q_Q(const QMenu);
@@ -2338,6 +2380,12 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
d->updateLayoutDirection();
d->adjustMenuScreen(p);
+ const bool contextMenu = d->isContextMenu();
+ if (d->lastContextMenu != contextMenu) {
+ d->itemsDirty = true;
+ d->lastContextMenu = contextMenu;
+ }
+
#if QT_CONFIG(menubar)
// if this menu is part of a chain attached to a QMenuBar, set the
// _NET_WM_WINDOW_TYPE_DROPDOWN_MENU X11 window type
@@ -3476,43 +3524,6 @@ QMenu::timerEvent(QTimerEvent *e)
}
}
-static void copyActionToPlatformItem(const QAction *action, QPlatformMenuItem *item, QPlatformMenu *itemsMenu)
-{
- item->setText(action->text());
- item->setIsSeparator(action->isSeparator());
- if (action->isIconVisibleInMenu()) {
- item->setIcon(action->icon());
- if (QWidget *w = action->parentWidget()) {
- QStyleOption opt;
- opt.init(w);
- item->setIconSize(w->style()->pixelMetric(QStyle::PM_SmallIconSize, &opt, w));
- } else {
- QStyleOption opt;
- item->setIconSize(qApp->style()->pixelMetric(QStyle::PM_SmallIconSize, &opt, 0));
- }
- } else {
- item->setIcon(QIcon());
- }
- item->setVisible(action->isVisible());
-#ifndef QT_NO_SHORTCUT
- item->setShortcut(action->shortcut());
-#endif
- item->setCheckable(action->isCheckable());
- item->setChecked(action->isChecked());
- item->setHasExclusiveGroup(action->actionGroup() && action->actionGroup()->isExclusive());
- item->setFont(action->font());
- item->setRole((QPlatformMenuItem::MenuRole) action->menuRole());
- item->setEnabled(action->isEnabled());
-
- if (action->menu()) {
- if (!action->menu()->platformMenu())
- action->menu()->setPlatformMenu(itemsMenu->createSubMenu());
- item->setMenu(action->menu()->platformMenu());
- } else {
- item->setMenu(0);
- }
-}
-
/*!
\reimp
*/
@@ -3566,15 +3577,10 @@ void QMenu::actionEvent(QActionEvent *e)
if (!d->platformMenu.isNull()) {
if (e->type() == QEvent::ActionAdded) {
- QPlatformMenuItem *menuItem = d->platformMenu->createMenuItem();
- menuItem->setTag(reinterpret_cast<quintptr>(e->action()));
- QObject::connect(menuItem, SIGNAL(activated()), e->action(), SLOT(trigger()));
- QObject::connect(menuItem, SIGNAL(hovered()), e->action(), SIGNAL(hovered()));
- copyActionToPlatformItem(e->action(), menuItem, d->platformMenu);
QPlatformMenuItem *beforeItem = e->before()
? d->platformMenu->menuItemForTag(reinterpret_cast<quintptr>(e->before()))
: nullptr;
- d->platformMenu->insertMenuItem(menuItem, beforeItem);
+ d->insertActionInPlatformMenu(e->action(), beforeItem);
} else if (e->type() == QEvent::ActionRemoved) {
QPlatformMenuItem *menuItem = d->platformMenu->menuItemForTag(reinterpret_cast<quintptr>(e->action()));
d->platformMenu->removeMenuItem(menuItem);
@@ -3582,7 +3588,7 @@ void QMenu::actionEvent(QActionEvent *e)
} else if (e->type() == QEvent::ActionChanged) {
QPlatformMenuItem *menuItem = d->platformMenu->menuItemForTag(reinterpret_cast<quintptr>(e->action()));
if (menuItem) {
- copyActionToPlatformItem(e->action(), menuItem, d->platformMenu);
+ d->copyActionToPlatformItem(e->action(), menuItem);
d->platformMenu->syncMenuItem(menuItem);
}
}
diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h
index fac58f59ab..b6afb05e3a 100644
--- a/src/widgets/widgets/qmenu_p.h
+++ b/src/widgets/widgets/qmenu_p.h
@@ -91,19 +91,10 @@ class QMenuSloppyState
Q_DISABLE_COPY(QMenuSloppyState)
public:
QMenuSloppyState()
- : m_menu(nullptr)
- , m_enabled(false)
+ : m_enabled(false)
, m_uni_directional(false)
, m_select_other_actions(false)
- , m_first_mouse(true)
- , m_init_guard(false)
, m_use_reset_action(true)
- , m_uni_dir_discarded_count(0)
- , m_uni_dir_fail_at_count(0)
- , m_timeout(0)
- , m_reset_action(nullptr)
- , m_origin_action(nullptr)
- , m_parent(nullptr)
{ }
~QMenuSloppyState() { reset(); }
@@ -252,44 +243,46 @@ public:
QMenu *subMenu() const { return m_sub_menu; }
private:
- QMenu *m_menu;
- bool m_enabled;
- bool m_uni_directional;
- bool m_select_other_actions;
- bool m_first_mouse;
- bool m_init_guard;
- bool m_discard_state_when_entering_parent;
- bool m_dont_start_time_on_leave;
- bool m_use_reset_action;
- short m_uni_dir_discarded_count;
- short m_uni_dir_fail_at_count;
- short m_timeout;
- QBasicTimer m_time;
- QAction *m_reset_action;
- QAction *m_origin_action;
+ QMenu *m_menu = nullptr;
+ QAction *m_reset_action = nullptr;
+ QAction *m_origin_action = nullptr;
QRectF m_action_rect;
QPointF m_previous_point;
QPointer<QMenu> m_sub_menu;
- QMenuSloppyState *m_parent;
+ QMenuSloppyState *m_parent = nullptr;
+ QBasicTimer m_time;
+ short m_uni_dir_discarded_count = 0;
+ short m_uni_dir_fail_at_count = 0;
+ short m_timeout = 0;
+ bool m_init_guard = false;
+ bool m_first_mouse = true;
+
+ bool m_enabled : 1;
+ bool m_uni_directional : 1;
+ bool m_select_other_actions : 1;
+ bool m_discard_state_when_entering_parent : 1;
+ bool m_dont_start_time_on_leave : 1;
+ bool m_use_reset_action : 1;
};
class QMenuPrivate : public QWidgetPrivate
{
Q_DECLARE_PUBLIC(QMenu)
public:
- QMenuPrivate() : itemsDirty(0), maxIconWidth(0), tabWidth(0), ncols(0),
- collapsibleSeparators(true), toolTipsVisible(false),
- activationRecursionGuard(false), delayedPopupGuard(false),
- hasReceievedEnter(false),
- hasHadMouse(0), aboutToHide(0), motions(0),
- currentAction(0),
-#ifdef QT_KEYPAD_NAVIGATION
- selectAction(0),
- cancelAction(0),
-#endif
- scroll(0), eventLoop(0), tearoff(0), tornoff(0), tearoffHighlighted(0),
- hasCheckableItems(0), doChildEffects(false), platformMenu(0),
- scrollUpTearOffItem(nullptr), scrollDownItem(nullptr)
+ QMenuPrivate() :
+ itemsDirty(false),
+ hasCheckableItems(false),
+ lastContextMenu(false),
+ collapsibleSeparators(true),
+ toolTipsVisible(false),
+ delayedPopupGuard(false),
+ hasReceievedEnter(false),
+ hasHadMouse(false),
+ aboutToHide(false),
+ tearoff(false),
+ tornoff(false),
+ tearoffHighlighted(false),
+ doChildEffects(false)
{ }
~QMenuPrivate()
@@ -302,6 +295,9 @@ public:
QPlatformMenu *createPlatformMenu();
void setPlatformMenu(QPlatformMenu *menu);
void syncPlatformMenu();
+ void copyActionToPlatformItem(const QAction *action, QPlatformMenuItem *item);
+ QPlatformMenuItem *insertActionInPlatformMenu(const QAction *action, QPlatformMenuItem *beforeItem);
+
#ifdef Q_OS_OSX
void moveWidgetToPlatformItem(QWidget *w, QPlatformMenuItem* item);
#endif
@@ -312,8 +308,6 @@ public:
bool isContextMenu() const;
//item calculations
- mutable uint itemsDirty : 1;
- mutable uint maxIconWidth, tabWidth;
QRect actionRect(QAction *) const;
mutable QVector<QRect> actionRects;
@@ -322,31 +316,19 @@ public:
void updateActionRects(const QRect &screen) const;
QRect popupGeometry() const;
QRect popupGeometry(int screen) const;
- mutable uint ncols : 4; //4 bits is probably plenty
- uint collapsibleSeparators : 1;
- uint toolTipsVisible : 1;
int getLastVisibleAction() const;
- bool activationRecursionGuard;
- bool delayedPopupGuard;
- bool hasReceievedEnter;
-
//selection
static QMenu *mouseDown;
QPoint mousePopupPos;
- uint hasHadMouse : 1;
- uint aboutToHide : 1;
- int motions;
- int mousePopupDelay;
- QAction *currentAction;
+
+ QAction *currentAction = nullptr;
#ifdef QT_KEYPAD_NAVIGATION
- QAction *selectAction;
- QAction *cancelAction;
+ QAction *selectAction = nullptr;
+ QAction *cancelAction = nullptr;
#endif
struct DelayState {
DelayState()
- : parent(0)
- , action(0)
{ }
void initialize(QMenu *parent)
{
@@ -366,9 +348,9 @@ public:
timer.stop();
}
- QMenu *parent;
+ QMenu *parent = nullptr;
+ QAction *action = nullptr;
QBasicTimer timer;
- QAction *action;
} delayState;
enum SelectionReason {
SelectedFromKeyboard,
@@ -385,19 +367,20 @@ public:
struct QMenuScroller {
enum ScrollLocation { ScrollStay, ScrollBottom, ScrollTop, ScrollCenter };
enum ScrollDirection { ScrollNone=0, ScrollUp=0x01, ScrollDown=0x02 };
- uint scrollFlags : 2, scrollDirection : 2;
- int scrollOffset;
+ int scrollOffset = 0;
QBasicTimer scrollTimer;
+ quint8 scrollFlags = ScrollNone;
+ quint8 scrollDirection = ScrollNone;
- QMenuScroller() : scrollFlags(ScrollNone), scrollDirection(ScrollNone), scrollOffset(0) { }
+ QMenuScroller() { }
~QMenuScroller() { }
- } *scroll;
+ } *scroll = nullptr;
void scrollMenu(QMenuScroller::ScrollLocation location, bool active=false);
void scrollMenu(QMenuScroller::ScrollDirection direction, bool page=false, bool active=false);
void scrollMenu(QAction *action, QMenuScroller::ScrollLocation location, bool active=false);
//synchronous operation (ie exec())
- QEventLoop *eventLoop;
+ QEventLoop *eventLoop = nullptr;
QPointer<QAction> syncAction;
//search buffer
@@ -423,18 +406,15 @@ public:
inline int indexOf(QAction *act) const { return q_func()->actions().indexOf(act); }
//tear off support
- uint tearoff : 1, tornoff : 1, tearoffHighlighted : 1;
QPointer<QTornOffMenu> tornPopup;
- mutable bool hasCheckableItems;
-
QMenuSloppyState sloppyState;
//default action
QPointer<QAction> defaultAction;
- QAction *menuAction;
- QAction *defaultMenuAction;
+ QAction *menuAction = nullptr;
+ QAction *defaultMenuAction = nullptr;
void setOverrideMenuAction(QAction *);
void _q_overrideMenuActionDestroyed();
@@ -452,9 +432,6 @@ public:
void adjustMenuScreen(const QPoint &p);
void updateLayoutDirection();
- //menu fading/scrolling effects
- bool doChildEffects;
-
QPointer<QPlatformMenu> platformMenu;
QPointer<QAction> actionAboutToTrigger;
@@ -473,12 +450,38 @@ public:
QMenuPrivate *menuPrivate;
Type scrollType;
};
- ScrollerTearOffItem *scrollUpTearOffItem;
- ScrollerTearOffItem *scrollDownItem;
+ ScrollerTearOffItem *scrollUpTearOffItem = nullptr;
+ ScrollerTearOffItem *scrollDownItem = nullptr;
void drawScroller(QPainter *painter, ScrollerTearOffItem::Type type, const QRect &rect);
void drawTearOff(QPainter *painter, const QRect &rect);
QRect rect() const;
+
+ mutable uint maxIconWidth = 0;
+ mutable uint tabWidth = 0;
+ int motions = 0;
+ int mousePopupDelay = 0;
+
+ bool activationRecursionGuard = false;
+
+ mutable quint8 ncols = 0; // "255cols ought to be enough for anybody."
+
+ mutable bool itemsDirty : 1;
+ mutable bool hasCheckableItems : 1;
+ bool lastContextMenu : 1;
+ bool collapsibleSeparators : 1;
+ bool toolTipsVisible : 1;
+ bool delayedPopupGuard : 1;
+ bool hasReceievedEnter : 1;
+ // Selection
+ bool hasHadMouse : 1;
+ bool aboutToHide : 1;
+ // Tear-off menus
+ bool tearoff : 1;
+ bool tornoff : 1;
+ bool tearoffHighlighted : 1;
+ //menu fading/scrolling effects
+ bool doChildEffects : 1;
};
QT_END_NAMESPACE
diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp
index c469c0b793..80c6d28e85 100644
--- a/src/widgets/widgets/qmenubar.cpp
+++ b/src/widgets/widgets/qmenubar.cpp
@@ -1188,7 +1188,7 @@ void QMenuBar::leaveEvent(QEvent *)
d->setCurrentAction(0);
}
-QPlatformMenu *QMenuBarPrivate::getPlatformMenu(QAction *action)
+QPlatformMenu *QMenuBarPrivate::getPlatformMenu(const QAction *action)
{
if (!action || !action->menu())
return 0;
@@ -1203,6 +1203,29 @@ QPlatformMenu *QMenuBarPrivate::getPlatformMenu(QAction *action)
return platformMenu;
}
+QPlatformMenu *QMenuBarPrivate::findInsertionPlatformMenu(const QAction *action)
+{
+ Q_Q(QMenuBar);
+ QPlatformMenu *beforeMenu = nullptr;
+ for (int beforeIndex = indexOf(const_cast<QAction *>(action)) + 1;
+ !beforeMenu && (beforeIndex < q->actions().size());
+ ++beforeIndex) {
+ beforeMenu = getPlatformMenu(q->actions().at(beforeIndex));
+ }
+
+ return beforeMenu;
+}
+
+void QMenuBarPrivate::copyActionToPlatformMenu(const QAction *action, QPlatformMenu *menu)
+{
+ const auto tag = reinterpret_cast<quintptr>(action);
+ if (menu->tag() != tag)
+ menu->setTag(tag);
+ menu->setText(action->text());
+ menu->setVisible(action->isVisible());
+ menu->setEnabled(action->isEnabled());
+}
+
/*!
\reimp
*/
@@ -1219,16 +1242,9 @@ void QMenuBar::actionEvent(QActionEvent *e)
if (e->type() == QEvent::ActionAdded) {
QPlatformMenu *menu = d->getPlatformMenu(e->action());
if (menu) {
- QPlatformMenu* beforeMenu = NULL;
- for (int beforeIndex = d->indexOf(e->action()) + 1;
- !beforeMenu && (beforeIndex < actions().size());
- ++beforeIndex)
- {
- beforeMenu = d->getPlatformMenu(actions().at(beforeIndex));
- }
+ d->copyActionToPlatformMenu(e->action(), menu);
- menu->setTag(reinterpret_cast<quintptr>(e->action()));
- menu->setText(e->action()->text());
+ QPlatformMenu *beforeMenu = d->findInsertionPlatformMenu(e->action());
d->platformMenuBar->insertMenu(menu, beforeMenu);
}
} else if (e->type() == QEvent::ActionRemoved) {
@@ -1236,7 +1252,7 @@ void QMenuBar::actionEvent(QActionEvent *e)
if (menu)
d->platformMenuBar->removeMenu(menu);
} else if (e->type() == QEvent::ActionChanged) {
- QPlatformMenu* cur = d->platformMenuBar->menuForTag(reinterpret_cast<quintptr>(e->action()));
+ QPlatformMenu *cur = d->platformMenuBar->menuForTag(reinterpret_cast<quintptr>(e->action()));
QPlatformMenu *menu = d->getPlatformMenu(e->action());
// the menu associated with the action can change, need to
@@ -1245,21 +1261,13 @@ void QMenuBar::actionEvent(QActionEvent *e)
if (cur)
d->platformMenuBar->removeMenu(cur);
if (menu) {
- menu->setTag(reinterpret_cast<quintptr>(e->action()));
-
- QPlatformMenu* beforeMenu = NULL;
- for (int beforeIndex = d->indexOf(e->action()) + 1;
- !beforeMenu && (beforeIndex < actions().size());
- ++beforeIndex)
- {
- beforeMenu = d->getPlatformMenu(actions().at(beforeIndex));
- }
+ d->copyActionToPlatformMenu(e->action(), menu);
+
+ QPlatformMenu *beforeMenu = d->findInsertionPlatformMenu(e->action());
d->platformMenuBar->insertMenu(menu, beforeMenu);
}
} else if (menu) {
- menu->setText(e->action()->text());
- menu->setVisible(e->action()->isVisible());
- menu->setEnabled(e->action()->isEnabled());
+ d->copyActionToPlatformMenu(e->action(), menu);
d->platformMenuBar->syncMenu(menu);
}
}
diff --git a/src/widgets/widgets/qmenubar_p.h b/src/widgets/widgets/qmenubar_p.h
index 01d8793a3a..c276a4512d 100644
--- a/src/widgets/widgets/qmenubar_p.h
+++ b/src/widgets/widgets/qmenubar_p.h
@@ -132,7 +132,9 @@ public:
QBasicTimer autoReleaseTimer;
QPlatformMenuBar *platformMenuBar;
- QPlatformMenu *getPlatformMenu(QAction *action);
+ QPlatformMenu *getPlatformMenu(const QAction *action);
+ QPlatformMenu *findInsertionPlatformMenu(const QAction *action);
+ void copyActionToPlatformMenu(const QAction *e, QPlatformMenu *menu);
inline int indexOf(QAction *act) const { return q_func()->actions().indexOf(act); }
};