Revert Mac event loop changes.
"Make QGuiApplication::exec() run within NSApplicationMain()" "Make Qt process native and timer events on Cocoa applications" "Cocoa: Fix QFontDialog, QColorDialog auto-tests" This reverts commits1e14762b8d
e4b2a0b4ba
df7944e7d7
Change-Id: I80b65b5ee0297b090f807bd420664233dfc44f7b Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@digia.com> Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
parent
585758389c
commit
8fc97fdfc7
@ -1,20 +1,6 @@
|
||||
load(default_post)
|
||||
!no_objective_c:CONFIG += objective_c
|
||||
|
||||
|
||||
equals(TEMPLATE, app):qt: {
|
||||
deps = $$replace(QT, -private$, )
|
||||
deps = $$resolve_depends(deps, "QT.", ".depends" ".private_depends" ".run_depends")
|
||||
contains(deps, gui): {
|
||||
DEFINES += QT_NEEDS_QMAIN
|
||||
CONFIG += link_prl
|
||||
# When CI'ing Qt we still need to link against libqtcocoamain.a, even before deployment.
|
||||
# Hence the /get variable, suffix which looks for the libraries location effective path.
|
||||
QMAKE_LIBDIR += $$[QT_INSTALL_LIBS/get]
|
||||
QMAKE_LIBS += -lqtcocoamain
|
||||
}
|
||||
}
|
||||
|
||||
qt:!isEmpty(QT_CONFIG) {
|
||||
# Pick a suitable default architecture for qmake-based applications.
|
||||
# If the Qt package contains one of x86 and x86_64, pick that one. If it
|
||||
|
@ -1,7 +1,109 @@
|
||||
TEMPLATE = subdirs
|
||||
TARGET = qcocoa
|
||||
|
||||
cocoamain.file = cocoamain.pro
|
||||
cocoaplugin.file = cocoaplugin.pro
|
||||
PLUGIN_TYPE = platforms
|
||||
PLUGIN_CLASS_NAME = QCocoaIntegrationPlugin
|
||||
load(qt_plugin)
|
||||
|
||||
SUBDIRS = cocoamain cocoaplugin
|
||||
OBJECTIVE_SOURCES += main.mm \
|
||||
qcocoaintegration.mm \
|
||||
qcocoatheme.mm \
|
||||
qcocoabackingstore.mm \
|
||||
qcocoawindow.mm \
|
||||
qnsview.mm \
|
||||
qnsviewaccessibility.mm \
|
||||
qcocoaautoreleasepool.mm \
|
||||
qnswindowdelegate.mm \
|
||||
qcocoaglcontext.mm \
|
||||
qcocoanativeinterface.mm \
|
||||
qcocoaeventdispatcher.mm \
|
||||
qcocoaapplicationdelegate.mm \
|
||||
qcocoaapplication.mm \
|
||||
qcocoamenu.mm \
|
||||
qcocoamenuitem.mm \
|
||||
qcocoamenubar.mm \
|
||||
qcocoamenuloader.mm \
|
||||
qcocoahelpers.mm \
|
||||
qmultitouch_mac.mm \
|
||||
qcocoaaccessibilityelement.mm \
|
||||
qcocoaaccessibility.mm \
|
||||
qcocoacolordialoghelper.mm \
|
||||
qcocoafiledialoghelper.mm \
|
||||
qcocoafontdialoghelper.mm \
|
||||
qcocoacursor.mm \
|
||||
qcocoaclipboard.mm \
|
||||
qcocoadrag.mm \
|
||||
qmacclipboard.mm \
|
||||
qmacmime.mm \
|
||||
qcocoasystemsettings.mm \
|
||||
qcocoainputcontext.mm \
|
||||
qcocoaservices.mm \
|
||||
qcocoasystemtrayicon.mm \
|
||||
qcocoaintrospection.mm \
|
||||
qcocoakeymapper.mm \
|
||||
|
||||
SOURCES += messages.cpp
|
||||
|
||||
HEADERS += qcocoaintegration.h \
|
||||
qcocoatheme.h \
|
||||
qcocoabackingstore.h \
|
||||
qcocoawindow.h \
|
||||
qnsview.h \
|
||||
qcocoaautoreleasepool.h \
|
||||
qnswindowdelegate.h \
|
||||
qcocoaglcontext.h \
|
||||
qcocoanativeinterface.h \
|
||||
qcocoaeventdispatcher.h \
|
||||
qcocoaapplicationdelegate.h \
|
||||
qcocoaapplication.h \
|
||||
qcocoamenu.h \
|
||||
qcocoamenuitem.h \
|
||||
qcocoamenubar.h \
|
||||
qcocoamenuloader.h \
|
||||
qcocoahelpers.h \
|
||||
qmultitouch_mac_p.h \
|
||||
qcocoaaccessibilityelement.h \
|
||||
qcocoaaccessibility.h \
|
||||
qcocoacolordialoghelper.h \
|
||||
qcocoafiledialoghelper.h \
|
||||
qcocoafontdialoghelper.h \
|
||||
qcocoacursor.h \
|
||||
qcocoaclipboard.h \
|
||||
qcocoadrag.h \
|
||||
qmacclipboard.h \
|
||||
qmacmime.h \
|
||||
qcocoasystemsettings.h \
|
||||
qcocoainputcontext.h \
|
||||
qcocoaservices.h \
|
||||
qcocoasystemtrayicon.h \
|
||||
qcocoaintrospection.h \
|
||||
qcocoakeymapper.h \
|
||||
messages.h
|
||||
|
||||
RESOURCES += qcocoaresources.qrc
|
||||
|
||||
LIBS += -framework Cocoa -framework Carbon -framework IOKit
|
||||
|
||||
QT += core-private gui-private platformsupport-private
|
||||
|
||||
qtHaveModule(widgets) {
|
||||
OBJECTIVE_SOURCES += \
|
||||
qpaintengine_mac.mm \
|
||||
qprintengine_mac.mm \
|
||||
qcocoaprintersupport.mm \
|
||||
|
||||
HEADERS += \
|
||||
qpaintengine_mac_p.h \
|
||||
qprintengine_mac_p.h \
|
||||
qcocoaprintersupport.h \
|
||||
|
||||
QT += widgets-private printsupport-private
|
||||
}
|
||||
|
||||
OTHER_FILES += cocoa.json
|
||||
|
||||
# Acccessibility debug support
|
||||
# DEFINES += QT_COCOA_ENABLE_ACCESSIBILITY_INSPECTOR
|
||||
# include ($$PWD/../../../../util/accessibilityinspector/accessibilityinspector.pri)
|
||||
|
||||
# Window debug support
|
||||
#DEFINES += QT_COCOA_ENABLE_WINDOW_DEBUG
|
||||
|
@ -1,19 +0,0 @@
|
||||
# Additional Qt project file for qtmain lib on OS X
|
||||
!macx:error("$$_FILE_ is intended only for OS X!")
|
||||
|
||||
TEMPLATE = lib
|
||||
TARGET = qtcocoamain
|
||||
DESTDIR = $$QT.core.libs
|
||||
|
||||
CONFIG += staticlib release
|
||||
|
||||
QT = core-private gui-private
|
||||
LIBS += -framework Cocoa
|
||||
|
||||
HEADERS = qcocoaintrospection.h
|
||||
|
||||
OBJECTIVE_SOURCES = qcocoamain.mm \
|
||||
qcocoaintrospection.mm
|
||||
|
||||
load(qt_installs)
|
||||
load(qt_targets)
|
@ -1,109 +0,0 @@
|
||||
TARGET = qcocoa
|
||||
|
||||
PLUGIN_TYPE = platforms
|
||||
PLUGIN_CLASS_NAME = QCocoaIntegrationPlugin
|
||||
load(qt_plugin)
|
||||
|
||||
OBJECTIVE_SOURCES += main.mm \
|
||||
qcocoaintegration.mm \
|
||||
qcocoatheme.mm \
|
||||
qcocoabackingstore.mm \
|
||||
qcocoawindow.mm \
|
||||
qnsview.mm \
|
||||
qnsviewaccessibility.mm \
|
||||
qcocoaautoreleasepool.mm \
|
||||
qnswindowdelegate.mm \
|
||||
qcocoaglcontext.mm \
|
||||
qcocoanativeinterface.mm \
|
||||
qcocoaeventdispatcher.mm \
|
||||
qcocoaapplicationdelegate.mm \
|
||||
qcocoaapplication.mm \
|
||||
qcocoamenu.mm \
|
||||
qcocoamenuitem.mm \
|
||||
qcocoamenubar.mm \
|
||||
qcocoamenuloader.mm \
|
||||
qcocoahelpers.mm \
|
||||
qmultitouch_mac.mm \
|
||||
qcocoaaccessibilityelement.mm \
|
||||
qcocoaaccessibility.mm \
|
||||
qcocoacolordialoghelper.mm \
|
||||
qcocoafiledialoghelper.mm \
|
||||
qcocoafontdialoghelper.mm \
|
||||
qcocoacursor.mm \
|
||||
qcocoaclipboard.mm \
|
||||
qcocoadrag.mm \
|
||||
qmacclipboard.mm \
|
||||
qmacmime.mm \
|
||||
qcocoasystemsettings.mm \
|
||||
qcocoainputcontext.mm \
|
||||
qcocoaservices.mm \
|
||||
qcocoasystemtrayicon.mm \
|
||||
qcocoaintrospection.mm \
|
||||
qcocoakeymapper.mm \
|
||||
|
||||
SOURCES += messages.cpp
|
||||
|
||||
HEADERS += qcocoaintegration.h \
|
||||
qcocoatheme.h \
|
||||
qcocoabackingstore.h \
|
||||
qcocoawindow.h \
|
||||
qnsview.h \
|
||||
qcocoaautoreleasepool.h \
|
||||
qnswindowdelegate.h \
|
||||
qcocoaglcontext.h \
|
||||
qcocoanativeinterface.h \
|
||||
qcocoaeventdispatcher.h \
|
||||
qcocoaapplicationdelegate.h \
|
||||
qcocoaapplication.h \
|
||||
qcocoamenu.h \
|
||||
qcocoamenuitem.h \
|
||||
qcocoamenubar.h \
|
||||
qcocoamenuloader.h \
|
||||
qcocoahelpers.h \
|
||||
qmultitouch_mac_p.h \
|
||||
qcocoaaccessibilityelement.h \
|
||||
qcocoaaccessibility.h \
|
||||
qcocoacolordialoghelper.h \
|
||||
qcocoafiledialoghelper.h \
|
||||
qcocoafontdialoghelper.h \
|
||||
qcocoacursor.h \
|
||||
qcocoaclipboard.h \
|
||||
qcocoadrag.h \
|
||||
qmacclipboard.h \
|
||||
qmacmime.h \
|
||||
qcocoasystemsettings.h \
|
||||
qcocoainputcontext.h \
|
||||
qcocoaservices.h \
|
||||
qcocoasystemtrayicon.h \
|
||||
qcocoaintrospection.h \
|
||||
qcocoakeymapper.h \
|
||||
messages.h
|
||||
|
||||
RESOURCES += qcocoaresources.qrc
|
||||
|
||||
LIBS += -framework Cocoa -framework Carbon -framework IOKit
|
||||
|
||||
QT += core-private gui-private platformsupport-private
|
||||
|
||||
qtHaveModule(widgets) {
|
||||
OBJECTIVE_SOURCES += \
|
||||
qpaintengine_mac.mm \
|
||||
qprintengine_mac.mm \
|
||||
qcocoaprintersupport.mm \
|
||||
|
||||
HEADERS += \
|
||||
qpaintengine_mac_p.h \
|
||||
qprintengine_mac_p.h \
|
||||
qcocoaprintersupport.h \
|
||||
|
||||
QT += widgets-private printsupport-private
|
||||
}
|
||||
|
||||
OTHER_FILES += cocoa.json
|
||||
|
||||
# Acccessibility debug support
|
||||
# DEFINES += QT_COCOA_ENABLE_ACCESSIBILITY_INSPECTOR
|
||||
# include ($$PWD/../../../../util/accessibilityinspector/accessibilityinspector.pri)
|
||||
|
||||
# Window debug support
|
||||
#DEFINES += QT_COCOA_ENABLE_WINDOW_DEBUG
|
@ -102,9 +102,13 @@
|
||||
|
||||
- (void)qt_sendPostedMessage:(NSEvent *)event;
|
||||
- (BOOL)qt_filterEvent:(NSEvent *)event;
|
||||
- (BOOL)qt_filterOrSendEvent:(NSEvent *)event;
|
||||
@end
|
||||
|
||||
@interface QT_MANGLE_NAMESPACE(QNSApplication) : NSApplication {
|
||||
}
|
||||
@end
|
||||
|
||||
QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSApplication);
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
@ -83,8 +83,6 @@
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
static SEL qt_sendEvent_original_SEL = @selector(qt_sendEvent_original:);
|
||||
|
||||
@implementation NSApplication (QT_MANGLE_NAMESPACE(QApplicationIntegration))
|
||||
|
||||
- (void)QT_MANGLE_NAMESPACE(qt_setDockMenu):(NSMenu *)newMenu
|
||||
@ -155,22 +153,34 @@ static const QByteArray q_macLocalEventType = QByteArrayLiteral("mac_generic_NSE
|
||||
return false;
|
||||
}
|
||||
|
||||
- (BOOL)qt_filterOrSendEvent:(NSEvent *)event
|
||||
{
|
||||
if ([self qt_filterEvent:event])
|
||||
return false;
|
||||
@end
|
||||
|
||||
Q_ASSERT_X([self respondsToSelector:qt_sendEvent_original_SEL], "qt_filterOrSendEvent:",
|
||||
"Running event loop before calling qt_redirectNSApplicationSendEvent()");
|
||||
[self performSelector:qt_sendEvent_original_SEL withObject:event];
|
||||
return true;
|
||||
@implementation QNSApplication
|
||||
|
||||
- (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: after redirection occurs.
|
||||
[self qt_filterOrSendEvent:event];
|
||||
// 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
|
||||
{
|
||||
// This method will be called if
|
||||
// no redirection occurs
|
||||
if (![NSApp qt_filterEvent:event])
|
||||
[super sendEvent:event];
|
||||
}
|
||||
|
||||
@end
|
||||
@ -179,16 +189,22 @@ 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.
|
||||
// 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:),
|
||||
[NSApplication class],
|
||||
[QNSApplication class],
|
||||
@selector(qt_sendEvent_replacement:),
|
||||
qt_sendEvent_original_SEL);
|
||||
@selector(qt_sendEvent_original:));
|
||||
}
|
||||
|
||||
void qt_resetNSApplicationSendEvent()
|
||||
|
@ -99,13 +99,15 @@
|
||||
NSMenu *dockMenu;
|
||||
QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader;
|
||||
NSObject <NSApplicationDelegate> *reflectionDelegate;
|
||||
bool inLaunch;
|
||||
}
|
||||
+ (QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate)*)sharedDelegate;
|
||||
- (void)setDockMenu:(NSMenu *)newMenu;
|
||||
- (void)setMenuLoader:(QT_MANGLE_NAMESPACE(QCocoaMenuLoader)*)menuLoader;
|
||||
- (QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)menuLoader;
|
||||
- (void)setReflectionDelegate:(NSObject <NSApplicationDelegate> *)oldDelegate;
|
||||
- (NSObject<NSApplicationDelegate> *)reflectionDelegate;
|
||||
- (void)getUrl:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent;
|
||||
- (void) removeAppleEventHandlers;
|
||||
@end
|
||||
|
||||
QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaApplicationDelegate);
|
||||
|
@ -101,6 +101,7 @@ static void cleanupCocoaApplicationDelegate()
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
inLaunch = true;
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver:self
|
||||
selector:@selector(updateScreens:)
|
||||
@ -240,6 +241,55 @@ 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);
|
||||
inLaunch = false;
|
||||
// qt_release_apple_event_handler();
|
||||
|
||||
|
||||
// Insert code here to initialize your application
|
||||
}
|
||||
|
||||
|
||||
|
||||
- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
|
||||
{
|
||||
Q_UNUSED(filenames);
|
||||
@ -247,6 +297,14 @@ static void cleanupCocoaApplicationDelegate()
|
||||
|
||||
for (NSString *fileName in filenames) {
|
||||
QString qtFileName = QCFString::toQString(fileName);
|
||||
if (inLaunch) {
|
||||
// We need to be careful because Cocoa will be nice enough to take
|
||||
// command line arguments and send them to us as events. Given the history
|
||||
// of Qt Applications, this will result in behavior people don't want, as
|
||||
// they might be doing the opening themselves with the command line parsing.
|
||||
if (qApp->arguments().contains(qtFileName))
|
||||
continue;
|
||||
}
|
||||
QWindowSystemInterface::handleFileOpenEvent(qtFileName);
|
||||
}
|
||||
|
||||
@ -309,11 +367,6 @@ static void cleanupCocoaApplicationDelegate()
|
||||
*/
|
||||
}
|
||||
|
||||
- (NSObject<NSApplicationDelegate> *)reflectionDelegate
|
||||
{
|
||||
return reflectionDelegate;
|
||||
}
|
||||
|
||||
- (void)setReflectionDelegate:(NSObject <NSApplicationDelegate> *)oldDelegate
|
||||
{
|
||||
[oldDelegate retain];
|
||||
@ -347,6 +400,20 @@ static void cleanupCocoaApplicationDelegate()
|
||||
[self doesNotRecognizeSelector:invocationSelector];
|
||||
}
|
||||
|
||||
- (void)getUrl:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
|
||||
{
|
||||
Q_UNUSED(replyEvent);
|
||||
NSString *urlString = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
|
||||
QWindowSystemInterface::handleFileOpenEvent(QCFString::toQString(urlString));
|
||||
}
|
||||
|
||||
- (void)appleEventQuit:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
Q_UNUSED(replyEvent);
|
||||
[NSApp terminate:self];
|
||||
}
|
||||
|
||||
- (void)qtDispatcherToQAction:(id)sender
|
||||
{
|
||||
Q_UNUSED(sender);
|
||||
|
@ -59,8 +59,6 @@ public:
|
||||
|
||||
void setCurrentColor(const QColor&);
|
||||
QColor currentColor() const;
|
||||
|
||||
bool event(QEvent *);
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -161,10 +161,6 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate);
|
||||
|
||||
- (void)closePanel
|
||||
{
|
||||
if (mDialogIsExecuting) {
|
||||
mDialogIsExecuting = false;
|
||||
[NSApp stopModal];
|
||||
}
|
||||
[mColorPanel close];
|
||||
}
|
||||
|
||||
@ -492,22 +488,6 @@ QColor QCocoaColorDialogHelper::currentColor() const
|
||||
return sharedColorPanel()->currentColor();
|
||||
}
|
||||
|
||||
bool QCocoaColorDialogHelper::event(QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::KeyPress) {
|
||||
QKeyEvent *ke = static_cast<QKeyEvent *>(e);
|
||||
if (ke->key() == Qt::Key_Enter || ke->key() == Qt::Key_Return) {
|
||||
emit accept();
|
||||
return true;
|
||||
} else if (ke->key() == Qt::Key_Escape) {
|
||||
emit reject();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_COLORDIALOG
|
||||
|
@ -162,6 +162,8 @@ public:
|
||||
bool blockSendPostedEvents;
|
||||
// The following variables help organizing modal sessions:
|
||||
QStack<QCocoaModalSessionInfo> cocoaModalSessionStack;
|
||||
bool currentExecIsNSAppRun;
|
||||
bool nsAppRunCalledByQt;
|
||||
bool cleanupModalSessionsNeeded;
|
||||
NSModalSession currentModalSessionCached;
|
||||
NSModalSession currentModalSession();
|
||||
@ -173,6 +175,7 @@ public:
|
||||
|
||||
void cancelWaitForMoreEvents();
|
||||
void maybeCancelWaitForMoreEvents();
|
||||
void ensureNSAppInitialized();
|
||||
|
||||
QCFSocketNotifier cfSocketNotifier;
|
||||
QList<void *> queuedUserInputEvents; // NSEvent *
|
||||
|
@ -86,13 +86,20 @@
|
||||
#include "private/qthread_p.h"
|
||||
#include "private/qguiapplication_p.h"
|
||||
#include <qdebug.h>
|
||||
#include "qcocoahelpers.h"
|
||||
#include "qcocoaapplication.h"
|
||||
|
||||
#undef slots
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
enum {
|
||||
QtCocoaEventSubTypeWakeup = SHRT_MAX,
|
||||
QtCocoaEventSubTypePostMessage = SHRT_MAX-1
|
||||
};
|
||||
|
||||
static inline CFRunLoopRef mainRunLoop()
|
||||
{
|
||||
return CFRunLoopGetMain();
|
||||
@ -111,6 +118,11 @@ static Boolean runLoopSourceEqualCallback(const void *info1, const void *info2)
|
||||
void QCocoaEventDispatcherPrivate::runLoopTimerCallback(CFRunLoopTimerRef, void *info)
|
||||
{
|
||||
QCocoaEventDispatcherPrivate *d = static_cast<QCocoaEventDispatcherPrivate *>(info);
|
||||
if ((d->processEventsFlags & QEventLoop::EventLoopExec) == 0) {
|
||||
// processEvents() was called "manually," ignore this source for now
|
||||
d->maybeCancelWaitForMoreEvents();
|
||||
return;
|
||||
}
|
||||
CFRunLoopSourceSignal(d->activateTimersSourceRef);
|
||||
}
|
||||
|
||||
@ -365,17 +377,53 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
|
||||
if (!excludeUserEvents) {
|
||||
while (!d->queuedUserInputEvents.isEmpty()) {
|
||||
event = static_cast<NSEvent *>(d->queuedUserInputEvents.takeFirst());
|
||||
if ([NSApp qt_filterOrSendEvent:event])
|
||||
if (!filterNativeEvent("NSEvent", event, 0)) {
|
||||
[NSApp sendEvent:event];
|
||||
retVal = true;
|
||||
}
|
||||
[event release];
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// If Qt is used as a plugin, or as an extension in a native cocoa
|
||||
// application, we should not run or stop NSApplication; This will be
|
||||
// done from the application itself. And if processEvents is called
|
||||
// manually (rather than from a QEventLoop), we cannot enter a tight
|
||||
// loop and block this call, but instead we need to return after one flush.
|
||||
// Finally, if we are to exclude user input events, we cannot call [NSApp run]
|
||||
// as we then loose control over which events gets dispatched:
|
||||
const bool canExec_3rdParty = d->nsAppRunCalledByQt || ![NSApp isRunning];
|
||||
const bool canExec_Qt = (!excludeUserEvents
|
||||
&& ((d->processEventsFlags & QEventLoop::DialogExec)
|
||||
|| (d->processEventsFlags & QEventLoop::EventLoopExec)));
|
||||
|
||||
if (canExec_Qt && canExec_3rdParty) {
|
||||
// We can use exec-mode, meaning that we can stay in a tight loop until
|
||||
// interrupted. This is mostly an optimization, but it allow us to use
|
||||
// [NSApp run], which is the normal code path for cocoa applications.
|
||||
if (NSModalSession session = d->currentModalSession()) {
|
||||
QBoolBlocker execGuard(d->currentExecIsNSAppRun, false);
|
||||
while ([NSApp runModalSession:session] == NSRunContinuesResponse && !d->interrupt)
|
||||
qt_mac_waitForMoreEvents(NSModalPanelRunLoopMode);
|
||||
|
||||
if (!d->interrupt && session == d->currentModalSessionCached) {
|
||||
// Someone called [NSApp stopModal:] from outside the event
|
||||
// dispatcher (e.g to stop a native dialog). But that call wrongly stopped
|
||||
// 'session' as well. As a result, we need to restart all internal sessions:
|
||||
d->temporarilyStopAllModalSessions();
|
||||
}
|
||||
} else {
|
||||
d->nsAppRunCalledByQt = true;
|
||||
QBoolBlocker execGuard(d->currentExecIsNSAppRun, true);
|
||||
[NSApp run];
|
||||
}
|
||||
retVal = true;
|
||||
} else {
|
||||
int lastSerialCopy = d->lastSerial;
|
||||
bool hadModalSession = d->currentModalSessionCached != 0;
|
||||
// We cannot block the thread (and run in a tight loop).
|
||||
// Instead we will process all current pending events and return.
|
||||
d->ensureNSAppInitialized();
|
||||
if (NSModalSession session = d->currentModalSession()) {
|
||||
// INVARIANT: a modal window is executing.
|
||||
if (!excludeUserEvents) {
|
||||
@ -396,9 +444,9 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
|
||||
// this case, we need more control over which events gets dispatched, and
|
||||
// cannot use [NSApp runModalSession:session]:
|
||||
event = [NSApp nextEventMatchingMask:NSAnyEventMask
|
||||
untilDate:nil
|
||||
inMode:NSModalPanelRunLoopMode
|
||||
dequeue:YES];
|
||||
untilDate:nil
|
||||
inMode:NSModalPanelRunLoopMode
|
||||
dequeue: YES];
|
||||
|
||||
if (event) {
|
||||
if (IsMouseOrKeyEvent(event)) {
|
||||
@ -406,16 +454,18 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
|
||||
d->queuedUserInputEvents.append(event);
|
||||
continue;
|
||||
}
|
||||
if ([NSApp qt_filterOrSendEvent:event])
|
||||
if (!filterNativeEvent("NSEvent", event, 0)) {
|
||||
[NSApp sendEvent:event];
|
||||
retVal = true;
|
||||
}
|
||||
}
|
||||
} while (!d->interrupt && event != nil);
|
||||
} else do {
|
||||
// INVARIANT: No modal window is executing.
|
||||
event = [NSApp nextEventMatchingMask:NSAnyEventMask
|
||||
untilDate:nil
|
||||
inMode:NSDefaultRunLoopMode
|
||||
dequeue:YES];
|
||||
untilDate:nil
|
||||
inMode:NSDefaultRunLoopMode
|
||||
dequeue: YES];
|
||||
|
||||
if (event) {
|
||||
if (flags & QEventLoop::ExcludeUserInputEvents) {
|
||||
@ -425,8 +475,10 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ([NSApp qt_filterOrSendEvent:event])
|
||||
if (!filterNativeEvent("NSEvent", event, 0)) {
|
||||
[NSApp sendEvent:event];
|
||||
retVal = true;
|
||||
}
|
||||
}
|
||||
} while (!d->interrupt && event != nil);
|
||||
|
||||
@ -505,6 +557,26 @@ void QCocoaEventDispatcher::wakeUp()
|
||||
QEventDispatcherMac Implementation
|
||||
*****************************************************************************/
|
||||
|
||||
void QCocoaEventDispatcherPrivate::ensureNSAppInitialized()
|
||||
{
|
||||
// Some elements in Cocoa require NSApplication to be running before
|
||||
// they get fully initialized, in particular the menu bar. This
|
||||
// function is intended for cases where a dialog is told to execute before
|
||||
// QGuiApplication::exec is called, or the application spins the events loop
|
||||
// manually rather than calling QGuiApplication:exec.
|
||||
// The function makes sure that NSApplication starts running, but stops
|
||||
// it again as soon as the send posted events callback is called. That way
|
||||
// we let Cocoa finish the initialization it seems to need. We'll only
|
||||
// apply this trick at most once for any application, and we avoid doing it
|
||||
// for the common case where main just starts QGuiApplication::exec.
|
||||
if (nsAppRunCalledByQt || [NSApp isRunning])
|
||||
return;
|
||||
nsAppRunCalledByQt = true;
|
||||
QBoolBlocker block1(interrupt, true);
|
||||
QBoolBlocker block2(currentExecIsNSAppRun, true);
|
||||
[NSApp run];
|
||||
}
|
||||
|
||||
void QCocoaEventDispatcherPrivate::temporarilyStopAllModalSessions()
|
||||
{
|
||||
// Flush, and Stop, all created modal session, and as
|
||||
@ -549,6 +621,7 @@ NSModalSession QCocoaEventDispatcherPrivate::currentModalSession()
|
||||
if (!nswindow)
|
||||
continue;
|
||||
|
||||
ensureNSAppInitialized();
|
||||
QBoolBlocker block1(blockSendPostedEvents, true);
|
||||
info.nswindow = nswindow;
|
||||
[(NSWindow*) info.nswindow retain];
|
||||
@ -693,6 +766,8 @@ QCocoaEventDispatcherPrivate::QCocoaEventDispatcherPrivate()
|
||||
: processEventsFlags(0),
|
||||
runLoopTimerRef(0),
|
||||
blockSendPostedEvents(false),
|
||||
currentExecIsNSAppRun(false),
|
||||
nsAppRunCalledByQt(false),
|
||||
cleanupModalSessionsNeeded(false),
|
||||
currentModalSessionCached(0),
|
||||
lastSerial(-1),
|
||||
@ -783,8 +858,19 @@ void QCocoaEventDispatcherPrivate::processPostedEvents()
|
||||
if (cleanupModalSessionsNeeded)
|
||||
cleanupModalSessions();
|
||||
|
||||
if (interrupt)
|
||||
if (interrupt) {
|
||||
if (currentExecIsNSAppRun) {
|
||||
// The event dispatcher has been interrupted. But since
|
||||
// [NSApplication run] is running the event loop, we
|
||||
// delayed stopping it until now (to let cocoa process
|
||||
// pending cocoa events first).
|
||||
if (currentModalSessionCached)
|
||||
temporarilyStopAllModalSessions();
|
||||
[NSApp stop:NSApp];
|
||||
cancelWaitForMoreEvents();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int serial = serialNumber.load();
|
||||
if (!threadData->canWait || (serial != lastSerial)) {
|
||||
@ -805,6 +891,11 @@ void QCocoaEventDispatcherPrivate::firstLoopEntry(CFRunLoopObserverRef ref,
|
||||
void QCocoaEventDispatcherPrivate::postedEventsSourceCallback(void *info)
|
||||
{
|
||||
QCocoaEventDispatcherPrivate *d = static_cast<QCocoaEventDispatcherPrivate *>(info);
|
||||
if ((d->processEventsFlags & QEventLoop::EventLoopExec) == 0) {
|
||||
// processEvents() was called "manually," ignore this source for now
|
||||
d->maybeCancelWaitForMoreEvents();
|
||||
return;
|
||||
}
|
||||
d->processPostedEvents();
|
||||
d->maybeCancelWaitForMoreEvents();
|
||||
}
|
||||
|
@ -203,10 +203,6 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate);
|
||||
|
||||
- (void)closePanel
|
||||
{
|
||||
if (mDialogIsExecuting) {
|
||||
mDialogIsExecuting = false;
|
||||
[NSApp stopModal];
|
||||
}
|
||||
[mFontPanel close];
|
||||
}
|
||||
|
||||
|
@ -232,7 +232,7 @@ QCocoaIntegration::QCocoaIntegration()
|
||||
|
||||
qApp->setAttribute(Qt::AA_DontUseNativeMenuBar, false);
|
||||
|
||||
NSApplication *cocoaApplication = NSApp;
|
||||
NSApplication *cocoaApplication = [QNSApplication sharedApplication];
|
||||
qt_redirectNSApplicationSendEvent();
|
||||
|
||||
if (qEnvironmentVariableIsEmpty("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM")) {
|
||||
@ -280,8 +280,9 @@ QCocoaIntegration::~QCocoaIntegration()
|
||||
if (!QCoreApplication::testAttribute(Qt::AA_MacPluginApplication)) {
|
||||
// remove the apple event handlers installed by QCocoaApplicationDelegate
|
||||
QCocoaApplicationDelegate *delegate = [QCocoaApplicationDelegate sharedDelegate];
|
||||
[delegate removeAppleEventHandlers];
|
||||
// reset the application delegate
|
||||
[[NSApplication sharedApplication] setDelegate:[delegate reflectionDelegate]];
|
||||
[[NSApplication sharedApplication] setDelegate: 0];
|
||||
}
|
||||
|
||||
// Delete the clipboard integration and destroy mime type converters.
|
||||
|
@ -79,33 +79,43 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
void qt_cocoa_change_implementation(Class baseClass, SEL originalSel, Class proxyClass, SEL replacementSel, SEL backupSel)
|
||||
{
|
||||
// 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.
|
||||
if (!replacementSel)
|
||||
replacementSel = originalSel;
|
||||
#ifndef QT_MAC_USE_COCOA
|
||||
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5)
|
||||
#endif
|
||||
{
|
||||
// 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.
|
||||
if (!replacementSel)
|
||||
replacementSel = originalSel;
|
||||
|
||||
Method originalMethod = class_getInstanceMethod(baseClass, originalSel);
|
||||
Method replacementMethod = class_getInstanceMethod(proxyClass, replacementSel);
|
||||
IMP originalImp = method_setImplementation(originalMethod, method_getImplementation(replacementMethod));
|
||||
Method originalMethod = class_getInstanceMethod(baseClass, originalSel);
|
||||
Method replacementMethod = class_getInstanceMethod(proxyClass, replacementSel);
|
||||
IMP originalImp = method_setImplementation(originalMethod, method_getImplementation(replacementMethod));
|
||||
|
||||
if (backupSel) {
|
||||
Method backupMethod = class_getInstanceMethod(proxyClass, backupSel);
|
||||
class_addMethod(baseClass, backupSel, originalImp, method_getTypeEncoding(backupMethod));
|
||||
if (backupSel) {
|
||||
Method backupMethod = class_getInstanceMethod(proxyClass, backupSel);
|
||||
class_addMethod(baseClass, backupSel, originalImp, method_getTypeEncoding(backupMethod));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void qt_cocoa_change_back_implementation(Class baseClass, SEL originalSel, SEL backupSel)
|
||||
{
|
||||
Method originalMethod = class_getInstanceMethod(baseClass, originalSel);
|
||||
Method backupMethodInBaseClass = class_getInstanceMethod(baseClass, backupSel);
|
||||
method_setImplementation(originalMethod, method_getImplementation(backupMethodInBaseClass));
|
||||
#ifndef QT_MAC_USE_COCOA
|
||||
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5)
|
||||
#endif
|
||||
{
|
||||
Method originalMethod = class_getInstanceMethod(baseClass, originalSel);
|
||||
Method backupMethodInBaseClass = class_getInstanceMethod(baseClass, backupSel);
|
||||
method_setImplementation(originalMethod, method_getImplementation(backupMethodInBaseClass));
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -1,181 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** 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, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#include <QtGui/qpa/qwindowsysteminterface.h>
|
||||
#include <QtCore/private/qcore_mac_p.h>
|
||||
#include "qcocoaintrospection.h"
|
||||
|
||||
extern int qMain(int argc, char *argv[]);
|
||||
|
||||
@interface QCocoaMainWrapper : NSObject
|
||||
|
||||
- (void)getUrl:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent;
|
||||
- (void)appleEventQuit:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent;
|
||||
- (void)runUserMain;
|
||||
|
||||
@end
|
||||
|
||||
@implementation QCocoaMainWrapper
|
||||
|
||||
- (void)applicationWillFinishLaunching:(NSNotification *)notification
|
||||
{
|
||||
if ([notification object] != NSApp) // Shouldn't happen AFAIK, but still
|
||||
return;
|
||||
|
||||
/*
|
||||
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];
|
||||
}
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)notification
|
||||
{
|
||||
if ([notification object] != NSApp) // Shouldn't happen AFAIK, but still
|
||||
return;
|
||||
|
||||
// We schedule the main-redirection for the next eventloop pass so that we
|
||||
// can return from this function and let NSApplicationMain finish its job.
|
||||
[NSTimer scheduledTimerWithTimeInterval:0 target:self
|
||||
selector:@selector(runUserMain) userInfo:nil repeats:NO];
|
||||
}
|
||||
|
||||
- (void)getUrl:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
|
||||
{
|
||||
Q_UNUSED(replyEvent);
|
||||
NSString *urlString = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
|
||||
QWindowSystemInterface::handleFileOpenEvent(QCFString::toQString(urlString));
|
||||
}
|
||||
|
||||
- (void)appleEventQuit:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
Q_UNUSED(replyEvent);
|
||||
[NSApp terminate:self];
|
||||
}
|
||||
|
||||
- (void)runUserMain
|
||||
{
|
||||
NSArray *arguments = [[NSProcessInfo processInfo] arguments];
|
||||
int argc = arguments.count;
|
||||
char **argv = new char*[argc];
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
NSString *arg = [arguments objectAtIndex:i];
|
||||
argv[i] = reinterpret_cast<char *>(malloc([arg lengthOfBytesUsingEncoding:[NSString defaultCStringEncoding]]));
|
||||
strcpy(argv[i], [arg cStringUsingEncoding:[NSString defaultCStringEncoding]]);
|
||||
}
|
||||
|
||||
qMain(argc, argv);
|
||||
delete[] argv;
|
||||
|
||||
NSAppleEventManager *eventManager = [NSAppleEventManager sharedAppleEventManager];
|
||||
[eventManager removeEventHandlerForEventClass:kCoreEventClass andEventID:kAEQuitApplication];
|
||||
[eventManager removeEventHandlerForEventClass:kInternetEventClass andEventID:kAEGetURL];
|
||||
|
||||
[NSApp terminate:self];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
static SEL qt_infoDictionary_original_SEL = @selector(qt_infoDictionary_original);
|
||||
|
||||
@implementation NSBundle (QT_MANGLE_NAMESPACE(QCocoaMain))
|
||||
|
||||
- (Class)qt_infoDictionary_replacement
|
||||
{
|
||||
if (self == [NSBundle mainBundle]) {
|
||||
static NSMutableDictionary *infoDict = nil;
|
||||
if (!infoDict) {
|
||||
infoDict = [[self performSelector:qt_infoDictionary_original_SEL] mutableCopy];
|
||||
[infoDict setValue:@"NSApplication" forKey:@"NSPrincipalClass"];
|
||||
}
|
||||
return infoDict;
|
||||
}
|
||||
|
||||
return [self performSelector:qt_infoDictionary_original_SEL];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
QCocoaMainWrapper *mainWrapper = [[QCocoaMainWrapper alloc] init];
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver:mainWrapper selector:@selector(applicationWillFinishLaunching:)
|
||||
name:NSApplicationWillFinishLaunchingNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver:mainWrapper selector:@selector(applicationDidFinishLaunching:)
|
||||
name:NSApplicationDidFinishLaunchingNotification object:nil];
|
||||
|
||||
NSBundle *mainBundle = [NSBundle mainBundle];
|
||||
if (!mainBundle.principalClass) {
|
||||
// Since several of the GUI based Qt utilities (e.g., qmlscene) are command
|
||||
// line applications, meaning non-bundle applications, we need to make Cocoa
|
||||
// believe everything is fine. So we fake the main bundle's dictionary by
|
||||
// adding the "NSPrincipalClass" property. So far, this seems to be enough to
|
||||
// keep NSApplicationMain() happy and running...
|
||||
qt_cocoa_change_implementation([NSBundle class], @selector(infoDictionary),
|
||||
[NSBundle class], @selector(qt_infoDictionary_replacement), qt_infoDictionary_original_SEL);
|
||||
}
|
||||
|
||||
return NSApplicationMain(argc, (const char **)argv);
|
||||
}
|
@ -2166,8 +2166,6 @@ void QColorDialog::keyPressEvent(QKeyEvent *e)
|
||||
}
|
||||
e->accept();
|
||||
return;
|
||||
} else if (d->nativeDialogInUse && d->platformColorDialogHelper()->event(e)) {
|
||||
return;
|
||||
}
|
||||
QDialog::keyPressEvent(e);
|
||||
}
|
||||
|
@ -983,9 +983,14 @@ void QFontDialog::setVisible(bool visible)
|
||||
Q_D(QFontDialog);
|
||||
if (d->canBeNativeDialog())
|
||||
d->setNativeDialogVisible(visible);
|
||||
// Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below
|
||||
// updates the state correctly, but skips showing the non-native version:
|
||||
setAttribute(Qt::WA_DontShowOnScreen, d->nativeDialogInUse);
|
||||
if (d->nativeDialogInUse) {
|
||||
// Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below
|
||||
// updates the state correctly, but skips showing the non-native version:
|
||||
setAttribute(Qt::WA_DontShowOnScreen, true);
|
||||
} else {
|
||||
d->nativeDialogInUse = false;
|
||||
setAttribute(Qt::WA_DontShowOnScreen, false);
|
||||
}
|
||||
QDialog::setVisible(visible);
|
||||
}
|
||||
|
||||
|
@ -144,10 +144,13 @@ void tst_QColorDialog::postKeyReturn() {
|
||||
|
||||
void tst_QColorDialog::testGetRgba()
|
||||
{
|
||||
QColorDialog cd;
|
||||
cd.show();
|
||||
QTimer::singleShot(0, this, SLOT(postKeyReturn()));
|
||||
QTRY_COMPARE(cd.result(), int(QDialog::Accepted));
|
||||
#ifdef Q_OS_MAC
|
||||
QEXPECT_FAIL("", "Sending QTest::keyClick to OSX color dialog helper fails, see QTBUG-24320", Continue);
|
||||
#endif
|
||||
bool ok = false;
|
||||
QTimer::singleShot(500, this, SLOT(postKeyReturn()));
|
||||
QColorDialog::getRgba(0xffffffff, &ok);
|
||||
QVERIFY(ok);
|
||||
}
|
||||
|
||||
void tst_QColorDialog::defaultOkButton()
|
||||
|
@ -64,7 +64,7 @@ public:
|
||||
|
||||
public slots:
|
||||
void postKeyReturn();
|
||||
void testDefaultOkButton();
|
||||
void testGetFont();
|
||||
void testSetFont();
|
||||
|
||||
public slots:
|
||||
@ -116,12 +116,15 @@ void tst_QFontDialog::postKeyReturn() {
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QFontDialog::testDefaultOkButton()
|
||||
void tst_QFontDialog::testGetFont()
|
||||
{
|
||||
QFontDialog fd;
|
||||
fd.show();
|
||||
QTimer::singleShot(0, this, SLOT(postKeyReturn()));
|
||||
QTRY_COMPARE(fd.result(), int(QDialog::Accepted));
|
||||
#ifdef Q_OS_MAC
|
||||
QEXPECT_FAIL("", "Sending QTest::keyClick to OSX font dialog helper fails, see QTBUG-24321", Continue);
|
||||
#endif
|
||||
bool ok = false;
|
||||
QTimer::singleShot(2000, this, SLOT(postKeyReturn()));
|
||||
QFontDialog::getFont(&ok);
|
||||
QVERIFY(ok);
|
||||
}
|
||||
|
||||
void tst_QFontDialog::runSlotWithFailsafeTimer(const char *member)
|
||||
@ -141,7 +144,7 @@ void tst_QFontDialog::runSlotWithFailsafeTimer(const char *member)
|
||||
|
||||
void tst_QFontDialog::defaultOkButton()
|
||||
{
|
||||
runSlotWithFailsafeTimer(SLOT(testDefaultOkButton()));
|
||||
runSlotWithFailsafeTimer(SLOT(testGetFont()));
|
||||
}
|
||||
|
||||
void tst_QFontDialog::testSetFont()
|
||||
|
Loading…
Reference in New Issue
Block a user