]> git.saurik.com Git - wxWidgets.git/blame - src/cocoa/evtloop.mm
use reserve() instead of Alloc() in WX_APPEND_ARRAY so that it works with std classes too
[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>
065e208e 9// License: wxWidgets licence
f5e10026
DE
10///////////////////////////////////////////////////////////////////////////////
11
12#include "wx/wxprec.h"
13#ifndef WX_PRECOMP
14 #include "wx/log.h"
eb537cfb 15 #include "wx/app.h"
f5e10026
DE
16#endif //WX_PRECOMP
17
18#include "wx/evtloop.h"
19
20#import <AppKit/NSApplication.h>
72ae85dd
DE
21#import <AppKit/NSEvent.h>
22#import <Foundation/NSRunLoop.h>
f5e10026
DE
23
24// ========================================================================
25// wxEventLoopImpl
26// ========================================================================
27
28class WXDLLEXPORT wxEventLoopImpl
29{
30public:
31 // ctor
32 wxEventLoopImpl() { SetExitCode(0); }
33
34 // set/get the exit code
35 void SetExitCode(int exitcode) { m_exitcode = exitcode; }
36 int GetExitCode() const { return m_exitcode; }
37
38private:
39 // the exit code of the event loop
40 int m_exitcode;
41};
42
43// ========================================================================
b46b1d59 44// wxGUIEventLoop
f5e10026
DE
45// ========================================================================
46
47// ----------------------------------------------------------------------------
b46b1d59 48// wxGUIEventLoop running and exiting
f5e10026
DE
49// ----------------------------------------------------------------------------
50
b46b1d59 51wxGUIEventLoop::~wxGUIEventLoop()
f5e10026
DE
52{
53 wxASSERT_MSG( !m_impl, _T("should have been deleted in Run()") );
54}
55
b46b1d59 56int wxGUIEventLoop::Run()
f5e10026
DE
57{
58 // event loops are not recursive, you need to create another loop!
59 wxCHECK_MSG( !IsRunning(), -1, _T("can't reenter a message loop") );
60
77fb1a02 61 wxEventLoopActivator activate(this);
f5e10026
DE
62
63 m_impl = new wxEventLoopImpl;
64
65 [[NSApplication sharedApplication] run];
66
16d17da6
VZ
67 OnExit();
68
f5e10026
DE
69 int exitcode = m_impl->GetExitCode();
70 delete m_impl;
71 m_impl = NULL;
72
f5e10026
DE
73 return exitcode;
74}
75
b46b1d59 76void wxGUIEventLoop::Exit(int rc)
f5e10026
DE
77{
78 wxCHECK_RET( IsRunning(), _T("can't call Exit() if not running") );
79
80 m_impl->SetExitCode(rc);
81
82 NSApplication *cocoaApp = [NSApplication sharedApplication];
48580976 83 wxLogTrace(wxTRACE_COCOA,wxT("wxEventLoop::Exit isRunning=%d"), (int)[cocoaApp isRunning]);
eb537cfb 84 wxTheApp->WakeUpIdle();
9670dfc4 85 /* Notes:
eb537cfb
DE
86 If we're being called from idle time (which occurs while checking the
87 queue for new events) there may or may not be any events in the queue.
88 In order to successfully stop the event loop, at least one event must
89 be processed. To ensure this always happens, WakeUpIdle is called.
9670dfc4
DE
90
91 If the application was active when closed then this is unnecessary
92 because it would receive a deactivate event anyway. However, if the
93 application was not active when closed, then no events would be
94 added to the queue by Cocoa and thus the application would wait
95 indefinitely for the next event.
96 */
f5e10026
DE
97 [cocoaApp stop: cocoaApp];
98}
99
100// ----------------------------------------------------------------------------
101// wxEventLoop message processing dispatching
102// ----------------------------------------------------------------------------
103
b46b1d59 104bool wxGUIEventLoop::Pending() const
f5e10026 105{
72ae85dd
DE
106 // a pointer to the event is returned if there is one, or nil if not
107 return [[NSApplication sharedApplication]
108 nextEventMatchingMask: NSAnyEventMask
109 untilDate: nil /* Equivalent to [NSDate distantPast] */
110 inMode: NSDefaultRunLoopMode
111 dequeue: NO];
f5e10026
DE
112}
113
b46b1d59 114bool wxGUIEventLoop::Dispatch()
f5e10026 115{
72ae85dd
DE
116 // This check is required by wxGTK but probably not really for wxCocoa
117 // Keep it here to encourage developers to write cross-platform code
f5e10026 118 wxCHECK_MSG( IsRunning(), false, _T("can't call Dispatch() if not running") );
72ae85dd
DE
119 NSApplication *cocoaApp = [NSApplication sharedApplication];
120 // Block to retrieve an event then send it
121 if(NSEvent *event = [cocoaApp
122 nextEventMatchingMask:NSAnyEventMask
123 untilDate:[NSDate distantFuture]
124 inMode:NSDefaultRunLoopMode
125 dequeue: YES])
126 {
127 [cocoaApp sendEvent: event];
128 return true;
129 }
f5e10026
DE
130 return false;
131}
132