summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kernel')
-rw-r--r--src/gui/kernel/kernel.pri3
-rw-r--r--src/gui/kernel/qapplication_mac.mm5
-rw-r--r--src/gui/kernel/qcocoapanel_mac.mm140
-rw-r--r--src/gui/kernel/qcocoapanel_mac_p.h2
-rw-r--r--src/gui/kernel/qcocoasharedwindowmethods_mac_p.h187
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm28
-rw-r--r--src/gui/kernel/qcocoawindow_mac.mm137
-rw-r--r--src/gui/kernel/qcocoawindow_mac_p.h8
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac.mm45
-rw-r--r--src/gui/kernel/qwidget.cpp4
-rw-r--r--src/gui/kernel/qwidget_mac.mm112
11 files changed, 301 insertions, 370 deletions
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index 7d0e5c7..f2bd288 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -206,7 +206,8 @@ embedded {
qcocoaapplication_mac_p.h \
qcocoaapplicationdelegate_mac_p.h \
qmacgesturerecognizer_mac_p.h \
- qmultitouch_mac_p.h
+ qmultitouch_mac_p.h \
+ qcocoasharedwindowmethods_mac_p.h
OBJECTIVE_SOURCES += \
kernel/qcursor_mac.mm \
diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm
index 22a0959..688e51f 100644
--- a/src/gui/kernel/qapplication_mac.mm
+++ b/src/gui/kernel/qapplication_mac.mm
@@ -1687,7 +1687,10 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event
UInt32 mac_buttons = 0;
GetEventParameter(event, kEventParamMouseChord, typeUInt32, 0,
sizeof(mac_buttons), 0, &mac_buttons);
- buttons = qt_mac_get_buttons(mac_buttons);
+ if (ekind != kEventMouseWheelMoved)
+ buttons = qt_mac_get_buttons(mac_buttons);
+ else
+ buttons = QApplication::mouseButtons();
}
int wheel_deltaX = 0;
diff --git a/src/gui/kernel/qcocoapanel_mac.mm b/src/gui/kernel/qcocoapanel_mac.mm
index a26d775..9154284 100644
--- a/src/gui/kernel/qcocoapanel_mac.mm
+++ b/src/gui/kernel/qcocoapanel_mac.mm
@@ -50,152 +50,16 @@
#include <QtGui/QWidget>
QT_FORWARD_DECLARE_CLASS(QWidget);
-QT_BEGIN_NAMESPACE
-extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.mm
-QT_END_NAMESPACE
QT_USE_NAMESPACE
-
-@interface NSWindow (QtCoverForHackWithCategory)
-+ (Class)frameViewClassForStyleMask:(NSUInteger)styleMask;
-@end
-
-
@implementation QT_MANGLE_NAMESPACE(QCocoaPanel)
-- (BOOL)canBecomeKeyWindow
-{
- QWidget *widget = [self QT_MANGLE_NAMESPACE(qt_qwidget)];
-
- bool isToolTip = (widget->windowType() == Qt::ToolTip);
- bool isPopup = (widget->windowType() == Qt::Popup);
- return !(isPopup || isToolTip);
-}
-
/***********************************************************************
- BEGIN Copy and Paste between QCocoaWindow and QCocoaPanel
+ Copy and Paste between QCocoaWindow and QCocoaPanel
This is a bit unfortunate, but thanks to the dynamic dispatch we
have to duplicate this code or resort to really silly forwarding methods
**************************************************************************/
-
-/*
- The methods keyDown, keyUp, and flagsChanged... These really shouldn't ever
- get hit. We automatically say we can be first responder if we are a window.
- So, the handling should get handled by the view. This is here more as a
- last resort (i.e., this is code that can potentially be removed).
- */
-
-- (void)toggleToolbarShown:(id)sender
-{
- macSendToolbarChangeEvent([self QT_MANGLE_NAMESPACE(qt_qwidget)]);
- [super toggleToolbarShown:sender];
-}
-
-- (void)keyDown:(NSEvent *)theEvent
-{
- bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]);
- if (!keyOK)
- [super keyDown:theEvent];
-}
-
-- (void)keyUp:(NSEvent *)theEvent
-{
- bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]);
- if (!keyOK)
- [super keyUp:theEvent];
-}
-
-- (void)flagsChanged:(NSEvent *)theEvent
-{
- qt_dispatchModifiersChanged(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]);
- [super flagsChanged:theEvent];
-}
-
-
-- (void)tabletProximity:(NSEvent *)tabletEvent
-{
- qt_dispatchTabletProximityEvent(tabletEvent);
-}
-
-- (void)sendEvent:(NSEvent *)event
-{
- QWidget *widget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self];
-
- // Cocoa can hold onto the window after we've disavowed its knowledge. So,
- // if we get sent an event afterwards just have it go through the super's
- // version and don't do any stuff with Qt.
- if (!widget) {
- [super sendEvent:event];
- return;
- }
- [self retain];
- QT_MANGLE_NAMESPACE(QCocoaView) *view = static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(qt_mac_nativeview_for(widget));
- Qt::MouseButton mouseButton = cocoaButton2QtButton([event buttonNumber]);
-
- // sometimes need to redirect mouse events to the popup.
- QWidget *popup = qAppInstance()->activePopupWidget();
- if (popup && popup != widget) {
- switch([event type])
- {
- case NSLeftMouseDown:
- qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonPress, mouseButton);
- // Don't call super here. This prevents us from getting the mouseUp event,
- // which we need to send even if the mouseDown event was not accepted.
- // (this is standard Qt behavior.)
- break;
- case NSRightMouseDown:
- case NSOtherMouseDown:
- if (!qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonPress, mouseButton))
- [super sendEvent:event];
- break;
- case NSLeftMouseUp:
- case NSRightMouseUp:
- case NSOtherMouseUp:
- if (!qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonRelease, mouseButton))
- [super sendEvent:event];
- break;
- case NSMouseMoved:
- qt_mac_handleMouseEvent(view, event, QEvent::MouseMove, Qt::NoButton);
- break;
- case NSLeftMouseDragged:
- case NSRightMouseDragged:
- case NSOtherMouseDragged:
- [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->view = view;
- [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->theEvent = event;
- if (!qt_mac_handleMouseEvent(view, event, QEvent::MouseMove, mouseButton))
- [super sendEvent:event];
- break;
- default:
- [super sendEvent:event];
- break;
- }
- } else {
- [super sendEvent:event];
- }
- qt_mac_dispatchNCMouseMessage(self, event, [self QT_MANGLE_NAMESPACE(qt_qwidget)], leftButtonIsRightButton);
-
-
- [self release];
-}
-
-- (BOOL)makeFirstResponder:(NSResponder *)responder
-{
- // For some reason Cocoa wants to flip the first responder
- // when Qt doesn't want to, sorry, but "No" :-)
- if (responder == nil && qApp->focusWidget())
- return NO;
- return [super makeFirstResponder:responder];
-}
-
-/***********************************************************************
- END Copy and Paste between QCocoaWindow and QCocoaPanel
-***********************************************************************/
-+ (Class)frameViewClassForStyleMask:(NSUInteger)styleMask
-{
- if (styleMask & QtMacCustomizeWindow)
- return [QT_MANGLE_NAMESPACE(QCocoaWindowCustomThemeFrame) class];
- return [super frameViewClassForStyleMask:styleMask];
-}
+#include "qcocoasharedwindowmethods_mac_p.h"
@end
#endif
diff --git a/src/gui/kernel/qcocoapanel_mac_p.h b/src/gui/kernel/qcocoapanel_mac_p.h
index d95cd93..69dca1e 100644
--- a/src/gui/kernel/qcocoapanel_mac_p.h
+++ b/src/gui/kernel/qcocoapanel_mac_p.h
@@ -54,12 +54,10 @@
#ifdef QT_MAC_USE_COCOA
#import <Cocoa/Cocoa.h>
-
@interface QT_MANGLE_NAMESPACE(QCocoaPanel) : NSPanel {
bool leftButtonIsRightButton;
}
+ (Class)frameViewClassForStyleMask:(NSUInteger)styleMask;
-
@end
#endif
diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
new file mode 100644
index 0000000..f347240
--- /dev/null
+++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/****************************************************************************
+ NB: This is not a header file, dispite the file name suffix. This file is
+ included directly into the source code of qcocoawindow_mac.mm and
+ qcocoapanel_mac.mm to avoid manually doing copy and paste of the exact
+ same code needed at both places. This solution makes it more difficult
+ to e.g fix a bug in qcocoawindow_mac.mm, but forget to do the same in
+ qcocoapanel_mac.mm.
+ The reason we need to do copy and paste in the first place, rather than
+ resolve to method overriding, is that QCocoaPanel needs to inherit from
+ NSPanel, while QCocoaWindow needs to inherit NSWindow rather than NSPanel).
+****************************************************************************/
+
+QT_BEGIN_NAMESPACE
+extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.mm
+extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
+QT_END_NAMESPACE
+
+- (BOOL)canBecomeKeyWindow
+{
+ QWidget *widget = [self QT_MANGLE_NAMESPACE(qt_qwidget)];
+
+ bool isToolTip = (widget->windowType() == Qt::ToolTip);
+ bool isPopup = (widget->windowType() == Qt::Popup);
+ return !(isPopup || isToolTip);
+}
+
+- (void)toggleToolbarShown:(id)sender
+{
+ macSendToolbarChangeEvent([self QT_MANGLE_NAMESPACE(qt_qwidget)]);
+ [super toggleToolbarShown:sender];
+}
+
+/*
+ The methods keyDown, keyUp, and flagsChanged... These really shouldn't ever
+ get hit. We automatically say we can be first responder if we are a window.
+ So, the handling should get handled by the view. This is here more as a
+ last resort (i.e., this is code that can potentially be removed).
+ */
+- (void)keyDown:(NSEvent *)theEvent
+{
+ bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]);
+ if (!keyOK)
+ [super keyDown:theEvent];
+}
+
+- (void)keyUp:(NSEvent *)theEvent
+{
+ bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]);
+ if (!keyOK)
+ [super keyUp:theEvent];
+}
+
+- (void)flagsChanged:(NSEvent *)theEvent
+{
+ qt_dispatchModifiersChanged(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]);
+ [super flagsChanged:theEvent];
+}
+
+
+- (void)tabletProximity:(NSEvent *)tabletEvent
+{
+ qt_dispatchTabletProximityEvent(tabletEvent);
+}
+
+- (void)sendEvent:(NSEvent *)event
+{
+ QWidget *widget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self];
+
+ // Cocoa can hold onto the window after we've disavowed its knowledge. So,
+ // if we get sent an event afterwards just have it go through the super's
+ // version and don't do any stuff with Qt.
+ if (!widget) {
+ [super sendEvent:event];
+ return;
+ }
+
+ [self retain];
+ QT_MANGLE_NAMESPACE(QCocoaView) *view = static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(qt_mac_nativeview_for(widget));
+ Qt::MouseButton mouseButton = cocoaButton2QtButton([event buttonNumber]);
+
+ bool handled = false;
+ // sometimes need to redirect mouse events to the popup.
+ QWidget *popup = qAppInstance()->activePopupWidget();
+ if (popup) {
+ switch([event type])
+ {
+ case NSLeftMouseDown:
+ if (!qt_button_down)
+ qt_button_down = widget;
+ handled = qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonPress, mouseButton);
+ // Don't call super here. This prevents us from getting the mouseUp event,
+ // which we need to send even if the mouseDown event was not accepted.
+ // (this is standard Qt behavior.)
+ break;
+ case NSRightMouseDown:
+ case NSOtherMouseDown:
+ if (!qt_button_down)
+ qt_button_down = widget;
+ handled = qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonPress, mouseButton);
+ break;
+ case NSLeftMouseUp:
+ case NSRightMouseUp:
+ case NSOtherMouseUp:
+ handled = qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonRelease, mouseButton);
+ qt_button_down = 0;
+ break;
+ case NSMouseMoved:
+ handled = qt_mac_handleMouseEvent(view, event, QEvent::MouseMove, Qt::NoButton);
+ break;
+ case NSLeftMouseDragged:
+ case NSRightMouseDragged:
+ case NSOtherMouseDragged:
+ [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->view = view;
+ [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->theEvent = event;
+ handled = qt_mac_handleMouseEvent(view, event, QEvent::MouseMove, mouseButton);
+ break;
+ default:
+ [super sendEvent:event];
+ break;
+ }
+ } else {
+ [super sendEvent:event];
+ }
+
+ if (!handled)
+ qt_mac_dispatchNCMouseMessage(self, event, [self QT_MANGLE_NAMESPACE(qt_qwidget)], leftButtonIsRightButton);
+
+ [self release];
+}
+
+- (BOOL)makeFirstResponder:(NSResponder *)responder
+{
+ // For some reason Cocoa wants to flip the first responder
+ // when Qt doesn't want to, sorry, but "No" :-)
+ if (responder == nil && qApp->focusWidget())
+ return NO;
+ return [super makeFirstResponder:responder];
+}
+
++ (Class)frameViewClassForStyleMask:(NSUInteger)styleMask
+{
+ if (styleMask & QtMacCustomizeWindow)
+ return [QT_MANGLE_NAMESPACE(QCocoaWindowCustomThemeFrame) class];
+ return [super frameViewClassForStyleMask:styleMask];
+}
+
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index 3da783f..ddd8ca6 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -708,9 +708,9 @@ extern "C" {
- (void)mouseUp:(NSEvent *)theEvent
{
- qt_button_down = 0;
-
qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonRelease, Qt::LeftButton);
+
+ qt_button_down = 0;
}
- (void)rightMouseDown:(NSEvent *)theEvent
@@ -723,9 +723,9 @@ extern "C" {
- (void)rightMouseUp:(NSEvent *)theEvent
{
- qt_button_down = 0;
-
qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonRelease, Qt::RightButton);
+
+ qt_button_down = 0;
}
- (void)otherMouseDown:(NSEvent *)theEvent
@@ -739,10 +739,10 @@ extern "C" {
- (void)otherMouseUp:(NSEvent *)theEvent
{
- qt_button_down = 0;
-
Qt::MouseButton mouseButton = cocoaButton2QtButton([theEvent buttonNumber]);
qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonRelease, mouseButton);
+
+ qt_button_down = 0;
}
- (void)mouseDragged:(NSEvent *)theEvent
@@ -777,12 +777,19 @@ extern "C" {
NSPoint windowPoint = [theEvent locationInWindow];
NSPoint globalPoint = [[theEvent window] convertBaseToScreen:windowPoint];
NSPoint localPoint = [self convertPoint:windowPoint fromView:nil];
- QPoint qlocal = QPoint(localPoint.x, localPoint.y);
- QPoint qglobal = QPoint(globalPoint.x, globalPoint.y);
- Qt::MouseButton buttons = cocoaButton2QtButton([theEvent buttonNumber]);
+ QPoint qlocal = QPoint(localPoint.x, flipYCoordinate(localPoint.y));
+ QPoint qglobal = QPoint(globalPoint.x, flipYCoordinate(globalPoint.y));
+ Qt::MouseButtons buttons = QApplication::mouseButtons();
bool wheelOK = false;
Qt::KeyboardModifiers keyMods = qt_cocoaModifiers2QtModifiers([theEvent modifierFlags]);
QWidget *widgetToGetMouse = qwidget;
+ // if popup is open it should get wheel events if the cursor is over the popup,
+ // otherwise the event should be ignored.
+ if (QWidget *popup = qAppInstance()->activePopupWidget()) {
+ if (!popup->geometry().contains(qglobal))
+ return;
+ }
+
int deltaX = 0;
int deltaY = 0;
int deltaZ = 0;
@@ -1442,6 +1449,9 @@ Qt::DropAction QDragManager::drag(QDrag *o)
pasteboard:pboard
source:dndParams.view
slideBack:YES];
+ // reset the implicit grab widget when drag ends because we will not
+ // receive the mouse release event when DND is active.
+ qt_button_down = 0;
[dndParams.view release];
[image release];
dragPrivate()->executed_action = Qt::IgnoreAction;
diff --git a/src/gui/kernel/qcocoawindow_mac.mm b/src/gui/kernel/qcocoawindow_mac.mm
index 263f0ac..a9aa373 100644
--- a/src/gui/kernel/qcocoawindow_mac.mm
+++ b/src/gui/kernel/qcocoawindow_mac.mm
@@ -50,15 +50,8 @@
#include <QtGui/QWidget>
QT_FORWARD_DECLARE_CLASS(QWidget);
-QT_BEGIN_NAMESPACE
-extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.mm
-QT_END_NAMESPACE
QT_USE_NAMESPACE
-@interface NSWindow (QtCoverForHackWithCategory)
-+ (Class)frameViewClassForStyleMask:(NSUInteger)styleMask;
-@end
-
@implementation NSWindow (QT_MANGLE_NAMESPACE(QWidgetIntegration))
- (id)QT_MANGLE_NAMESPACE(qt_initWithQWidget):(QWidget*)widget contentRect:(NSRect)rect styleMask:(NSUInteger)mask;
@@ -83,138 +76,12 @@ QT_USE_NAMESPACE
@implementation QT_MANGLE_NAMESPACE(QCocoaWindow)
-- (BOOL)canBecomeKeyWindow
-{
- return YES;
-}
-
/***********************************************************************
- BEGIN Copy and Paste between QCocoaWindow and QCocoaPanel
+ Copy and Paste between QCocoaWindow and QCocoaPanel
This is a bit unfortunate, but thanks to the dynamic dispatch we
have to duplicate this code or resort to really silly forwarding methods
**************************************************************************/
-
-/*
- The methods keyDown, keyUp, and flagsChanged... These really shouldn't ever
- get hit. We automatically say we can be first responder if we are a window.
- So, the handling should get handled by the view. This is here more as a
- last resort (i.e., this is code that can potentially be removed).
- */
-
-- (void)toggleToolbarShown:(id)sender
-{
- macSendToolbarChangeEvent([self QT_MANGLE_NAMESPACE(qt_qwidget)]);
- [super toggleToolbarShown:sender];
-}
-
-- (void)keyDown:(NSEvent *)theEvent
-{
- bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]);
- if (!keyOK)
- [super keyDown:theEvent];
-}
-
-- (void)keyUp:(NSEvent *)theEvent
-{
- bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]);
- if (!keyOK)
- [super keyUp:theEvent];
-}
-
-- (void)flagsChanged:(NSEvent *)theEvent
-{
- qt_dispatchModifiersChanged(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]);
- [super flagsChanged:theEvent];
-}
-
-
-- (void)tabletProximity:(NSEvent *)tabletEvent
-{
- qt_dispatchTabletProximityEvent(tabletEvent);
-}
-
-- (void)sendEvent:(NSEvent *)event
-{
- QWidget *widget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self];
-
- // Cocoa can hold onto the window after we've disavowed its knowledge. So,
- // if we get sent an event afterwards just have it go through the super's
- // version and don't do any stuff with Qt.
- if (!widget) {
- [super sendEvent:event];
- return;
- }
-
- [self retain];
- QT_MANGLE_NAMESPACE(QCocoaView) *view = static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(qt_mac_nativeview_for(widget));
- Qt::MouseButton mouseButton = cocoaButton2QtButton([event buttonNumber]);
- // sometimes need to redirect mouse events to the popup.
- QWidget *popup = qAppInstance()->activePopupWidget();
- if (popup && popup != widget) {
- switch([event type])
- {
- case NSLeftMouseDown:
- qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonPress, mouseButton);
- // Don't call super here. This prevents us from getting the mouseUp event,
- // which we need to send even if the mouseDown event was not accepted.
- // (this is standard Qt behavior.)
- break;
- case NSRightMouseDown:
- case NSOtherMouseDown:
- if (!qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonPress, mouseButton))
- [super sendEvent:event];
- break;
- case NSLeftMouseUp:
- case NSRightMouseUp:
- case NSOtherMouseUp:
- if (!qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonRelease, mouseButton))
- [super sendEvent:event];
- break;
- case NSMouseMoved:
- qt_mac_handleMouseEvent(view, event, QEvent::MouseMove, Qt::NoButton);
- break;
- case NSLeftMouseDragged:
- case NSRightMouseDragged:
- case NSOtherMouseDragged:
- [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->view = view;
- [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->theEvent = event;
- if (!qt_mac_handleMouseEvent(view, event, QEvent::MouseMove, mouseButton))
- [super sendEvent:event];
- break;
- default:
- [super sendEvent:event];
- break;
- }
- } else {
- [super sendEvent:event];
- }
- qt_mac_dispatchNCMouseMessage(self, event, [self QT_MANGLE_NAMESPACE(qt_qwidget)], leftButtonIsRightButton);
-
-
- [self release];
-}
-
-
-- (BOOL)makeFirstResponder:(NSResponder *)responder
-{
- // For some reason Cocoa wants to flip the first responder
- // when Qt doesn't want to, sorry, but "No" :-)
- if (responder == nil && qApp->focusWidget())
- return NO;
- return [super makeFirstResponder:responder];
-}
-
-/***********************************************************************
- END Copy and Paste between QCocoaWindow and QCocoaPanel
-***********************************************************************/
-
-+ (Class)frameViewClassForStyleMask:(NSUInteger)styleMask
-{
- if (styleMask & QtMacCustomizeWindow)
- return [QT_MANGLE_NAMESPACE(QCocoaWindowCustomThemeFrame) class];
- return [super frameViewClassForStyleMask:styleMask];
-}
+#include "qcocoasharedwindowmethods_mac_p.h"
@end
-
#endif
diff --git a/src/gui/kernel/qcocoawindow_mac_p.h b/src/gui/kernel/qcocoawindow_mac_p.h
index a688d96..91c5d4e 100644
--- a/src/gui/kernel/qcocoawindow_mac_p.h
+++ b/src/gui/kernel/qcocoawindow_mac_p.h
@@ -50,13 +50,18 @@
// We mean it.
//
-#include "qmacdefines_mac.h"
#ifdef QT_MAC_USE_COCOA
+#include "qmacdefines_mac.h"
#import <Cocoa/Cocoa.h>
enum { QtMacCustomizeWindow = 1 << 21 }; // This will one day be run over by
QT_FORWARD_DECLARE_CLASS(QWidget);
+QT_FORWARD_DECLARE_CLASS(QStringList);
+
+@interface NSWindow (QtCoverForHackWithCategory)
++ (Class)frameViewClassForStyleMask:(NSUInteger)styleMask;
+@end
@interface NSWindow (QT_MANGLE_NAMESPACE(QWidgetIntegration))
- (id)QT_MANGLE_NAMESPACE(qt_initWithQWidget):(QWidget *)widget contentRect:(NSRect)rect styleMask:(NSUInteger)mask;
@@ -70,3 +75,4 @@ QT_FORWARD_DECLARE_CLASS(QWidget);
+ (Class)frameViewClassForStyleMask:(NSUInteger)styleMask;
@end
#endif
+
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm
index 2bf1465..ef680a4 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac.mm
+++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm
@@ -139,6 +139,7 @@ void QMacWindowFader::performFade()
extern bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); // qapplication.cpp;
extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.mm
extern QWidget * mac_mouse_grabber;
+extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
void macWindowFade(void * /*OSWindowRef*/ window, float durationSeconds)
{
@@ -748,7 +749,11 @@ void qt_mac_dispatchNCMouseMessage(void * /* NSWindow* */eventWindow, void * /*
NSRect frameRect = [window frame];
if (fakeNCEvents || NSMouseInRect(globalPoint, frameRect, NO)) {
NSRect contentRect = [window contentRectForFrameRect:frameRect];
- if (fakeNCEvents || !NSMouseInRect(globalPoint, contentRect, NO)) {
+ qglobalPoint = QPoint(flipPoint(globalPoint).toPoint());
+ QWidget *w = widgetToGetEvent->childAt(widgetToGetEvent->mapFromGlobal(qglobalPoint));
+ // check that the mouse pointer is on the non-client area and
+ // there are not widgets in it.
+ if (fakeNCEvents || (!NSMouseInRect(globalPoint, contentRect, NO) && !w)) {
qglobalPoint = QPoint(flipPoint(globalPoint).toPoint());
qlocalPoint = widgetToGetEvent->mapFromGlobal(qglobalPoint);
processThisEvent = true;
@@ -759,8 +764,11 @@ void qt_mac_dispatchNCMouseMessage(void * /* NSWindow* */eventWindow, void * /*
// This is not an NC area mouse message.
if (!processThisEvent)
return;
+
// If the window is frame less, generate fake mouse events instead. (floating QToolBar)
- if (fakeNCEvents && (widgetToGetEvent->window()->windowFlags() & Qt::FramelessWindowHint))
+ // or if someone already got an explicit or implicit grab
+ if (mac_mouse_grabber || qt_button_down ||
+ (fakeNCEvents && (widgetToGetEvent->window()->windowFlags() & Qt::FramelessWindowHint)))
fakeMouseEvents = true;
Qt::MouseButton button;
@@ -838,8 +846,15 @@ void qt_mac_dispatchNCMouseMessage(void * /* NSWindow* */eventWindow, void * /*
leftButtonIsRightButton = false;
}
}
+
QMouseEvent qme(eventType, qlocalPoint, qglobalPoint, button, button, keyMods);
qt_sendSpontaneousEvent(widgetToGetEvent, &qme);
+
+ // We don't need to set the implicit grab widget here because we won't
+ // reach this point if then event type is Press over a Qt widget.
+ // However we might need to unset it if the event is Release.
+ if (eventType == QEvent::MouseButtonRelease)
+ qt_button_down = 0;
#endif
}
@@ -873,15 +888,12 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev
// Find the widget that *should* get the event (e.g., maybe it was a pop-up,
// they always get the mouse event).
QWidget *qwidget = [theView qt_qwidget];
- QWidget *widgetToGetMouse = qwidget;
+ QWidget *widgetToGetMouse = 0;
+ NSView *tmpView = 0;
QWidget *popup = qAppInstance()->activePopupWidget();
- NSView *tmpView = theView;
- if (mac_mouse_grabber && mac_mouse_grabber != widgetToGetMouse) {
- widgetToGetMouse = mac_mouse_grabber;
- tmpView = qt_mac_nativeview_for(widgetToGetMouse);
- }
+ QPoint qglobalPoint(flipPoint(globalPoint).toPoint());
- if (popup && popup != qwidget->window()) {
+ if (popup) {
widgetToGetMouse = popup;
tmpView = qt_mac_nativeview_for(popup);
windowPoint = [[tmpView window] convertScreenToBase:globalPoint];
@@ -901,13 +913,15 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev
}
} else {
extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
- if (!mac_mouse_grabber && qt_button_down) {
- // if there is no explicit grabber, and the mouse was grabbed
- // implicitely (i.e. a mousebutton was pressed)
- widgetToGetMouse = qt_button_down;
+ QPoint pos;
+ widgetToGetMouse = QApplicationPrivate::pickMouseReceiver(qwidget, qglobalPoint,
+ pos, eventType,
+ button, qt_button_down, 0);
+ if (widgetToGetMouse)
tmpView = qt_mac_nativeview_for(widgetToGetMouse);
- }
}
+ if (!widgetToGetMouse)
+ return false;
NSPoint localPoint = [tmpView convertPoint:windowPoint fromView:nil];
QPoint qlocalPoint(localPoint.x, localPoint.y);
@@ -953,14 +967,13 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev
break;
}
[QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->localPoint = localPoint;
- QPoint qglobalPoint(flipPoint(globalPoint).toPoint());
QMouseEvent qme(eventType, qlocalPoint, qglobalPoint, button, buttons, keyMods);
qt_sendSpontaneousEvent(widgetToGetMouse, &qme);
if (eventType == QEvent::MouseButtonPress && button == Qt::RightButton) {
QContextMenuEvent qcme(QContextMenuEvent::Mouse, qlocalPoint, qglobalPoint, keyMods);
qt_sendSpontaneousEvent(widgetToGetMouse, &qcme);
}
- return qme.isAccepted();
+ return true;
#endif
}
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 21aae3e..e551a1d 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -8376,9 +8376,10 @@ bool QWidget::event(QEvent *event)
case QEvent::TouchUpdate:
case QEvent::TouchEnd:
{
+#ifndef Q_WS_MAC
QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().first();
- if (touchPoint.isPrimary())
+ if (touchPoint.isPrimary() || touchEvent->deviceType() == QTouchEvent::TouchPad)
break;
// fake a mouse event!
@@ -8407,6 +8408,7 @@ bool QWidget::event(QEvent *event)
Qt::LeftButton,
touchEvent->modifiers());
(void) QApplication::sendEvent(this, &mouseEvent);
+#endif // Q_WS_MAC
break;
}
case QEvent::Gesture:
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index 1907cca..7dc4d85 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -3654,6 +3654,16 @@ void QWidgetPrivate::setFocus_sys()
}
}
+NSComparisonResult compareViews2Raise(id view1, id view2, void *context)
+{
+ id topView = reinterpret_cast<id>(context);
+ if (view1 == topView)
+ return NSOrderedDescending;
+ if (view2 == topView)
+ return NSOrderedAscending;
+ return NSOrderedSame;
+}
+
void QWidgetPrivate::raise_sys()
{
Q_Q(QWidget);
@@ -3661,7 +3671,6 @@ void QWidgetPrivate::raise_sys()
return;
#if QT_MAC_USE_COCOA
- QMacCocoaAutoReleasePool pool;
if (isRealWindow()) {
// Calling orderFront shows the window on Cocoa too.
if (!q->testAttribute(Qt::WA_DontShowOnScreen) && q->isVisible()) {
@@ -3673,16 +3682,9 @@ void QWidgetPrivate::raise_sys()
SetFrontProcessWithOptions(&psn, kSetFrontProcessFrontWindowOnly);
}
} else {
- // Cocoa doesn't really have an idea of Z-ordering, but you can
- // fake it by changing the order of it. But beware, removing an
- // NSView will also remove it as the first responder. So we re-set
- // the first responder just in case:
NSView *view = qt_mac_nativeview_for(q);
NSView *parentView = [view superview];
- NSResponder *firstResponder = [[view window] firstResponder];
- [view removeFromSuperview];
- [parentView addSubview:view];
- [[view window] makeFirstResponder:firstResponder];
+ [parentView sortSubviewsUsingFunction:compareViews2Raise context:reinterpret_cast<void *>(view)];
}
#else
if(q->isWindow()) {
@@ -3700,47 +3702,29 @@ void QWidgetPrivate::raise_sys()
#endif
}
+NSComparisonResult compareViews2Lower(id view1, id view2, void *context)
+{
+ id topView = reinterpret_cast<id>(context);
+ if (view1 == topView)
+ return NSOrderedAscending;
+ if (view2 == topView)
+ return NSOrderedDescending;
+ return NSOrderedSame;
+}
+
void QWidgetPrivate::lower_sys()
{
Q_Q(QWidget);
if((q->windowType() == Qt::Desktop))
return;
#ifdef QT_MAC_USE_COCOA
- QMacCocoaAutoReleasePool pool;
if (isRealWindow()) {
OSWindowRef window = qt_mac_window_for(q);
[window orderBack:window];
} else {
- // Cocoa doesn't really have an idea of Z-ordering, but you can
- // fake it by changing the order of it. In this case
- // we put the item at the beginning of the list, but that means
- // we must re-insert everything since we cannot modify the list directly.
- NSView *myview = qt_mac_nativeview_for(q);
- NSView *parentView = [myview superview];
- NSArray *tmpViews = [parentView subviews];
- NSMutableArray *subviews = [[NSMutableArray alloc] initWithCapacity:[tmpViews count]];
- [subviews addObjectsFromArray:tmpViews];
- NSResponder *firstResponder = [[myview window] firstResponder];
- // Implicit assumption that myViewIndex is included in subviews, that's why I'm not checking
- // myViewIndex.
- NSUInteger index = 0;
- NSUInteger myViewIndex = 0;
- bool foundMyView = false;
- for (NSView *subview in subviews) {
- [subview removeFromSuperview];
- if (subview == myview) {
- foundMyView = true;
- myViewIndex = index;
- }
- ++index;
- }
- [parentView addSubview:myview];
- if (foundMyView)
- [subviews removeObjectAtIndex:myViewIndex];
- for (NSView *subview in subviews)
- [parentView addSubview:subview];
- [subviews release];
- [[myview window] makeFirstResponder:firstResponder];
+ NSView *view = qt_mac_nativeview_for(q);
+ NSView *parentView = [view superview];
+ [parentView sortSubviewsUsingFunction:compareViews2Lower context:reinterpret_cast<void *>(view)];
}
#else
if(q->isWindow()) {
@@ -3753,6 +3737,16 @@ void QWidgetPrivate::lower_sys()
#endif
}
+NSComparisonResult compareViews2StackUnder(id view1, id view2, void *context)
+{
+ const QHash<NSView *, int> &viewOrder = *reinterpret_cast<QHash<NSView *, int> *>(context);
+ if (viewOrder[view1] < viewOrder[view2])
+ return NSOrderedAscending;
+ if (viewOrder[view1] > viewOrder[view2])
+ return NSOrderedDescending;
+ return NSOrderedSame;
+}
+
void QWidgetPrivate::stackUnder_sys(QWidget *w)
{
// stackUnder
@@ -3761,37 +3755,23 @@ void QWidgetPrivate::stackUnder_sys(QWidget *w)
return;
#ifdef QT_MAC_USE_COCOA
// Do the same trick as lower_sys() and put this widget before the widget passed in.
- QMacCocoaAutoReleasePool pool;
- NSView *myview = qt_mac_nativeview_for(q);
+ NSView *myView = qt_mac_nativeview_for(q);
NSView *wView = qt_mac_nativeview_for(w);
- NSView *parentView = [myview superview];
- NSArray *tmpViews = [parentView subviews];
- NSMutableArray *subviews = [[NSMutableArray alloc] initWithCapacity:[tmpViews count]];
- [subviews addObjectsFromArray:tmpViews];
- // Implicit assumption that myViewIndex and wViewIndex is included in subviews,
- // that's why I'm not checking myViewIndex.
- NSUInteger index = 0;
- NSUInteger myViewIndex = 0;
- NSUInteger wViewIndex = 0;
- for (NSView *subview in subviews) {
- [subview removeFromSuperview];
- if (subview == myview)
- myViewIndex = index;
- else if (subview == wView)
- wViewIndex = index;
- ++index;
- }
- index = 0;
+ QHash<NSView *, int> viewOrder;
+ NSView *parentView = [myView superview];
+ NSArray *subviews = [parentView subviews];
+ NSUInteger index = 1;
+ // make a hash of view->zorderindex and make sure z-value is always odd,
+ // so that when we modify the order we create a new (even) z-value which
+ // will not interfere with others.
for (NSView *subview in subviews) {
- if (index == myViewIndex)
- continue;
- if (index == wViewIndex)
- [parentView addSubview:myview];
- [parentView addSubview:subview];
+ viewOrder.insert(subview, index * 2);
++index;
}
- [subviews release];
+ viewOrder[myView] = viewOrder[wView] - 1;
+
+ [parentView sortSubviewsUsingFunction:compareViews2StackUnder context:reinterpret_cast<void *>(&viewOrder)];
#else
QWidget *p = q->parentWidget();
if(!p || p != w->parentWidget())