]> git.saurik.com Git - wxWidgets.git/blob - src/osx/carbon/evtloop.cpp
always use hw-accel, fixes #15536, applied with thanks
[wxWidgets.git] / src / osx / carbon / evtloop.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/carbon/evtloop.cpp
3 // Purpose: implementation of wxEventLoop for wxMac
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 2006-01-12
7 // Copyright: (c) 2006 Vadim Zeitlin <vadim@wxwindows.org>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 // for compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #include "wx/evtloop.h"
27
28 #ifndef WX_PRECOMP
29 #include "wx/app.h"
30 #include "wx/log.h"
31 #endif // WX_PRECOMP
32
33 #if wxUSE_GUI
34 #include "wx/nonownedwnd.h"
35 #endif
36
37 #include "wx/osx/private.h"
38
39 // ============================================================================
40 // wxEventLoop implementation
41 // ============================================================================
42
43 wxGUIEventLoop::wxGUIEventLoop()
44 {
45 }
46
47 static void DispatchAndReleaseEvent(EventRef theEvent)
48 {
49 if ( wxTheApp )
50 wxTheApp->MacSetCurrentEvent( theEvent, NULL );
51
52 OSStatus status = SendEventToEventTarget(theEvent, GetEventDispatcherTarget());
53 if (status == eventNotHandledErr && wxTheApp)
54 wxTheApp->MacHandleUnhandledEvent(theEvent);
55
56 ReleaseEvent( theEvent );
57 }
58
59 int wxGUIEventLoop::DoDispatchTimeout(unsigned long timeout)
60 {
61 wxMacAutoreleasePool autoreleasepool;
62
63 EventRef event;
64 OSStatus status = ReceiveNextEvent(0, NULL, timeout/1000, true, &event);
65 switch ( status )
66 {
67 default:
68 wxFAIL_MSG( "unexpected ReceiveNextEvent() error" );
69 // fall through
70
71 case eventLoopTimedOutErr:
72 return -1;
73
74 case eventLoopQuitErr:
75 // according to QA1061 this may also occur
76 // when a WakeUp Process is executed
77 return 0;
78
79 case noErr:
80 DispatchAndReleaseEvent(event);
81 return 1;
82 }
83 }
84
85 void wxGUIEventLoop::WakeUp()
86 {
87 OSStatus err = noErr;
88 wxMacCarbonEvent wakeupEvent;
89 wakeupEvent.Create( 'WXMC', 'WXMC', GetCurrentEventTime(),
90 kEventAttributeNone );
91 err = PostEventToQueue(GetMainEventQueue(), wakeupEvent,
92 kEventPriorityHigh );
93 }
94
95 void wxGUIEventLoop::OSXDoRun()
96 {
97 wxMacAutoreleasePool autoreleasepool;
98
99 while (!m_shouldExit)
100 {
101 RunApplicationEventLoop();
102 }
103
104 // Force enclosing event loop to temporarily exit and check
105 // if it should be stopped.
106 QuitApplicationEventLoop();
107 }
108
109 void wxGUIEventLoop::OSXDoStop()
110 {
111 QuitApplicationEventLoop();
112 }
113
114 CFRunLoopRef wxGUIEventLoop::CFGetCurrentRunLoop() const
115 {
116 return wxCFEventLoop::CFGetCurrentRunLoop();
117 }
118
119 // TODO move into a evtloop_osx.cpp
120
121 wxModalEventLoop::wxModalEventLoop(wxWindow *modalWindow)
122 {
123 m_modalWindow = wxDynamicCast(modalWindow, wxNonOwnedWindow);
124 wxASSERT_MSG( m_modalWindow != NULL, "must pass in a toplevel window for modal event loop" );
125 m_modalNativeWindow = m_modalWindow->GetWXWindow();
126 }
127
128 wxModalEventLoop::wxModalEventLoop(WXWindow modalNativeWindow)
129 {
130 m_modalWindow = NULL;
131 wxASSERT_MSG( modalNativeWindow != NULL, "must pass in a toplevel window for modal event loop" );
132 m_modalNativeWindow = modalNativeWindow;
133 }
134
135 // END move into a evtloop_osx.cpp
136
137 void wxModalEventLoop::OSXDoRun()
138 {
139 wxWindowDisabler disabler(m_modalWindow);
140 wxMacAutoreleasePool autoreleasepool;
141
142 bool resetGroupParent = false;
143
144 WindowGroupRef windowGroup = NULL;
145 WindowGroupRef formerParentGroup = NULL;
146
147 // make sure modal dialogs are in the right layer so that they are not covered
148 if ( m_modalWindow != NULL )
149 {
150 if ( m_modalWindow->GetParent() == NULL )
151 {
152 windowGroup = GetWindowGroup(m_modalNativeWindow) ;
153 if ( windowGroup != GetWindowGroupOfClass( kMovableModalWindowClass ) )
154 {
155 formerParentGroup = GetWindowGroupParent( windowGroup );
156 SetWindowGroupParent( windowGroup, GetWindowGroupOfClass( kMovableModalWindowClass ) );
157 resetGroupParent = true;
158 }
159 }
160 }
161
162 m_modalWindow->SetFocus();
163
164 RunAppModalLoopForWindow(m_modalNativeWindow);
165
166 if ( resetGroupParent )
167 {
168 SetWindowGroupParent( windowGroup , formerParentGroup );
169 }
170
171 }
172
173 void wxModalEventLoop::OSXDoStop()
174 {
175 wxMacAutoreleasePool autoreleasepool;
176 QuitAppModalLoopForWindow(m_modalNativeWindow);
177 }
178
179