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