diff options
author | pierre lamot <pierre.lamot@openwide.fr> | 2015-02-19 16:34:33 +0100 |
---|---|---|
committer | Cedric BAIL <cedric@osg.samsung.com> | 2015-03-12 07:43:59 +0100 |
commit | ae4389a7bd8a6807c3df041cde7c1357b0c13a0c (patch) | |
tree | ec3507e606c11b4759c4e369a83a18c8e873b597 /src/lib/ecore_cocoa | |
parent | d9830a199fc1dc755b4091cc4194942f2d3e3670 (diff) |
ecore_cocoa: fix keyboad event handling
This patch allows to interpret correctly several types of key combinations:
- alt keys : € œ ¬
- dead keys : ä ë
- dead keys (bis, they are handled differently) : ~ ã
- control keys: ^C ^A
- page up/ page down
@fix
Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
Diffstat (limited to 'src/lib/ecore_cocoa')
-rw-r--r-- | src/lib/ecore_cocoa/Ecore_Cocoa_Keys.h | 4 | ||||
-rw-r--r-- | src/lib/ecore_cocoa/ecore_cocoa.m | 150 |
2 files changed, 79 insertions, 75 deletions
diff --git a/src/lib/ecore_cocoa/Ecore_Cocoa_Keys.h b/src/lib/ecore_cocoa/Ecore_Cocoa_Keys.h index f66ae9188e..89004d2b00 100644 --- a/src/lib/ecore_cocoa/Ecore_Cocoa_Keys.h +++ b/src/lib/ecore_cocoa/Ecore_Cocoa_Keys.h | |||
@@ -240,8 +240,8 @@ static const struct _ecore_cocoa_keys_s keystable[] = | |||
240 | { NSInsertFunctionKey, "Insert", "" }, | 240 | { NSInsertFunctionKey, "Insert", "" }, |
241 | { NSHomeFunctionKey, "Home", "" }, | 241 | { NSHomeFunctionKey, "Home", "" }, |
242 | { NSEndFunctionKey, "End", "" }, | 242 | { NSEndFunctionKey, "End", "" }, |
243 | { NSPageUpFunctionKey, "Page_Up", "" }, | 243 | { NSPageUpFunctionKey, "Prior", "" }, |
244 | { NSPageDownFunctionKey, "Page_Down", "" }, | 244 | { NSPageDownFunctionKey, "Next", "" }, |
245 | { NSDeleteFunctionKey, "Delete", "\010"}, | 245 | { NSDeleteFunctionKey, "Delete", "\010"}, |
246 | 246 | ||
247 | { NSF1FunctionKey, "F1", "" }, | 247 | { NSF1FunctionKey, "F1", "" }, |
diff --git a/src/lib/ecore_cocoa/ecore_cocoa.m b/src/lib/ecore_cocoa/ecore_cocoa.m index 60229b774d..4f1b01fe91 100644 --- a/src/lib/ecore_cocoa/ecore_cocoa.m +++ b/src/lib/ecore_cocoa/ecore_cocoa.m | |||
@@ -86,7 +86,7 @@ _ecore_cocoa_event_modifiers(unsigned int mod) | |||
86 | 86 | ||
87 | if(mod & NSShiftKeyMask) modifiers |= ECORE_EVENT_MODIFIER_SHIFT; | 87 | if(mod & NSShiftKeyMask) modifiers |= ECORE_EVENT_MODIFIER_SHIFT; |
88 | if(mod & NSControlKeyMask) modifiers |= ECORE_EVENT_MODIFIER_CTRL; | 88 | if(mod & NSControlKeyMask) modifiers |= ECORE_EVENT_MODIFIER_CTRL; |
89 | if(mod & NSAlternateKeyMask) modifiers |= ECORE_EVENT_MODIFIER_ALT; | 89 | if(mod & NSAlternateKeyMask) modifiers |= ECORE_EVENT_MODIFIER_ALTGR; |
90 | if(mod & NSCommandKeyMask) modifiers |= ECORE_EVENT_MODIFIER_WIN; | 90 | if(mod & NSCommandKeyMask) modifiers |= ECORE_EVENT_MODIFIER_WIN; |
91 | if(mod & NSNumericPadKeyMask) modifiers |= ECORE_EVENT_LOCK_NUM; | 91 | if(mod & NSNumericPadKeyMask) modifiers |= ECORE_EVENT_LOCK_NUM; |
92 | 92 | ||
@@ -94,6 +94,63 @@ _ecore_cocoa_event_modifiers(unsigned int mod) | |||
94 | return modifiers; | 94 | return modifiers; |
95 | } | 95 | } |
96 | 96 | ||
97 | |||
98 | static inline Ecore_Event_Key* | ||
99 | _ecore_cocoa_event_key(NSEvent *event, int keyType) | ||
100 | { | ||
101 | static Eina_Bool compose = EINA_FALSE; | ||
102 | static NSText *edit; | ||
103 | unsigned int i; | ||
104 | |||
105 | Ecore_Event_Key *ev; | ||
106 | |||
107 | EcoreCocoaWindow *window = (EcoreCocoaWindow *)[event window]; | ||
108 | NSString *keychar = [event charactersIgnoringModifiers]; | ||
109 | NSString *keycharRaw = [event characters]; | ||
110 | |||
111 | ev = calloc(1, sizeof (Ecore_Event_Key)); | ||
112 | if (!ev) return NULL; | ||
113 | |||
114 | if (compose && keyType == NSKeyDown) | ||
115 | { | ||
116 | [edit interpretKeyEvents:[NSArray arrayWithObject:event]]; | ||
117 | compose=EINA_FALSE; | ||
118 | } | ||
119 | |||
120 | ev->modifiers = _ecore_cocoa_event_modifiers([event modifierFlags]); | ||
121 | |||
122 | ev->keycode = event.keyCode; | ||
123 | ev->string = [keycharRaw cStringUsingEncoding:NSUTF8StringEncoding]; | ||
124 | ev->compose = ev->string; | ||
125 | |||
126 | ev->window = (Ecore_Window)window.ecore_window_data; | ||
127 | ev->event_window = ev->window; | ||
128 | |||
129 | if ([keychar length] > 0) | ||
130 | { | ||
131 | for (i = 0; i < sizeof (keystable) / sizeof (struct _ecore_cocoa_keys_s); ++i) | ||
132 | { | ||
133 | if (keystable[i].code == [keychar characterAtIndex:0]) | ||
134 | { | ||
135 | ev->keyname = keystable[i].name; | ||
136 | ev->key = ev->keyname; | ||
137 | break; | ||
138 | } | ||
139 | } | ||
140 | } | ||
141 | |||
142 | if ([keycharRaw length] == 0 && keyType == NSKeyDown) | ||
143 | { | ||
144 | compose=EINA_TRUE; | ||
145 | edit = [[event window] fieldEditor:YES forObject:nil]; | ||
146 | [edit interpretKeyEvents:[NSArray arrayWithObject:event]]; | ||
147 | free(ev); | ||
148 | return NULL; | ||
149 | } | ||
150 | |||
151 | return ev; | ||
152 | } | ||
153 | |||
97 | static inline Eina_Bool | 154 | static inline Eina_Bool |
98 | _nsevent_window_is_type_of(NSEvent *event, Class class) | 155 | _nsevent_window_is_type_of(NSEvent *event, Class class) |
99 | { | 156 | { |
@@ -116,8 +173,6 @@ ecore_cocoa_feed_events(void *anEvent) | |||
116 | NSEvent *event = anEvent; | 173 | NSEvent *event = anEvent; |
117 | unsigned int time = (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff); | 174 | unsigned int time = (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff); |
118 | Eina_Bool pass = EINA_FALSE; | 175 | Eina_Bool pass = EINA_FALSE; |
119 | static Eina_Bool compose = EINA_FALSE; | ||
120 | static NSText *edit; | ||
121 | 176 | ||
122 | switch ([event type]) | 177 | switch ([event type]) |
123 | { | 178 | { |
@@ -138,77 +193,24 @@ ecore_cocoa_feed_events(void *anEvent) | |||
138 | case NSKeyDown: | 193 | case NSKeyDown: |
139 | { | 194 | { |
140 | Ecore_Event_Key *ev; | 195 | Ecore_Event_Key *ev; |
141 | unsigned int i; | ||
142 | EcoreCocoaWindow *window = (EcoreCocoaWindow *)[event window]; | ||
143 | NSString *keychar = [event characters]; | ||
144 | |||
145 | ev = calloc(1, sizeof (Ecore_Event_Key)); | ||
146 | if (!ev) return pass; | ||
147 | ev->timestamp = time; | ||
148 | ev->modifiers = _ecore_cocoa_event_modifiers([event modifierFlags]); | ||
149 | 196 | ||
150 | if (compose) | 197 | ev = _ecore_cocoa_event_key(event, NSKeyDown); |
151 | { | 198 | if (ev == NULL) return EINA_TRUE; |
152 | [edit interpretKeyEvents:[NSArray arrayWithObject:event]]; | ||
153 | compose=EINA_FALSE; | ||
154 | } | ||
155 | 199 | ||
156 | if ([keychar length] > 0) | 200 | ev->timestamp = time; |
157 | { | 201 | ecore_event_add(ECORE_EVENT_KEY_DOWN, ev, NULL, NULL); |
158 | for (i = 0; i < sizeof (keystable) / sizeof (struct _ecore_cocoa_keys_s); ++i) | ||
159 | { | ||
160 | if (keystable[i].code == [keychar characterAtIndex:0]) | ||
161 | { | ||
162 | DBG("Key pressed: %s %d\n", keystable[i].name, [keychar characterAtIndex:0]); | ||
163 | ev->keyname = keystable[i].name; | ||
164 | ev->key = keystable[i].name; | ||
165 | ev->string = keystable[i].compose; | ||
166 | ev->window = (Ecore_Window)window.ecore_window_data; | ||
167 | ev->event_window = ev->window; | ||
168 | ecore_event_add(ECORE_EVENT_KEY_DOWN, ev, NULL, NULL); | ||
169 | return pass; | ||
170 | } | ||
171 | } | ||
172 | } | ||
173 | else | ||
174 | { | ||
175 | compose=EINA_TRUE; | ||
176 | edit = [[event window] fieldEditor:YES forObject:nil]; | ||
177 | [edit interpretKeyEvents:[NSArray arrayWithObject:event]]; | ||
178 | } | ||
179 | 202 | ||
180 | break; | 203 | break; |
181 | } | 204 | } |
182 | case NSKeyUp: | 205 | case NSKeyUp: |
183 | { | 206 | { |
184 | Ecore_Event_Key *ev; | 207 | Ecore_Event_Key *ev; |
185 | unsigned int i; | ||
186 | EcoreCocoaWindow *window = (EcoreCocoaWindow *)[event window]; | ||
187 | NSString *keychar = [event characters]; | ||
188 | 208 | ||
189 | DBG("Key Up\n"); | 209 | ev = _ecore_cocoa_event_key(event, NSKeyUp); |
210 | if (ev == NULL) return EINA_TRUE; | ||
190 | 211 | ||
191 | ev = calloc(1, sizeof (Ecore_Event_Key)); | ||
192 | if (!ev) return pass; | ||
193 | ev->timestamp = time; | 212 | ev->timestamp = time; |
194 | ev->modifiers = _ecore_cocoa_event_modifiers([event modifierFlags]); | 213 | ecore_event_add(ECORE_EVENT_KEY_UP, ev, NULL, NULL); |
195 | |||
196 | if ([keychar length] > 0) | ||
197 | { | ||
198 | for (i = 0; i < sizeof (keystable) / sizeof (struct _ecore_cocoa_keys_s); ++i) | ||
199 | { | ||
200 | if (keystable[i].code == [keychar characterAtIndex:0]) | ||
201 | { | ||
202 | ev->keyname = keystable[i].name; | ||
203 | ev->key = keystable[i].name; | ||
204 | ev->string = keystable[i].compose; | ||
205 | ev->window = (Ecore_Window)window.ecore_window_data; | ||
206 | ev->event_window = ev->window; | ||
207 | ecore_event_add(ECORE_EVENT_KEY_UP, ev, NULL, NULL); | ||
208 | return pass; | ||
209 | } | ||
210 | } | ||
211 | } | ||
212 | 214 | ||
213 | break; | 215 | break; |
214 | } | 216 | } |
@@ -222,13 +224,6 @@ ecore_cocoa_feed_events(void *anEvent) | |||
222 | evDown = calloc(1, sizeof (Ecore_Event_Key)); | 224 | evDown = calloc(1, sizeof (Ecore_Event_Key)); |
223 | if (!evDown) return pass; | 225 | if (!evDown) return pass; |
224 | 226 | ||
225 | evUp = calloc(1, sizeof (Ecore_Event_Key)); | ||
226 | if (!evUp) | ||
227 | { | ||
228 | free(evDown); | ||
229 | return pass; | ||
230 | } | ||
231 | |||
232 | // Turn special key flags on | 227 | // Turn special key flags on |
233 | if (flags & NSShiftKeyMask) | 228 | if (flags & NSShiftKeyMask) |
234 | evDown->key = "Shift_L"; | 229 | evDown->key = "Shift_L"; |
@@ -243,13 +238,22 @@ ecore_cocoa_feed_events(void *anEvent) | |||
243 | 238 | ||
244 | if (evDown->key) | 239 | if (evDown->key) |
245 | { | 240 | { |
241 | evDown->keyname = evDown->key; | ||
246 | evDown->timestamp = time; | 242 | evDown->timestamp = time; |
247 | evDown->string = ""; | 243 | evDown->string = NULL; |
248 | ecore_event_add(ECORE_EVENT_KEY_DOWN, evDown, NULL, NULL); | 244 | ecore_event_add(ECORE_EVENT_KEY_DOWN, evDown, NULL, NULL); |
249 | old_flags = flags; | 245 | old_flags = flags; |
250 | break; | 246 | break; |
251 | } | 247 | } |
252 | 248 | ||
249 | free(evDown); | ||
250 | |||
251 | evUp = calloc(1, sizeof (Ecore_Event_Key)); | ||
252 | if (!evUp) | ||
253 | { | ||
254 | return pass; | ||
255 | } | ||
256 | |||
253 | int changed_flags = flags ^ old_flags; | 257 | int changed_flags = flags ^ old_flags; |
254 | 258 | ||
255 | // Turn special key flags off | 259 | // Turn special key flags off |
@@ -266,8 +270,9 @@ ecore_cocoa_feed_events(void *anEvent) | |||
266 | 270 | ||
267 | if (evUp->key) | 271 | if (evUp->key) |
268 | { | 272 | { |
273 | evUp->keyname = evDown->key; | ||
269 | evUp->timestamp = time; | 274 | evUp->timestamp = time; |
270 | evUp->string = ""; | 275 | evUp->string = NULL; |
271 | ecore_event_add(ECORE_EVENT_KEY_UP, evUp, NULL, NULL); | 276 | ecore_event_add(ECORE_EVENT_KEY_UP, evUp, NULL, NULL); |
272 | old_flags = flags; | 277 | old_flags = flags; |
273 | break; | 278 | break; |
@@ -361,4 +366,3 @@ ecore_cocoa_titlebar_height_get(void) | |||
361 | } | 366 | } |
362 | return height; | 367 | return height; |
363 | } | 368 | } |
364 | |||