diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/kernel/kernel.pri | 1 | ||||
-rw-r--r-- | src/gui/kernel/qdesktopwidget.cpp | 67 | ||||
-rw-r--r-- | src/gui/kernel/qdesktopwidget.h | 6 | ||||
-rw-r--r-- | src/gui/kernel/qwidget.cpp | 22 | ||||
-rw-r--r-- | src/gui/kernel/qwidget_p.h | 53 | ||||
-rw-r--r-- | src/gui/widgets/qmenu.cpp | 31 | ||||
-rw-r--r-- | src/gui/widgets/qmenu_p.h | 3 | ||||
-rw-r--r-- | src/gui/widgets/qpushbutton.cpp | 4 |
8 files changed, 155 insertions, 32 deletions
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri index 53c2611..8859358 100644 --- a/src/gui/kernel/kernel.pri +++ b/src/gui/kernel/kernel.pri @@ -84,6 +84,7 @@ SOURCES += \ kernel/qgesturerecognizer.cpp \ kernel/qgesturemanager.cpp \ kernel/qsoftkeymanager.cpp \ + kernel/qdesktopwidget.cpp \ kernel/qguiplatformplugin.cpp win32 { diff --git a/src/gui/kernel/qdesktopwidget.cpp b/src/gui/kernel/qdesktopwidget.cpp new file mode 100644 index 0000000..b1e1008 --- /dev/null +++ b/src/gui/kernel/qdesktopwidget.cpp @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qglobal.h" + +QT_BEGIN_NAMESPACE + +#include "qdesktopwidget.h" +#include "qwidget_p.h" + +const QRect QDesktopWidget::screenGeometry(const QWidget *widget) const +{ + QRect rect = QWidgetPrivate::screenGeometry(widget); + if (rect.isNull()) + return screenGeometry(screenNumber(widget)); + else return rect; +} + +const QRect QDesktopWidget::availableGeometry(const QWidget *widget) const +{ + QRect rect = QWidgetPrivate::screenGeometry(widget); + if (rect.isNull()) + return availableGeometry(screenNumber(widget)); + else + return rect; +} + +QT_END_NAMESPACE + diff --git a/src/gui/kernel/qdesktopwidget.h b/src/gui/kernel/qdesktopwidget.h index 85f479e..6e3447c 100644 --- a/src/gui/kernel/qdesktopwidget.h +++ b/src/gui/kernel/qdesktopwidget.h @@ -75,14 +75,12 @@ public: QWidget *screen(int screen = -1); const QRect screenGeometry(int screen = -1) const; - const QRect screenGeometry(const QWidget *widget) const - { return screenGeometry(screenNumber(widget)); } + const QRect screenGeometry(const QWidget *widget) const; const QRect screenGeometry(const QPoint &point) const { return screenGeometry(screenNumber(point)); } const QRect availableGeometry(int screen = -1) const; - const QRect availableGeometry(const QWidget *widget) const - { return availableGeometry(screenNumber(widget)); } + const QRect availableGeometry(const QWidget *widget) const; const QRect availableGeometry(const QPoint &point) const { return availableGeometry(screenNumber(point)); } diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 7dc3ae9..e561aca 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -149,24 +149,6 @@ static inline bool hasBackingStoreSupport() #endif } -/*! - \internal - - Returns true if \a p or any of its parents enable the - Qt::BypassGraphicsProxyWidget window flag. Used in QWidget::show() and - QWidget::setParent() to determine whether it's necessary to embed the - widget into a QGraphicsProxyWidget or not. -*/ -static inline bool bypassGraphicsProxyWidget(QWidget *p) -{ - while (p) { - if (p->windowFlags() & Qt::BypassGraphicsProxyWidget) - return true; - p = p->parentWidget(); - } - return false; -} - #ifdef Q_WS_MAC # define QT_NO_PAINT_DEBUG #endif @@ -5473,6 +5455,7 @@ QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint * return pixmap; } +#ifndef QT_NO_GRAPHICSVIEW /*! \internal @@ -5481,7 +5464,7 @@ QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint * If successful, the function returns the proxy that embeds the widget, or 0 if no embedded widget was found. */ -QGraphicsProxyWidget * QWidgetPrivate::nearestGraphicsProxyWidget(QWidget *origin) +QGraphicsProxyWidget * QWidgetPrivate::nearestGraphicsProxyWidget(const QWidget *origin) { if (origin) { QWExtra *extra = origin->d_func()->extra; @@ -5491,6 +5474,7 @@ QGraphicsProxyWidget * QWidgetPrivate::nearestGraphicsProxyWidget(QWidget *origi } return 0; } +#endif /*! \property QWidget::locale diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index a549740..2132474 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -63,7 +63,9 @@ #include "QtGui/qstyle.h" #include "QtGui/qapplication.h" #include <private/qgraphicseffect_p.h> - +#include "QtGui/qgraphicsproxywidget.h" +#include "QtGui/qgraphicsscene.h" +#include "QtGui/qgraphicsview.h" #include <private/qgesture_p.h> #ifdef Q_WS_WIN @@ -180,7 +182,9 @@ struct QWExtra { // Regular pointers (keep them together to avoid gaps on 64 bits architectures). void *glContext; // if the widget is hijacked by QGLWindowSurface QTLWExtra *topextra; // only useful for TLWs +#ifndef QT_NO_GRAPHICSVIEW QGraphicsProxyWidget *proxyWidget; // if the widget is embedded +#endif #ifndef QT_NO_CURSOR QCursor *curs; #endif @@ -235,6 +239,24 @@ struct QWExtra { #endif }; +/*! + \internal + + Returns true if \a p or any of its parents enable the + Qt::BypassGraphicsProxyWidget window flag. Used in QWidget::show() and + QWidget::setParent() to determine whether it's necessary to embed the + widget into a QGraphicsProxyWidget or not. +*/ +static inline bool bypassGraphicsProxyWidget(const QWidget *p) +{ + while (p) { + if (p->windowFlags() & Qt::BypassGraphicsProxyWidget) + return true; + p = p->parentWidget(); + } + return false; +} + class Q_GUI_EXPORT QWidgetPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QWidget) @@ -344,7 +366,9 @@ public: QPainter *beginSharedPainter(); bool endSharedPainter(); - static QGraphicsProxyWidget * nearestGraphicsProxyWidget(QWidget *origin); +#ifndef QT_NO_GRAPHICSVIEW + static QGraphicsProxyWidget * nearestGraphicsProxyWidget(const QWidget *origin); +#endif QWindowSurface *createDefaultWindowSurface(); QWindowSurface *createDefaultWindowSurface_sys(); void repaint_sys(const QRegion &rgn); @@ -441,6 +465,31 @@ public: void setModal_sys(); + // This is an helper function that return the available geometry for + // a widget and takes care is this one is in QGraphicsView. + // If the widget is not embed in a scene then the geometry available is + // null, we let QDesktopWidget decide for us. + static QRect screenGeometry(const QWidget *widget) + { + QRect screen; +#ifndef QT_NO_GRAPHICSVIEW + QGraphicsProxyWidget *ancestorProxy = widget->d_func()->nearestGraphicsProxyWidget(widget); + //It's embedded if it has an ancestor + if (ancestorProxy) { + if (!bypassGraphicsProxyWidget(widget)) { + // One view, let be smart and return the viewport rect then the popup is aligned + if (ancestorProxy->scene()->views().size() == 1) { + QGraphicsView *view = ancestorProxy->scene()->views().at(0); + screen = view->mapToScene(view->viewport()->rect()).boundingRect().toRect(); + } else { + screen = ancestorProxy->scene()->sceneRect().toRect(); + } + } + } +#endif + return screen; + } + inline void setRedirected(QPaintDevice *replacement, const QPoint &offset) { Q_ASSERT(q_func()->testAttribute(Qt::WA_WState_InPaintEvent)); diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index 687e1bc..324bc90 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -180,6 +180,21 @@ int QMenuPrivate::scrollerHeight() const } //Windows and KDE allows menus to cover the taskbar, while GNOME and Mac don't +QRect QMenuPrivate::popupGeometry(const QWidget *widget) const +{ +#ifdef Q_WS_WIN + return QApplication::desktop()->screenGeometry(widget); +#elif defined Q_WS_X11 + if (X11->desktopEnvironment == DE_KDE) + return QApplication::desktop()->screenGeometry(widget); + else + return QApplication::desktop()->availableGeometry(widget); +#else + return QApplication::desktop()->availableGeometry(widget); +#endif +} + +//Windows and KDE allows menus to cover the taskbar, while GNOME and Mac don't QRect QMenuPrivate::popupGeometry(int screen) const { #ifdef Q_WS_WIN @@ -234,7 +249,7 @@ void QMenuPrivate::updateActionRects() const } int max_column_width = 0, - dh = popupGeometry(QApplication::desktop()->screenNumber(q)).height(), + dh = popupGeometry(q).height(), y = 0; QStyle *style = q->style(); QStyleOption opt; @@ -744,7 +759,7 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc if (newScrollFlags & QMenuScroller::ScrollUp) newOffset -= vmargin; - QRect screen = popupGeometry(QApplication::desktop()->screenNumber(q)); + QRect screen = popupGeometry(q); const int desktopFrame = q->style()->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, q); if (q->height() < screen.height()-(desktopFrame*2)-1) { QRect geom = q->geometry(); @@ -1789,7 +1804,15 @@ void QMenu::popup(const QPoint &p, QAction *atAction) d->updateActionRects(); QPoint pos = p; QSize size = sizeHint(); - QRect screen = d->popupGeometry(QApplication::desktop()->screenNumber(p)); + QRect screen; +#ifndef QT_NO_GRAPHICSVIEW + bool isEmbedded = d->nearestGraphicsProxyWidget(this); + if (isEmbedded) + screen = d->popupGeometry(this); + 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); #ifdef QT_KEYPAD_NAVIGATION @@ -2927,7 +2950,7 @@ void QMenu::internalDelayedPopup() QPoint pos(rightPos); QMenu *caused = qobject_cast<QMenu*>(d->activeMenu->d_func()->causedPopup.widget); - const QRect availGeometry(d->popupGeometry(QApplication::desktop()->screenNumber(caused))); + const QRect availGeometry(d->popupGeometry(caused)); if (isRightToLeft()) { pos = leftPos; if ((caused && caused->x() < x()) || pos.x() < availGeometry.left()) { diff --git a/src/gui/widgets/qmenu_p.h b/src/gui/widgets/qmenu_p.h index 9c4f260..6a8e4b0 100644 --- a/src/gui/widgets/qmenu_p.h +++ b/src/gui/widgets/qmenu_p.h @@ -192,7 +192,8 @@ public: mutable QVector<QRect> actionRects; mutable QWidgetList widgetItems; void updateActionRects() const; - QRect popupGeometry(int screen=-1) 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; diff --git a/src/gui/widgets/qpushbutton.cpp b/src/gui/widgets/qpushbutton.cpp index 1352e1b..eb34336 100644 --- a/src/gui/widgets/qpushbutton.cpp +++ b/src/gui/widgets/qpushbutton.cpp @@ -590,7 +590,7 @@ void QPushButtonPrivate::_q_popupPressed() int x = globalPos.x(); int y = globalPos.y(); if (horizontal) { - if (globalPos.y() + rect.height() + menuSize.height() <= QApplication::desktop()->height()) { + if (globalPos.y() + rect.height() + menuSize.height() <= QApplication::desktop()->availableGeometry(q).height()) { y += rect.height(); } else { y -= menuSize.height(); @@ -598,7 +598,7 @@ void QPushButtonPrivate::_q_popupPressed() if (q->layoutDirection() == Qt::RightToLeft) x += rect.width() - menuSize.width(); } else { - if (globalPos.x() + rect.width() + menu->sizeHint().width() <= QApplication::desktop()->width()) + if (globalPos.x() + rect.width() + menu->sizeHint().width() <= QApplication::desktop()->availableGeometry(q).width()) x += rect.width(); else x -= menuSize.width(); |