streamlining OSX event support third step, using platform specific native run methods for event loops

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@63697 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Stefan Csomor 2010-03-17 07:14:03 +00:00
parent 0e92a846e4
commit 80eee8378f
10 changed files with 221 additions and 46 deletions

View File

@ -185,7 +185,7 @@ protected:
wxDECLARE_NO_COPY_CLASS(wxEventLoopBase);
};
#if defined(__WXMSW__) || defined(__WXMAC__) || defined(__WXDFB__) || defined(__UNIX__)
#if defined(__WXMSW__) || defined(__WXMAC__) || defined(__WXDFB__) || (defined(__UNIX__) && !defined(__WXOSX__))
// this class can be used to implement a standard event loop logic using
// Pending() and Dispatch()
@ -318,7 +318,7 @@ protected:
inline bool wxEventLoopBase::IsRunning() const { return GetActive() == this; }
#if wxUSE_GUI
#if wxUSE_GUI && !defined(__WXOSX__)
// ----------------------------------------------------------------------------
// wxModalEventLoop
// ----------------------------------------------------------------------------

View File

@ -23,6 +23,9 @@ public:
protected:
virtual int DoDispatchTimeout(unsigned long timeout);
virtual void DoRun();
virtual void DoStop();
};
#endif // _WX_MAC_CARBON_EVTLOOP_H_

View File

@ -19,6 +19,9 @@ public:
protected:
virtual int DoDispatchTimeout(unsigned long timeout);
virtual void DoRun();
virtual void DoStop();
};
#endif // _WX_OSX_COCOA_EVTLOOP_H_

View File

@ -59,7 +59,11 @@ protected:
virtual CFRunLoopRef CFGetCurrentRunLoop() const;
virtual int DoDispatchTimeout(unsigned long timeout);
virtual void DoRun();
virtual void DoStop();
// should we exit the loop?
bool m_shouldExit;
@ -68,22 +72,40 @@ protected:
// runloop observer
CFRunLoopObserverRef m_runLoopObserver;
private:
// process all already pending events and dispatch a new one (blocking
// until it appears in the event queue if necessary)
//
// returns the return value of DoDispatchTimeout()
int DoProcessEvents();
};
#if wxUSE_GUI
#ifdef __WXOSX_COCOA__
#include "wx/osx/cocoa/evtloop.h"
#else
#include "wx/osx/carbon/evtloop.h"
#endif
#ifdef __WXOSX_COCOA__
#include "wx/osx/cocoa/evtloop.h"
#else
#include "wx/osx/carbon/evtloop.h"
#endif
class WXDLLIMPEXP_FWD_CORE wxWindow;
class WXDLLIMPEXP_FWD_CORE wxNonOwnedWindow;
class WXDLLIMPEXP_CORE wxModalEventLoop : public wxGUIEventLoop
{
public:
wxModalEventLoop(wxWindow *winModal);
protected:
virtual void DoRun();
virtual void DoStop();
// (in case) the modal window for this event loop
wxNonOwnedWindow* m_modalWindow;
};
#endif // wxUSE_GUI
#endif // _WX_OSX_EVTLOOP_H_

View File

@ -25,7 +25,12 @@ namespace wxPrivate
class PipeIOHandler;
}
class WXDLLIMPEXP_BASE wxConsoleEventLoop : public wxEventLoopManual
class WXDLLIMPEXP_BASE wxConsoleEventLoop
#ifdef __WXOSX__
: public wxEventLoopBase
#else
: public wxEventLoopManual
#endif
{
public:
// initialize the event loop, use IsOk() to check if we were successful

View File

@ -82,7 +82,7 @@ bool wxEventLoopBase::Yield(bool onlyIfNeeded)
}
// wxEventLoopManual is unused in the other ports
#if defined(__WXMSW__) || defined(__WXMAC__) || defined(__WXDFB__) || (defined(__UNIX__) && wxUSE_BASE)
#if defined(__WXMSW__) || defined(__WXDFB__) || ( ( defined(__UNIX__) && !defined(__WXOSX__) ) && wxUSE_BASE)
// ============================================================================
// wxEventLoopManual implementation

View File

@ -55,6 +55,8 @@ static void DispatchAndReleaseEvent(EventRef theEvent)
int wxGUIEventLoop::DoDispatchTimeout(unsigned long timeout)
{
wxMacAutoreleasePool autoreleasepool;
EventRef event;
OSStatus status = ReceiveNextEvent(0, NULL, timeout/1000, true, &event);
switch ( status )
@ -76,3 +78,56 @@ int wxGUIEventLoop::DoDispatchTimeout(unsigned long timeout)
return 1;
}
}
void wxGUIEventLoop::DoRun()
{
wxMacAutoreleasePool autoreleasepool;
RunApplicationEventLoop();
}
void wxGUIEventLoop::DoStop()
{
QuitApplicationEventLoop();
}
void wxModalEventLoop::DoRun()
{
wxMacAutoreleasePool autoreleasepool;
WindowRef windowRef = m_modalWindow->GetWXWindow();
WindowGroupRef windowGroup = NULL;
WindowGroupRef formerParentGroup = NULL;
bool resetGroupParent = false;
// make sure modal dialogs are in the right layer so that they are not covered
if ( m_modalWindow->GetParent() == NULL )
{
windowGroup = GetWindowGroup(windowRef) ;
if ( windowGroup != GetWindowGroupOfClass( kMovableModalWindowClass ) )
{
formerParentGroup = GetWindowGroupParent( windowGroup );
SetWindowGroupParent( windowGroup, GetWindowGroupOfClass( kMovableModalWindowClass ) );
resetGroupParent = true;
}
}
m_modalWindow->SetFocus();
RunAppModalLoopForWindow(windowRef);
if ( resetGroupParent )
{
SetWindowGroupParent( windowGroup , formerParentGroup );
}
}
void wxModalEventLoop::DoStop()
{
wxMacAutoreleasePool autoreleasepool;
WindowRef theWindow = m_modalWindow->GetWXWindow();
QuitAppModalLoopForWindow(theWindow);
}

