--- a/src/gui/kernel/qwidget.cpp Tue Jul 06 15:10:48 2010 +0300
+++ b/src/gui/kernel/qwidget.cpp Wed Aug 18 10:37:55 2010 +0300
@@ -67,6 +67,7 @@
# include "qt_mac_p.h"
# include "qt_cocoa_helpers_mac_p.h"
# include "qmainwindow.h"
+# include "qtoolbar.h"
#endif
#if defined(Q_WS_QWS)
# include "qwsdisplay_qws.h"
@@ -161,6 +162,47 @@
extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); // qapplication.cpp
extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp
+QRefCountedWidgetBackingStore::QRefCountedWidgetBackingStore()
+ : m_ptr(0)
+{
+
+}
+
+QRefCountedWidgetBackingStore::~QRefCountedWidgetBackingStore()
+{
+ delete m_ptr;
+}
+
+void QRefCountedWidgetBackingStore::create(QWidget *widget)
+{
+ destroy();
+ m_ptr = new QWidgetBackingStore(widget);
+}
+
+void QRefCountedWidgetBackingStore::destroy()
+{
+ delete m_ptr;
+ m_ptr = 0;
+ m_visibleWidgets.clear();
+}
+
+void QRefCountedWidgetBackingStore::widgetShown(QWidget *w)
+{
+ Q_ASSERT(m_ptr);
+ Q_ASSERT(w->internalWinId());
+ Q_ASSERT(qt_widget_private(w)->maybeBackingStore() == m_ptr);
+ m_visibleWidgets.insert(w);
+}
+
+void QRefCountedWidgetBackingStore::widgetHidden(QWidget *w)
+{
+ if (m_visibleWidgets.remove(w) && m_visibleWidgets.isEmpty()) {
+ delete m_ptr;
+ m_ptr = 0;
+ }
+}
+
+
QWidgetPrivate::QWidgetPrivate(int version)
: QObjectPrivate(version)
, extra(0)
@@ -202,7 +244,9 @@
, picture(0)
#elif defined(Q_WS_WIN)
, noPaintOnScreen(0)
+ #ifndef QT_NO_GESTURES
, nativeGesturePanEnabled(0)
+ #endif
#elif defined(Q_WS_MAC)
, needWindowChange(0)
, hasAlienChildren(0)
@@ -248,9 +292,14 @@
QWindowSurface *QWidgetPrivate::createDefaultWindowSurface()
{
Q_Q(QWidget);
+
+ QWindowSurface *surface;
if (QApplicationPrivate::graphicsSystem())
- return QApplicationPrivate::graphicsSystem()->createWindowSurface(q);
- return createDefaultWindowSurface_sys();
+ surface = QApplicationPrivate::graphicsSystem()->createWindowSurface(q);
+ else
+ surface = createDefaultWindowSurface_sys();
+
+ return surface;
}
/*!
@@ -285,8 +334,10 @@
#ifndef QT_NO_IM
if (ic)
return ic;
-#endif
return qApp->inputContext();
+#else
+ return 0;
+#endif
}
/*!
@@ -312,6 +363,8 @@
This function sets the input context \a context
on this widget.
+ Qt takes ownership of the given input \a context.
+
\sa inputContext()
*/
void QWidget::setInputContext(QInputContext *context)
@@ -320,9 +373,13 @@
if (!testAttribute(Qt::WA_InputMethodEnabled))
return;
#ifndef QT_NO_IM
+ if (context == d->ic)
+ return;
if (d->ic)
delete d->ic;
d->ic = context;
+ if (d->ic)
+ d->ic->setParent(this);
#endif
}
@@ -670,8 +727,8 @@
(to move the keyboard focus), and passes on most of the other events to
one of the more specialized handlers above.
- Events and the mechanism used to deliver them are covered in the
- \l{Events and Event Filters} document.
+ Events and the mechanism used to deliver them are covered in
+ \l{The Event System}.
\section1 Groups of Functions and Properties
@@ -1010,7 +1067,6 @@
\sa windowFlags
*/
-
QWidget::QWidget(QWidget *parent, Qt::WindowFlags f)
: QObject(*new QWidgetPrivate, 0), QPaintDevice()
{
@@ -1339,11 +1395,9 @@
// a real toplevel window needs a backing store
if (isWindow() && windowType() != Qt::Desktop) {
- delete d->topData()->backingStore;
- // QWidgetBackingStore will check this variable, hence it must be 0
- d->topData()->backingStore = 0;
+ d->topData()->backingStore.destroy();
if (hasBackingStoreSupport())
- d->topData()->backingStore = new QWidgetBackingStore(this);
+ d->topData()->backingStore.create(this);
}
d->setModal_sys();
@@ -1388,8 +1442,10 @@
qWarning("QWidget: %s (%s) deleted while being painted", className(), name());
#endif
+#ifndef QT_NO_GESTURES
foreach (Qt::GestureType type, d->gestureContext.keys())
ungrabGesture(type);
+#endif
// force acceptDrops false before winId is destroyed.
d->registerDropSite(false);
@@ -1469,8 +1525,7 @@
// the backing store will delete its window surface, which may or may
// not have a reference to this widget that will be used later to
// notify the window it no longer has a surface.
- delete d->extra->topextra->backingStore;
- d->extra->topextra->backingStore = 0;
+ d->extra->topextra->backingStore.destroy();
}
#endif
if (QWidgetBackingStore *bs = d->maybeBackingStore()) {
@@ -1567,7 +1622,6 @@
QTLWExtra* x = extra->topextra = new QTLWExtra;
x->icon = 0;
x->iconPixmap = 0;
- x->backingStore = 0;
x->windowSurface = 0;
x->sharedPainter = 0;
x->incw = x->inch = 0;
@@ -1651,7 +1705,7 @@
#endif
if (extra->topextra) {
deleteTLSysExtra();
- delete extra->topextra->backingStore;
+ extra->topextra->backingStore.destroy();
delete extra->topextra->icon;
delete extra->topextra->iconPixmap;
#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER)
@@ -4774,6 +4828,11 @@
{
Q_D(QWidget);
+ if (direction == Qt::LayoutDirectionAuto) {
+ unsetLayoutDirection();
+ return;
+ }
+
setAttribute(Qt::WA_SetLayoutDirection);
d->setLayoutDirection_helper(direction);
}
@@ -8530,9 +8589,11 @@
#endif // Q_WS_MAC
break;
}
+#ifndef QT_NO_GESTURES
case QEvent::Gesture:
event->ignore();
break;
+#endif
#ifndef QT_NO_PROPERTIES
case QEvent::DynamicPropertyChange: {
const QByteArray &propName = static_cast<QDynamicPropertyChangeEvent *>(event)->propertyName();
@@ -9655,46 +9716,58 @@
QWidget *QWidgetPrivate::childAt_helper(const QPoint &p, bool ignoreChildrenInDestructor) const
{
+ if (children.isEmpty())
+ return 0;
+
+#ifdef Q_WS_MAC
Q_Q(const QWidget);
-#ifdef Q_WS_MAC
+ // Unified tool bars on the Mac require special handling since they live outside
+ // QMainWindow's geometry(). See commit: 35667fd45ada49269a5987c235fdedfc43e92bb8
bool includeFrame = q->isWindow() && qobject_cast<const QMainWindow *>(q)
&& static_cast<const QMainWindow *>(q)->unifiedTitleAndToolBarOnMac();
-#endif
-
- if (
-#ifdef Q_WS_MAC
- !includeFrame &&
-#endif
- !q->rect().contains(p))
+ if (includeFrame)
+ return childAtRecursiveHelper(p, ignoreChildrenInDestructor, includeFrame);
+#endif
+
+ if (!pointInsideRectAndMask(p))
return 0;
-
- for (int i = children.size(); i > 0 ;) {
- --i;
- QWidget *w = qobject_cast<QWidget *>(children.at(i));
- if (w && !w->isWindow() && !w->isHidden()
- && (w->geometry().contains(p)
+ return childAtRecursiveHelper(p, ignoreChildrenInDestructor);
+}
+
+QWidget *QWidgetPrivate::childAtRecursiveHelper(const QPoint &p, bool ignoreChildrenInDestructor, bool includeFrame) const
+{
+#ifndef Q_WS_MAC
+ Q_UNUSED(includeFrame);
+#endif
+ for (int i = children.size() - 1; i >= 0; --i) {
+ QWidget *child = qobject_cast<QWidget *>(children.at(i));
+ if (!child || child->isWindow() || child->isHidden() || child->testAttribute(Qt::WA_TransparentForMouseEvents)
+ || (ignoreChildrenInDestructor && child->data->in_destructor)) {
+ continue;
+ }
+
+ // Map the point 'p' from parent coordinates to child coordinates.
+ QPoint childPoint = p;
#ifdef Q_WS_MAC
- || (includeFrame && w->geometry().contains(qt_mac_nativeMapFromParent(w, p)))
-#endif
- )) {
- if (ignoreChildrenInDestructor && w->data->in_destructor)
- continue;
- if (w->testAttribute(Qt::WA_TransparentForMouseEvents))
- continue;
- QPoint childPoint = w->mapFromParent(p);
-#ifdef Q_WS_MAC
- if (includeFrame && !w->geometry().contains(p))
- childPoint = qt_mac_nativeMapFromParent(w, p);
-#endif
- if (QWidget *t = w->d_func()->childAt_helper(childPoint, ignoreChildrenInDestructor))
- return t;
- // if WMouseNoMask is set the widget mask is ignored, if
- // the widget has no mask then the WMouseNoMask flag has no
- // effect
- if (w->testAttribute(Qt::WA_MouseNoMask) || w->mask().contains(childPoint)
- || w->mask().isEmpty())
- return w;
- }
+ // 'includeFrame' is true if the child's parent is a top-level QMainWindow with an unified tool bar.
+ // An unified tool bar on the Mac lives outside QMainWindow's geometry(), so a normal
+ // QWidget::mapFromParent won't do the trick.
+ if (includeFrame && qobject_cast<QToolBar *>(child))
+ childPoint = qt_mac_nativeMapFromParent(child, p);
+ else
+#endif
+ childPoint -= child->data->crect.topLeft();
+
+ // Check if the point hits the child.
+ if (!child->d_func()->pointInsideRectAndMask(childPoint))
+ continue;
+
+ // Do the same for the child's descendants.
+ if (QWidget *w = child->d_func()->childAtRecursiveHelper(childPoint, ignoreChildrenInDestructor))
+ return w;
+
+ // We have found our target; namely the child at position 'p'.
+ return child;
}
return 0;
}
@@ -10620,7 +10693,7 @@
break;
case Qt::WA_AcceptTouchEvents:
-#if defined(Q_WS_WIN) || defined(Q_WS_MAC) || defined(Q_WS_S60)
+#if defined(Q_WS_WIN) || defined(Q_WS_MAC) || defined(Q_OS_SYMBIAN)
if (on)
d->registerTouchWindow();
#endif
@@ -11948,6 +12021,7 @@
Synonym for QList<QWidget *>.
*/
+#ifndef QT_NO_GESTURES
/*!
Subscribes the widget to a given \a gesture with specific \a flags.
@@ -11975,7 +12049,7 @@
manager->cleanupCachedGestures(this, gesture);
}
}
-
+#endif // QT_NO_GESTURES
/*!
\typedef WId