streamlining OSX event support third step, using platform specific native run methods...
[wxWidgets.git] / src / osx / cocoa / evtloop.mm
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        src/osx/cocoa/evtloop.mm
3 // Purpose:     implementation of wxEventLoop for OS X
4 // Author:      Vadim Zeitlin, Stefan Csomor
5 // Modified by:
6 // Created:     2006-01-12
7 // RCS-ID:      $Id: evtloop.cpp 54845 2008-07-30 14:52:41Z SC $
8 // Copyright:   (c) 2006 Vadim Zeitlin <vadim@wxwindows.org>
9 // Licence:     wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // for compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24     #pragma hdrstop
25 #endif
26
27 #include "wx/evtloop.h"
28
29 #ifndef WX_PRECOMP
30     #include "wx/app.h"
31 #endif // WX_PRECOMP
32
33 #include "wx/log.h"
34
35 #include "wx/osx/private.h"
36
37 // ============================================================================
38 // wxEventLoop implementation
39 // ============================================================================
40
41 /*
42 static int CalculateNSEventMaskFromEventCategory(wxEventCategory cat)
43 {
44         NSLeftMouseDownMask     |
45         NSLeftMouseUpMask |
46         NSRightMouseDownMask |
47         NSRightMouseUpMask              = 1 << NSRightMouseUp,
48         NSMouseMovedMask                = 1 << NSMouseMoved,
49         NSLeftMouseDraggedMask          = 1 << NSLeftMouseDragged,
50         NSRightMouseDraggedMask         = 1 << NSRightMouseDragged,
51         NSMouseEnteredMask              = 1 << NSMouseEntered,
52         NSMouseExitedMask               = 1 << NSMouseExited,
53         NSScrollWheelMask               = 1 << NSScrollWheel,
54 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
55         NSTabletPointMask               = 1 << NSTabletPoint,
56         NSTabletProximityMask           = 1 << NSTabletProximity,
57 #endif
58         NSOtherMouseDownMask            = 1 << NSOtherMouseDown,
59         NSOtherMouseUpMask              = 1 << NSOtherMouseUp,
60         NSOtherMouseDraggedMask         = 1 << NSOtherMouseDragged,
61
62
63
64         NSKeyDownMask                   = 1 << NSKeyDown,
65         NSKeyUpMask                     = 1 << NSKeyUp,
66         NSFlagsChangedMask              = 1 << NSFlagsChanged,
67
68         NSAppKitDefinedMask             = 1 << NSAppKitDefined,
69         NSSystemDefinedMask             = 1 << NSSystemDefined,
70         NSApplicationDefinedMask        = 1 << NSApplicationDefined,
71         NSPeriodicMask                  = 1 << NSPeriodic,
72         NSCursorUpdateMask              = 1 << NSCursorUpdate,
73
74         NSAnyEventMask                  = 0xffffffffU
75 }
76 */
77
78 wxGUIEventLoop::wxGUIEventLoop()
79 {
80 }
81
82 //-----------------------------------------------------------------------------
83 // events dispatch and loop handling
84 //-----------------------------------------------------------------------------
85
86 #if 0
87
88 bool wxGUIEventLoop::Pending() const
89 {
90 #if 0
91     // this code doesn't reliably detect pending events
92     // so better return true and have the dispatch deal with it
93     // as otherwise we end up in a tight loop when idle events are responded
94     // to by RequestMore(true)
95     wxMacAutoreleasePool autoreleasepool;
96   
97     return [[NSApplication sharedApplication]
98             nextEventMatchingMask: NSAnyEventMask
99             untilDate: nil
100             inMode: NSDefaultRunLoopMode
101             dequeue: NO] != nil;
102 #else
103     return true;
104 #endif
105 }
106
107 bool wxGUIEventLoop::Dispatch()
108 {
109     if ( !wxTheApp )
110         return false;
111
112     wxMacAutoreleasePool autoreleasepool;
113
114     if(NSEvent *event = [NSApp
115                 nextEventMatchingMask:NSAnyEventMask
116                 untilDate:[NSDate dateWithTimeIntervalSinceNow: m_sleepTime]
117                 inMode:NSDefaultRunLoopMode
118                 dequeue: YES])
119     {
120         if (wxTheApp)
121             wxTheApp->MacSetCurrentEvent(event, NULL);
122         m_sleepTime = 0.0;
123         [NSApp sendEvent: event];
124     }
125     else
126     {
127         if (wxTheApp)
128             wxTheApp->ProcessPendingEvents();
129         
130         if ( wxTheApp->ProcessIdle() )
131             m_sleepTime = 0.0 ;
132         else
133         {
134             m_sleepTime = 1.0;
135 #if wxUSE_THREADS
136             wxMutexGuiLeave();
137             wxMilliSleep(20);
138             wxMutexGuiEnter();
139 #endif
140         }
141     }
142
143     return true;
144 }
145
146 #endif
147
148 int wxGUIEventLoop::DoDispatchTimeout(unsigned long timeout)
149 {
150     wxMacAutoreleasePool autoreleasepool;
151
152     NSEvent *event = [NSApp
153                 nextEventMatchingMask:NSAnyEventMask
154                 untilDate:[NSDate dateWithTimeIntervalSinceNow: timeout/1000]
155                 inMode:NSDefaultRunLoopMode
156                 dequeue: YES];
157     
158     if ( event == nil )
159         return -1;
160
161     [NSApp sendEvent: event];
162
163     return 1;
164 }
165
166 void wxGUIEventLoop::DoRun()
167 {
168     wxMacAutoreleasePool autoreleasepool;
169     [NSApp run];
170 }
171
172 void wxGUIEventLoop::DoStop()
173 {
174     [NSApp stop:0];
175 }
176
177 void wxModalEventLoop::DoRun()
178 {
179     wxMacAutoreleasePool pool;
180
181     // If the app hasn't started, flush the event queue
182     // If we don't do this, the Dock doesn't get the message that
183     // the app has started so will refuse to activate it.
184     [NSApplication sharedApplication];
185     if (![NSApp isRunning])
186     {
187         while(NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil inMode:NSDefaultRunLoopMode dequeue:YES])
188         {
189             [NSApp sendEvent:event];
190         }
191     }
192     
193     NSWindow* theWindow = m_modalWindow->GetWXWindow();
194     [NSApp runModalForWindow:theWindow];
195 }
196
197 void wxModalEventLoop::DoStop()
198 {
199     [NSApp stopModal];
200 }
201