summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kernel')
-rw-r--r--src/gui/kernel/qapplication.cpp7
-rw-r--r--src/gui/kernel/qapplication_mac.mm12
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm116
-rw-r--r--src/gui/kernel/qcocoaview_mac_p.h4
-rw-r--r--src/gui/kernel/qt_mac.cpp6
-rw-r--r--src/gui/kernel/qwidget.cpp5
-rw-r--r--src/gui/kernel/qwidget_mac.mm7
7 files changed, 82 insertions, 75 deletions
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index 839e465..a7cc5af 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -3716,6 +3716,13 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
Qt::MouseFocusReason);
}
+ // ### Qt 5 These dynamic tool tips should be an OPT-IN feature. Some platforms
+ // like Mac OS X (probably others too), can optimize their views by not
+ // dispatching mouse move events. We have attributes to control hover,
+ // and mouse tracking, but as long as we are deciding to implement this
+ // feature without choice of opting-in or out, you ALWAYS have to have
+ // tracking enabled. Therefore, the other properties give a false sense of
+ // performance enhancement.
if (e->type() == QEvent::MouseMove && mouse->buttons() == 0) {
d->toolTipWidget = w;
d->toolTipPos = relpos;
diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm
index 0884976..beccfb0 100644
--- a/src/gui/kernel/qapplication_mac.mm
+++ b/src/gui/kernel/qapplication_mac.mm
@@ -1316,8 +1316,13 @@ void QApplication::setOverrideCursor(const QCursor &cursor)
{
qApp->d_func()->cursor_list.prepend(cursor);
+#ifdef QT_MAC_USE_COCOA
+ QMacCocoaAutoReleasePool pool;
+ [static_cast<NSCursor *>(qt_mac_nsCursorForQCursor(cursor)) push];
+#else
if (qApp && qApp->activeWindow())
qt_mac_set_cursor(&qApp->d_func()->cursor_list.first(), QCursor::pos());
+#endif
}
void QApplication::restoreOverrideCursor()
@@ -1326,12 +1331,17 @@ void QApplication::restoreOverrideCursor()
return;
qApp->d_func()->cursor_list.removeFirst();
+#ifdef QT_MAC_USE_COCOA
+ QMacCocoaAutoReleasePool pool;
+ [NSCursor pop];
+#else
if (qApp && qApp->activeWindow()) {
const QCursor def(Qt::ArrowCursor);
qt_mac_set_cursor(qApp->d_func()->cursor_list.isEmpty() ? &def : &qApp->d_func()->cursor_list.first(), QCursor::pos());
}
-}
#endif
+}
+#endif // QT_NO_CURSOR
QWidget *QApplication::topLevelAt(const QPoint &p)
{
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index 64cdae6..52685ca 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -290,11 +290,18 @@ extern "C" {
{
if (qwidget->testAttribute(Qt::WA_DropSiteRegistered) == false)
return NSDragOperationNone;
+ NSPoint windowPoint = [sender draggingLocation];
+ if (qwidget->testAttribute(Qt::WA_TransparentForMouseEvents)) {
+ // pass the drag enter event to the view underneath.
+ NSView *candidateView = [[[self window] contentView] hitTest:windowPoint];
+ if (candidateView && candidateView != self)
+ return [candidateView draggingEntered:sender];
+ }
+ dragEnterSequence = [sender draggingSequenceNumber];
[self addDropData:sender];
QMimeData *mimeData = dropData;
if (QDragManager::self()->source())
mimeData = QDragManager::self()->dragPrivate()->data;
- NSPoint windowPoint = [sender draggingLocation];
NSPoint globalPoint = [[sender draggingDestinationWindow] convertBaseToScreen:windowPoint];
NSPoint localPoint = [self convertPoint:windowPoint fromView:nil];
QPoint posDrag(localPoint.x, localPoint.y);
@@ -318,6 +325,9 @@ extern "C" {
[self removeDropData];
return NSDragOperationNone;
} else {
+ // save the mouse position, used by draggingExited handler.
+ DnDParams *dndParams = [QCocoaView currentMouseEvent];
+ dndParams->activeDragEnterPos = windowPoint;
// send a drag move event immediately after a drag enter event (as per documentation).
QDragMoveEvent qDMEvent(posDrag, qtAllowed, mimeData, QApplication::mouseButtons(), modifiers);
qDMEvent.setDropAction(qDEEvent.dropAction());
@@ -338,11 +348,22 @@ extern "C" {
- (NSDragOperation)draggingUpdated:(id < NSDraggingInfo >)sender
{
- // drag enter event was rejected, so ignore the move event.
+ NSPoint windowPoint = [sender draggingLocation];
+ if (qwidget->testAttribute(Qt::WA_TransparentForMouseEvents)) {
+ // pass the drag move event to the view underneath.
+ NSView *candidateView = [[[self window] contentView] hitTest:windowPoint];
+ if (candidateView && candidateView != self)
+ return [candidateView draggingUpdated:sender];
+ }
+ // in cases like QFocusFrame, the view under the mouse might
+ // not have received the drag enter. Generate a synthetic
+ // drag enter event for that view.
+ if (dragEnterSequence != [sender draggingSequenceNumber])
+ [self draggingEntered:sender];
+ // drag enter event was rejected, so ignore the move event.
if (dropData == 0)
return NSDragOperationNone;
// return last value, if we are still in the answerRect.
- NSPoint windowPoint = [sender draggingLocation];
NSPoint globalPoint = [[sender draggingDestinationWindow] convertBaseToScreen:windowPoint];
NSPoint localPoint = [self convertPoint:windowPoint fromView:nil];
NSDragOperation nsActions = [sender draggingSourceOperationMask];
@@ -381,21 +402,34 @@ extern "C" {
- (void)draggingExited:(id < NSDraggingInfo >)sender
{
- Q_UNUSED(sender)
- // drag enter event was rejected, so ignore the move event.
+ dragEnterSequence = -1;
+ if (qwidget->testAttribute(Qt::WA_TransparentForMouseEvents)) {
+ // try sending the leave event to the last view which accepted drag enter.
+ DnDParams *dndParams = [QCocoaView currentMouseEvent];
+ NSView *candidateView = [[[self window] contentView] hitTest:dndParams->activeDragEnterPos];
+ if (candidateView && candidateView != self)
+ return [candidateView draggingExited:sender];
+ }
+ // drag enter event was rejected, so ignore the move event.
if (dropData) {
QDragLeaveEvent de;
QApplication::sendEvent(qwidget, &de);
[self removeDropData];
}
-
}
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
+ NSPoint windowPoint = [sender draggingLocation];
+ dragEnterSequence = -1;
+ if (qwidget->testAttribute(Qt::WA_TransparentForMouseEvents)) {
+ // pass the drop event to the view underneath.
+ NSView *candidateView = [[[self window] contentView] hitTest:windowPoint];
+ if (candidateView && candidateView != self)
+ return [candidateView performDragOperation:sender];
+ }
[self addDropData:sender];
- NSPoint windowPoint = [sender draggingLocation];
NSPoint globalPoint = [[sender draggingDestinationWindow] convertBaseToScreen:windowPoint];
NSPoint localPoint = [self convertPoint:windowPoint fromView:nil];
QPoint posDrop(localPoint.x, localPoint.y);
@@ -574,11 +608,15 @@ extern "C" {
[self removeTrackingArea:t];
}
}
+
+ // Ideally, we shouldn't have NSTrackingMouseMoved events included below, it should
+ // only be turned on if mouseTracking, hover is on or a tool tip is set.
+ // Unfortunately, Qt will send "tooltip" events on mouse moves, so we need to
+ // turn it on in ALL case. That means EVERY QCocoaView gets to pay the cost of
+ // mouse moves delivered to it (Apple recommends keeping it OFF because there
+ // is a performance hit). So it goes.
NSUInteger trackingOptions = NSTrackingMouseEnteredAndExited | NSTrackingActiveInActiveApp
- | NSTrackingInVisibleRect;
- if (qwidget->hasMouseTracking() || !qwidgetprivate->toolTip.isEmpty()
- || qwidget->testAttribute(Qt::WA_Hover))
- trackingOptions |= NSTrackingMouseMoved;
+ | NSTrackingInVisibleRect | NSTrackingMouseMoved;
NSTrackingArea *ta = [[NSTrackingArea alloc] initWithRect:NSMakeRect(0, 0,
qwidget->width(),
qwidget->height())
@@ -643,62 +681,6 @@ extern "C" {
qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::NoButton);
}
-- (NSView *)viewUnderTransparentForMouseView:(NSView *)mouseView widget:(QWidget *)widgetToGetMouse
- withWindowPoint:(NSPoint)windowPoint
-{
- NSMutableArray *viewsToLookAt = [NSMutableArray arrayWithCapacity:5];
- [viewsToLookAt addObject:mouseView];
- QWidget *parentWidget = widgetToGetMouse->parentWidget();
- while (parentWidget) {
- [viewsToLookAt addObject:qt_mac_nativeview_for(parentWidget)];
- parentWidget = parentWidget->parentWidget();
- }
-
- // Now walk through the subviews of each view and determine which subview should
- // get the event. We look through all the subviews at a given level with
- // the assumption that the last item to be found the candidate has a higher z-order.
- // Unfortunately, fast enumeration doesn't go backwards in 10.5, so assume go fast
- // forward is quicker than the slow normal way backwards.
- NSView *candidateView = nil;
- for (NSView *lookView in viewsToLookAt) {
- NSPoint tmpPoint = [lookView convertPoint:windowPoint fromView:nil];
- for (NSView *view in [lookView subviews]) {
- if (view == mouseView || [view isHidden])
- continue;
- NSRect frameRect = [view frame];
- if (NSMouseInRect(tmpPoint, [view frame], [view isFlipped]))
- candidateView = view;
- }
- if (candidateView)
- break;
- }
-
-
- if (candidateView != nil) {
- // Now that we've got a candidate, we have to dig into it's tree and see where it is.
- NSView *lowerView = nil;
- NSView *viewForDescent = candidateView;
- while (viewForDescent) {
- NSPoint tmpPoint = [viewForDescent convertPoint:windowPoint fromView:nil];
- // Apply same rule as above wrt z-order.
- for (NSView *view in [viewForDescent subviews]) {
- if (![view isHidden] && NSMouseInRect(tmpPoint, [view frame], [view isFlipped]))
- lowerView = view;
- }
- if (!lowerView) // Low as we can be at this point.
- candidateView = viewForDescent;
-
- // Try to go deeper, will also exit out of the loop, if we found the point.
- viewForDescent = lowerView;
- lowerView = nil;
- }
- }
- // I am transparent, so I can't be a candidate.
- if (candidateView == mouseView)
- candidateView = nil;
- return candidateView;
-}
-
- (void)mouseDown:(NSEvent *)theEvent
{
qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonPress, Qt::LeftButton);
diff --git a/src/gui/kernel/qcocoaview_mac_p.h b/src/gui/kernel/qcocoaview_mac_p.h
index 6583139..4762b17 100644
--- a/src/gui/kernel/qcocoaview_mac_p.h
+++ b/src/gui/kernel/qcocoaview_mac_p.h
@@ -68,6 +68,7 @@ struct DnDParams
NSEvent *theEvent;
NSPoint localPoint;
NSDragOperation performedAction;
+ NSPoint activeDragEnterPos;
};
QT_END_NAMESPACE
@@ -86,6 +87,7 @@ Q_GUI_EXPORT
bool sendKeyEvents;
QString *composingText;
QStringList *currentCustomTypes;
+ NSInteger dragEnterSequence;
}
- (id)initWithQWidget:(QWidget *)widget widgetPrivate:(QWidgetPrivate *)widgetprivate;
- (void) finishInitWithQWidget:(QWidget *)widget widgetPrivate:(QWidgetPrivate *)widgetprivate;
@@ -104,8 +106,6 @@ Q_GUI_EXPORT
- (QWidget *)qt_qwidget;
- (BOOL)qt_leftButtonIsRightButton;
- (void)qt_setLeftButtonIsRightButton:(BOOL)isSwapped;
-- (NSView *)viewUnderTransparentForMouseView:(NSView *)mouseView widget:(QWidget *)widgetToGetMouse
- withWindowPoint:(NSPoint)windowPoint;
+ (DnDParams*)currentMouseEvent;
@end
diff --git a/src/gui/kernel/qt_mac.cpp b/src/gui/kernel/qt_mac.cpp
index 27df5d1..0c3b707 100644
--- a/src/gui/kernel/qt_mac.cpp
+++ b/src/gui/kernel/qt_mac.cpp
@@ -134,7 +134,7 @@ QColor qcolorForThemeTextColor(ThemeTextColor themeColor)
#ifdef Q_OS_MAC32
RGBColor c;
GetThemeTextColor(themeColor, 32, true, &c);
- QColor color = QColor(c.red / 265, c.green / 256, c.blue / 256);
+ QColor color = QColor(c.red / 256, c.green / 256, c.blue / 256);
return color;
#else
// There is no equivalent to GetThemeTextColor in 64-bit and it was rather bad that
@@ -156,13 +156,13 @@ QColor qcolorForThemeTextColor(ThemeTextColor themeColor)
case kThemeTextColorAlertInactive:
case kThemeTextColorDialogInactive:
case kThemeTextColorPlacardInactive:
- return QColor(67, 69, 69, 255);
+ return QColor(69, 69, 69, 255);
case kThemeTextColorPopupButtonInactive:
case kThemeTextColorPopupLabelInactive:
case kThemeTextColorPushButtonInactive:
case kThemeTextColorTabFrontInactive:
case kThemeTextColorBevelButtonInactive:
- return QColor(123, 127, 127, 255);
+ return QColor(127, 127, 127, 255);
default: {
QNativeImage nativeImage(16,16, QNativeImage::systemFormat());
CGRect cgrect = CGRectMake(0, 0, 16, 16);
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index d1ab45a..a1a160e 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -4541,6 +4541,11 @@ void QWidget::unsetLayoutDirection()
By default, this property contains a cursor with the Qt::ArrowCursor
shape.
+ Some underlying window implementations will reset the cursor if it
+ leaves a widget even if the mouse is grabbed. If you want to have
+ a cursor set for all widgets, even when outside the window, consider
+ QApplication::setOverrideCursor().
+
\sa QApplication::setOverrideCursor()
*/
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index ad16485..dcc5056 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -1521,12 +1521,16 @@ void QWidgetPrivate::toggleDrawers(bool visible)
*****************************************************************************/
bool QWidgetPrivate::qt_mac_update_sizer(QWidget *w, int up)
{
+ // I'm not sure what "up" is
if(!w || !w->isWindow())
return false;
QTLWExtra *topData = w->d_func()->topData();
QWExtra *extraData = w->d_func()->extraData();
- topData->resizer += up;
+ // topData->resizer is only 4 bits, so subtracting -1 from zero causes bad stuff
+ // to happen, prevent that here (you really want the thing hidden).
+ if (up >= 0 || topData->resizer != 0)
+ topData->resizer += up;
OSWindowRef windowRef = qt_mac_window_for(OSViewRef(w->winId()));
{
#ifndef QT_MAC_USE_COCOA
@@ -1539,7 +1543,6 @@ bool QWidgetPrivate::qt_mac_update_sizer(QWidget *w, int up)
bool remove_grip = (topData->resizer || (w->windowFlags() & Qt::FramelessWindowHint)
|| (extraData->maxw && extraData->maxh &&
extraData->maxw == extraData->minw && extraData->maxh == extraData->minh));
-
#ifndef QT_MAC_USE_COCOA
WindowAttributes attr;
GetWindowAttributes(windowRef, &attr);