]> git.saurik.com Git - wxWidgets.git/blame - src/osx/uiaction_osx.cpp
guarding open combo box against AppDefined NSEvents issued by wxEventLoop::WakeUp...
[wxWidgets.git] / src / osx / uiaction_osx.cpp
CommitLineData
a02a5cfc
KO
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/osx/uiaction_osx.cpp
3// Purpose: wxUIActionSimulator implementation
571d991b 4// Author: Kevin Ollivier, Steven Lamerton, Vadim Zeitlin
a02a5cfc
KO
5// Modified by:
6// Created: 2010-03-06
b5b208a1 7// RCS-ID: $Id$
a02a5cfc 8// Copyright: (c) Kevin Ollivier
571d991b
VZ
9// (c) 2010 Steven Lamerton
10// (c) 2010 Vadim Zeitlin
a02a5cfc
KO
11// Licence: wxWindows licence
12/////////////////////////////////////////////////////////////////////////////
13
d6eb3ff8
SC
14#include "wx/wxprec.h"
15
16#ifndef WX_PRECOMP
17#include "wx/object.h"
18#endif
9b7e0226
VZ
19
20#if wxUSE_UIACTIONSIMULATOR
21
22#include "wx/uiaction.h"
a02a5cfc 23
571d991b
VZ
24#include "wx/log.h"
25
26#include "wx/osx/private.h"
27#include "wx/osx/core/cfref.h"
28
cd0f218c
SC
29#include "wx/evtloop.h"
30
571d991b
VZ
31namespace
32{
eeb7bdd0 33
a02a5cfc
KO
34CGEventTapLocation tap = kCGSessionEventTap;
35
36CGEventType CGEventTypeForMouseButton(int button, bool isDown)
37{
571d991b 38 switch ( button )
a02a5cfc
KO
39 {
40 case wxMOUSE_BTN_LEFT:
571d991b 41 return isDown ? kCGEventLeftMouseDown : kCGEventLeftMouseUp;
9b7e0226 42
571d991b
VZ
43 case wxMOUSE_BTN_RIGHT:
44 return isDown ? kCGEventRightMouseDown : kCGEventRightMouseUp;
9b7e0226 45
571d991b
VZ
46 // All the other buttons use the constant OtherMouseDown but we still
47 // want to check for invalid parameters so assert first
a02a5cfc 48 default:
571d991b
VZ
49 wxFAIL_MSG("Unsupported button passed in.");
50 // fall back to the only known remaining case
51
52 case wxMOUSE_BTN_MIDDLE:
53 return isDown ? kCGEventOtherMouseDown : kCGEventOtherMouseUp;
a02a5cfc
KO
54 }
55}
5ed9f8b2
SC
56
57CGEventType CGEventTypeForMouseDrag(int button)
58{
59 switch ( button )
60 {
61 case wxMOUSE_BTN_LEFT:
62 return kCGEventLeftMouseDragged;
63 break;
64
65 case wxMOUSE_BTN_RIGHT:
66 return kCGEventRightMouseDragged;
67 break;
68
69 // All the other buttons use the constant OtherMouseDown but we still
70 // want to check for invalid parameters so assert first
71 default:
72 wxFAIL_MSG("Unsupported button passed in.");
73 // fall back to the only known remaining case
74
75 case wxMOUSE_BTN_MIDDLE:
76 return kCGEventOtherMouseDragged;
77 break;
78 }
79
80}
a02a5cfc 81
5ed9f8b2
SC
82CGMouseButton CGButtonForMouseButton(int button)
83{
84 switch ( button )
85 {
86 case wxMOUSE_BTN_LEFT:
87 return kCGMouseButtonLeft;
88
89 case wxMOUSE_BTN_RIGHT:
90 return kCGMouseButtonRight;
91
92 // All the other buttons use the constant OtherMouseDown but we still
93 // want to check for invalid parameters so assert first
94 default:
95 wxFAIL_MSG("Unsupported button passed in.");
96 // fall back to the only known remaining case
97
98 case wxMOUSE_BTN_MIDDLE:
99 return kCGMouseButtonCenter;
100 }
101}
102
571d991b 103CGPoint GetMousePosition()
a02a5cfc 104{
571d991b
VZ
105 int x, y;
106 wxGetMousePosition(&x, &y);
107
108 CGPoint pos;
109 pos.x = x;
110 pos.y = y;
111
112 return pos;
113}
114
571d991b
VZ
115} // anonymous namespace
116
a02a5cfc
KO
117bool wxUIActionSimulator::MouseDown(int button)
118{
a02a5cfc 119 CGEventType type = CGEventTypeForMouseButton(button, true);
571d991b 120 wxCFRef<CGEventRef> event(
5ed9f8b2
SC
121 CGEventCreateMouseEvent(NULL, type, GetMousePosition(), CGButtonForMouseButton(button)));
122
123 if ( !event )
124 return false;
125
126 CGEventSetType(event, type);
127 CGEventPost(tap, event);
128 wxCFEventLoop* loop = dynamic_cast<wxCFEventLoop*>(wxEventLoop::GetActive());
129 if (loop)
130 loop->SetShouldWaitForEvent(true);
131
132 return true;
133}
134
135bool wxUIActionSimulator::MouseMove(long x, long y)
136{
137 CGPoint pos;
138 pos.x = x;
139 pos.y = y;
140
141 CGEventType type = kCGEventMouseMoved;
142 wxCFRef<CGEventRef> event(
143 CGEventCreateMouseEvent(NULL, type, pos, kCGMouseButtonLeft));
144
145 if ( !event )
146 return false;
147
148 CGEventSetType(event, type);
149 CGEventPost(tap, event);
150
151 wxCFEventLoop* loop = dynamic_cast<wxCFEventLoop*>(wxEventLoop::GetActive());
152 if (loop)
153 loop->SetShouldWaitForEvent(true);
154
155 return true;
156}
157
158bool wxUIActionSimulator::MouseUp(int button)
159{
160 CGEventType type = CGEventTypeForMouseButton(button, false);
161 wxCFRef<CGEventRef> event(
162 CGEventCreateMouseEvent(NULL, type, GetMousePosition(), CGButtonForMouseButton(button)));
571d991b
VZ
163
164 if ( !event )
165 return false;
166
a02a5cfc 167 CGEventSetType(event, type);
571d991b 168 CGEventPost(tap, event);
cd0f218c
SC
169 wxCFEventLoop* loop = dynamic_cast<wxCFEventLoop*>(wxEventLoop::GetActive());
170 if (loop)
171 loop->SetShouldWaitForEvent(true);
172
173 return true;
174}
175
176bool wxUIActionSimulator::MouseDblClick(int button)
177{
178 CGEventType downtype = CGEventTypeForMouseButton(button, true);
179 CGEventType uptype = CGEventTypeForMouseButton(button, false);
180 wxCFRef<CGEventRef> event(
5ed9f8b2 181 CGEventCreateMouseEvent(NULL, downtype, GetMousePosition(), CGButtonForMouseButton(button)));
cd0f218c
SC
182
183 if ( !event )
184 return false;
185
186 CGEventSetType(event,downtype);
187 CGEventPost(tap, event);
5ed9f8b2 188
cd0f218c
SC
189 CGEventSetType(event, uptype);
190 CGEventPost(tap, event);
191
192 CGEventSetIntegerValueField(event, kCGMouseEventClickState, 2);
193 CGEventSetType(event, downtype);
194 CGEventPost(tap, event);
195
196 CGEventSetType(event, uptype);
197 CGEventPost(tap, event);
198 wxCFEventLoop* loop = dynamic_cast<wxCFEventLoop*>(wxEventLoop::GetActive());
199 if (loop)
200 loop->SetShouldWaitForEvent(true);
201
a02a5cfc
KO
202 return true;
203}
204
5ed9f8b2 205bool wxUIActionSimulator::MouseClickAndDragTo(long x, long y, int button)
a02a5cfc 206{
5ed9f8b2
SC
207 CGEventType downtype = CGEventTypeForMouseButton(button, true);
208 CGEventType uptype = CGEventTypeForMouseButton(button, false);
209 CGEventType dragtype = CGEventTypeForMouseDrag(button) ;
571d991b 210
571d991b 211 wxCFRef<CGEventRef> event(
5ed9f8b2
SC
212 CGEventCreateMouseEvent(NULL, downtype, GetMousePosition(), CGButtonForMouseButton(button)));
213
571d991b
VZ
214 if ( !event )
215 return false;
5ed9f8b2
SC
216
217 CGEventSetType(event,downtype);
571d991b 218 CGEventPost(tap, event);
cd0f218c 219
5ed9f8b2
SC
220 CGPoint pos;
221 pos.x = x;
222 pos.y = y;
223
224 CGEventSetType(event, dragtype);
225 CGEventSetLocation(event,pos);
226 CGEventPost(tap, event);
227
228 CGEventSetType(event, uptype);
571d991b 229 CGEventPost(tap, event);
cd0f218c
SC
230 wxCFEventLoop* loop = dynamic_cast<wxCFEventLoop*>(wxEventLoop::GetActive());
231 if (loop)
232 loop->SetShouldWaitForEvent(true);
233
a02a5cfc
KO
234 return true;
235}
236
03bec791
VZ
237bool
238wxUIActionSimulator::DoKey(int keycode, int WXUNUSED(modifiers), bool isDown)
a02a5cfc 239{
571d991b 240 CGKeyCode cgcode = wxCharCodeWXToOSX((wxKeyCode)keycode);
571d991b 241
37141214
VZ
242 wxCFRef<CGEventRef>
243 event(CGEventCreateKeyboardEvent(NULL, cgcode, isDown));
244 if ( !event )
245 return false;
9b7e0226 246
37141214 247 CGEventPost(kCGHIDEventTap, event);
cd0f218c
SC
248 wxCFEventLoop* loop = dynamic_cast<wxCFEventLoop*>(wxEventLoop::GetActive());
249 if (loop)
250 loop->SetShouldWaitForEvent(true);
251
a02a5cfc
KO
252 return true;
253}
254
9b7e0226 255#endif // wxUSE_UIACTIONSIMULATOR
a02a5cfc 256