View File

@ -162,3 +162,40 @@ int wxGUIEventLoop::DoDispatchTimeout(unsigned long timeout)
return 1;
}
void wxGUIEventLoop::DoRun()
{
wxMacAutoreleasePool autoreleasepool;
[NSApp run];
}
void wxGUIEventLoop::DoStop()
{
[NSApp stop:0];
}
void wxModalEventLoop::DoRun()
{
wxMacAutoreleasePool pool;
// If the app hasn't started, flush the event queue
// If we don't do this, the Dock doesn't get the message that
// the app has started so will refuse to activate it.
[NSApplication sharedApplication];
if (![NSApp isRunning])
{
while(NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil inMode:NSDefaultRunLoopMode dequeue:YES])
{
[NSApp sendEvent:event];
}
}
NSWindow* theWindow = m_modalWindow->GetWXWindow();
[NSApp runModalForWindow:theWindow];
}
void wxModalEventLoop::DoStop()
{
[NSApp stopModal];
}

View File

@ -185,6 +185,7 @@ void wxCFEventLoop::ObserverCallBack(CFRunLoopObserverRef observer, int activity
wxCFEventLoop::wxCFEventLoop()
{
m_shouldExit = false;
CFRunLoopObserverContext ctxt;
bzero( &ctxt, sizeof(ctxt) );
ctxt.info = this;
@ -272,8 +273,6 @@ int wxCFEventLoop::DispatchTimeout(unsigned long timeout)
if ( !wxTheApp )
return 0;
wxMacAutoreleasePool autoreleasepool;
int status = DoDispatchTimeout(timeout);
switch( status )
@ -313,6 +312,32 @@ int wxCFEventLoop::DoDispatchTimeout(unsigned long timeout)
return 1;
}
void wxCFEventLoop::DoRun()
{
for ( ;; )
{
// generate and process idle events for as long as we don't
// have anything else to do
DoProcessEvents();
// if the "should exit" flag is set, the loop should terminate
// but not before processing any remaining messages so while
// Pending() returns true, do process them
if ( m_shouldExit )
{
while ( DoProcessEvents() == 1 )
;
break;
}
}
}
void wxCFEventLoop::DoStop()
{
CFRunLoopStop(CFGetCurrentRunLoop());
}
// enters a loop calling OnNextIteration(), Pending() and Dispatch() and
// terminating when Exit() is called
int wxCFEventLoop::Run()
@ -336,23 +361,8 @@ int wxCFEventLoop::Run()
try
{
#endif // wxUSE_EXCEPTIONS
for ( ;; )
{
// generate and process idle events for as long as we don't
// have anything else to do
DoProcessEvents();
// if the "should exit" flag is set, the loop should terminate
// but not before processing any remaining messages so while
// Pending() returns true, do process them
if ( m_shouldExit )
{
while ( DoProcessEvents() == 1 )
;
break;
}
}
DoRun();
#if wxUSE_EXCEPTIONS
// exit the outer loop as well
@ -390,6 +400,29 @@ void wxCFEventLoop::Exit(int rc)
{
m_exitcode = rc;
m_shouldExit = true;
DoStop();
}
#if wxUSE_GUI
wxModalEventLoop::wxModalEventLoop(wxWindow *winModal)
{
m_modalWindow = dynamic_cast<wxNonOwnedWindow*> (winModal);
wxASSERT_MSG( m_modalWindow != NULL, "must pass in a toplevel window for modal event loop" );
}
#ifdef __WXOSX_IPHONE__
void wxModalEventLoop::DoRun()
{
// presentModalViewController:animated:
}
void wxModalEventLoop::DoStop()
{
// (void)dismissModalViewControllerAnimated:(BOOL)animated
}
#endif // wxUSE_GUI
#endif

View File

@ -75,26 +75,43 @@ static int CalculateUIEventMaskFromEventCategory(wxEventCategory cat)
}
*/
@interface wxAppDelegate : NSObject <UIApplicationDelegate> {
}
@end
@implementation wxAppDelegate
- (void)applicationDidFinishLaunching:(UIApplication *)application {
wxTheApp->OnInit();
}
- (void)applicationWillTerminate:(UIApplication *)application {
wxCloseEvent event;
wxTheApp->OnEndSession(event);
}
- (void)dealloc {
[super dealloc];
}
@end
wxGUIEventLoop::wxGUIEventLoop()
{
m_sleepTime = 0.0;
}
int wxGUIEventLoop::DoDispatchTimeout(unsigned long timeout)
void wxGUIEventLoop::DoRun()
{
wxMacAutoreleasePool autoreleasepool;
/*
UIEvent *event = [[UIApplication sharedApplication]
nextEventMatchingMask:NSAnyEventMask
untilDate:[NSDate dateWithTimeIntervalSinceNow: timeout/1000]
inMode:NSDefaultRunLoopMode
dequeue: YES];
if ( event == nil )
return -1;
[NSApp sendEvent: event];
*/
return 1;
if ( IsMain() )
{
wxMacAutoreleasePool pool;
const char* appname = "app";
UIApplicationMain( 1, (char**) &appname, nil, @"wxAppDelegate" );
}
else
{
wxCFEventLoop::DoRun();
}
}