Cocoa: re-enable getUrl: and appleEventQuit: AppleEvent handlers

The getUrl: and appleEventQuit: handlers are only called if we register
them with the NSAppleEventManager. The Cocoa documentation says the best
place to do this is in the applicationWillFinishLaunching: delegate
method, so add this method and move the code from
qcocoaeventdispatcher.mm to there. Since QCocoaApplicationDelegate is
only used when AA_MacPluginApplication is not set, we do not need to
check again in the delegate code. Be sure to remove these event handlers
when shutting down the application.

For the getUrl: handler, send file open events when receiving this
event. This restores Qt 4 behavior.

Remove the qDebug() from the appleEventQuit: handler.

Change-Id: Ibcbdd541695176e3d236366d4d541e4811882d6c
Reviewed-by: Morten Johan Sørvig <morten.sorvig@nokia.com>
This commit is contained in:
Bradley T. Hughes 2012-06-08 13:37:27 +02:00 committed by Qt by Nokia
parent b0e0671152
commit 46abc9138b
4 changed files with 46 additions and 29 deletions

View File

@ -119,4 +119,5 @@
- (QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)menuLoader;
- (void)setReflectionDelegate:(NSObject <NSApplicationDelegate> *)oldDelegate;
- (void)getUrl:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent;
- (void) removeAppleEventHandlers;
@end

View File

@ -217,6 +217,43 @@ static void cleanupCocoaApplicationDelegate()
return NSTerminateCancel;
}
- (void) applicationWillFinishLaunching:(NSNotification *)notification
{
Q_UNUSED(notification);
/*
From the Cocoa documentation: "A good place to install event handlers
is in the applicationWillFinishLaunching: method of the application
delegate. At that point, the Application Kit has installed its default
event handlers, so if you install a handler for one of the same events,
it will replace the Application Kit version."
*/
/*
If Qt is used as a plugin, we let the 3rd party application handle
events like quit and open file events. Otherwise, if we install our own
handlers, we easily end up breaking functionality the 3rd party
application depends on.
*/
NSAppleEventManager *eventManager = [NSAppleEventManager sharedAppleEventManager];
[eventManager setEventHandler:self
andSelector:@selector(appleEventQuit:withReplyEvent:)
forEventClass:kCoreEventClass
andEventID:kAEQuitApplication];
[eventManager setEventHandler:self
andSelector:@selector(getUrl:withReplyEvent:)
forEventClass:kInternetEventClass
andEventID:kAEGetURL];
}
// called by QCocoaIntegration's destructor before resetting the application delegate to nil
- (void) removeAppleEventHandlers
{
NSAppleEventManager *eventManager = [NSAppleEventManager sharedAppleEventManager];
[eventManager removeEventHandlerForEventClass:kCoreEventClass andEventID:kAEQuitApplication];
[eventManager removeEventHandlerForEventClass:kInternetEventClass andEventID:kAEGetURL];
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
Q_UNUSED(aNotification);
@ -347,22 +384,15 @@ static void cleanupCocoaApplicationDelegate()
- (void)getUrl:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
{
Q_UNUSED(event);
Q_UNUSED(replyEvent);
/*
NSString *urlString = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
QUrl url(QCFString::toQString(urlString));
QFileOpenEvent qtEvent(url);
qt_sendSpontaneousEvent(qAppInstance(), &qtEvent);
*/
QWindowSystemInterface::handleFileOpenEvent(QCFString::toQString(urlString));
}
- (void)appleEventQuit:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
{
Q_UNUSED(event);
Q_UNUSED(replyEvent);
qDebug() << "appleEventQuit";
[NSApp terminate:self];
}

View File

@ -1042,26 +1042,6 @@ void QCocoaEventDispatcherPrivate::firstLoopEntry(CFRunLoopObserverRef ref,
{
Q_UNUSED(ref);
Q_UNUSED(activity);
/*
// This function is called when NSApplication has finished initialization,
// which appears to be just after [NSApplication run] has started to execute.
// By setting up our apple events handlers this late, we override the ones
// set up by NSApplication.
// If Qt is used as a plugin, we let the 3rd party application handle events
// like quit and open file events. Otherwise, if we install our own handlers, we
// easily end up breaking functionallity the 3rd party application depend on:
if (QGuiApplication::testAttribute(Qt::AA_MacPluginApplication))
return;
QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *newDelegate = [QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate];
NSAppleEventManager *eventManager = [NSAppleEventManager sharedAppleEventManager];
[eventManager setEventHandler:newDelegate andSelector:@selector(appleEventQuit:withReplyEvent:)
forEventClass:kCoreEventClass andEventID:kAEQuitApplication];
[eventManager setEventHandler:newDelegate andSelector:@selector(getUrl:withReplyEvent:)
forEventClass:kInternetEventClass andEventID:kAEGetURL];
*/
static_cast<QCocoaEventDispatcherPrivate *>(info)->processPostedEvents();
}

View File

@ -148,7 +148,13 @@ QCocoaIntegration::QCocoaIntegration()
QCocoaIntegration::~QCocoaIntegration()
{
[[NSApplication sharedApplication] setDelegate: 0];
if (!QCoreApplication::testAttribute(Qt::AA_MacPluginApplication)) {
// remove the apple event handlers installed by QCocoaApplicationDelegate
QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *delegate = [QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate];
[delegate removeAppleEventHandlers];
// reset the application delegate
[[NSApplication sharedApplication] setDelegate: 0];
}
// Delete the clipboard integration and destroy mime type converters.
// Deleting the clipboard integration flushes promised pastes using