summaryrefslogtreecommitdiff
path: root/src/gui/kernel/qt_cocoa_helpers_mac.mm
diff options
context:
space:
mode:
authorMorten Johan Sørvig <morten.sorvig@nokia.com>2010-02-15 14:06:32 +0100
committerMorten Johan Sørvig <morten.sorvig@nokia.com>2010-03-02 11:33:16 +0100
commit7366200d7600271c86144e70ae59ce77f39b2a16 (patch)
tree9460cd64d996dd03285e2ebcc14ed4f0ddcb802b /src/gui/kernel/qt_cocoa_helpers_mac.mm
parent13f23b71cee682ccaaec455d72b1578afc2800ee (diff)
downloadqt4-tools-7366200d7600271c86144e70ae59ce77f39b2a16.tar.gz
Implement alien widgets on Mac/Cocoa.
This commit makes alien widgets opt in on a per-widget basis on Mac, set the Qt::WA_NativeWindow flag when creating the widget to enable. Setting this flag on widgets that have native child or sibling NSViews is not supported. The main use case for alien widgets on Mac is to improve performance for applications that have complex user interfaces. Qt can handle thousands of widgets per window, while Cocoa is designed to use a smaller number of NSViews in combination with NSCells and custom control implementations. This commit moves us in the direction of having a few main NSViews with "leaf" qwidgets implemented as a custom control.
Diffstat (limited to 'src/gui/kernel/qt_cocoa_helpers_mac.mm')
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac.mm39
1 files changed, 35 insertions, 4 deletions
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm
index 9560952e18..19bae5aecb 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac.mm
+++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm
@@ -139,7 +139,7 @@ void QMacWindowFader::performFade()
extern bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); // qapplication.cpp;
extern QWidget * mac_mouse_grabber;
-extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
+extern QWidget *qt_button_down; //qapplication_mac.cpp
void macWindowFade(void * /*OSWindowRef*/ window, float durationSeconds)
{
@@ -686,6 +686,12 @@ bool qt_dispatchKeyEvent(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEve
if ([event type] == NSKeyDown) {
qt_keymapper_private()->updateKeyMap(0, key_event, 0);
}
+
+ // Redirect keys to alien widgets.
+ if (widgetToGetEvent->testAttribute(Qt::WA_NativeWindow) == false) {
+ widgetToGetEvent = qApp->focusWidget();
+ }
+
if (widgetToGetEvent == 0)
return false;
@@ -940,7 +946,7 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev
[static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(tmpView) qt_qwidget];
}
} else {
- extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
+ extern QWidget * qt_button_down; //qapplication_mac.cpp
QPoint pos;
widgetToGetMouse = QApplicationPrivate::pickMouseReceiver(qwidget, qglobalPoint,
pos, eventType,
@@ -952,7 +958,20 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev
return false;
NSPoint localPoint = [tmpView convertPoint:windowPoint fromView:nil];
- QPoint qlocalPoint(localPoint.x, localPoint.y);
+ QPoint qlocalPoint = QPoint(localPoint.x, localPoint.y);
+
+ // Search for alien child widgets (either on this qwidget or on the popup)
+ if (widgetToGetMouse->testAttribute(Qt::WA_NativeWindow) == false || qt_widget_private(widgetToGetMouse)->hasAlienChildren) {
+ QPoint qScreenPoint = flipPoint(globalPoint).toPoint();
+#ifdef ALIEN_DEBUG
+ qDebug() << "alien mouse event" << qScreenPoint << possibleAlien;
+#endif
+ QWidget *possibleAlien = widgetToGetMouse->childAt(qlocalPoint);
+ if (possibleAlien) {
+ qlocalPoint = possibleAlien->mapFromGlobal(widgetToGetMouse->mapToGlobal(qlocalPoint));
+ widgetToGetMouse = possibleAlien;
+ }
+ }
EventRef carbonEvent = static_cast<EventRef>(const_cast<void *>([theEvent eventRef]));
if (qt_mac_sendMacEventToWidget(widgetToGetMouse, carbonEvent))
@@ -997,7 +1016,19 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev
}
[QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->localPoint = localPoint;
QMouseEvent qme(eventType, qlocalPoint, qglobalPoint, button, buttons, keyMods);
- qt_sendSpontaneousEvent(widgetToGetMouse, &qme);
+
+#ifdef ALIEN_DEBUG
+ qDebug() << "sending mouse event to" << widgetToGetMouse;
+#endif
+ extern QWidget *qt_button_down;
+ extern QPointer<QWidget> qt_last_mouse_receiver;
+
+ if (qwidget->testAttribute(Qt::WA_NativeWindow) && qt_widget_private(qwidget)->hasAlienChildren == false)
+ qt_sendSpontaneousEvent(widgetToGetMouse, &qme);
+ else
+ QApplicationPrivate::sendMouseEvent(widgetToGetMouse, &qme, widgetToGetMouse, qwidget, &qt_button_down,
+ qt_last_mouse_receiver);
+
if (eventType == QEvent::MouseButtonPress && button == Qt::RightButton) {
QContextMenuEvent qcme(QContextMenuEvent::Mouse, qlocalPoint, qglobalPoint, keyMods);
qt_sendSpontaneousEvent(widgetToGetMouse, &qcme);