summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp97
-rw-r--r--src/gui/graphicsview/qgraphicsitem.h1
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h26
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp41
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h5
-rw-r--r--src/gui/graphicsview/qgraphicssceneindex.cpp7
-rw-r--r--src/gui/graphicsview/qgraphicssceneindex_p.h4
-rw-r--r--src/gui/kernel/qapplication.cpp20
-rw-r--r--src/gui/kernel/qapplication_mac.mm82
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm35
10 files changed, 274 insertions, 44 deletions
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 3249bb1..c3934c7 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -1479,6 +1479,7 @@ QList<QGraphicsItem *> QGraphicsItem::children() const
*/
QList<QGraphicsItem *> QGraphicsItem::childItems() const
{
+ const_cast<QGraphicsItem *>(this)->d_ptr->ensureSortedChildren();
return d_ptr->children;
}
@@ -4048,6 +4049,82 @@ void QGraphicsItem::setZValue(qreal z)
}
/*!
+ \internal
+
+ Ensures that the list of children is sorted by insertion order, and that
+ the siblingIndexes are packed (no gaps), and start at 0.
+
+ ### This function is almost identical to
+ QGraphicsScenePrivate::ensureSequentialTopLevelSiblingIndexes().
+*/
+void QGraphicsItemPrivate::ensureSequentialSiblingIndex()
+{
+ if (!sequentialOrdering) {
+ qSort(children.begin(), children.end(), insertionOrder);
+ sequentialOrdering = 1;
+ needSortChildren = 1;
+ }
+ if (holesInSiblingIndex) {
+ holesInSiblingIndex = 0;
+ for (int i = 0; i < children.size(); ++i)
+ children[i]->d_ptr->siblingIndex = i;
+ }
+}
+
+/*!
+ \since 4.6
+
+ Stacks this item before \a sibling, which must be a sibling item (i.e., the
+ two items must share the same parent item, or must both be toplevel items).
+ The \a sibling must have the same Z value as this item, otherwise calling
+ this function will have no effect.
+
+ By default, all items are stacked by insertion order (i.e., the first item
+ you add is drawn before the next item you add). If two items' Z values are
+ different, then the item with the highest Z value is drawn on top. When the
+ Z values are the same, the insertion order will decide the stacking order.
+
+ \sa setZValue(), ItemStacksBehindParent
+*/
+void QGraphicsItem::stackBefore(const QGraphicsItem *sibling)
+{
+ if (sibling == this)
+ return;
+ if (!sibling || d_ptr->parent != sibling->parentItem()) {
+ qWarning("QGraphicsItem::stackUnder: cannot stack under %p, which must be a sibling", sibling);
+ return;
+ }
+ QList<QGraphicsItem *> *siblings = d_ptr->parent
+ ? &d_ptr->parent->d_ptr->children
+ : (d_ptr->scene ? &d_ptr->scene->d_func()->topLevelItems : 0);
+ if (!siblings) {
+ qWarning("QGraphicsItem::stackUnder: cannot stack under %p, which must be a sibling", sibling);
+ return;
+ }
+
+ // First, make sure that the sibling indexes have no holes. This also
+ // marks the children list for sorting.
+ if (d_ptr->parent)
+ d_ptr->parent->d_ptr->ensureSequentialSiblingIndex();
+ else
+ d_ptr->scene->d_func()->ensureSequentialTopLevelSiblingIndexes();
+
+ // Only move items with the same Z value, and that need moving.
+ int siblingIndex = sibling->d_ptr->siblingIndex;
+ int myIndex = d_ptr->siblingIndex;
+ if (myIndex >= siblingIndex && d_ptr->z == sibling->d_ptr->z) {
+ siblings->move(myIndex, siblingIndex);
+ // Fixup the insertion ordering.
+ for (int i = 0; i < siblings->size(); ++i) {
+ int &index = siblings->at(i)->d_ptr->siblingIndex;
+ if (i != siblingIndex && index >= siblingIndex && index <= myIndex)
+ ++index;
+ }
+ d_ptr->siblingIndex = siblingIndex;
+ }
+}
+
+/*!
Returns the bounding rect of this item's descendants (i.e., its
children, their children, etc.) in local coordinates. The
rectangle will contain all descendants after they have been mapped
@@ -4753,20 +4830,36 @@ void QGraphicsItemPrivate::resolveDepth()
/*!
\internal
+
+ ### This function is almost identical to
+ QGraphicsScenePrivate::registerTopLevelItem().
*/
void QGraphicsItemPrivate::addChild(QGraphicsItem *child)
{
- needSortChildren = 1;
+ // Remove all holes from the sibling index list. Now the max index
+ // number is equal to the size of the children list.
+ ensureSequentialSiblingIndex();
+ needSortChildren = 1; // ### maybe 0
child->d_ptr->siblingIndex = children.size();
children.append(child);
}
/*!
\internal
+
+ ### This function is almost identical to
+ QGraphicsScenePrivate::unregisterTopLevelItem().
*/
void QGraphicsItemPrivate::removeChild(QGraphicsItem *child)
{
- children.removeOne(child);
+ // When removing elements in the middle of the children list,
+ // there will be a "gap" in the list of sibling indexes (0,1,3,4).
+ if (!holesInSiblingIndex)
+ holesInSiblingIndex = child->d_ptr->siblingIndex != children.size() - 1;
+ if (sequentialOrdering && !holesInSiblingIndex)
+ children.removeAt(child->d_ptr->siblingIndex);
+ else
+ children.removeOne(child);
// NB! Do not use children.removeAt(child->d_ptr->siblingIndex) because
// the child is not guaranteed to be at the index after the list is sorted.
// (see ensureSortedChildren()).
diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h
index 089d6fe..99d2e12 100644
--- a/src/gui/graphicsview/qgraphicsitem.h
+++ b/src/gui/graphicsview/qgraphicsitem.h
@@ -302,6 +302,7 @@ public:
// Stacking order
qreal zValue() const;
void setZValue(qreal z);
+ void stackBefore(const QGraphicsItem *sibling);
// Hit test
virtual QRectF boundingRect() const = 0;
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index fd2ff34..3feccdc 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -153,7 +153,7 @@ public:
dirtyClipPath(1),
emptyClipPath(0),
inSetPosHelper(0),
- needSortChildren(1),
+ needSortChildren(1), // ### can be 0 by default?
allChildrenDirty(0),
fullUpdatePending(0),
flags(0),
@@ -174,6 +174,8 @@ public:
mouseSetsFocus(1),
explicitActivate(0),
wantsActive(0),
+ holesInSiblingIndex(0),
+ sequentialOrdering(1),
globalStackingOrder(-1),
q_ptr(0)
{
@@ -421,6 +423,8 @@ public:
inline QTransform transformToParent() const;
inline void ensureSortedChildren();
+ static inline bool insertionOrder(QGraphicsItem *a, QGraphicsItem *b);
+ void ensureSequentialSiblingIndex();
QPainterPath cachedClipPath;
QRectF childrenBoundingRect;
@@ -493,6 +497,8 @@ public:
// New 32 bits
quint32 explicitActivate : 1;
quint32 wantsActive : 1;
+ quint32 holesInSiblingIndex : 1;
+ quint32 sequentialOrdering : 1;
// Optional stacking order
int globalStackingOrder;
@@ -646,14 +652,32 @@ inline QTransform QGraphicsItemPrivate::transformToParent() const
return matrix;
}
+/*!
+ \internal
+*/
inline void QGraphicsItemPrivate::ensureSortedChildren()
{
if (needSortChildren) {
qSort(children.begin(), children.end(), qt_notclosestLeaf);
needSortChildren = 0;
+ sequentialOrdering = 1;
+ for (int i = 0; i < children.size(); ++i) {
+ if (children[i]->d_ptr->siblingIndex != i) {
+ sequentialOrdering = 0;
+ break;
+ }
+ }
}
}
+/*!
+ \internal
+*/
+inline bool QGraphicsItemPrivate::insertionOrder(QGraphicsItem *a, QGraphicsItem *b)
+{
+ return a->d_ptr->siblingIndex < b->d_ptr->siblingIndex;
+}
+
QT_END_NAMESPACE
#endif // QT_NO_GRAPHICSVIEW
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 0655ecc..4b74b67 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -283,6 +283,8 @@ QGraphicsScenePrivate::QGraphicsScenePrivate()
processDirtyItemsEmitted(false),
selectionChanging(0),
needSortTopLevelItems(true),
+ holesInTopLevelSiblingIndex(false),
+ topLevelSequentialOrdering(true),
stickyFocus(false),
hasFocus(false),
focusItem(0),
@@ -379,24 +381,36 @@ void QGraphicsScenePrivate::_q_emitUpdated()
/*!
\internal
+
+ ### This function is almost identical to QGraphicsItemPrivate::addChild().
*/
void QGraphicsScenePrivate::registerTopLevelItem(QGraphicsItem *item)
{
- needSortTopLevelItems = true;
+ item->d_ptr->ensureSequentialSiblingIndex();
+ needSortTopLevelItems = true; // ### maybe false
item->d_ptr->siblingIndex = topLevelItems.size();
topLevelItems.append(item);
}
/*!
\internal
+
+ ### This function is almost identical to QGraphicsItemPrivate::removeChild().
*/
void QGraphicsScenePrivate::unregisterTopLevelItem(QGraphicsItem *item)
{
- topLevelItems.removeOne(item);
+ if (!holesInTopLevelSiblingIndex)
+ holesInTopLevelSiblingIndex = item->d_ptr->siblingIndex != topLevelItems.size() - 1;
+ if (topLevelSequentialOrdering && !holesInTopLevelSiblingIndex)
+ topLevelItems.removeAt(item->d_ptr->siblingIndex);
+ else
+ topLevelItems.removeOne(item);
// NB! Do not use topLevelItems.removeAt(item->d_ptr->siblingIndex) because
// the item is not guaranteed to be at the index after the list is sorted
// (see ensureSortedTopLevelItems()).
item->d_ptr->siblingIndex = -1;
+ if (topLevelSequentialOrdering)
+ topLevelSequentialOrdering = !holesInTopLevelSiblingIndex;
}
/*!
@@ -1239,6 +1253,29 @@ void QGraphicsScenePrivate::mousePressEventHandler(QGraphicsSceneMouseEvent *mou
/*!
\internal
+ Ensures that the list of toplevels is sorted by insertion order, and that
+ the siblingIndexes are packed (no gaps), and start at 0.
+
+ ### This function is almost identical to
+ QGraphicsItemPrivate::ensureSequentialSiblingIndex().
+*/
+void QGraphicsScenePrivate::ensureSequentialTopLevelSiblingIndexes()
+{
+ if (!topLevelSequentialOrdering) {
+ qSort(topLevelItems.begin(), topLevelItems.end(), QGraphicsItemPrivate::insertionOrder);
+ topLevelSequentialOrdering = true;
+ needSortTopLevelItems = 1;
+ }
+ if (holesInTopLevelSiblingIndex) {
+ holesInTopLevelSiblingIndex = 0;
+ for (int i = 0; i < topLevelItems.size(); ++i)
+ topLevelItems[i]->d_ptr->siblingIndex = i;
+ }
+}
+
+/*!
+ \internal
+
Set the font and propagate the changes if the font is different from the
current font.
*/
diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h
index 3b03624..46917ce 100644
--- a/src/gui/graphicsview/qgraphicsscene_p.h
+++ b/src/gui/graphicsview/qgraphicsscene_p.h
@@ -111,6 +111,9 @@ public:
QList<QGraphicsItem *> unpolishedItems;
QList<QGraphicsItem *> topLevelItems;
bool needSortTopLevelItems;
+ bool holesInTopLevelSiblingIndex;
+ bool topLevelSequentialOrdering;
+
QMap<QGraphicsItem *, QPointF> movingItemsInitialPositions;
void registerTopLevelItem(QGraphicsItem *item);
void unregisterTopLevelItem(QGraphicsItem *item);
@@ -255,6 +258,8 @@ public:
}
}
+ void ensureSequentialTopLevelSiblingIndexes();
+
QStyle *style;
QFont font;
void setFont_helper(const QFont &font);
diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp
index 3ea957f..f0404fd 100644
--- a/src/gui/graphicsview/qgraphicssceneindex.cpp
+++ b/src/gui/graphicsview/qgraphicssceneindex.cpp
@@ -265,12 +265,13 @@ bool QGraphicsSceneIndexPrivate::itemCollidesWithPath(const QGraphicsItem *item,
/*!
\internal
+ This function returns the items in ascending order.
*/
void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRectF exposeRect,
QGraphicsSceneIndexIntersector *intersector,
QList<QGraphicsItem *> *items,
const QTransform &viewTransform,
- Qt::ItemSelectionMode mode, Qt::SortOrder order,
+ Qt::ItemSelectionMode mode,
qreal parentOpacity) const
{
Q_ASSERT(item);
@@ -326,7 +327,7 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe
if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity))
continue;
recursive_items_helper(child, exposeRect, intersector, items, viewTransform,
- mode, order, opacity);
+ mode, opacity);
}
}
@@ -343,7 +344,7 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe
if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity))
continue;
recursive_items_helper(child, exposeRect, intersector, items, viewTransform,
- mode, order, opacity);
+ mode, opacity);
}
}
}
diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h
index 768c724..adebfde 100644
--- a/src/gui/graphicsview/qgraphicssceneindex_p.h
+++ b/src/gui/graphicsview/qgraphicssceneindex_p.h
@@ -138,7 +138,7 @@ public:
void recursive_items_helper(QGraphicsItem *item, QRectF exposeRect,
QGraphicsSceneIndexIntersector *intersector, QList<QGraphicsItem *> *items,
const QTransform &viewTransform,
- Qt::ItemSelectionMode mode, Qt::SortOrder order, qreal parentOpacity = 1.0) const;
+ Qt::ItemSelectionMode mode, qreal parentOpacity = 1.0) const;
inline void items_helper(const QRectF &rect, QGraphicsSceneIndexIntersector *intersector,
QList<QGraphicsItem *> *items, const QTransform &viewTransform,
Qt::ItemSelectionMode mode, Qt::SortOrder order) const;
@@ -156,7 +156,7 @@ inline void QGraphicsSceneIndexPrivate::items_helper(const QRectF &rect, QGraphi
Q_Q(const QGraphicsSceneIndex);
const QList<QGraphicsItem *> tli = q->estimateTopLevelItems(rect, Qt::AscendingOrder);
for (int i = 0; i < tli.size(); ++i)
- recursive_items_helper(tli.at(i), rect, intersector, items, viewTransform, mode, order);
+ recursive_items_helper(tli.at(i), rect, intersector, items, viewTransform, mode);
if (order == Qt::DescendingOrder) {
const int n = items->size();
for (int i = 0; i < n / 2; ++i)
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index 774ec23..2ad89a2 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -68,6 +68,9 @@
#include "private/qstylesheetstyle_p.h"
#include "private/qstyle_p.h"
#include "qmessagebox.h"
+#include "qlineedit.h"
+#include "qlistview.h"
+#include "qtextedit.h"
#include <QtGui/qgraphicsproxywidget.h>
#include "qinputcontext.h"
@@ -2487,8 +2490,6 @@ void QApplication::setActiveWindow(QWidget* act)
*/
QWidget *QApplicationPrivate::focusNextPrevChild_helper(QWidget *toplevel, bool next)
{
- uint focus_flag = qt_tab_all_widgets ? Qt::TabFocus : Qt::StrongFocus;
-
QWidget *f = toplevel->focusWidget();
if (!f)
f = toplevel;
@@ -2496,11 +2497,22 @@ QWidget *QApplicationPrivate::focusNextPrevChild_helper(QWidget *toplevel, bool
QWidget *w = f;
QWidget *test = f->d_func()->focus_next;
while (test && test != f) {
- if ((test->focusPolicy() & focus_flag) == focus_flag
+ if ((test->focusPolicy() & Qt::TabFocus)
&& !(test->d_func()->extra && test->d_func()->extra->focus_proxy)
&& test->isVisibleTo(toplevel) && test->isEnabled()
&& !(w->windowType() == Qt::SubWindow && !w->isAncestorOf(test))
- && (toplevel->windowType() != Qt::SubWindow || toplevel->isAncestorOf(test))) {
+ && (toplevel->windowType() != Qt::SubWindow || toplevel->isAncestorOf(test))
+ && (qt_tab_all_widgets
+#ifndef QT_NO_LINEEDIT
+ || qobject_cast<QLineEdit*>(test)
+#endif
+#ifndef QT_NO_TEXTEDIT
+ || qobject_cast<QTextEdit*>(test)
+#endif
+#ifndef QT_NO_ITEMVIEWS
+ || qobject_cast<QListView*>(test)
+#endif
+ )) {
w = test;
if (next)
break;
diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm
index 7e8d96f..a656c7f 100644
--- a/src/gui/kernel/qapplication_mac.mm
+++ b/src/gui/kernel/qapplication_mac.mm
@@ -972,6 +972,7 @@ static EventTypeSpec app_events[] = {
{ kEventClassWindow, kEventWindowActivated },
{ kEventClassWindow, kEventWindowDeactivated },
+ { kEventClassMouse, kEventMouseScroll },
{ kEventClassMouse, kEventMouseWheelMoved },
{ kEventClassMouse, kEventMouseDown },
{ kEventClassMouse, kEventMouseUp },
@@ -1639,6 +1640,7 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event
case kEventMouseDown: edesc = "MouseButtonPress"; break;
case kEventMouseUp: edesc = "MouseButtonRelease"; break;
case kEventMouseDragged: case kEventMouseMoved: edesc = "MouseMove"; break;
+ case kEventMouseScroll: edesc = "MouseWheelScroll"; break;
case kEventMouseWheelMoved: edesc = "MouseWheelMove"; break;
}
if(ekind == kEventMouseDown || ekind == kEventMouseUp)
@@ -1659,12 +1661,43 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event
sizeof(mac_buttons), 0, &mac_buttons);
buttons = qt_mac_get_buttons(mac_buttons);
}
- int wheel_delta=0;
- if(ekind == kEventMouseWheelMoved) {
- int mdelt = 0;
- GetEventParameter(event, kEventParamMouseWheelDelta, typeSInt32, 0,
+
+ int wheel_deltaX = 0;
+ int wheel_deltaY = 0;
+ static EventRef compatibilityEvent = 0;
+
+ if (ekind == kEventMouseScroll) {
+ // kEventMouseScroll is the new way of dealing with mouse wheel
+ // events (kEventMouseWheelMoved was the old). kEventMouseScroll results
+ // in much smoother scrolling when using Mighty Mouse or TrackPad. For
+ // compatibility with older applications, carbon will also send us
+ // kEventMouseWheelMoved events if we dont eat this event
+ // (actually two events; one for horizontal and one for vertical).
+ // As a results of this, and to make sure we dont't receive duplicate events,
+ // we try to detect when this happend by checking the 'compatibilityEvent'.
+ SInt32 mdelt = 0;
+ GetEventParameter(event, kEventParamMouseWheelSmoothHorizontalDelta, typeSInt32, 0,
+ sizeof(mdelt), 0, &mdelt);
+ wheel_deltaX = mdelt;
+ GetEventParameter(event, kEventParamMouseWheelSmoothVerticalDelta, typeSInt32, 0,
sizeof(mdelt), 0, &mdelt);
- wheel_delta = mdelt * 120;
+ wheel_deltaY = mdelt;
+ GetEventParameter(event, kEventParamEventRef, typeEventRef, 0,
+ sizeof(compatibilityEvent), 0, &compatibilityEvent);
+ } else if (ekind == kEventMouseWheelMoved) {
+ if (event != compatibilityEvent) {
+ compatibilityEvent = 0;
+ int mdelt = 0;
+ GetEventParameter(event, kEventParamMouseWheelDelta, typeSInt32, 0,
+ sizeof(mdelt), 0, &mdelt);
+ EventMouseWheelAxis axis;
+ GetEventParameter(event, kEventParamMouseWheelAxis, typeMouseWheelAxis, 0,
+ sizeof(axis), 0, &axis);
+ if (axis == kEventMouseWheelAxisX)
+ wheel_deltaX = mdelt * 120;
+ else
+ wheel_deltaY = mdelt * 120;
+ }
}
Qt::MouseButton button = Qt::NoButton;
@@ -2054,20 +2087,29 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event
qt_mac_dblclick.last_button = button;
qt_mac_dblclick.last_time = GetEventTime(event);
}
- if(wheel_delta) {
- EventMouseWheelAxis axis;
- GetEventParameter(event, kEventParamMouseWheelAxis, typeMouseWheelAxis, 0,
- sizeof(axis), 0, &axis);
- QWheelEvent qwe(plocal, p, wheel_delta, buttons, modifiers,
- axis == kEventMouseWheelAxisX ? Qt::Horizontal : Qt::Vertical);
- QApplication::sendSpontaneousEvent(widget, &qwe);
- if(!qwe.isAccepted() && QApplicationPrivate::focus_widget && QApplicationPrivate::focus_widget != widget) {
- QWheelEvent qwe2(QApplicationPrivate::focus_widget->mapFromGlobal(p), p,
- wheel_delta, buttons, modifiers,
- axis == kEventMouseWheelAxisX ? Qt::Horizontal : Qt::Vertical);
- QApplication::sendSpontaneousEvent(QApplicationPrivate::focus_widget, &qwe2);
- if(!qwe2.isAccepted())
- handled_event = false;
+
+ if (wheel_deltaX || wheel_deltaY) {
+ if (wheel_deltaX) {
+ QWheelEvent qwe(plocal, p, wheel_deltaX, buttons, modifiers, Qt::Horizontal);
+ QApplication::sendSpontaneousEvent(widget, &qwe);
+ if (!qwe.isAccepted() && QApplicationPrivate::focus_widget && QApplicationPrivate::focus_widget != widget) {
+ QWheelEvent qwe2(QApplicationPrivate::focus_widget->mapFromGlobal(p), p,
+ wheel_deltaX, buttons, modifiers, Qt::Horizontal);
+ QApplication::sendSpontaneousEvent(QApplicationPrivate::focus_widget, &qwe2);
+ if (!qwe2.isAccepted())
+ handled_event = false;
+ }
+ }
+ if (wheel_deltaY) {
+ QWheelEvent qwe(plocal, p, wheel_deltaY, buttons, modifiers, Qt::Vertical);
+ QApplication::sendSpontaneousEvent(widget, &qwe);
+ if (!qwe.isAccepted() && QApplicationPrivate::focus_widget && QApplicationPrivate::focus_widget != widget) {
+ QWheelEvent qwe2(QApplicationPrivate::focus_widget->mapFromGlobal(p), p,
+ wheel_deltaY, buttons, modifiers, Qt::Vertical);
+ QApplication::sendSpontaneousEvent(QApplicationPrivate::focus_widget, &qwe2);
+ if (!qwe2.isAccepted())
+ handled_event = false;
+ }
}
} else {
#ifdef QMAC_SPEAK_TO_ME
@@ -2130,7 +2172,7 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event
plocal.x(), plocal.y(), event_desc, (QWidget*)widget,
widget ? widget->objectName().toLocal8Bit().constData() : "*Unknown*",
widget ? widget->metaObject()->className() : "*Unknown*",
- button, (int)buttons, (int)modifiers, wheel_delta);
+ button, (int)buttons, (int)modifiers, wheel_deltaX);
#endif
} else {
handled_event = false;
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index 7693ca7..4ebf8a9 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -63,6 +63,11 @@
#include <qdebug.h>
+@interface NSEvent (DeviceDelta)
+ - (float)deviceDeltaX;
+ - (float)deviceDeltaY;
+ - (float)deviceDeltaZ;
+@end
QT_BEGIN_NAMESPACE
@@ -776,17 +781,27 @@ extern "C" {
Qt::MouseButton buttons = cocoaButton2QtButton([theEvent buttonNumber]);
bool wheelOK = false;
Qt::KeyboardModifiers keyMods = qt_cocoaModifiers2QtModifiers([theEvent modifierFlags]);
-
QWidget *widgetToGetMouse = qwidget;
-
- // Mouse wheel deltas seem to tick in at increments of 0.1. Qt widgets
- // expect the delta to be a multiple of 120.
- const int ScrollFactor = 10 * 120;
- // The qMax(...) factor reduces the
- // acceleration for large wheel deltas.
- int deltaX = [theEvent deltaX] * ScrollFactor * qMax(0.6, 1.1 - qAbs([theEvent deltaX]));
- int deltaY = [theEvent deltaY] * ScrollFactor * qMax(0.6, 1.1 - qAbs([theEvent deltaY]));
- int deltaZ = [theEvent deltaZ] * ScrollFactor * qMax(0.6, 1.1 - qAbs([theEvent deltaZ]));
+ int deltaX = 0;
+ int deltaY = 0;
+ int deltaZ = 0;
+
+ const EventRef carbonEvent = (EventRef)[theEvent eventRef];
+ const UInt32 carbonEventKind = carbonEvent ? ::GetEventKind(carbonEvent) : 0;
+ if (carbonEventKind == kEventMouseScroll) {
+ // The mouse device containts pixel scroll
+ // wheel support (Mighty Mouse, Trackpad)
+ deltaX = (int)[theEvent deviceDeltaX] * 120;
+ deltaY = (int)[theEvent deviceDeltaY] * 120;
+ deltaZ = (int)[theEvent deviceDeltaZ] * 120;
+ } else { // carbonEventKind == kEventMouseWheelMoved
+ // Mouse wheel deltas seem to tick in at increments of 0.1.
+ // Qt widgets expect the delta to be a multiple of 120.
+ const int scrollFactor = 10 * 120;
+ deltaX = [theEvent deltaX] * scrollFactor * qMax(0.6, 1.1 - qAbs([theEvent deltaX]));
+ deltaY = [theEvent deltaY] * scrollFactor * qMax(0.6, 1.1 - qAbs([theEvent deltaY]));
+ deltaZ = [theEvent deltaZ] * scrollFactor * qMax(0.6, 1.1 - qAbs([theEvent deltaZ]));
+ }
if (deltaX != 0) {
QWheelEvent qwe(qlocal, qglobal, deltaX, buttons, keyMods, Qt::Horizontal);