]> git.saurik.com Git - wxWidgets.git/blame - src/cocoa/evtloop.mm
mention ShouldInheritColours() change
[wxWidgets.git] / src / cocoa / evtloop.mm
CommitLineData
f5e10026
DE
1///////////////////////////////////////////////////////////////////////////////
2// Name: cocoa/evtloop.mm
3// Purpose: implements wxEventLoop for Cocoa
4// Author: David Elliott
5// Modified by:
6// Created: 2003/10/02
7// RCS-ID: $Id$
8// Copyright: (c) 2003 David Elliott <dfe@cox.net>
9// License: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12#include "wx/wxprec.h"
13#ifndef WX_PRECOMP
14 #include "wx/log.h"
15#endif //WX_PRECOMP
16
17#include "wx/evtloop.h"
18
19#import <AppKit/NSApplication.h>
72ae85dd
DE
20#import <AppKit/NSEvent.h>
21#import <Foundation/NSRunLoop.h>
f5e10026
DE
22
23// ========================================================================
24// wxEventLoopImpl
25// ========================================================================
26
27class WXDLLEXPORT wxEventLoopImpl
28{
29public:
30 // ctor
31 wxEventLoopImpl() { SetExitCode(0); }
32
33 // set/get the exit code
34 void SetExitCode(int exitcode) { m_exitcode = exitcode; }
35 int GetExitCode() const { return m_exitcode; }
36
37private:
38 // the exit code of the event loop
39 int m_exitcode;
40};
41
42// ========================================================================
43// wxEventLoop
44// ========================================================================
45
46// ----------------------------------------------------------------------------
47// wxEventLoop running and exiting
48// ----------------------------------------------------------------------------
49
50wxEventLoop *wxEventLoop::ms_activeLoop = NULL;
51
52wxEventLoop::~wxEventLoop()
53{
54 wxASSERT_MSG( !m_impl, _T("should have been deleted in Run()") );
55}
56
57bool wxEventLoop::IsRunning() const
58{
59 return m_impl;
60}
61
62int wxEventLoop::Run()
63{
64 // event loops are not recursive, you need to create another loop!
65 wxCHECK_MSG( !IsRunning(), -1, _T("can't reenter a message loop") );
66
67 wxEventLoop *oldLoop = ms_activeLoop;
68 ms_activeLoop = this;
69
70 m_impl = new wxEventLoopImpl;
71
72 [[NSApplication sharedApplication] run];
73
74 int exitcode = m_impl->GetExitCode();
75 delete m_impl;
76 m_impl = NULL;
77
78 ms_activeLoop = oldLoop;
79
80 return exitcode;
81}
82
83void wxEventLoop::Exit(int rc)
84{
85 wxCHECK_RET( IsRunning(), _T("can't call Exit() if not running") );
86
87 m_impl->SetExitCode(rc);
88
89 NSApplication *cocoaApp = [NSApplication sharedApplication];
90 wxLogDebug("wxEventLoop::Exit isRunning=%d", (int)[cocoaApp isRunning]);
9670dfc4
DE
91 // This works around a bug in Cocoa.
92 [NSEvent startPeriodicEventsAfterDelay:0.0 withPeriod:5.0];
93 /* Notes:
94 This function is most often called during idle time. See
95 wxApp::CocoaInstallIdleHandler() for an overview of the implications
96 of idle event time. In short, Cocoa must have at least one real event
97 in the queue (of which an idle "event" is not) in order for it to
98 realize that the application has been stopped. The above method
99 generates the first periodic event immediately, and would generate
100 further events every 5 seconds if not for the fact that the next
101 method stops the event loop.
102
103 If the application was active when closed then this is unnecessary
104 because it would receive a deactivate event anyway. However, if the
105 application was not active when closed, then no events would be
106 added to the queue by Cocoa and thus the application would wait
107 indefinitely for the next event.
108 */
f5e10026
DE
109 [cocoaApp stop: cocoaApp];
110}
111
112// ----------------------------------------------------------------------------
113// wxEventLoop message processing dispatching
114// ----------------------------------------------------------------------------
115
116bool wxEventLoop::Pending() const
117{
72ae85dd
DE
118 // a pointer to the event is returned if there is one, or nil if not
119 return [[NSApplication sharedApplication]
120 nextEventMatchingMask: NSAnyEventMask
121 untilDate: nil /* Equivalent to [NSDate distantPast] */
122 inMode: NSDefaultRunLoopMode
123 dequeue: NO];
f5e10026
DE
124}
125
126bool wxEventLoop::Dispatch()
127{
72ae85dd
DE
128 // This check is required by wxGTK but probably not really for wxCocoa
129 // Keep it here to encourage developers to write cross-platform code
f5e10026 130 wxCHECK_MSG( IsRunning(), false, _T("can't call Dispatch() if not running") );
72ae85dd
DE
131 NSApplication *cocoaApp = [NSApplication sharedApplication];
132 // Block to retrieve an event then send it
133 if(NSEvent *event = [cocoaApp
134 nextEventMatchingMask:NSAnyEventMask
135 untilDate:[NSDate distantFuture]
136 inMode:NSDefaultRunLoopMode
137 dequeue: YES])
138 {
139 [cocoaApp sendEvent: event];
140 return true;
141 }
f5e10026
DE
142 return false;
143}
144