diff options
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/dialogs/qnspanelproxy_mac.mm | 87 | ||||
-rw-r--r-- | src/gui/kernel/kernel.pri | 6 | ||||
-rw-r--r-- | src/gui/kernel/qapplication.h | 1 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_mac.mm | 42 | ||||
-rw-r--r-- | src/gui/kernel/qcocoaapplication_mac.mm | 72 | ||||
-rw-r--r-- | src/gui/kernel/qcocoaapplication_mac_p.h | 8 | ||||
-rw-r--r-- | src/gui/kernel/qcocoasharedwindowmethods_mac_p.h | 11 | ||||
-rw-r--r-- | src/gui/kernel/qkeysequence.cpp | 2 | ||||
-rw-r--r-- | src/gui/kernel/qt_cocoa_helpers_mac.mm | 199 | ||||
-rw-r--r-- | src/gui/kernel/qt_cocoa_helpers_mac_p.h | 12 | ||||
-rw-r--r-- | src/gui/widgets/qmenu_mac.mm | 17 |
11 files changed, 256 insertions, 201 deletions
diff --git a/src/gui/dialogs/qnspanelproxy_mac.mm b/src/gui/dialogs/qnspanelproxy_mac.mm index 0bd5c63..0e8d64d 100644 --- a/src/gui/dialogs/qnspanelproxy_mac.mm +++ b/src/gui/dialogs/qnspanelproxy_mac.mm @@ -42,6 +42,7 @@ #include <qdialogbuttonbox.h> #if defined(Q_WS_MAC) #include <private/qt_mac_p.h> +#include <private/qcocoaintrospection_p.h> #import <AppKit/AppKit.h> #import <Foundation/Foundation.h> #import <objc/objc-class.h> @@ -137,46 +138,6 @@ QT_USE_NAMESPACE QT_BEGIN_NAMESPACE -void macStartIntercept(SEL originalSel, SEL fakeSel, Class baseClass, Class proxyClass) -{ -#ifndef QT_MAC_USE_COCOA - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) -#endif - { -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - // The following code replaces the _implementation_ for the selector we want to hack - // (originalSel) with the implementation found in proxyClass. Then it creates - // a new 'backup' method inside baseClass containing the old, original, - // implementation (fakeSel). You can let the proxy implementation of originalSel - // call fakeSel if needed (similar approach to calling a super class implementation). - // fakeSel must also be implemented in proxyClass, as the signature is used - // as template for the method one we add into baseClass. - // NB: You will typically never create any instances of proxyClass; we use it - // only for stealing its contents and put it into baseClass. - Method originalMethod = class_getInstanceMethod(baseClass, originalSel); - Method newMethod = class_getInstanceMethod(proxyClass, originalSel); - Method fakeMethod = class_getInstanceMethod(proxyClass, fakeSel); - - IMP originalImp = method_setImplementation(originalMethod, method_getImplementation(newMethod)); - class_addMethod(baseClass, fakeSel, originalImp, method_getTypeEncoding(fakeMethod)); -#endif - } -} - -void macStopIntercept(SEL originalSel, SEL fakeSel, Class baseClass, Class /* proxyClass */) -{ -#ifndef QT_MAC_USE_COCOA - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) -#endif - { -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - Method originalMethod = class_getInstanceMethod(baseClass, originalSel); - Method fakeMethodInBaseClass = class_getInstanceMethod(baseClass, fakeSel); - method_setImplementation(originalMethod, method_getImplementation(fakeMethodInBaseClass)); -#endif - } -} - /* Intercept the NSColorPanel constructor if the shared color panel doesn't exist yet. What's going on here is @@ -188,12 +149,18 @@ void macStopIntercept(SEL originalSel, SEL fakeSel, Class baseClass, Class /* pr */ void macStartInterceptNSPanelCtor() { - macStartIntercept(@selector(initWithContentRect:styleMask:backing:defer:), - @selector(qt_fakeInitWithContentRect:styleMask:backing:defer:), - [NSPanel class], [QT_MANGLE_NAMESPACE(QNSPanelProxy) class]); - macStartIntercept(@selector(initWithContentRect:styleMask:backing:defer:screen:), - @selector(qt_fakeInitWithContentRect:styleMask:backing:defer:screen:), - [NSPanel class], [QT_MANGLE_NAMESPACE(QNSPanelProxy) class]); + qt_cocoa_change_implementation( + [NSPanel class], + @selector(initWithContentRect:styleMask:backing:defer:), + [QT_MANGLE_NAMESPACE(QNSPanelProxy) class], + @selector(initWithContentRect:styleMask:backing:defer:), + @selector(qt_fakeInitWithContentRect:styleMask:backing:defer:)); + qt_cocoa_change_implementation( + [NSPanel class], + @selector(initWithContentRect:styleMask:backing:defer:screen:), + [QT_MANGLE_NAMESPACE(QNSPanelProxy) class], + @selector(initWithContentRect:styleMask:backing:defer:screen:), + @selector(qt_fakeInitWithContentRect:styleMask:backing:defer:screen:)); } /* @@ -201,12 +168,14 @@ void macStartInterceptNSPanelCtor() */ void macStopInterceptNSPanelCtor() { - macStopIntercept(@selector(initWithContentRect:styleMask:backing:defer:screen:), - @selector(qt_fakeInitWithContentRect:styleMask:backing:defer:screen:), - [NSPanel class], [QT_MANGLE_NAMESPACE(QNSPanelProxy) class]); - macStopIntercept(@selector(initWithContentRect:styleMask:backing:defer:), - @selector(qt_fakeInitWithContentRect:styleMask:backing:defer:), - [NSPanel class], [QT_MANGLE_NAMESPACE(QNSPanelProxy) class]); + qt_cocoa_change_back_implementation( + [NSPanel class], + @selector(initWithContentRect:styleMask:backing:defer:screen:), + @selector(qt_fakeInitWithContentRect:styleMask:backing:defer:screen:)); + qt_cocoa_change_back_implementation( + [NSPanel class], + @selector(initWithContentRect:styleMask:backing:defer:), + @selector(qt_fakeInitWithContentRect:styleMask:backing:defer:)); } /* @@ -216,8 +185,12 @@ void macStopInterceptNSPanelCtor() void macStartInterceptWindowTitle(QWidget *window) { currentWindow = window; - macStartIntercept(@selector(setTitle:), @selector(qt_fakeSetTitle:), - [NSWindow class], [QT_MANGLE_NAMESPACE(QNSWindowProxy) class]); + qt_cocoa_change_implementation( + [NSWindow class], + @selector(setTitle:), + [QT_MANGLE_NAMESPACE(QNSWindowProxy) class], + @selector(setTitle:), + @selector(qt_fakeSetTitle:)); } /* @@ -226,8 +199,10 @@ void macStartInterceptWindowTitle(QWidget *window) void macStopInterceptWindowTitle() { currentWindow = 0; - macStopIntercept(@selector(setTitle:), @selector(qt_fakeSetTitle:), - [NSWindow class], [QT_MANGLE_NAMESPACE(QNSWindowProxy) class]); + qt_cocoa_change_back_implementation( + [NSWindow class], + @selector(setTitle:), + @selector(qt_fakeSetTitle:)); } /* diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri index 6fd45ad..b6cc2ac 100644 --- a/src/gui/kernel/kernel.pri +++ b/src/gui/kernel/kernel.pri @@ -213,7 +213,8 @@ embedded { qcocoaapplicationdelegate_mac_p.h \ qmacgesturerecognizer_mac_p.h \ qmultitouch_mac_p.h \ - qcocoasharedwindowmethods_mac_p.h + qcocoasharedwindowmethods_mac_p.h \ + qcocoaintrospection_p.h OBJECTIVE_SOURCES += \ kernel/qcursor_mac.mm \ @@ -233,7 +234,8 @@ embedded { kernel/qeventdispatcher_mac.mm \ kernel/qcocoawindowcustomthemeframe_mac.mm \ kernel/qmacgesturerecognizer_mac.mm \ - kernel/qmultitouch_mac.mm + kernel/qmultitouch_mac.mm \ + kernel/qcocoaintrospection_mac.mm HEADERS += \ kernel/qt_cocoa_helpers_mac_p.h \ diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h index c21b982..ebb329b 100644 --- a/src/gui/kernel/qapplication.h +++ b/src/gui/kernel/qapplication.h @@ -233,6 +233,7 @@ public: #if defined(Q_WS_MAC) virtual bool macEventFilter(EventHandlerCallRef, EventRef); + virtual bool macEventFilter(void *); #endif #if defined(Q_WS_X11) virtual bool x11EventFilter(XEvent *); diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm index 321492d..4cd14df 100644 --- a/src/gui/kernel/qapplication_mac.mm +++ b/src/gui/kernel/qapplication_mac.mm @@ -1246,6 +1246,8 @@ void qt_init(QApplicationPrivate *priv, int) // Cocoa application delegate #ifdef QT_MAC_USE_COCOA NSApplication *cocoaApp = [QNSApplication sharedApplication]; + qt_redirectNSApplicationSendEvent(); + QMacCocoaAutoReleasePool pool; NSObject *oldDelegate = [cocoaApp delegate]; QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *newDelegate = [QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate]; @@ -2611,7 +2613,7 @@ OSStatus QApplicationPrivate::globalAppleEventProcessor(const AppleEvent *ae, Ap /*! \fn bool QApplication::macEventFilter(EventHandlerCallRef caller, EventRef event) - \warning This virtual function is only implemented under Mac OS X when against Carbon. + \warning This virtual function is only used under Mac OS X when Qt is based on Carbon. If you create an application that inherits QApplication and reimplement this function, you get direct access to all Carbon Events that Qt registers @@ -2622,14 +2624,7 @@ OSStatus QApplicationPrivate::globalAppleEventProcessor(const AppleEvent *ae, Ap Return false for normal event dispatching. The default implementation returns false. - Cocoa uses a different event system which means this function is NOT CALLED - when building Qt against Cocoa. If you want similar functionality subclass - NSApplication and reimplement the sendEvent: message to handle all the - NSEvents. You also will need to to instantiate your custom NSApplication - before creating a QApplication. See \l - {http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/NSApplication_Class/Reference/Reference.html}{Apple's - NSApplication Reference} for more information. - + \sa macEventFilter(void *nsevent) */ bool QApplication::macEventFilter(EventHandlerCallRef, EventRef) { @@ -2637,6 +2632,29 @@ bool QApplication::macEventFilter(EventHandlerCallRef, EventRef) } /*! + \fn bool QApplication::macEventFilter(void *nsevent) + + \warning This virtual function is only used under Mac OS X when Qt is based on Cocoa. + + If you create an application that inherits QApplication and reimplement + this function, you get direct access to all NSEvents that Qt receives + from Cocoa. + \a nsevent is of type NSEvent *: + + NSEvent *e = static_cast<NSEvent *>(nsevent); + + Return true if you want to stop the event from being processed. + Return false for normal event dispatching. The default + implementation returns false. + + \sa macEventFilter(EventHandlerCallRef caller, EventRef event) +*/ +bool QApplication::macEventFilter(void * /*NSEvent*/) +{ + return false; +} + +/*! \internal */ void QApplicationPrivate::openPopup(QWidget *popup) @@ -3110,11 +3128,7 @@ void onApplicationChangedActivation( bool activated ) } if (!app->activeWindow()) { -#if QT_MAC_USE_COCOA - OSWindowRef wp = [NSApp keyWindow]; -#else - OSWindowRef wp = ActiveNonFloatingWindow(); -#endif + OSWindowRef wp = [NSApp keyWindow]; if (QWidget *tmp_w = qt_mac_find_window(wp)) app->setActiveWindow(tmp_w); } diff --git a/src/gui/kernel/qcocoaapplication_mac.mm b/src/gui/kernel/qcocoaapplication_mac.mm index 4962863..5cd32a1 100644 --- a/src/gui/kernel/qcocoaapplication_mac.mm +++ b/src/gui/kernel/qcocoaapplication_mac.mm @@ -78,6 +78,7 @@ #include <private/qcocoaapplication_mac_p.h> #include <private/qcocoaapplicationdelegate_mac_p.h> #include <private/qt_cocoa_helpers_mac_p.h> +#include <private/qcocoaintrospection_p.h> QT_USE_NAMESPACE @@ -116,12 +117,26 @@ QT_USE_NAMESPACE quint64 lower = [event data1]; quint64 upper = [event data2]; QCocoaPostMessageArgs *args = reinterpret_cast<QCocoaPostMessageArgs *>(lower | (upper << 32)); - [args->target performSelector:args->selector]; + switch (args->argCount) { + case 0: + [args->target performSelector:args->selector]; + break; + case 1: + [args->target performSelector:args->selector withObject:args->arg1]; + break; + case 3: + [args->target performSelector:args->selector withObject:args->arg1 withObject:args->arg2]; + break; + } + delete args; } -- (BOOL)qt_sendEvent:(NSEvent *)event +- (BOOL)qt_filterEvent:(NSEvent *)event { + if (qApp->macEventFilter(event)) + return true; + if ([event type] == NSApplicationDefined) { switch ([event subtype]) { case QtCocoaEventSubTypePostMessage: @@ -138,20 +153,55 @@ QT_USE_NAMESPACE @implementation QNSApplication -// WARNING: If Qt did not create NSApplication (this can e.g. -// happend if Qt is used as a plugin from a 3rd-party cocoa -// application), QNSApplication::sendEvent will never be called. -// SO DO NOT RELY ON THIS FUNCTION BEING AVAILABLE. -// Plugin developers that _do_ control the NSApplication sub-class -// implementation of the 3rd-party application can call qt_sendEvent -// from the sub-class event handler (like we do here) to work around -// any issues. +- (void)qt_sendEvent_original:(NSEvent *)event +{ + Q_UNUSED(event); + // This method will only be used as a signature + // template for the method we add into NSApplication + // containing the original [NSApplication sendEvent:] implementation +} + +- (void)qt_sendEvent_replacement:(NSEvent *)event +{ + // This method (or its implementation to be precise) will + // be called instead of sendEvent if redirection occurs. + // 'self' will then be an instance of NSApplication + // (and not QNSApplication) + if (![NSApp qt_filterEvent:event]) + [self qt_sendEvent_original:event]; +} + - (void)sendEvent:(NSEvent *)event { - if (![self qt_sendEvent:event]) + // This method will be called if + // no redirection occurs + if (![NSApp qt_filterEvent:event]) [super sendEvent:event]; } @end +QT_BEGIN_NAMESPACE + +void qt_redirectNSApplicationSendEvent() +{ + if ([NSApp isMemberOfClass:[QNSApplication class]]) { + // No need to change implementation since Qt + // already controls a subclass of NSApplication + return; + } + + // Change the implementation of [NSApplication sendEvent] to the + // implementation of qt_sendEvent_replacement found in QNSApplication. + // And keep the old implementation that gets overwritten inside a new + // method 'qt_sendEvent_original' that we add to NSApplication + qt_cocoa_change_implementation( + [NSApplication class], + @selector(sendEvent:), + [QNSApplication class], + @selector(qt_sendEvent_replacement:), + @selector(qt_sendEvent_original:)); + } + +QT_END_NAMESPACE #endif diff --git a/src/gui/kernel/qcocoaapplication_mac_p.h b/src/gui/kernel/qcocoaapplication_mac_p.h index 5569feb..c89ff36 100644 --- a/src/gui/kernel/qcocoaapplication_mac_p.h +++ b/src/gui/kernel/qcocoaapplication_mac_p.h @@ -101,11 +101,17 @@ QT_FORWARD_DECLARE_CLASS(QApplicationPrivate) - (int)QT_MANGLE_NAMESPACE(qt_validModesForFontPanel):(NSFontPanel *)fontPanel; - (void)qt_sendPostedMessage:(NSEvent *)event; -- (BOOL)qt_sendEvent:(NSEvent *)event; +- (BOOL)qt_filterEvent:(NSEvent *)event; @end @interface QNSApplication : NSApplication { } @end +QT_BEGIN_NAMESPACE + +void qt_redirectNSApplicationSendEvent(); + +QT_END_NAMESPACE + #endif diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h index 8652816..717cfa5 100644 --- a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h +++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h @@ -149,17 +149,6 @@ QT_END_NAMESPACE - (void)sendEvent:(NSEvent *)event { - if ([event type] == NSApplicationDefined) { - switch ([event subtype]) { - case QtCocoaEventSubTypePostMessage: - [NSApp qt_sendPostedMessage:event]; - return; - default: - break; - } - return; - } - 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 diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index d9a0952..b038fde 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -76,7 +76,7 @@ static const MacSpecialKey entries[NumEntries] = { { Qt::Key_Backtab, 0x21E4 }, { Qt::Key_Backspace, 0x232B }, { Qt::Key_Return, 0x21B5 }, - { Qt::Key_Enter, 0x21B5 }, + { Qt::Key_Enter, 0x2324 }, { Qt::Key_Delete, 0x2326 }, { Qt::Key_Home, 0x2196 }, { Qt::Key_End, 0x2198 }, diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index 8cef03c..de4e125 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -469,7 +469,6 @@ void qt_dispatchTabletProximityEvent(const ::TabletProximityRec &proxRec) qt_sendSpontaneousEvent(qApp, &qtabletProximity); } -#ifdef QT_MAC_USE_COCOA // Use this method to keep all the information in the TextSegment. As long as it is ordered // we are in OK shape, and we can influence that ourselves. struct KeyPair @@ -493,69 +492,107 @@ bool operator<(QChar qchar, const KeyPair &entry) return qchar < entry.cocoaKey; } +bool operator<(const Qt::Key &key, const KeyPair &entry) +{ + return key < entry.qtKey; +} + +bool operator<(const KeyPair &entry, const Qt::Key &key) +{ + return entry.qtKey < key; +} + +static bool qtKey2CocoaKeySortLessThan(const KeyPair &entry1, const KeyPair &entry2) +{ + return entry1.qtKey < entry2.qtKey; +} + +static const int NumEntries = 59; +static const KeyPair entries[NumEntries] = { + { NSEnterCharacter, Qt::Key_Enter }, + { NSBackspaceCharacter, Qt::Key_Backspace }, + { NSTabCharacter, Qt::Key_Tab }, + { NSNewlineCharacter, Qt::Key_Return }, + { NSCarriageReturnCharacter, Qt::Key_Return }, + { NSBackTabCharacter, Qt::Key_Backtab }, + { NSDeleteCharacter, Qt::Key_Delete }, + { kEscapeCharCode, Qt::Key_Escape }, + { NSUpArrowFunctionKey, Qt::Key_Up }, + { NSDownArrowFunctionKey, Qt::Key_Down }, + { NSLeftArrowFunctionKey, Qt::Key_Left }, + { NSRightArrowFunctionKey, Qt::Key_Right }, + { NSF1FunctionKey, Qt::Key_F1 }, + { NSF2FunctionKey, Qt::Key_F2 }, + { NSF3FunctionKey, Qt::Key_F3 }, + { NSF4FunctionKey, Qt::Key_F4 }, + { NSF5FunctionKey, Qt::Key_F5 }, + { NSF6FunctionKey, Qt::Key_F6 }, + { NSF7FunctionKey, Qt::Key_F7 }, + { NSF8FunctionKey, Qt::Key_F8 }, + { NSF9FunctionKey, Qt::Key_F8 }, + { NSF10FunctionKey, Qt::Key_F10 }, + { NSF11FunctionKey, Qt::Key_F11 }, + { NSF12FunctionKey, Qt::Key_F12 }, + { NSF13FunctionKey, Qt::Key_F13 }, + { NSF14FunctionKey, Qt::Key_F14 }, + { NSF15FunctionKey, Qt::Key_F15 }, + { NSF16FunctionKey, Qt::Key_F16 }, + { NSF17FunctionKey, Qt::Key_F17 }, + { NSF18FunctionKey, Qt::Key_F18 }, + { NSF19FunctionKey, Qt::Key_F19 }, + { NSF20FunctionKey, Qt::Key_F20 }, + { NSF21FunctionKey, Qt::Key_F21 }, + { NSF22FunctionKey, Qt::Key_F22 }, + { NSF23FunctionKey, Qt::Key_F23 }, + { NSF24FunctionKey, Qt::Key_F24 }, + { NSF25FunctionKey, Qt::Key_F25 }, + { NSF26FunctionKey, Qt::Key_F26 }, + { NSF27FunctionKey, Qt::Key_F27 }, + { NSF28FunctionKey, Qt::Key_F28 }, + { NSF29FunctionKey, Qt::Key_F29 }, + { NSF30FunctionKey, Qt::Key_F30 }, + { NSF31FunctionKey, Qt::Key_F31 }, + { NSF32FunctionKey, Qt::Key_F32 }, + { NSF33FunctionKey, Qt::Key_F33 }, + { NSF34FunctionKey, Qt::Key_F34 }, + { NSF35FunctionKey, Qt::Key_F35 }, + { NSInsertFunctionKey, Qt::Key_Insert }, + { NSDeleteFunctionKey, Qt::Key_Delete }, + { NSHomeFunctionKey, Qt::Key_Home }, + { NSEndFunctionKey, Qt::Key_End }, + { NSPageUpFunctionKey, Qt::Key_PageUp }, + { NSPageDownFunctionKey, Qt::Key_PageDown }, + { NSPrintScreenFunctionKey, Qt::Key_Print }, + { NSScrollLockFunctionKey, Qt::Key_ScrollLock }, + { NSPauseFunctionKey, Qt::Key_Pause }, + { NSSysReqFunctionKey, Qt::Key_SysReq }, + { NSMenuFunctionKey, Qt::Key_Menu }, + { NSHelpFunctionKey, Qt::Key_Help }, +}; +static const KeyPair * const end = entries + NumEntries; + +QChar qtKey2CocoaKey(Qt::Key key) +{ + // The first time this function is called, create a reverse + // looup table sorted on Qt Key rather than Cocoa key: + static QVector<KeyPair> rev_entries(NumEntries); + static bool mustInit = true; + if (mustInit){ + mustInit = false; + for (int i=0; i<NumEntries; ++i) + rev_entries[i] = entries[i]; + qSort(rev_entries.begin(), rev_entries.end(), qtKey2CocoaKeySortLessThan); + } + const QVector<KeyPair>::iterator i + = qBinaryFind(rev_entries.begin(), rev_entries.end(), key); + if (i == rev_entries.end()) + return QChar(); + return i->cocoaKey; +} + +#ifdef QT_MAC_USE_COCOA static Qt::Key cocoaKey2QtKey(QChar keyCode) { - static const int NumEntries = 57; - static const KeyPair entries[NumEntries] = { - { NSEnterCharacter, Qt::Key_Enter }, - { NSTabCharacter, Qt::Key_Tab }, - { NSCarriageReturnCharacter, Qt::Key_Return }, - { NSBackTabCharacter, Qt::Key_Backtab }, - { kEscapeCharCode, Qt::Key_Escape }, - { NSDeleteCharacter, Qt::Key_Backspace }, - { NSUpArrowFunctionKey, Qt::Key_Up }, - { NSDownArrowFunctionKey, Qt::Key_Down }, - { NSLeftArrowFunctionKey, Qt::Key_Left }, - { NSRightArrowFunctionKey, Qt::Key_Right }, - { NSF1FunctionKey, Qt::Key_F1 }, - { NSF2FunctionKey, Qt::Key_F2 }, - { NSF3FunctionKey, Qt::Key_F3 }, - { NSF4FunctionKey, Qt::Key_F4 }, - { NSF5FunctionKey, Qt::Key_F5 }, - { NSF6FunctionKey, Qt::Key_F6 }, - { NSF7FunctionKey, Qt::Key_F7 }, - { NSF8FunctionKey, Qt::Key_F8 }, - { NSF9FunctionKey, Qt::Key_F8 }, - { NSF10FunctionKey, Qt::Key_F10 }, - { NSF11FunctionKey, Qt::Key_F11 }, - { NSF12FunctionKey, Qt::Key_F12 }, - { NSF13FunctionKey, Qt::Key_F13 }, - { NSF14FunctionKey, Qt::Key_F14 }, - { NSF15FunctionKey, Qt::Key_F15 }, - { NSF16FunctionKey, Qt::Key_F16 }, - { NSF17FunctionKey, Qt::Key_F17 }, - { NSF18FunctionKey, Qt::Key_F18 }, - { NSF19FunctionKey, Qt::Key_F19 }, - { NSF20FunctionKey, Qt::Key_F20 }, - { NSF21FunctionKey, Qt::Key_F21 }, - { NSF22FunctionKey, Qt::Key_F22 }, - { NSF23FunctionKey, Qt::Key_F23 }, - { NSF24FunctionKey, Qt::Key_F24 }, - { NSF25FunctionKey, Qt::Key_F25 }, - { NSF26FunctionKey, Qt::Key_F26 }, - { NSF27FunctionKey, Qt::Key_F27 }, - { NSF28FunctionKey, Qt::Key_F28 }, - { NSF29FunctionKey, Qt::Key_F29 }, - { NSF30FunctionKey, Qt::Key_F30 }, - { NSF31FunctionKey, Qt::Key_F31 }, - { NSF32FunctionKey, Qt::Key_F32 }, - { NSF33FunctionKey, Qt::Key_F33 }, - { NSF34FunctionKey, Qt::Key_F34 }, - { NSF35FunctionKey, Qt::Key_F35 }, - { NSInsertFunctionKey, Qt::Key_Insert }, - { NSDeleteFunctionKey, Qt::Key_Delete }, - { NSHomeFunctionKey, Qt::Key_Home }, - { NSEndFunctionKey, Qt::Key_End }, - { NSPageUpFunctionKey, Qt::Key_PageUp }, - { NSPageDownFunctionKey, Qt::Key_PageDown }, - { NSPrintScreenFunctionKey, Qt::Key_Print }, - { NSScrollLockFunctionKey, Qt::Key_ScrollLock }, - { NSPauseFunctionKey, Qt::Key_Pause }, - { NSSysReqFunctionKey, Qt::Key_SysReq }, - { NSMenuFunctionKey, Qt::Key_Menu }, - { NSHelpFunctionKey, Qt::Key_Help }, - }; - static const KeyPair * const end = entries + NumEntries; const KeyPair *i = qBinaryFind(entries, end, keyCode); if (i == end) return Qt::Key(keyCode.unicode()); @@ -1201,7 +1238,7 @@ void qt_mac_replaceDrawRect(void * /*OSWindowRef */window, QWidgetPrivate *widge // We have the original method here. Proceed and swap the methods. method_exchangeImplementations(m1, m0); widget->originalDrawMethod = false; - [window display]; + [theWindow display]; } } @@ -1224,7 +1261,7 @@ void qt_mac_replaceDrawRectOriginal(void * /*OSWindowRef */window, QWidgetPrivat } method_exchangeImplementations(m1, m0); widget->originalDrawMethod = true; - [window display]; + [theWindow display]; } #endif // QT_MAC_USE_COCOA @@ -1423,39 +1460,17 @@ void qt_cocoaChangeOverrideCursor(const QCursor &cursor) [static_cast<NSCursor *>(qt_mac_nsCursorForQCursor(cursor)) set]; } -// WARNING: If Qt did not create NSApplication (e.g. in case it is -// used as a plugin), and at the same time, there is no window on -// screen (or the window that the event is sendt to becomes hidden etc -// before the event gets delivered), the message will not be performed. -bool qt_cocoaPostMessage(id target, SEL selector) +void qt_cocoaPostMessage(id target, SEL selector, int argCount, id arg1, id arg2) { - if (!target) - return false; - - NSInteger windowNumber = 0; - if (![NSApp isMemberOfClass:[QNSApplication class]]) { - // INVARIANT: Cocoa is not using our NSApplication subclass. That means - // we don't control the main event handler either. So target the event - // for one of the windows on screen: - NSWindow *nswin = [NSApp mainWindow]; - if (!nswin) { - nswin = [NSApp keyWindow]; - if (!nswin) - return false; - } - windowNumber = [nswin windowNumber]; - } - - // WARNING: data1 and data2 is truncated to from 64-bit to 32-bit on OS 10.5! + // WARNING: data1 and data2 is truncated to from 64-bit to 32-bit on OS 10.5! // That is why we need to split the address in two parts: - QCocoaPostMessageArgs *args = new QCocoaPostMessageArgs(target, selector); + QCocoaPostMessageArgs *args = new QCocoaPostMessageArgs(target, selector, argCount, arg1, arg2); quint32 lower = quintptr(args); quint32 upper = quintptr(args) >> 32; NSEvent *e = [NSEvent otherEventWithType:NSApplicationDefined - location:NSZeroPoint modifierFlags:0 timestamp:0 windowNumber:windowNumber + location:NSZeroPoint modifierFlags:0 timestamp:0 windowNumber:0 context:nil subtype:QtCocoaEventSubTypePostMessage data1:lower data2:upper]; [NSApp postEvent:e atStart:NO]; - return true; } #endif @@ -1494,7 +1509,7 @@ void macDrawRectOnTop(void * /*OSWindowRef */window) NSRect contentRect = [contentView frame]; // Draw a line on top of the already drawn line. // We need to check if we are active or not to use the proper color. - if([window isKeyWindow] || [window isMainWindow]) { + if([theWindow isKeyWindow] || [theWindow isMainWindow]) { [[NSColor colorWithCalibratedRed:1.0 green:1.0 blue:1.0 alpha:1.0] set]; } else { [[NSColor colorWithCalibratedRed:1.0 green:1.0 blue:1.0 alpha:1.0] set]; @@ -1514,7 +1529,7 @@ void macSyncDrawingOnFirstInvocation(void * /*OSWindowRef */window) { OSWindowRef theWindow = static_cast<OSWindowRef>(window); NSApplication *application = [NSApplication sharedApplication]; - NSToolbar *toolbar = [window toolbar]; + NSToolbar *toolbar = [theWindow toolbar]; if([application isActive]) { // Launched from finder [toolbar setShowsBaselineSeparator:NO]; diff --git a/src/gui/kernel/qt_cocoa_helpers_mac_p.h b/src/gui/kernel/qt_cocoa_helpers_mac_p.h index 5db121a..6b005ca 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac_p.h +++ b/src/gui/kernel/qt_cocoa_helpers_mac_p.h @@ -198,17 +198,25 @@ class QCocoaPostMessageArgs { public: id target; SEL selector; - QCocoaPostMessageArgs(id target, SEL selector) : target(target), selector(selector) + int argCount; + id arg1; + id arg2; + QCocoaPostMessageArgs(id target, SEL selector, int argCount=0, id arg1=0, id arg2=0) + : target(target), selector(selector), argCount(argCount), arg1(arg1), arg2(arg2) { [target retain]; + [arg1 retain]; + [arg2 retain]; } ~QCocoaPostMessageArgs() { + [arg2 release]; + [arg1 release]; [target release]; } }; -bool qt_cocoaPostMessage(id target, SEL selector); +void qt_cocoaPostMessage(id target, SEL selector, int argCount=0, id arg1=0, id arg2=0); #endif #endif diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm index aaa113b..60023a8 100644 --- a/src/gui/widgets/qmenu_mac.mm +++ b/src/gui/widgets/qmenu_mac.mm @@ -1254,15 +1254,11 @@ QMenuPrivate::QMacMenuPrivate::addAction(QMacMenuAction *action, QMacMenuAction NSString *keySequenceToKeyEqivalent(const QKeySequence &accel) { quint32 accel_key = (accel[0] & ~(Qt::MODIFIER_MASK | Qt::UNICODE_ACCEL)); - extern QChar qt_macSymbolForQtKey(int key); // qkeysequence.cpp - QChar keyEquiv = qt_macSymbolForQtKey(accel_key); - if (keyEquiv.isNull()) { - if (accel_key >= Qt::Key_F1 && accel_key <= Qt::Key_F15) - keyEquiv = (accel_key - Qt::Key_F1) + NSF1FunctionKey; - else - keyEquiv = unichar(QChar(accel_key).toLower().unicode()); - } - return [NSString stringWithCharacters:&keyEquiv.unicode() length:1]; + extern QChar qtKey2CocoaKey(Qt::Key key); + QChar cocoa_key = qtKey2CocoaKey(Qt::Key(accel_key)); + if (cocoa_key.isNull()) + cocoa_key = QChar(accel_key).toLower().unicode(); + return [NSString stringWithCharacters:&cocoa_key.unicode() length:1]; } // return the cocoa modifier mask for the QKeySequence (currently only looks at the first one). @@ -2052,8 +2048,7 @@ bool QMenuBar::macUpdateMenuBar() { #ifdef QT_MAC_USE_COCOA QMacCocoaAutoReleasePool pool; - if (!qt_cocoaPostMessage(getMenuLoader(), @selector(qtUpdateMenubar))) - return QMenuBarPrivate::macUpdateMenuBarImmediatly(); + qt_cocoaPostMessage(getMenuLoader(), @selector(qtUpdateMenubar)); return true; #else return QMenuBarPrivate::macUpdateMenuBarImmediatly(); |