diff options
author | Jørgen Lind <jorgen.lind@nokia.com> | 2010-10-28 12:35:43 (GMT) |
---|---|---|
committer | Jørgen Lind <jorgen.lind@nokia.com> | 2010-10-28 12:57:40 (GMT) |
commit | c1148ee9a60a6fae88ca09c21203e3f6c68c3c63 (patch) | |
tree | 434cd7aca5e8498e6cca489b9606015e9e8d8803 /src | |
parent | 8b7dad6c1290c3c5f9ce35ea9d13a4b7e6398572 (diff) | |
download | Qt-c1148ee9a60a6fae88ca09c21203e3f6c68c3c63.zip Qt-c1148ee9a60a6fae88ca09c21203e3f6c68c3c63.tar.gz Qt-c1148ee9a60a6fae88ca09c21203e3f6c68c3c63.tar.bz2 |
Lighthouse: eventloop integration rework.
For cocoa we really need to be able to run the cocoa eventloop
[NSApplicatyion run]. Also it makes sense for openKODE
without nvidia extensions.
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/kernel/qeventdispatcher_qpa.cpp | 45 | ||||
-rw-r--r-- | src/gui/kernel/qplatformeventloopintegration_qpa.cpp | 45 | ||||
-rw-r--r-- | src/gui/kernel/qplatformeventloopintegration_qpa.h | 24 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaeventloopintegration.h | 21 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm | 104 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaintegration.mm | 2 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoawindow.mm | 8 |
7 files changed, 158 insertions, 91 deletions
diff --git a/src/gui/kernel/qeventdispatcher_qpa.cpp b/src/gui/kernel/qeventdispatcher_qpa.cpp index cb70141..31fb356 100644 --- a/src/gui/kernel/qeventdispatcher_qpa.cpp +++ b/src/gui/kernel/qeventdispatcher_qpa.cpp @@ -51,6 +51,8 @@ #include <QtCore/QAtomicInt> #include <QtCore/QSemaphore> +#include <QtCore/QDebug> + #include <errno.h> QT_BEGIN_NAMESPACE @@ -122,7 +124,8 @@ public: selectWorkerNeedsSync(true), selectWorkerHasResult(false), m_integrationInitialised(false), - m_hasIntegration(false) + m_hasIntegration(false), + m_isEventLoopIntegrationRunning(false) { } @@ -160,6 +163,20 @@ public: return m_hasIntegration; } + bool isEventLoopIntegrationRunning() const + { + return m_isEventLoopIntegrationRunning; + } + + void runEventLoopIntegration() + { + if (qApp && (qApp->thread() == QThread::currentThread())) { + m_isEventLoopIntegrationRunning = true; + QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents); + eventLoopIntegration->startEventLoop(); + } + } + QPlatformEventLoopIntegration *eventLoopIntegration; Rendezvous *barrierBeforeBlocking; Rendezvous *barrierReturnValue; @@ -172,6 +189,7 @@ public: private: bool m_integrationInitialised; bool m_hasIntegration; + bool m_isEventLoopIntegrationRunning; }; QEventDispatcherQPA::QEventDispatcherQPA(QObject *parent) @@ -184,6 +202,17 @@ QEventDispatcherQPA::~QEventDispatcherQPA() bool QEventDispatcherQPA::processEvents(QEventLoop::ProcessEventsFlags flags) { Q_D(QEventDispatcherQPA); + + if (d->hasIntegration()) { + if (!d->isEventLoopIntegrationRunning()) { + d->runEventLoopIntegration(); + } + if (d->threadData->quitNow) { + d->eventLoopIntegration->quitEventLoop(); + return false; + } + } + int nevents = 0; // handle gui and posted events @@ -213,8 +242,10 @@ bool QEventDispatcherQPA::processEvents(QEventLoop::ProcessEventsFlags flags) } if (!d->interrupt) { - if (QEventDispatcherUNIX::processEvents(flags)) + if (QEventDispatcherUNIX::processEvents(flags)) { + QEventDispatcherUNIX::processEvents(flags); return true; + } } return (nevents > 0); } @@ -248,7 +279,6 @@ void QEventDispatcherQPA::flush() qApp->sendPostedEvents(); } - int QEventDispatcherQPA::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, timeval *timeout) { @@ -266,6 +296,7 @@ int QEventDispatcherQPA::select(int nfds, fd_set *readfds, fd_set *writefds, fd_ d->selectReturnMutex->unlock(); d->barrierReturnValue->checkpoint(); + d->eventLoopIntegration->setNextTimerEvent(0); return retVal; } else { d->selectWorkerNeedsSync = false; @@ -274,7 +305,7 @@ int QEventDispatcherQPA::select(int nfds, fd_set *readfds, fd_set *writefds, fd_ } } d->selectReturnMutex->unlock(); - d->eventLoopIntegration->processEvents(timeoutmsec); + d->eventLoopIntegration->setNextTimerEvent(timeoutmsec); retVal = 0; //is 0 if select has not returned } else { retVal = QEventDispatcherUNIX::select(nfds, readfds, writefds, exceptfds, timeout); @@ -282,14 +313,16 @@ int QEventDispatcherQPA::select(int nfds, fd_set *readfds, fd_set *writefds, fd_ return retVal; } + void SelectWorker::run() { + while(true) { m_retVal = 0; m_edPrivate->barrierBeforeBlocking->checkpoint(); // wait for mainthread int tmpRet = qt_safe_select(m_nfds,m_readfds,m_writefds,m_exceptfds,0); m_edPrivate->selectReturnMutex->lock(); - m_edPrivate->eventLoopIntegration->wakeup(); + m_edPrivate->eventLoopIntegration->qtNeedsToProcessEvents(); m_edPrivate->selectWorkerNeedsSync = true; m_edPrivate->selectWorkerHasResult = true; @@ -299,4 +332,6 @@ void SelectWorker::run() m_edPrivate->barrierReturnValue->checkpoint(); } } + +#include "qeventdispatcher_qpa.moc" QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatformeventloopintegration_qpa.cpp b/src/gui/kernel/qplatformeventloopintegration_qpa.cpp index 8bdba5e..fdb3852 100644 --- a/src/gui/kernel/qplatformeventloopintegration_qpa.cpp +++ b/src/gui/kernel/qplatformeventloopintegration_qpa.cpp @@ -39,3 +39,48 @@ ** ****************************************************************************/ +#include "qplatformeventloopintegration_qpa.h" + +#include <QtCore/QCoreApplication> + +#include <QtCore/QDebug> + +class QPlatformEventLoopIntegrationPrivate +{ +public: + QPlatformEventLoopIntegrationPrivate(); + qint64 nextTimerEvent; +}; + +QPlatformEventLoopIntegrationPrivate::QPlatformEventLoopIntegrationPrivate() + : nextTimerEvent(0) +{ +} + +QPlatformEventLoopIntegration::QPlatformEventLoopIntegration() + : d_ptr(new QPlatformEventLoopIntegrationPrivate) + +{ +} + +QPlatformEventLoopIntegration::~QPlatformEventLoopIntegration() +{ +} + +qint64 QPlatformEventLoopIntegration::nextTimerEvent() const +{ + Q_D(const QPlatformEventLoopIntegration); + return d->nextTimerEvent; +} + + +void QPlatformEventLoopIntegration::setNextTimerEvent(qint64 nextTimerEvent) +{ + Q_D(QPlatformEventLoopIntegration); + d->nextTimerEvent = nextTimerEvent; +} + +void QPlatformEventLoopIntegration::processEvents() +{ + QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents); +} diff --git a/src/gui/kernel/qplatformeventloopintegration_qpa.h b/src/gui/kernel/qplatformeventloopintegration_qpa.h index a06fecf..6e0f984 100644 --- a/src/gui/kernel/qplatformeventloopintegration_qpa.h +++ b/src/gui/kernel/qplatformeventloopintegration_qpa.h @@ -43,6 +43,7 @@ #define QPLATFORMEVENTLOOPINTEGRATION_QPA_H #include <QtCore/qglobal.h> +#include <QtCore/QScopedPointer> QT_BEGIN_HEADER @@ -50,11 +51,28 @@ QT_BEGIN_NAMESPACE QT_MODULE(Gui) -class QPlatformEventLoopIntegration +class QPlatformEventLoopIntegrationPrivate; + +class Q_GUI_EXPORT QPlatformEventLoopIntegration { + Q_DECLARE_PRIVATE(QPlatformEventLoopIntegration); public: - virtual void processEvents( qint64 msec ) = 0; - virtual void wakeup() = 0; + QPlatformEventLoopIntegration(); + virtual ~QPlatformEventLoopIntegration(); + + virtual void startEventLoop() = 0; + virtual void quitEventLoop() = 0; + virtual void qtNeedsToProcessEvents() = 0; + + qint64 nextTimerEvent() const; + void setNextTimerEvent(qint64 nextTimerEvent); + + static void processEvents(); +protected: + QScopedPointer<QPlatformEventLoopIntegrationPrivate> d_ptr; +private: + Q_DISABLE_COPY(QPlatformEventLoopIntegration); + friend class QEventDispatcherQPA; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoaeventloopintegration.h b/src/plugins/platforms/cocoa/qcocoaeventloopintegration.h index 8c21944..87998e3 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventloopintegration.h +++ b/src/plugins/platforms/cocoa/qcocoaeventloopintegration.h @@ -46,29 +46,20 @@ #include <QPlatformEventLoopIntegration> -@interface OurApplication: NSApplication -{ - bool shouldKeepRunning; -} - -- (void) run; -- (void) processEvents: (int) msec; - -@end class QCocoaEventLoopIntegration : public QPlatformEventLoopIntegration { public: QCocoaEventLoopIntegration(); - void processEvents( qint64 msec ); - void wakeup(); + void startEventLoop(); + void quitEventLoop(); + void qtNeedsToProcessEvents(); - static int wakeupEventId; private: - OurApplication *app; + CFRunLoopSourceContext m_sourceContext; + CFRunLoopTimerContext m_timerContext; + CFRunLoopSourceRef m_source; }; - - #endif // QCOCAEVENTLOOPINTEGRATION_H diff --git a/src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm b/src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm index b184f90..844751c 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm @@ -48,81 +48,65 @@ #include <QtCore/QElapsedTimer> #include <QDebug> +#include <QApplication> -@implementation OurApplication - -- (void) run -{ - QCocoaAutoReleasePool pool; - [self finishLaunching]; - - shouldKeepRunning = YES; +void wakeupCallback ( void * ) { + QPlatformEventLoopIntegration::processEvents(); } -- (void) processEvents : (int) msec +void timerCallback( CFRunLoopTimerRef timer, void *info) { - QCocoaAutoReleasePool pool; - Q_UNUSED(pool); - - QElapsedTimer timer; - timer.start(); - - NSTimeInterval seconds = NSTimeInterval(msec)/1000; - id untilDate = [NSDate dateWithTimeIntervalSinceNow:seconds]; - bool continueLooping = true; - while ((timer.elapsed() < (msec-1)) && continueLooping) { - NSEvent *event = - [self nextEventMatchingMask:NSAnyEventMask - untilDate:untilDate - inMode:NSDefaultRunLoopMode - dequeue:YES]; - if ([event type] == NSApplicationDefined - && [event subtype] == QCocoaEventLoopIntegration::wakeupEventId) { - continueLooping = false; - } else { - [self sendEvent:event]; - } - - } - [self updateWindows]; + QPlatformEventLoopIntegration::processEvents(); + QCocoaEventLoopIntegration *eventLoopIntegration = + static_cast<QCocoaEventLoopIntegration *>(info); + qint64 nextTime = eventLoopIntegration->nextTimerEvent(); + CFAbsoluteTime nexttime = CFAbsoluteTimeGetCurrent(); + nexttime = nexttime + (double(nextTime)/1000); + CFRunLoopTimerSetNextFireDate(timer,nexttime); } -@end - -int QCocoaEventLoopIntegration::wakeupEventId = SHRT_MAX; - QCocoaEventLoopIntegration::QCocoaEventLoopIntegration() : QPlatformEventLoopIntegration() { - app = (OurApplication *)[OurApplication sharedApplication]; - [app run]; + [NSApplication sharedApplication]; + m_sourceContext.version = 0; + m_sourceContext.info = this; + m_sourceContext.retain = 0; + m_sourceContext.release = 0; + m_sourceContext.copyDescription = 0; + m_sourceContext.equal = 0; + m_sourceContext.hash = 0; + m_sourceContext.schedule = 0; + m_sourceContext.cancel = 0; + m_sourceContext.perform = wakeupCallback; + + m_source = CFRunLoopSourceCreate(0,0,&m_sourceContext); + CFRunLoopAddSource(CFRunLoopGetMain(),m_source,kCFRunLoopCommonModes); + + m_timerContext.version = 0; + m_timerContext.info = this; + m_timerContext.retain = 0; + m_timerContext.release = 0; + m_timerContext.copyDescription = 0; + CFAbsoluteTime fireDate = CFAbsoluteTimeGetCurrent (); + CFTimeInterval interval = 30; + + CFRunLoopTimerRef m_timerSource = CFRunLoopTimerCreate(0,fireDate,interval,0,0,timerCallback,&m_timerContext); + CFRunLoopAddTimer(CFRunLoopGetMain(),m_timerSource,kCFRunLoopCommonModes); } -void QCocoaEventLoopIntegration::processEvents(qint64 msec) +void QCocoaEventLoopIntegration::startEventLoop() { - [app processEvents:msec]; + [[NSApplication sharedApplication] run]; } -void QCocoaEventLoopIntegration::wakeup() +void QCocoaEventLoopIntegration::quitEventLoop() { - QCocoaAutoReleasePool pool; - Q_UNUSED(pool); - - NSPoint p = NSMakePoint(0,0); - NSWindow *nswin = [app keyWindow]; - double timestamp = (double)(AbsoluteToDuration(UpTime())) / 1000.0; - NSEvent *event = [NSEvent - otherEventWithType:NSApplicationDefined - location:NSZeroPoint - modifierFlags:0 - timestamp: timestamp - windowNumber:[nswin windowNumber] - context:0 - subtype:QCocoaEventLoopIntegration::wakeupEventId - data1:0 - data2:0 - ]; - [app postEvent:event atStart:NO]; + [[NSApplication sharedApplication] terminate:nil]; +} +void QCocoaEventLoopIntegration::qtNeedsToProcessEvents() +{ + CFRunLoopSourceSignal(m_source); } diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 79d5f51..28e894c 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -79,7 +79,7 @@ QCocoaIntegration::QCocoaIntegration() mPool = new QCocoaAutoReleasePool; //Make sure we have a nsapplication :) - [OurApplication sharedApplication]; + [NSApplication sharedApplication]; // [[OurApplication alloc] init]; NSArray *screens = [NSScreen screens]; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index f004cb8..4e233ee 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -106,11 +106,5 @@ void QCocoaWindow::windowDidResize() //jlind: XXX This isn't ideal. Eventdispatcher does not run when resizing... NSRect rect = [[m_nsWindow contentView]frame]; QRect geo(rect.origin.x,rect.origin.y,rect.size.width,rect.size.height); - if (geometry() != geo) { - widget()->setGeometry(geo); - QResizeEvent e(geo.size(), geometry().size()); - setGeometry(geo); - QApplication::sendEvent(widget(), &e); - widget()->repaint(); - } + QWindowSystemInterface::handleGeometryChange(widget(),geo); } |