summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/dialogs/qnspanelproxy_mac.mm87
-rw-r--r--src/gui/kernel/kernel.pri6
-rw-r--r--src/gui/kernel/qapplication.h1
-rw-r--r--src/gui/kernel/qapplication_mac.mm42
-rw-r--r--src/gui/kernel/qcocoaapplication_mac.mm72
-rw-r--r--src/gui/kernel/qcocoaapplication_mac_p.h8
-rw-r--r--src/gui/kernel/qcocoasharedwindowmethods_mac_p.h11
-rw-r--r--src/gui/kernel/qkeysequence.cpp2
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac.mm199
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac_p.h12
-rw-r--r--src/gui/widgets/qmenu_mac.mm17
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();