summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre Rossi <pierre.rossi@nokia.com>2011-01-10 18:46:19 +0100
committerQt Commercial Integration <QtCommercial@digia.com>2012-01-31 12:25:02 +0200
commitfd8df6ad5640cbdb4f4d24b8dcd72e14b063cc76 (patch)
tree73e3c49a3db8eb255509b8ada90e20e164afb54a
parent8b6cbe211675828ad2a53d109e85af2503ffe93c (diff)
Fix a bug with menu overflowing from a lower resolution second screen.
The menu needs to take into account the screen geometry of the screen it's about to be shown on (not the last screen it was shown on) when updating its actions rects Task-number: QTBUG-2748 Reviewed-by: Thierry
-rw-r--r--src/gui/widgets/qmenu.cpp61
-rw-r--r--src/gui/widgets/qmenu_p.h4
2 files changed, 51 insertions, 14 deletions
diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp
index 118c073385..2a9a3a99f7 100644
--- a/src/gui/widgets/qmenu.cpp
+++ b/src/gui/widgets/qmenu.cpp
@@ -240,6 +240,12 @@ QList<QPointer<QWidget> > QMenuPrivate::calcCausedStack() const
void QMenuPrivate::updateActionRects() const
{
Q_Q(const QMenu);
+ updateActionRects(popupGeometry(q));
+}
+
+void QMenuPrivate::updateActionRects(const QRect &screen) const
+{
+ Q_Q(const QMenu);
if (!itemsDirty)
return;
@@ -249,20 +255,10 @@ void QMenuPrivate::updateActionRects() const
actionRects.resize(actions.count());
actionRects.fill(QRect());
- //let's try to get the last visible action
- int lastVisibleAction = actions.count() - 1;
- for(;lastVisibleAction >= 0; --lastVisibleAction) {
- const QAction *action = actions.at(lastVisibleAction);
- if (action->isVisible()) {
- //removing trailing separators
- if (action->isSeparator() && collapsibleSeparators)
- continue;
- break;
- }
- }
+ int lastVisibleAction = getLastVisibleAction();
int max_column_width = 0,
- dh = popupGeometry(q).height(),
+ dh = screen.height(),
y = 0;
QStyle *style = q->style();
QStyleOption opt;
@@ -394,6 +390,34 @@ void QMenuPrivate::updateActionRects() const
itemsDirty = 0;
}
+QSize QMenuPrivate::adjustMenuSizeForScreen(const QRect &screen)
+{
+ Q_Q(QMenu);
+ QSize ret = screen.size();
+ itemsDirty = true;
+ updateActionRects(screen);
+ const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q);
+ ret.setWidth(actionRects.at(getLastVisibleAction()).right() + fw);
+ return ret;
+}
+
+int QMenuPrivate::getLastVisibleAction() const
+{
+ //let's try to get the last visible action
+ int lastVisibleAction = actions.count() - 1;
+ for (;lastVisibleAction >= 0; --lastVisibleAction) {
+ const QAction *action = actions.at(lastVisibleAction);
+ if (action->isVisible()) {
+ //removing trailing separators
+ if (action->isSeparator() && collapsibleSeparators)
+ continue;
+ break;
+ }
+ }
+ return lastVisibleAction;
+}
+
+
QRect QMenuPrivate::actionRect(QAction *act) const
{
int index = actions.indexOf(act);
@@ -1825,9 +1849,20 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
else
#endif
screen = d->popupGeometry(QApplication::desktop()->screenNumber(p));
-
const int desktopFrame = style()->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, this);
bool adjustToDesktop = !window()->testAttribute(Qt::WA_DontShowOnScreen);
+
+ // if the screens have very different geometries and the menu is too big, we have to recalculate
+ if (size.height() > screen.height() || size.width() > screen.width()) {
+ size = d->adjustMenuSizeForScreen(screen);
+ adjustToDesktop = true;
+ }
+ // Layout is not right, we might be able to save horizontal space
+ if (d->ncols >1 && size.height() < screen.height()) {
+ size = d->adjustMenuSizeForScreen(screen);
+ adjustToDesktop = true;
+ }
+
#ifdef QT_KEYPAD_NAVIGATION
if (!atAction && QApplication::keypadNavigationEnabled()) {
// Try to have one item activated
diff --git a/src/gui/widgets/qmenu_p.h b/src/gui/widgets/qmenu_p.h
index 809555d232..0e6379990f 100644
--- a/src/gui/widgets/qmenu_p.h
+++ b/src/gui/widgets/qmenu_p.h
@@ -194,10 +194,13 @@ public:
mutable QVector<QRect> actionRects;
mutable QHash<QAction *, QWidget *> widgetItems;
void updateActionRects() const;
+ void updateActionRects(const QRect &screen) const;
QRect popupGeometry(const QWidget *widget) const;
QRect popupGeometry(int screen = -1) const;
mutable uint ncols : 4; //4 bits is probably plenty
uint collapsibleSeparators : 1;
+ QSize adjustMenuSizeForScreen(const QRect & screen);
+ int getLastVisibleAction() const;
bool activationRecursionGuard;
@@ -296,7 +299,6 @@ public:
void updateLayoutDirection();
-
//menu fading/scrolling effects
bool doChildEffects;