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.cpp80
1 files changed, 49 insertions, 31 deletions
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 895c85d..492954a 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -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"
@@ -4828,6 +4829,11 @@ void QWidget::setLayoutDirection(Qt::LayoutDirection direction)
{
Q_D(QWidget);
+ if (direction == Qt::LayoutDirectionAuto) {
+ unsetLayoutDirection();
+ return;
+ }
+
setAttribute(Qt::WA_SetLayoutDirection);
d->setLayoutDirection_helper(direction);
}
@@ -9711,46 +9717,58 @@ QWidget *QWidget::childAt(const QPoint &p) const
QWidget *QWidgetPrivate::childAt_helper(const QPoint &p, bool ignoreChildrenInDestructor) const
{
- Q_Q(const QWidget);
+ if (children.isEmpty())
+ return 0;
+
#ifdef Q_WS_MAC
+ Q_Q(const QWidget);
+ // 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();
+ if (includeFrame)
+ return childAtRecursiveHelper(p, ignoreChildrenInDestructor, includeFrame);
#endif
- if (
-#ifdef Q_WS_MAC
- !includeFrame &&
-#endif
- !q->rect().contains(p))
+ if (!pointInsideRectAndMask(p))
return 0;
+ return childAtRecursiveHelper(p, ignoreChildrenInDestructor);
+}
- 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)
-#ifdef Q_WS_MAC
- || (includeFrame && w->geometry().contains(qt_mac_nativeMapFromParent(w, p)))
+QWidget *QWidgetPrivate::childAtRecursiveHelper(const QPoint &p, bool ignoreChildrenInDestructor, bool includeFrame) const
+{
+#ifndef Q_WS_MAC
+ Q_UNUSED(includeFrame);
#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;
+ 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' 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;
}