diff options
Diffstat (limited to 'src/plugins/platforms/cocoa')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoabackingstore.h | 1 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoabackingstore.mm | 10 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoacolordialoghelper.h | 4 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm | 14 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaeventdispatcher.h | 11 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm | 154 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoafiledialoghelper.h | 4 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm | 20 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoafontdialoghelper.h | 4 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm | 14 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaprintersupport.h | 8 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoawindow.h | 7 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoawindow.mm | 123 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview.h | 5 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview.mm | 95 |
15 files changed, 321 insertions, 153 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h index 489938c4b3..72bb5936c0 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.h +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h @@ -63,7 +63,6 @@ public: bool scroll(const QRegion &area, int dx, int dy); private: - QCocoaWindow *m_cocoaWindow; QImage *m_image; }; diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm index f0ff7ba0d6..660c2b651f 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm @@ -50,7 +50,6 @@ QT_BEGIN_NAMESPACE QCocoaBackingStore::QCocoaBackingStore(QWindow *window) : QPlatformBackingStore(window) { - m_cocoaWindow = static_cast<QCocoaWindow *>(window->handle()); m_image = new QImage(window->geometry().size(),QImage::Format_ARGB32_Premultiplied); } @@ -72,14 +71,19 @@ void QCocoaBackingStore::flush(QWindow *widget, const QRegion ®ion, const QPo QRect geo = region.boundingRect(); NSRect rect = NSMakeRect(geo.x(), geo.y(), geo.width(), geo.height()); - [m_cocoaWindow->m_contentView displayRect:rect]; + QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window()->handle()); + if (cocoaWindow) + [cocoaWindow->m_contentView displayRect:rect]; } void QCocoaBackingStore::resize(const QSize &size, const QRegion &) { delete m_image; m_image = new QImage(size, QImage::Format_ARGB32_Premultiplied); - [static_cast<QNSView *>(m_cocoaWindow->m_contentView) setImage:m_image]; + + QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window()->handle()); + if (cocoaWindow) + [static_cast<QNSView *>(cocoaWindow->m_contentView) setImage:m_image]; } bool QCocoaBackingStore::scroll(const QRegion &area, int dx, int dy) diff --git a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.h b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.h index 505fd4f111..4b901f3ef3 100644 --- a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.h +++ b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.h @@ -56,7 +56,7 @@ public: void platformNativeDialogModalHelp(); void _q_platformRunNativeAppModalPanel(); void deleteNativeDialog_sys(); - bool show_sys(QFlags<QPlatformDialogHelper::ShowFlag>, Qt::WindowFlags, QWindow*); + bool show_sys(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent); void hide_sys(); DialogCode dialogResultCode_sys(); @@ -64,7 +64,7 @@ public: QColor currentColor_sys() const; public: - bool showCocoaColorPanel(QWindow *parent); + bool showCocoaColorPanel(Qt::WindowModality windowModality, QWindow *parent); bool hideCocoaColorPanel(); void createNSColorPanelDelegate(); diff --git a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm index 405cacee01..9f4446b32e 100644 --- a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm @@ -381,9 +381,13 @@ void QCocoaColorDialogHelper::deleteNativeDialog_sys() mDelegate = 0; } -bool QCocoaColorDialogHelper::show_sys(QFlags<QPlatformDialogHelper::ShowFlag>, Qt::WindowFlags, QWindow *parent) +bool QCocoaColorDialogHelper::show_sys(Qt::WindowFlags, Qt::WindowModality windowModality, QWindow *parent) { - return showCocoaColorPanel(parent); + if (windowModality == Qt::WindowModal) { + // Cocoa's shared color panel cannot be shown as a sheet + return false; + } + return showCocoaColorPanel(windowModality, parent); } void QCocoaColorDialogHelper::hide_sys() @@ -447,13 +451,15 @@ void QCocoaColorDialogHelper::createNSColorPanelDelegate() mDelegate = delegate; } -bool QCocoaColorDialogHelper::showCocoaColorPanel(QWindow *parent) +bool QCocoaColorDialogHelper::showCocoaColorPanel(Qt::WindowModality windowModality, QWindow *parent) { Q_UNUSED(parent); createNSColorPanelDelegate(); QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) *>(mDelegate); [delegate->mColorPanel setShowsAlpha:options()->testOption(QColorDialogOptions::ShowAlphaChannel)]; - [delegate showModelessPanel]; + if (windowModality == Qt::NonModal) + [delegate showModelessPanel]; + // no need to show a Qt::ApplicationModal dialog here, since it will be done in _q_platformRunNativeAppModalPanel() return true; } diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h index 7fa1f0971f..4be30c44ed 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h @@ -116,7 +116,6 @@ public: explicit QCocoaEventDispatcher(QObject *parent = 0); ~QCocoaEventDispatcher(); - bool processEvents(QEventLoop::ProcessEventsFlags flags); bool hasPendingEvents(); @@ -156,9 +155,11 @@ public: // timer handling QTimerInfoList timerInfoList; CFRunLoopTimerRef runLoopTimerRef; + CFRunLoopSourceRef activateTimersSourceRef; void maybeStartCFRunLoopTimer(); void maybeStopCFRunLoopTimer(); - static void activateTimer(CFRunLoopTimerRef, void *info); + static void runLoopTimerCallback(CFRunLoopTimerRef, void *info); + static void activateTimersSourceCallback(void *info); // Set 'blockSendPostedEvents' to true if you _really_ need // to make sure that qt events are not posted while calling @@ -176,9 +177,10 @@ public: void temporarilyStopAllModalSessions(); void beginModalSession(QWindow *widget); void endModalSession(QWindow *widget); + void cleanupModalSessions(); + void cancelWaitForMoreEvents(); void maybeCancelWaitForMoreEvents(); - void cleanupModalSessions(); void ensureNSAppInitialized(); MacSocketHash macSockets; @@ -190,8 +192,7 @@ public: int lastSerial; bool interrupt; - static Boolean postedEventSourceEqualCallback(const void *info1, const void *info2); - static void postedEventsSourcePerformCallback(void *info); + static void postedEventsSourceCallback(void *info); static void waitingObserverCallback(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info); static void firstLoopEntry(CFRunLoopObserverRef ref, CFRunLoopActivity activity, void *info); diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index 02722ce5bf..a3bd4a95ca 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -82,6 +82,7 @@ #include "qmutex.h" #include "qsocketnotifier.h" #include <qplatformwindow_qpa.h> +#include <qplatformnativeinterface_qpa.h> #include "private/qthread_p.h" #include "private/qguiapplication_p.h" #include <qdebug.h> @@ -104,12 +105,28 @@ static inline CFRunLoopRef mainRunLoop() return CFRunLoopGetMain(); } +static Boolean runLoopSourceEqualCallback(const void *info1, const void *info2) +{ + return info1 == info2; +} + /***************************************************************************** Timers stuff *****************************************************************************/ /* timer call back */ -void QCocoaEventDispatcherPrivate::activateTimer(CFRunLoopTimerRef, void *info) +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); +} + +void QCocoaEventDispatcherPrivate::activateTimersSourceCallback(void *info) { QCocoaEventDispatcherPrivate *d = static_cast<QCocoaEventDispatcherPrivate *>(info); (void) d->timerInfoList.activateTimers(); @@ -145,7 +162,7 @@ void QCocoaEventDispatcherPrivate::maybeStartCFRunLoopTimer() CFRunLoopTimerContext info = { 0, this, 0, 0, 0 }; // create the timer with a large interval, as recommended by the CFRunLoopTimerSetNextFireDate() // documentation, since we will adjust the timer's time-to-fire as needed to keep Qt timers working - runLoopTimerRef = CFRunLoopTimerCreate(0, ttf, oneyear, 0, 0, QCocoaEventDispatcherPrivate::activateTimer, &info); + runLoopTimerRef = CFRunLoopTimerCreate(0, ttf, oneyear, 0, 0, QCocoaEventDispatcherPrivate::runLoopTimerCallback, &info); Q_ASSERT(runLoopTimerRef != 0); CFRunLoopAddTimer(mainRunLoop(), runLoopTimerRef, kCFRunLoopCommonModes); @@ -513,10 +530,10 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) emit awake(); - bool excludeUserEvents = flags & QEventLoop::ExcludeUserInputEvents; - bool retVal = false; uint oldflags = d->processEventsFlags; d->processEventsFlags = flags; + bool excludeUserEvents = d->processEventsFlags & QEventLoop::ExcludeUserInputEvents; + bool retVal = false; forever { if (d->interrupt) break; @@ -544,8 +561,9 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) // 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 && - (flags & QEventLoop::DialogExec || flags & QEventLoop::EventLoopExec) ; + 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 @@ -632,9 +650,11 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) } } while (!d->interrupt && event != nil); - if ((flags & QEventLoop::WaitForMoreEvents) == 0) { - // when called "manually", always send posted events + if ((d->processEventsFlags & QEventLoop::EventLoopExec) == 0) { + // when called "manually", always send posted events and timers d->processPostedEvents(); + retVal = d->timerInfoList.activateTimers() > 0 || retVal; + d->maybeStartCFRunLoopTimer(); } // be sure to return true if the posted event source fired @@ -651,12 +671,12 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) bool canWait = (d->threadData->canWait && !retVal && !d->interrupt - && (flags & QEventLoop::WaitForMoreEvents)); + && (d->processEventsFlags & QEventLoop::WaitForMoreEvents)); if (canWait) { // INVARIANT: We haven't processed any events yet. And we're told // to stay inside this function until at least one event is processed. qt_mac_waitForMoreEvents(); - flags &= ~QEventLoop::WaitForMoreEvents; + d->processEventsFlags &= ~QEventLoop::WaitForMoreEvents; } else { // Done with event processing for now. // Leave the function: @@ -762,26 +782,18 @@ NSModalSession QCocoaEventDispatcherPrivate::currentModalSession() QCocoaModalSessionInfo &info = cocoaModalSessionStack[i]; if (!info.window) continue; -// ### port -// if (info.window->testAttribute(Qt::WA_DontShowOnScreen)) -// continue; if (!info.session) { QCocoaAutoReleasePool pool; - NSWindow *window = reinterpret_cast<NSWindow *>(info.window->handle()->winId()); - if (!window) + NSWindow *nswindow = static_cast<NSWindow *>(QGuiApplication::platformNativeInterface()->nativeResourceForWindow("nswindow", info.window)); + if (!nswindow) continue; ensureNSAppInitialized(); QBoolBlocker block1(blockSendPostedEvents, true); - info.nswindow = window; + info.nswindow = nswindow; [(NSWindow*) info.nswindow retain]; - int levelBeforeEnterModal = [window level]; - info.session = [NSApp beginModalSessionForWindow:window]; - // Make sure we don't stack the window lower that it was before - // entering modal, in case it e.g. had the stays-on-top flag set: - if (levelBeforeEnterModal > [window level]) - [window setLevel:levelBeforeEnterModal]; + info.session = [NSApp beginModalSessionForWindow:nswindow]; } currentModalSessionCached = info.session; cleanupModalSessionsNeeded = false; @@ -850,12 +862,14 @@ void QCocoaEventDispatcherPrivate::cleanupModalSessions() currentModalSessionCached = info.session; break; } - cocoaModalSessionStack.remove(i); currentModalSessionCached = 0; if (info.session) { + Q_ASSERT(info.nswindow != 0); [NSApp endModalSession:info.session]; [(NSWindow *)info.nswindow release]; } + // remove the info now that we are finished with it + cocoaModalSessionStack.remove(i); } updateChildrenWorksWhenModal(); @@ -864,6 +878,14 @@ void QCocoaEventDispatcherPrivate::cleanupModalSessions() void QCocoaEventDispatcherPrivate::beginModalSession(QWindow *window) { + // We need to start spinning the modal session. Usually this is done with + // QDialog::exec() for QtWidgets based applications, but for others that + // just call show(), we need to interrupt(). We call this here, before + // setting currentModalSessionCached to zero, so that interrupt() calls + // [NSApp abortModal] if another modal session is currently running + Q_Q(QCocoaEventDispatcher); + q->interrupt(); + // Add a new, empty (null), NSModalSession to the stack. // It will become active the next time QEventDispatcher::processEvents is called. // A QCocoaModalSessionInfo is considered pending to become active if the window pointer @@ -879,6 +901,8 @@ void QCocoaEventDispatcherPrivate::beginModalSession(QWindow *window) void QCocoaEventDispatcherPrivate::endModalSession(QWindow *window) { + Q_Q(QCocoaEventDispatcher); + // Mark all sessions attached to window as pending to be stopped. We do this // by setting the window pointer to zero, but leave the session pointer. // We don't tell cocoa to stop any sessions just yet, because cocoa only understands @@ -890,11 +914,14 @@ void QCocoaEventDispatcherPrivate::endModalSession(QWindow *window) if (info.window == window) { info.window = 0; if (i == stackSize-1) { - // The top sessions ended. Interrupt the event dispatcher - // to start spinning the correct session immidiatly: + // The top sessions ended. Interrupt the event dispatcher to + // start spinning the correct session immediately. Like in + // beginModalSession(), we call interrupt() before clearing + // currentModalSessionCached to make sure we stop any currently + // running modal session with [NSApp abortModal] + q->interrupt(); currentModalSessionCached = 0; cleanupModalSessionsNeeded = true; - QCocoaEventDispatcher::instance()->interrupt(); } } } @@ -917,15 +944,28 @@ QCocoaEventDispatcher::QCocoaEventDispatcher(QObject *parent) : QAbstractEventDispatcher(*new QCocoaEventDispatcherPrivate, parent) { Q_D(QCocoaEventDispatcher); + + // keep our sources running when modal loops are running + CFRunLoopAddCommonMode(mainRunLoop(), (CFStringRef) NSModalPanelRunLoopMode); + CFRunLoopSourceContext context; bzero(&context, sizeof(CFRunLoopSourceContext)); context.info = d; - context.equal = QCocoaEventDispatcherPrivate::postedEventSourceEqualCallback; - context.perform = QCocoaEventDispatcherPrivate::postedEventsSourcePerformCallback; - d->postedEventsSource = CFRunLoopSourceCreate(0, 0, &context); + context.equal = runLoopSourceEqualCallback; + + // source used to activate timers + context.perform = QCocoaEventDispatcherPrivate::activateTimersSourceCallback; + d->activateTimersSourceRef = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context); + Q_ASSERT(d->activateTimersSourceRef); + CFRunLoopAddSource(mainRunLoop(), d->activateTimersSourceRef, kCFRunLoopCommonModes); + + // source used to send posted events + context.perform = QCocoaEventDispatcherPrivate::postedEventsSourceCallback; + d->postedEventsSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context); Q_ASSERT(d->postedEventsSource); CFRunLoopAddSource(mainRunLoop(), d->postedEventsSource, kCFRunLoopCommonModes); + // observer to emit aboutToBlock() and awake() CFRunLoopObserverContext observerContext; bzero(&observerContext, sizeof(CFRunLoopObserverContext)); observerContext.info = this; @@ -961,11 +1001,6 @@ void QCocoaEventDispatcherPrivate::waitingObserverCallback(CFRunLoopObserverRef, emit static_cast<QCocoaEventDispatcher*>(info)->awake(); } -Boolean QCocoaEventDispatcherPrivate::postedEventSourceEqualCallback(const void *info1, const void *info2) -{ - return info1 == info2; -} - void QCocoaEventDispatcherPrivate::processPostedEvents() { if (blockSendPostedEvents) { @@ -1030,9 +1065,14 @@ void QCocoaEventDispatcherPrivate::firstLoopEntry(CFRunLoopObserverRef ref, static_cast<QCocoaEventDispatcherPrivate *>(info)->processPostedEvents(); } -void QCocoaEventDispatcherPrivate::postedEventsSourcePerformCallback(void *info) +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(); } @@ -1061,16 +1101,23 @@ void QCocoaEventDispatcher::interrupt() { Q_D(QCocoaEventDispatcher); d->interrupt = true; - wakeUp(); - - // We do nothing more here than setting d->interrupt = true, and - // poke the event loop if it is sleeping. Actually stopping - // NSApp, or the current modal session, is done inside the send - // posted events callback. We do this to ensure that all current pending - // cocoa events gets delivered before we stop. Otherwise, if we now stop - // the last event loop recursion, cocoa will just drop pending posted - // events on the floor before we get a chance to reestablish a new session. - d->cancelWaitForMoreEvents(); + if (d->currentModalSessionCached) { + // If a modal session is active, abort it so that we can clean it up + // later. We can't use [NSApp stopModal] here, because we do not know + // where the interrupt() came from. + [NSApp abortModal]; + } else { + wakeUp(); + + // We do nothing more here than setting d->interrupt = true, and + // poke the event loop if it is sleeping. Actually stopping + // NSApp, or the current modal session, is done inside the send + // posted events callback. We do this to ensure that all current pending + // cocoa events gets delivered before we stop. Otherwise, if we now stop + // the last event loop recursion, cocoa will just drop pending posted + // events on the floor before we get a chance to reestablish a new session. + d->cancelWaitForMoreEvents(); + } } void QCocoaEventDispatcher::flush() @@ -1082,6 +1129,23 @@ QCocoaEventDispatcher::~QCocoaEventDispatcher() qDeleteAll(d->timerInfoList); d->maybeStopCFRunLoopTimer(); + CFRunLoopRemoveSource(mainRunLoop(), d->activateTimersSourceRef, kCFRunLoopCommonModes); + CFRelease(d->activateTimersSourceRef); + + // end all modal sessions + for (int i = 0; i < d->cocoaModalSessionStack.count(); ++i) { + QCocoaModalSessionInfo &info = d->cocoaModalSessionStack[i]; + if (info.session) { + [NSApp endModalSession:info.session]; + [(NSWindow *)info.nswindow release]; + } + } + + // release all queued user input events + for (int i = 0; i < d->queuedUserInputEvents.count(); ++i) { + NSEvent *nsevent = static_cast<NSEvent *>(d->queuedUserInputEvents.at(i)); + [nsevent release]; + } // Remove CFSockets from the runloop. for (MacSocketHash::ConstIterator it = d->macSockets.constBegin(); it != d->macSockets.constEnd(); ++it) { diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h index 7d4da019c2..9768d3e6f9 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h @@ -62,7 +62,7 @@ public: bool defaultNameFilterDisables() const; void deleteNativeDialog_sys(); - bool show_sys(ShowFlags flags, Qt::WindowFlags windowFlags, QWindow *parent); + bool show_sys(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent); void hide_sys(); QPlatformFileDialogHelper::DialogCode dialogResultCode_sys(); void setDirectory_sys(const QString &directory); @@ -74,7 +74,7 @@ public: QString selectedNameFilter_sys() const; public: - bool showCocoaFilePanel(QWindow *parent); + bool showCocoaFilePanel(Qt::WindowModality windowModality, QWindow *parent); bool hideCocoaFilePanel(); void createNSOpenSavePanelDelegate(); diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index c333e3ac1f..9bc7df02fb 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -244,18 +244,18 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions; return (mReturnCode == NSOKButton) ? QT_PREPEND_NAMESPACE(QPlatformDialogHelper::Accepted) : QT_PREPEND_NAMESPACE(QPlatformDialogHelper::Rejected); } -- (void)showWindowModalSheet:(QWindow *)docWidget +- (void)showWindowModalSheet:(QWindow *)parent { - Q_UNUSED(docWidget); QFileInfo info(*mCurrentSelection); NSString *filename = QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.fileName()); NSString *filepath = QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.filePath()); bool selectable = (mOptions->acceptMode() == QFileDialogOptions::AcceptSave) || [self panel:nil shouldShowFilename:filepath]; + NSWindow *nsparent = static_cast<NSWindow *>(qGuiApp->platformNativeInterface()->nativeResourceForWindow("nswindow", parent)); [mSavePanel beginSheetForDirectory:mCurrentDir file:selectable ? filename : nil - modalForWindow:nil + modalForWindow:nsparent modalDelegate:self didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:) contextInfo:nil]; @@ -613,7 +613,7 @@ void QCocoaFileDialogHelper::hide_sys() hideCocoaFilePanel(); } -bool QCocoaFileDialogHelper::show_sys(ShowFlags /* flags */, Qt::WindowFlags windowFlags, QWindow *parent) +bool QCocoaFileDialogHelper::show_sys(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) { // Q_Q(QFileDialog); if (windowFlags & Qt::WindowStaysOnTopHint) { @@ -624,7 +624,7 @@ bool QCocoaFileDialogHelper::show_sys(ShowFlags /* flags */, Qt::WindowFlags win return false; } - return showCocoaFilePanel(parent); + return showCocoaFilePanel(windowModality, parent); } void QCocoaFileDialogHelper::createNSOpenSavePanelDelegate() @@ -645,15 +645,15 @@ void QCocoaFileDialogHelper::createNSOpenSavePanelDelegate() mDelegate = delegate; } -bool QCocoaFileDialogHelper::showCocoaFilePanel(QWindow *parent) +bool QCocoaFileDialogHelper::showCocoaFilePanel(Qt::WindowModality windowModality, QWindow *parent) { -// Q_Q(QFileDialog); createNSOpenSavePanelDelegate(); QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate); - if (0 /*qt_mac_is_macsheet(qtFileDialog)*/) // ### sheet support. - [delegate showWindowModalSheet:parent]; - else + if (windowModality == Qt::NonModal) [delegate showModelessPanel]; + else if (windowModality == Qt::WindowModal && parent) + [delegate showWindowModalSheet:parent]; + // no need to show a Qt::ApplicationModal dialog here, since it will be done in _q_platformRunNativeAppModalPanel() return true; } diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.h b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.h index 8a914bf632..f9dd4357a5 100644 --- a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.h +++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.h @@ -60,7 +60,7 @@ public: void _q_platformRunNativeAppModalPanel(); void deleteNativeDialog_sys(); - bool show_sys(ShowFlags showFlags, Qt::WindowFlags windowFlags, QWindow *parent); + bool show_sys(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent); void hide_sys(); QPlatformDialogHelper::DialogCode dialogResultCode_sys(); @@ -70,7 +70,7 @@ public: protected: void createNSFontPanelDelegate(); - bool showCocoaFontPanel(QWindow *parent); + bool showCocoaFontPanel(Qt::WindowModality windowModality, QWindow *parent); bool hideCocoaFontPanel(); private: diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm index 1e89270775..515bc2a6ee 100644 --- a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm @@ -400,9 +400,13 @@ void QCocoaFontDialogHelper::deleteNativeDialog_sys() mDelegate = 0; } -bool QCocoaFontDialogHelper::show_sys(QFlags<QPlatformDialogHelper::ShowFlag>, Qt::WindowFlags, QWindow *parent) +bool QCocoaFontDialogHelper::show_sys(Qt::WindowFlags, Qt::WindowModality windowModality, QWindow *parent) { - return showCocoaFontPanel(parent); + if (windowModality == Qt::WindowModal) { + // Cocoa's shared font panel cannot be shown as a sheet + return false; + } + return showCocoaFontPanel(windowModality, parent); } void QCocoaFontDialogHelper::hide_sys() @@ -466,12 +470,14 @@ void QCocoaFontDialogHelper::createNSFontPanelDelegate() mDelegate = delegate; } -bool QCocoaFontDialogHelper::showCocoaFontPanel(QWindow *parent) +bool QCocoaFontDialogHelper::showCocoaFontPanel(Qt::WindowModality windowModality, QWindow *parent) { Q_UNUSED(parent); createNSFontPanelDelegate(); QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate); - [delegate showModelessPanel]; + if (windowModality == Qt::NonModal) + [delegate showModelessPanel]; + // no need to show a Qt::ApplicationModal dialog here, since it will be done in _q_platformRunNativeAppModalPanel() return true; } diff --git a/src/plugins/platforms/cocoa/qcocoaprintersupport.h b/src/plugins/platforms/cocoa/qcocoaprintersupport.h index db473dfabb..2309025bb3 100644 --- a/src/plugins/platforms/cocoa/qcocoaprintersupport.h +++ b/src/plugins/platforms/cocoa/qcocoaprintersupport.h @@ -50,11 +50,11 @@ public: QCocoaPrinterSupport(); ~QCocoaPrinterSupport(); - Q_DECL_OVERRIDE QPrintEngine *createNativePrintEngine(QPrinter::PrinterMode printerMode); - Q_DECL_OVERRIDE QPaintEngine *createPaintEngine(QPrintEngine *, QPrinter::PrinterMode printerMode); - Q_DECL_OVERRIDE QList<QPrinter::PaperSize> supportedPaperSizes(const QPrinterInfo &) const; + QPrintEngine *createNativePrintEngine(QPrinter::PrinterMode printerMode) Q_DECL_OVERRIDE; + QPaintEngine *createPaintEngine(QPrintEngine *, QPrinter::PrinterMode printerMode) Q_DECL_OVERRIDE; + QList<QPrinter::PaperSize> supportedPaperSizes(const QPrinterInfo &) const Q_DECL_OVERRIDE; - Q_DECL_OVERRIDE QList<QPrinterInfo> availablePrinters(); + QList<QPrinterInfo> availablePrinters() Q_DECL_OVERRIDE; }; #endif // QCOCOAPRINTERSUPPORT_H diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 184422a04a..d08bbe79ce 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -95,6 +95,7 @@ public: void setCocoaGeometry(const QRect &rect); void setVisible(bool visible); Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags); + Qt::WindowState setWindowState(Qt::WindowState state); void setWindowTitle(const QString &title); void raise(); void lower(); @@ -117,6 +118,8 @@ public: void setCurrentContext(QCocoaGLContext *context); QCocoaGLContext *currentContext() const; + bool setWindowModified(bool modified) Q_DECL_OVERRIDE; + protected: // NSWindow handling. The QCocoaWindow/QNSView can either be displayed // in an existing NSWindow or in one created by Qt. @@ -127,6 +130,7 @@ protected: QRect windowGeometry() const; QCocoaWindow *parentCocoaWindow() const; + void syncWindowState(Qt::WindowState newState); // private: public: // for QNSView @@ -136,10 +140,13 @@ public: // for QNSView QNSView *m_contentView; NSWindow *m_nsWindow; Qt::WindowFlags m_windowFlags; + Qt::WindowState m_synchedWindowState; QPointer<QWindow> m_activePopupWindow; bool m_inConstructor; QCocoaGLContext *m_glContext; + + bool m_hasModalSession; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index de58842772..83b6534b7c 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -41,6 +41,7 @@ #include "qcocoawindow.h" #include "qnswindowdelegate.h" #include "qcocoaautoreleasepool.h" +#include "qcocoaeventdispatcher.h" #include "qcocoaglcontext.h" #include "qcocoahelpers.h" #include "qnsview.h" @@ -96,8 +97,10 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) : QPlatformWindow(tlw) , m_nsWindow(0) + , m_synchedWindowState(Qt::WindowActive) , m_inConstructor(true) , m_glContext(0) + , m_hasModalSession(false) { QCocoaAutoReleasePool pool; @@ -145,7 +148,10 @@ void QCocoaWindow::setVisible(bool visible) qDebug() << "QCocoaWindow::setVisible" << window() << visible; #endif if (visible) { + QCocoaWindow *parentCocoaWindow = 0; if (window()->transientParent()) { + parentCocoaWindow = static_cast<QCocoaWindow *>(window()->transientParent()->handle()); + // The parent window might have moved while this window was hidden, // update the window geometry if there is a parent. setGeometry(window()->geometry()); @@ -154,8 +160,6 @@ void QCocoaWindow::setVisible(bool visible) // close them when needed. if (window()->windowType() == Qt::Popup) { // qDebug() << "transientParent and popup" << window()->windowType() << Qt::Popup << (window()->windowType() & Qt::Popup); - - QCocoaWindow *parentCocoaWindow = static_cast<QCocoaWindow *>(window()->transientParent()->handle()); parentCocoaWindow->m_activePopupWindow = window(); } @@ -165,15 +169,47 @@ void QCocoaWindow::setVisible(bool visible) QWindowSystemInterface::handleSynchronousExposeEvent(window(), QRect(QPoint(), geometry().size())); if (m_nsWindow) { - if ([m_nsWindow canBecomeKeyWindow]) - [m_nsWindow makeKeyAndOrderFront:nil]; - else - [m_nsWindow orderFront: nil]; + // setWindowState might have been called while the window was hidden and + // will not change the NSWindow state in that case. Sync up here: + syncWindowState(window()->windowState()); + + if (window()->windowState() != Qt::WindowMinimized) { + if ((window()->windowModality() == Qt::WindowModal + || window()->windowType() == Qt::Sheet) + && parentCocoaWindow) { + // show the window as a sheet + [NSApp beginSheet:m_nsWindow modalForWindow:parentCocoaWindow->m_nsWindow modalDelegate:nil didEndSelector:nil contextInfo:nil]; + } else if (window()->windowModality() != Qt::NonModal) { + // show the window as application modal + QCocoaEventDispatcher *cocoaEventDispatcher = qobject_cast<QCocoaEventDispatcher *>(QGuiApplication::instance()->eventDispatcher()); + Q_ASSERT(cocoaEventDispatcher != 0); + QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate = static_cast<QCocoaEventDispatcherPrivate *>(QObjectPrivate::get(cocoaEventDispatcher)); + cocoaEventDispatcherPrivate->beginModalSession(window()); + m_hasModalSession = true; + } else if ([m_nsWindow canBecomeKeyWindow]) { + [m_nsWindow makeKeyAndOrderFront:nil]; + } else { + [m_nsWindow orderFront: nil]; + } + } } } else { // qDebug() << "close" << this; - if (m_nsWindow) + if (m_nsWindow) { + if (m_hasModalSession) { + QCocoaEventDispatcher *cocoaEventDispatcher = qobject_cast<QCocoaEventDispatcher *>(QGuiApplication::instance()->eventDispatcher()); + Q_ASSERT(cocoaEventDispatcher != 0); + QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate = static_cast<QCocoaEventDispatcherPrivate *>(QObjectPrivate::get(cocoaEventDispatcher)); + cocoaEventDispatcherPrivate->endModalSession(window()); + m_hasModalSession = false; + } else { + if ([m_nsWindow isSheet]) + [NSApp endSheet:m_nsWindow]; + } [m_nsWindow orderOut:m_nsWindow]; + } + if (!QCoreApplication::closingDown()) + QWindowSystemInterface::handleExposeEvent(window(), QRegion()); } } @@ -183,6 +219,14 @@ Qt::WindowFlags QCocoaWindow::setWindowFlags(Qt::WindowFlags flags) return m_windowFlags; } +Qt::WindowState QCocoaWindow::setWindowState(Qt::WindowState state) +{ + if ([m_nsWindow isVisible]) + syncWindowState(state); // Window state set for hidden windows take effect when show() is called. + + return state; +} + void QCocoaWindow::setWindowTitle(const QString &title) { QCocoaAutoReleasePool pool; @@ -347,6 +391,12 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow) // Create a new NSWindow if this is a top-level window. m_nsWindow = createNSWindow(); setNSWindow(m_nsWindow); + + if (window()->transientParent()) { + // keep this window on the same level as its transient parent (which may be a modal dialog, for example) + QCocoaWindow *parentCocoaWindow = static_cast<QCocoaWindow *>(window()->transientParent()->handle()); + [m_nsWindow setLevel:[parentCocoaWindow->m_nsWindow level]]; + } } else { // Child windows have no NSWindow, link the NSViews instead. const QCocoaWindow *parentCococaWindow = static_cast<const QCocoaWindow *>(parentWindow); @@ -446,27 +496,12 @@ void QCocoaWindow::setNSWindow(NSWindow *window) // QCocoaWindow is deleted by Qt. [window setReleasedWhenClosed : NO]; - [[NSNotificationCenter defaultCenter] addObserver:m_contentView - selector:@selector(windowDidBecomeKey) - name:NSWindowDidBecomeKeyNotification - object:m_nsWindow]; [[NSNotificationCenter defaultCenter] addObserver:m_contentView - selector:@selector(windowDidResignKey) - name:NSWindowDidResignKeyNotification + selector:@selector(windowNotification:) + name:nil // Get all notifications object:m_nsWindow]; - [[NSNotificationCenter defaultCenter] addObserver:m_contentView - selector:@selector(windowDidBecomeMain) - name:NSWindowDidBecomeMainNotification - object:m_nsWindow]; - - [[NSNotificationCenter defaultCenter] addObserver:m_contentView - selector:@selector(windowDidResignMain) - name:NSWindowDidResignMainNotification - object:m_nsWindow]; - - // ### Accept touch events by default. // Beware that enabling touch events has a negative impact on the overall performance. // We probably need a QWindowSystemInterface API to enable/disable touch events. @@ -479,7 +514,6 @@ void QCocoaWindow::clearNSWindow(NSWindow *window) { [window setDelegate:nil]; [[NSNotificationCenter defaultCenter] removeObserver:m_contentView]; - [m_contentView removeFromSuperviewWithoutNeedingDisplay]; } // Returns the current global screen geometry for the nswindow associated with this window. @@ -504,3 +538,42 @@ QCocoaWindow *QCocoaWindow::parentCocoaWindow() const return 0; } +// Syncs the NSWindow minimize/maximize/fullscreen state with the current QWindow state +void QCocoaWindow::syncWindowState(Qt::WindowState newState) +{ + if (!m_nsWindow) + return; + + if ((m_synchedWindowState & Qt::WindowMaximized) != (newState & Qt::WindowMaximized)) { + [m_nsWindow performZoom : m_nsWindow]; // toggles + } + + if ((m_synchedWindowState & Qt::WindowMinimized) != (newState & Qt::WindowMinimized)) { + if (newState & Qt::WindowMinimized) { + [m_nsWindow performMiniaturize : m_nsWindow]; + } else { + [m_nsWindow deminiaturize : m_nsWindow]; + } + } + + if ((m_synchedWindowState & Qt::WindowFullScreen) != (newState & Qt::WindowFullScreen)) { +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 + if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) { + [m_nsWindow toggleFullScreen : m_nsWindow]; + } else { + // TODO: "normal" fullscreen + } +#endif + } + + // New state is now the current synched state + m_synchedWindowState = newState; +} + +bool QCocoaWindow::setWindowModified(bool modified) +{ + if (!m_nsWindow) + return false; + [m_nsWindow setDocumentEdited:(modified?YES:NO)]; + return true; +} diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index 2b7caae688..16775621bf 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE class QCocoaWindow; QT_END_NAMESPACE -@interface QNSView : NSView <NSTextInput> { +@interface QNSView : NSView <NSTextInputClient> { CGImageRef m_cgImage; QWindow *m_window; QCocoaWindow *m_platformWindow; @@ -70,8 +70,7 @@ QT_END_NAMESPACE - (void)setImage:(QImage *)image; - (void)drawRect:(NSRect)dirtyRect; - (void)updateGeometry; -- (void)windowDidBecomeKey; -- (void)windowDidResignKey; +- (void)windowNotification : (NSNotification *) windowNotification; - (BOOL)isFlipped; - (BOOL)acceptsFirstResponder; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index e76c02704f..a8372f754f 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -144,29 +144,40 @@ static QTouchDevice *touchDevice = 0; QWindowSystemInterface::handleSynchronousGeometryChange(m_window, geo); } -- (void)windowDidBecomeKey -{ - if (!m_platformWindow->windowIsPopupType()) - QWindowSystemInterface::handleWindowActivated(m_window); -} - -- (void)windowDidResignKey -{ - if (!m_platformWindow->windowIsPopupType()) - QWindowSystemInterface::handleWindowActivated(0); -} +- (void)windowNotification : (NSNotification *) windowNotification +{ + //qDebug() << "windowNotification" << QCFString::toQString([windowNotification name]); + + NSString *notificationName = [windowNotification name]; + if (notificationName == NSWindowDidBecomeKeyNotification) { + if (!m_platformWindow->windowIsPopupType()) + QWindowSystemInterface::handleWindowActivated(m_window); + } else if (notificationName == NSWindowDidResignKeyNotification) { + if (!m_platformWindow->windowIsPopupType()) + QWindowSystemInterface::handleWindowActivated(0); + } else if (notificationName == NSWindowDidMiniaturizeNotification) { + QWindowSystemInterface::handleWindowStateChanged(m_window, Qt::WindowMinimized); + } else if (notificationName == NSWindowDidDeminiaturizeNotification) { + QWindowSystemInterface::handleWindowStateChanged(m_window, Qt::WindowNoState); + // Qt expects an expose event after restore/deminiaturize. This also needs + // to be a non-synchronous event to make sure it gets processed after + // the state change event sent above. + QWindowSystemInterface::handleExposeEvent(m_window, QRegion(m_window->geometry())); + } else { -- (void)windowDidBecomeMain -{ -// qDebug() << "window did become main" << m_window; -} +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 + if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) { + if (notificationName == NSWindowDidEnterFullScreenNotification) { + QWindowSystemInterface::handleWindowStateChanged(m_window, Qt::WindowFullScreen); + } else if (notificationName == NSWindowDidExitFullScreenNotification) { + QWindowSystemInterface::handleWindowStateChanged(m_window, Qt::WindowNoState); + } + } +#endif -- (void)windowDidResignMain -{ -// qDebug() << "window did resign main" << m_window; + } } - - (void) setImage:(QImage *)image { CGImageRelease(m_cgImage); @@ -681,8 +692,9 @@ static QTouchDevice *touchDevice = 0; [self tryToPerform:aSelector with:self]; } -- (void) insertText:(id)aString +- (void) insertText:(id)aString replacementRange:(NSRange)replacementRange { + Q_UNUSED(replacementRange) QString commitString; if ([aString length]) { if ([aString isKindOfClass:[NSAttributedString class]]) { @@ -707,12 +719,13 @@ static QTouchDevice *touchDevice = 0; m_composingText.clear(); } -- (void) setMarkedText:(id)aString selectedRange:(NSRange)selRange +- (void) setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange { + Q_UNUSED(replacementRange) QString preeditString; QList<QInputMethodEvent::Attribute> attrs; - attrs<<QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, selRange.location + selRange.length, 1, QVariant()); + attrs<<QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, selectedRange.location + selectedRange.length, 1, QVariant()); if ([aString isKindOfClass:[NSAttributedString class]]) { // Preedit string has attribution @@ -793,13 +806,9 @@ static QTouchDevice *touchDevice = 0; return (m_composingText.isEmpty() ? NO: YES); } -- (NSInteger) conversationIdentifier -{ - return (NSInteger)self; -} - -- (NSAttributedString *) attributedSubstringFromRange:(NSRange)theRange +- (NSAttributedString *) attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange { + Q_UNUSED(actualRange) QObject *fo = QGuiApplication::focusObject(); if (!fo) return nil; @@ -813,7 +822,7 @@ static QTouchDevice *touchDevice = 0; if (selectedText.isEmpty()) return nil; - QCFString string(selectedText.mid(theRange.location, theRange.length)); + QCFString string(selectedText.mid(aRange.location, aRange.length)); const NSString *tmpString = reinterpret_cast<const NSString *>((CFStringRef)string); return [[[NSAttributedString alloc] initWithString:const_cast<NSString *>(tmpString)] autorelease]; } @@ -831,34 +840,34 @@ static QTouchDevice *touchDevice = 0; return range; } - - (NSRange) selectedRange { - NSRange selRange = {NSNotFound, 0}; - selRange.location = NSNotFound; - selRange.length = 0; + NSRange selectedRange = {NSNotFound, 0}; + selectedRange.location = NSNotFound; + selectedRange.length = 0; QObject *fo = QGuiApplication::focusObject(); if (!fo) - return selRange; + return selectedRange; QInputMethodQueryEvent queryEvent(Qt::ImEnabled | Qt::ImCurrentSelection); if (!QCoreApplication::sendEvent(fo, &queryEvent)) - return selRange; + return selectedRange; if (!queryEvent.value(Qt::ImEnabled).toBool()) - return selRange; + return selectedRange; QString selectedText = queryEvent.value(Qt::ImCurrentSelection).toString(); if (!selectedText.isEmpty()) { - selRange.location = 0; - selRange.length = selectedText.length(); + selectedRange.location = 0; + selectedRange.length = selectedText.length(); } - return selRange; + return selectedRange; } -- (NSRect) firstRectForCharacterRange:(NSRange)theRange +- (NSRect) firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange { - Q_UNUSED(theRange); + Q_UNUSED(aRange) + Q_UNUSED(actualRange) QObject *fo = QGuiApplication::focusObject(); if (!fo) return NSZeroRect; @@ -884,10 +893,10 @@ static QTouchDevice *touchDevice = 0; return rect; } -- (NSUInteger)characterIndexForPoint:(NSPoint)thePoint +- (NSUInteger)characterIndexForPoint:(NSPoint)aPoint { // We dont support cursor movements using mouse while composing. - Q_UNUSED(thePoint); + Q_UNUSED(aPoint); return NSNotFound; } |