summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel/qwidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kernel/qwidget.cpp')
-rw-r--r--src/gui/kernel/qwidget.cpp179
1 files changed, 143 insertions, 36 deletions
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 9d9cd75..80d7b85 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -76,6 +76,9 @@
# include "qpaintengine.h" // for PorterDuff
# include "private/qwindowsurface_qws_p.h"
#endif
+#if defined(Q_WS_QPA)
+#include "qplatformwindow_qpa.h"
+#endif
#include "qpainter.h"
#include "qtooltip.h"
#include "qwhatsthis.h"
@@ -145,6 +148,10 @@ Q_GUI_EXPORT void qt_x11_set_global_double_buffer(bool enable)
}
#endif
+#if defined(QT_MAC_USE_COCOA)
+bool qt_mac_clearDirtyOnWidgetInsideDrawWidget = false;
+#endif
+
static inline bool qRectIntersects(const QRect &r1, const QRect &r2)
{
return (qMax(r1.left(), r2.left()) <= qMin(r1.right(), r2.right()) &&
@@ -301,7 +308,6 @@ QWidgetPrivate::QWidgetPrivate(int version)
#endif
#elif defined(Q_WS_MAC)
, needWindowChange(0)
- , hasAlienChildren(0)
, window_event(0)
, qd_hd(0)
#elif defined(Q_OS_SYMBIAN)
@@ -323,6 +329,11 @@ QWidgetPrivate::QWidgetPrivate(int version)
drawRectOriginalAdded = false;
originalDrawMethod = true;
changeMethods = false;
+ isInUnifiedToolbar = false;
+ unifiedSurface = 0;
+ toolbar_ancestor = 0;
+ flushRequested = false;
+ touchEventsEnabled = false;
#endif // QT_MAC_USE_COCOA
#ifdef QWIDGET_EXTRA_DEBUG
static int count = 0;
@@ -357,9 +368,12 @@ QWindowSurface *QWidgetPrivate::createDefaultWindowSurface()
Q_Q(QWidget);
QWindowSurface *surface;
+#ifndef QT_NO_PROPERTIES
if (q->property("_q_DummyWindowSurface").toBool()) {
surface = new QDummyWindowSurface(q);
- } else {
+ } else
+#endif
+ {
if (QApplicationPrivate::graphicsSystem())
surface = QApplicationPrivate::graphicsSystem()->createWindowSurface(q);
else
@@ -1290,6 +1304,12 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
if (desktopWidget) {
symbianScreenNumber = qt_widget_private(desktopWidget)->symbianScreenNumber;
}
+#elif defined(Q_WS_QPA)
+ if (desktopWidget) {
+ int screen = desktopWidget->d_func()->topData()->screenIndex;
+ QPlatformIntegration *platform = QApplicationPrivate::platformIntegration();
+ platform->moveToScreen(q, screen);
+ }
#else
Q_UNUSED(desktopWidget);
#endif
@@ -1314,9 +1334,9 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
if (f & Qt::MSWindowsOwnDC)
q->setAttribute(Qt::WA_NativeWindow);
-#ifdef Q_WS_MAC
- q->setAttribute(Qt::WA_NativeWindow);
-#endif
+//#ifdef Q_WS_MAC
+// q->setAttribute(Qt::WA_NativeWindow);
+//#endif
q->setAttribute(Qt::WA_QuitOnClose); // might be cleared in adjustQuitOnCloseAttribute()
adjustQuitOnCloseAttribute();
@@ -1369,6 +1389,16 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
QApplication::postEvent(q, new QEvent(QEvent::PolishRequest));
extraPaintEngine = 0;
+
+#ifdef QT_MAC_USE_COCOA
+ // If we add a child to the unified toolbar, we have to redirect the painting.
+ if (parentWidget && parentWidget->d_func() && parentWidget->d_func()->isInUnifiedToolbar) {
+ if (parentWidget->d_func()->unifiedSurface) {
+ QWidget *toolbar = parentWidget->d_func()->toolbar_ancestor;
+ parentWidget->d_func()->unifiedSurface->recursiveRedirect(toolbar, toolbar, toolbar->d_func()->toolbar_offset);
+ }
+ }
+#endif // QT_MAC_USE_COCOA
}
@@ -1421,11 +1451,8 @@ void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow)
flags |= Qt::Window;
}
+#ifndef Q_WS_QPA
if (QWidget *parent = parentWidget()) {
-#ifdef Q_WS_MAC
- if (testAttribute(Qt::WA_NativeWindow) == false)
- parent->d_func()->hasAlienChildren = true;
-#endif
if (type & Qt::Window) {
if (!parent->testAttribute(Qt::WA_WState_Created))
parent->createWinId();
@@ -1441,6 +1468,7 @@ void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow)
return;
}
}
+#endif //Q_WS_QPA
#ifdef QT3_SUPPORT
if (flags & Qt::WStaticContents)
@@ -1560,6 +1588,7 @@ QWidget::~QWidget()
// delete layout while we still are a valid widget
delete d->layout;
+ d->layout = 0;
// Remove myself from focus list
Q_ASSERT(d->focus_next->d_func()->focus_prev == this);
@@ -1599,13 +1628,13 @@ QWidget::~QWidget()
}
}
-#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC)
+#if defined(Q_WS_WIN) || defined(Q_WS_X11)|| defined(Q_WS_MAC)
else if (!internalWinId() && isVisible()) {
qApp->d_func()->sendSyntheticEnterLeave(this);
-#ifdef Q_WS_QWS
- } else if (isVisible()) {
+ }
+#elif defined(Q_WS_QWS) || defined(Q_WS_QPA)
+ else if (isVisible()) {
qApp->d_func()->sendSyntheticEnterLeave(this);
-#endif
}
#endif
@@ -1630,7 +1659,8 @@ QWidget::~QWidget()
d->needsFlush = 0;
// set all QPointers for this object to zero
- QObjectPrivate::clearGuards(this);
+ if (d->hasGuards)
+ QObjectPrivate::clearGuards(this);
if (d->declarativeData) {
QAbstractDeclarativeData::destroyed(d->declarativeData, this);
@@ -1732,6 +1762,11 @@ void QWidgetPrivate::createTLExtra()
static int count = 0;
qDebug() << "tlextra" << ++count;
#endif
+#if defined(Q_WS_QPA)
+ x->platformWindow = 0;
+ x->platformWindowFormat = QPlatformWindowFormat::defaultFormat();
+ x->screenIndex = 0;
+#endif
}
}
@@ -1853,13 +1888,7 @@ void QWidgetPrivate::syncBackingStore()
repaint_sys(dirty);
dirty = QRegion();
} else if (QWidgetBackingStore *bs = maybeBackingStore()) {
-#ifdef QT_MAC_USE_COCOA
- Q_UNUSED(bs);
- void qt_mac_set_needs_display(QWidget *, QRegion);
- qt_mac_set_needs_display(q_func(), QRegion());
-#else
bs->sync();
-#endif
}
}
@@ -1868,13 +1897,7 @@ void QWidgetPrivate::syncBackingStore(const QRegion &region)
if (paintOnScreen())
repaint_sys(region);
else if (QWidgetBackingStore *bs = maybeBackingStore()) {
-#ifdef QT_MAC_USE_COCOA
- Q_UNUSED(bs);
- void qt_mac_set_needs_display(QWidget *, QRegion);
- qt_mac_set_needs_display(q_func(), region);
-#else
bs->sync(q_func(), region);
-#endif
}
}
@@ -2091,6 +2114,11 @@ void QWidgetPrivate::subtractOpaqueSiblings(QRegion &sourceRegion, bool *hasDirt
if (disableSubtractOpaqueSiblings || q->isWindow())
return;
+#ifdef QT_MAC_USE_COCOA
+ if (q->d_func()->isInUnifiedToolbar)
+ return;
+#endif // QT_MAC_USE_COCOA
+
QRect clipBoundingRect;
bool dirtyClipBoundingRect = true;
@@ -2478,7 +2506,9 @@ WId QWidget::winId() const
qDebug() << "QWidget::winId: creating native window for" << this;
#endif
QWidget *that = const_cast<QWidget*>(this);
+#ifndef Q_WS_QPA
that->setAttribute(Qt::WA_NativeWindow);
+#endif
that->d_func()->createWinId();
return that->data->winid;
}
@@ -2495,6 +2525,7 @@ void QWidgetPrivate::createWinId(WId winid)
#endif
const bool forceNativeWindow = q->testAttribute(Qt::WA_NativeWindow);
if (!q->testAttribute(Qt::WA_WState_Created) || (forceNativeWindow && !q->internalWinId())) {
+#ifndef Q_WS_QPA
if (!q->isWindow()) {
QWidget *parent = q->parentWidget();
QWidgetPrivate *pd = parent->d_func();
@@ -2522,6 +2553,11 @@ void QWidgetPrivate::createWinId(WId winid)
} else {
q->create();
}
+#else
+ Q_UNUSED(winid);
+ q->create();
+#endif //Q_WS_QPA
+
}
}
@@ -5405,6 +5441,17 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
if (rgn.isEmpty())
return;
+#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
+ if (qt_mac_clearDirtyOnWidgetInsideDrawWidget)
+ dirtyOnWidget = QRegion();
+
+ // We disable the rendering of QToolBar in the backingStore if
+ // it's supposed to be in the unified toolbar on Mac OS X.
+ if (backingStore && isInUnifiedToolbar)
+ return;
+#endif // Q_WS_MAC && QT_MAC_USE_COCOA
+
+
Q_Q(QWidget);
#ifndef QT_NO_GRAPHICSEFFECT
if (graphicsEffect && graphicsEffect->isEnabled()) {
@@ -5467,6 +5514,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
QPaintEngine *paintEngine = pdev->paintEngine();
if (paintEngine) {
setRedirected(pdev, -offset);
+
#ifdef Q_WS_MAC
// (Alien support) Special case for Mac when redirecting: If the paint device
// is of the Widget type we need to set WA_WState_InPaintEvent since painting
@@ -5484,7 +5532,6 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
//paint the background
if ((asRoot || q->autoFillBackground() || onScreen || q->testAttribute(Qt::WA_StyledBackground))
&& !q->testAttribute(Qt::WA_OpaquePaintEvent) && !q->testAttribute(Qt::WA_NoSystemBackground)) {
-
QPainter p(q);
paintBackground(&p, toBePainted, (asRoot || onScreen) ? flags | DrawAsRoot : 0);
}
@@ -5509,7 +5556,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
//actually send the paint event
QPaintEvent e(toBePainted);
QCoreApplication::sendSpontaneousEvent(q, &e);
-#if !defined(Q_WS_MAC) && !defined(Q_WS_QWS)
+#if !defined(Q_WS_QWS) && !defined(Q_WS_QPA)
if (backingStore && !onScreen && !asRoot && (q->internalWinId() || !q->nativeParentWidget()->isWindow()))
backingStore->markDirtyOnScreen(toBePainted, q, offset);
#endif
@@ -5666,10 +5713,12 @@ void QWidgetPrivate::paintSiblingsRecursive(QPaintDevice *pdev, const QObjectLis
QRect boundingRect;
bool dirtyBoundingRect = true;
const bool exludeOpaqueChildren = (flags & DontDrawOpaqueChildren);
+ const bool excludeNativeChildren = (flags & DontDrawNativeChildren);
do {
QWidget *x = qobject_cast<QWidget*>(siblings.at(index));
- if (x && !(exludeOpaqueChildren && x->d_func()->isOpaque) && !x->isHidden() && !x->isWindow()) {
+ if (x && !(exludeOpaqueChildren && x->d_func()->isOpaque) && !x->isHidden() && !x->isWindow()
+ && !(excludeNativeChildren && x->internalWinId())) {
if (dirtyBoundingRect) {
boundingRect = rgn.boundingRect();
dirtyBoundingRect = false;
@@ -6656,7 +6705,7 @@ void QWidget::setTabOrder(QWidget* first, QWidget *second)
// that can take keyboard focus so that second is inserted after
// that last child, and the focus order within first is (more
// likely to be) preserved.
- QList<QWidget *> l = qFindChildren<QWidget *>(first);
+ QList<QWidget *> l = first->findChildren<QWidget *>();
for (int i = l.size()-1; i >= 0; --i) {
QWidget * next = l.at(i);
if (next->window() == fp->window()) {
@@ -7045,7 +7094,11 @@ bool QWidget::restoreGeometry(const QByteArray &geometry)
if (maximized || fullScreen) {
// set geomerty before setting the window state to make
// sure the window is maximized to the right screen.
+ // Skip on windows: the window is restored into a broken
+ // half-maximized state.
+#ifndef Q_WS_WIN
setGeometry(restoredNormalGeometry);
+#endif
Qt::WindowStates ws = windowState();
if (maximized)
ws |= Qt::WindowMaximized;
@@ -7547,7 +7600,7 @@ void QWidgetPrivate::hide_helper()
// next bit tries to move the focus if the focus widget is now
// hidden.
if (wasVisible) {
-#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC)
+#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC) || defined(Q_WS_QPA)
qApp->d_func()->sendSyntheticEnterLeave(q);
#endif
@@ -7679,7 +7732,7 @@ void QWidget::setVisible(bool visible)
d->show_helper();
-#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC)
+#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC) || defined(Q_WS_QPA)
qApp->d_func()->sendSyntheticEnterLeave(this);
#endif
}
@@ -7811,7 +7864,7 @@ void QWidgetPrivate::hideChildren(bool spontaneous)
widget->d_func()->hide_sys();
}
}
-#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC)
+#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC) || defined(Q_WS_QPA)
qApp->d_func()->sendSyntheticEnterLeave(widget);
#endif
#ifndef QT_NO_ACCESSIBILITY
@@ -9820,6 +9873,23 @@ int QWidget::heightForWidth(int w) const
return -1;
}
+
+/*!
+ \internal
+
+ *virtual private*
+
+ This is a bit hackish, but ideally we would have created a virtual function
+ in the public API (however, too late...) so that subclasses could reimplement
+ their own function.
+ Instead we add a virtual function to QWidgetPrivate.
+ ### Qt5: move to public class and make virtual
+*/
+bool QWidgetPrivate::hasHeightForWidth() const
+{
+ return layout ? layout->hasHeightForWidth() : size_policy.hasHeightForWidth();
+}
+
/*!
\fn QWidget *QWidget::childAt(int x, int y) const
@@ -10052,7 +10122,13 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f)
#if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_WS_MAC) || defined(Q_OS_SYMBIAN)
if (newParent && parent && !desktopWidget) {
- if (testAttribute(Qt::WA_NativeWindow) && !qApp->testAttribute(Qt::AA_DontCreateNativeWidgetSiblings))
+ if (testAttribute(Qt::WA_NativeWindow) && !qApp->testAttribute(Qt::AA_DontCreateNativeWidgetSiblings)
+#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
+ // On Mac, toolbars inside the unified title bar will never overlap with
+ // siblings in the content view. So we skip enforce native siblings in that case
+ && !d->isInUnifiedToolbar && parentWidget() && parentWidget()->isWindow()
+#endif // Q_WS_MAC && QT_MAC_USE_COCOA
+ )
parent->d_func()->enforceNativeChildren();
else if (parent->d_func()->nativeChildrenForced() || parent->testAttribute(Qt::WA_PaintOnScreen))
setAttribute(Qt::WA_NativeWindow);
@@ -10335,6 +10411,12 @@ void QWidget::repaint(const QRect &rect)
return;
if (hasBackingStoreSupport()) {
+#ifdef QT_MAC_USE_COCOA
+ if (qt_widget_private(this)->isInUnifiedToolbar) {
+ qt_widget_private(this)->unifiedSurface->renderToolbar(this, true);
+ return;
+ }
+#endif // QT_MAC_USE_COCOA
QTLWExtra *tlwExtra = window()->d_func()->maybeTopData();
if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) {
tlwExtra->inRepaint = true;
@@ -10364,6 +10446,12 @@ void QWidget::repaint(const QRegion &rgn)
return;
if (hasBackingStoreSupport()) {
+#ifdef QT_MAC_USE_COCOA
+ if (qt_widget_private(this)->isInUnifiedToolbar) {
+ qt_widget_private(this)->unifiedSurface->renderToolbar(this, true);
+ return;
+ }
+#endif // QT_MAC_USE_COCOA
QTLWExtra *tlwExtra = window()->d_func()->maybeTopData();
if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) {
tlwExtra->inRepaint = true;
@@ -10421,6 +10509,12 @@ void QWidget::update(const QRect &rect)
}
if (hasBackingStoreSupport()) {
+#ifdef QT_MAC_USE_COCOA
+ if (qt_widget_private(this)->isInUnifiedToolbar) {
+ qt_widget_private(this)->unifiedSurface->renderToolbar(this, true);
+ return;
+ }
+#endif // QT_MAC_USE_COCOA
QTLWExtra *tlwExtra = window()->d_func()->maybeTopData();
if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore)
tlwExtra->backingStore->markDirty(rect, this);
@@ -10445,6 +10539,12 @@ void QWidget::update(const QRegion &rgn)
}
if (hasBackingStoreSupport()) {
+#ifdef QT_MAC_USE_COCOA
+ if (qt_widget_private(this)->isInUnifiedToolbar) {
+ qt_widget_private(this)->unifiedSurface->renderToolbar(this, true);
+ return;
+ }
+#endif // QT_MAC_USE_COCOA
QTLWExtra *tlwExtra = window()->d_func()->maybeTopData();
if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore)
tlwExtra->backingStore->markDirty(rgn, this);
@@ -10572,7 +10672,6 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
Q_ASSERT_X(sizeof(d->high_attributes)*8 >= (Qt::WA_AttributeCount - sizeof(uint)*8),
"QWidget::setAttribute(WidgetAttribute, bool)",
"QWidgetPrivate::high_attributes[] too small to contain all attributes in WidgetAttribute");
-
#ifdef Q_WS_WIN
// ### Don't use PaintOnScreen+paintEngine() to do native painting in 5.0
if (attribute == Qt::WA_PaintOnScreen && on && !inherits("QGLWidget")) {
@@ -10700,7 +10799,13 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
ic->setFocusWidget(0);
}
}
- if (!qApp->testAttribute(Qt::AA_DontCreateNativeWidgetSiblings) && parentWidget())
+ if (!qApp->testAttribute(Qt::AA_DontCreateNativeWidgetSiblings) && parentWidget()
+#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
+ // On Mac, toolbars inside the unified title bar will never overlap with
+ // siblings in the content view. So we skip enforce native siblings in that case
+ && !d->isInUnifiedToolbar && parentWidget()->isWindow()
+#endif // Q_WS_MAC && QT_MAC_USE_COCOA
+ )
parentWidget()->d_func()->enforceNativeChildren();
if (on && !internalWinId() && testAttribute(Qt::WA_WState_Created))
d->createWinId();
@@ -11101,6 +11206,7 @@ void QWidget::setAccessibleName(const QString &name)
{
Q_D(QWidget);
d->accessibleName = name;
+ QAccessible::updateAccessibility(this, 0, QAccessible::NameChanged);
}
QString QWidget::accessibleName() const
@@ -11122,6 +11228,7 @@ void QWidget::setAccessibleDescription(const QString &description)
{
Q_D(QWidget);
d->accessibleDescription = description;
+ QAccessible::updateAccessibility(this, 0, QAccessible::DescriptionChanged);
}
QString QWidget::accessibleDescription() const