]> git.saurik.com Git - wxWidgets.git/blob - src/osx/cocoa/evtloop.mm
making GetPosition 1:1 symmetrical to Move (respecting contentViews), fixing borderDr...
[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 #include "wx/nonownedwnd.h"
32 #endif // WX_PRECOMP
33
34 #include "wx/log.h"
35
36 #include "wx/osx/private.h"
37
38 // ============================================================================
39 // wxEventLoop implementation
40 // ============================================================================
41
42 /*
43 static int CalculateNSEventMaskFromEventCategory(wxEventCategory cat)
44 {
45 NSLeftMouseDownMask |
46 NSLeftMouseUpMask |
47 NSRightMouseDownMask |
48 NSRightMouseUpMask = 1 << NSRightMouseUp,
49 NSMouseMovedMask = 1 << NSMouseMoved,
50 NSLeftMouseDraggedMask = 1 << NSLeftMouseDragged,
51 NSRightMouseDraggedMask = 1 << NSRightMouseDragged,
52 NSMouseEnteredMask = 1 << NSMouseEntered,
53 NSMouseExitedMask = 1 << NSMouseExited,
54 NSScrollWheelMask = 1 << NSScrollWheel,
55 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
56 NSTabletPointMask = 1 << NSTabletPoint,
57 NSTabletProximityMask = 1 << NSTabletProximity,
58 #endif
59 NSOtherMouseDownMask = 1 << NSOtherMouseDown,
60 NSOtherMouseUpMask = 1 << NSOtherMouseUp,
61 NSOtherMouseDraggedMask = 1 << NSOtherMouseDragged,
62
63
64
65 NSKeyDownMask = 1 << NSKeyDown,
66 NSKeyUpMask = 1 << NSKeyUp,
67 NSFlagsChangedMask = 1 << NSFlagsChanged,
68
69 NSAppKitDefinedMask = 1 << NSAppKitDefined,
70 NSSystemDefinedMask = 1 << NSSystemDefined,
71 NSApplicationDefinedMask = 1 << NSApplicationDefined,
72 NSPeriodicMask = 1 << NSPeriodic,
73 NSCursorUpdateMask = 1 << NSCursorUpdate,
74
75 NSAnyEventMask = 0xffffffffU
76 }
77 */
78
79 wxGUIEventLoop::wxGUIEventLoop()
80 {
81 }
82
83 //-----------------------------------------------------------------------------
84 // events dispatch and loop handling
85 //-----------------------------------------------------------------------------
86
87 #if 0
88
89 bool wxGUIEventLoop::Pending() const
90 {
91 #if 0
92 // this code doesn't reliably detect pending events
93 // so better return true and have the dispatch deal with it
94 // as otherwise we end up in a tight loop when idle events are responded
95 // to by RequestMore(true)
96 wxMacAutoreleasePool autoreleasepool;
97
98 return [[NSApplication sharedApplication]
99 nextEventMatchingMask: NSAnyEventMask
100 untilDate: nil
101 inMode: NSDefaultRunLoopMode
102 dequeue: NO] != nil;
103 #else
104 return true;
105 #endif
106 }
107
108 bool wxGUIEventLoop::Dispatch()
109 {
110 if ( !wxTheApp )
111 return false;
112
113 wxMacAutoreleasePool autoreleasepool;
114
115 if(NSEvent *event = [NSApp
116 nextEventMatchingMask:NSAnyEventMask
117 untilDate:[NSDate dateWithTimeIntervalSinceNow: m_sleepTime]
118 inMode:NSDefaultRunLoopMode
119 dequeue: YES])
120 {
121 WXEVENTREF formerEvent = wxTheApp == NULL ? NULL : wxTheApp->MacGetCurrentEvent();
122 WXEVENTHANDLERCALLREF formerHandler = wxTheApp == NULL ? NULL : wxTheApp->MacGetCurrentEventHandlerCallRef();
123
124 if (wxTheApp)
125 wxTheApp->MacSetCurrentEvent(event, NULL);
126 m_sleepTime = 0.0;
127 [NSApp sendEvent: event];
128
129 if (wxTheApp)
130 wxTheApp->MacSetCurrentEvent(formerEvent , formerHandler);
131 }
132 else
133 {
134 if (wxTheApp)
135 wxTheApp->ProcessPendingEvents();
136
137 if ( wxTheApp->ProcessIdle() )
138 m_sleepTime = 0.0 ;
139 else
140 {
141 m_sleepTime = 1.0;
142 #if wxUSE_THREADS
143 wxMutexGuiLeave();
144 wxMilliSleep(20);
145 wxMutexGuiEnter();
146 #endif
147 }
148 }
149
150 return true;
151 }
152
153 #endif
154
155 int wxGUIEventLoop::DoDispatchTimeout(unsigned long timeout)
156 {
157 wxMacAutoreleasePool autoreleasepool;
158
159 NSEvent *event = [NSApp
160 nextEventMatchingMask:NSAnyEventMask
161 untilDate:[NSDate dateWithTimeIntervalSinceNow: timeout/1000]
162 inMode:NSDefaultRunLoopMode
163 dequeue: YES];
164
165 if ( event == nil )
166 return -1;
167
168 [NSApp sendEvent: event];
169
170 return 1;
171 }
172
173 void wxGUIEventLoop::DoRun()
174 {
175 wxMacAutoreleasePool autoreleasepool;
176 [NSApp run];
177 }
178
179 void wxGUIEventLoop::DoStop()
180 {
181 [NSApp stop:0];
182 // only calling stop: is not enough when called from a runloop-observer,
183 // therefore add a dummy event, to make sure the runloop gets another round
184 NSEvent *event = [NSEvent otherEventWithType:NSApplicationDefined
185 location:NSMakePoint(0.0, 0.0)
186 modifierFlags:0
187 timestamp:0
188 windowNumber:0
189 context:nil
190 subtype:0 data1:0 data2:0];
191 [NSApp postEvent:event atStart:FALSE];
192 }
193
194 CFRunLoopRef wxGUIEventLoop::CFGetCurrentRunLoop() const
195 {
196 NSRunLoop* nsloop = [NSRunLoop currentRunLoop];
197 return [nsloop getCFRunLoop];
198 }
199
200
201 // TODO move into a evtloop_osx.cpp
202
203 wxModalEventLoop::wxModalEventLoop(wxWindow *modalWindow)
204 {
205 m_modalWindow = dynamic_cast<wxNonOwnedWindow*> (modalWindow);
206 wxASSERT_MSG( m_modalWindow != NULL, "must pass in a toplevel window for modal event loop" );
207 m_modalNativeWindow = m_modalWindow->GetWXWindow();
208 }
209
210 wxModalEventLoop::wxModalEventLoop(WXWindow modalNativeWindow)
211 {
212 m_modalWindow = NULL;
213 wxASSERT_MSG( modalNativeWindow != NULL, "must pass in a toplevel window for modal event loop" );
214 m_modalNativeWindow = modalNativeWindow;
215 }
216
217 // END move into a evtloop_osx.cpp
218
219 void wxModalEventLoop::DoRun()
220 {
221 wxMacAutoreleasePool pool;
222
223 // If the app hasn't started, flush the event queue
224 // If we don't do this, the Dock doesn't get the message that
225 // the app has started so will refuse to activate it.
226 [NSApplication sharedApplication];
227 if (![NSApp isRunning])
228 {
229 while(NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil inMode:NSDefaultRunLoopMode dequeue:YES])
230 {
231 [NSApp sendEvent:event];
232 }
233 }
234
235 [NSApp runModalForWindow:m_modalNativeWindow];
236 }
237
238 void wxModalEventLoop::DoStop()
239 {
240 [NSApp stopModal];
241 }
242