forked from enlightenment/efl
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>
This commit is contained in:
parent
d9830a199f
commit
ae4389a7bd
|
@ -240,8 +240,8 @@ static const struct _ecore_cocoa_keys_s keystable[] =
|
|||
{ NSInsertFunctionKey, "Insert", "" },
|
||||
{ NSHomeFunctionKey, "Home", "" },
|
||||
{ NSEndFunctionKey, "End", "" },
|
||||
{ NSPageUpFunctionKey, "Page_Up", "" },
|
||||
{ NSPageDownFunctionKey, "Page_Down", "" },
|
||||
{ NSPageUpFunctionKey, "Prior", "" },
|
||||
{ NSPageDownFunctionKey, "Next", "" },
|
||||
{ NSDeleteFunctionKey, "Delete", "\010"},
|
||||
|
||||
{ NSF1FunctionKey, "F1", "" },
|
||||
|
|
|
@ -86,7 +86,7 @@ _ecore_cocoa_event_modifiers(unsigned int mod)
|
|||
|
||||
if(mod & NSShiftKeyMask) modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
|
||||
if(mod & NSControlKeyMask) modifiers |= ECORE_EVENT_MODIFIER_CTRL;
|
||||
if(mod & NSAlternateKeyMask) modifiers |= ECORE_EVENT_MODIFIER_ALT;
|
||||
if(mod & NSAlternateKeyMask) modifiers |= ECORE_EVENT_MODIFIER_ALTGR;
|
||||
if(mod & NSCommandKeyMask) modifiers |= ECORE_EVENT_MODIFIER_WIN;
|
||||
if(mod & NSNumericPadKeyMask) modifiers |= ECORE_EVENT_LOCK_NUM;
|
||||
|
||||
|
@ -94,6 +94,63 @@ _ecore_cocoa_event_modifiers(unsigned int mod)
|
|||
return modifiers;
|
||||
}
|
||||
|
||||
|
||||
static inline Ecore_Event_Key*
|
||||
_ecore_cocoa_event_key(NSEvent *event, int keyType)
|
||||
{
|
||||
static Eina_Bool compose = EINA_FALSE;
|
||||
static NSText *edit;
|
||||
unsigned int i;
|
||||
|
||||
Ecore_Event_Key *ev;
|
||||
|
||||
EcoreCocoaWindow *window = (EcoreCocoaWindow *)[event window];
|
||||
NSString *keychar = [event charactersIgnoringModifiers];
|
||||
NSString *keycharRaw = [event characters];
|
||||
|
||||
ev = calloc(1, sizeof (Ecore_Event_Key));
|
||||
if (!ev) return NULL;
|
||||
|
||||
if (compose && keyType == NSKeyDown)
|
||||
{
|
||||
[edit interpretKeyEvents:[NSArray arrayWithObject:event]];
|
||||
compose=EINA_FALSE;
|
||||
}
|
||||
|
||||
ev->modifiers = _ecore_cocoa_event_modifiers([event modifierFlags]);
|
||||
|
||||
ev->keycode = event.keyCode;
|
||||
ev->string = [keycharRaw cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
ev->compose = ev->string;
|
||||
|
||||
ev->window = (Ecore_Window)window.ecore_window_data;
|
||||
ev->event_window = ev->window;
|
||||
|
||||
if ([keychar length] > 0)
|
||||
{
|
||||
for (i = 0; i < sizeof (keystable) / sizeof (struct _ecore_cocoa_keys_s); ++i)
|
||||
{
|
||||
if (keystable[i].code == [keychar characterAtIndex:0])
|
||||
{
|
||||
ev->keyname = keystable[i].name;
|
||||
ev->key = ev->keyname;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ([keycharRaw length] == 0 && keyType == NSKeyDown)
|
||||
{
|
||||
compose=EINA_TRUE;
|
||||
edit = [[event window] fieldEditor:YES forObject:nil];
|
||||
[edit interpretKeyEvents:[NSArray arrayWithObject:event]];
|
||||
free(ev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ev;
|
||||
}
|
||||
|
||||
static inline Eina_Bool
|
||||
_nsevent_window_is_type_of(NSEvent *event, Class class)
|
||||
{
|
||||
|
@ -116,8 +173,6 @@ ecore_cocoa_feed_events(void *anEvent)
|
|||
NSEvent *event = anEvent;
|
||||
unsigned int time = (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff);
|
||||
Eina_Bool pass = EINA_FALSE;
|
||||
static Eina_Bool compose = EINA_FALSE;
|
||||
static NSText *edit;
|
||||
|
||||
switch ([event type])
|
||||
{
|
||||
|
@ -138,77 +193,24 @@ ecore_cocoa_feed_events(void *anEvent)
|
|||
case NSKeyDown:
|
||||
{
|
||||
Ecore_Event_Key *ev;
|
||||
unsigned int i;
|
||||
EcoreCocoaWindow *window = (EcoreCocoaWindow *)[event window];
|
||||
NSString *keychar = [event characters];
|
||||
|
||||
ev = calloc(1, sizeof (Ecore_Event_Key));
|
||||
if (!ev) return pass;
|
||||
ev = _ecore_cocoa_event_key(event, NSKeyDown);
|
||||
if (ev == NULL) return EINA_TRUE;
|
||||
|
||||
ev->timestamp = time;
|
||||
ev->modifiers = _ecore_cocoa_event_modifiers([event modifierFlags]);
|
||||
|
||||
if (compose)
|
||||
{
|
||||
[edit interpretKeyEvents:[NSArray arrayWithObject:event]];
|
||||
compose=EINA_FALSE;
|
||||
}
|
||||
|
||||
if ([keychar length] > 0)
|
||||
{
|
||||
for (i = 0; i < sizeof (keystable) / sizeof (struct _ecore_cocoa_keys_s); ++i)
|
||||
{
|
||||
if (keystable[i].code == [keychar characterAtIndex:0])
|
||||
{
|
||||
DBG("Key pressed: %s %d\n", keystable[i].name, [keychar characterAtIndex:0]);
|
||||
ev->keyname = keystable[i].name;
|
||||
ev->key = keystable[i].name;
|
||||
ev->string = keystable[i].compose;
|
||||
ev->window = (Ecore_Window)window.ecore_window_data;
|
||||
ev->event_window = ev->window;
|
||||
ecore_event_add(ECORE_EVENT_KEY_DOWN, ev, NULL, NULL);
|
||||
return pass;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
compose=EINA_TRUE;
|
||||
edit = [[event window] fieldEditor:YES forObject:nil];
|
||||
[edit interpretKeyEvents:[NSArray arrayWithObject:event]];
|
||||
}
|
||||
ecore_event_add(ECORE_EVENT_KEY_DOWN, ev, NULL, NULL);
|
||||
|
||||
break;
|
||||
}
|
||||
case NSKeyUp:
|
||||
{
|
||||
Ecore_Event_Key *ev;
|
||||
unsigned int i;
|
||||
EcoreCocoaWindow *window = (EcoreCocoaWindow *)[event window];
|
||||
NSString *keychar = [event characters];
|
||||
|
||||
DBG("Key Up\n");
|
||||
ev = _ecore_cocoa_event_key(event, NSKeyUp);
|
||||
if (ev == NULL) return EINA_TRUE;
|
||||
|
||||
ev = calloc(1, sizeof (Ecore_Event_Key));
|
||||
if (!ev) return pass;
|
||||
ev->timestamp = time;
|
||||
ev->modifiers = _ecore_cocoa_event_modifiers([event modifierFlags]);
|
||||
|
||||
if ([keychar length] > 0)
|
||||
{
|
||||
for (i = 0; i < sizeof (keystable) / sizeof (struct _ecore_cocoa_keys_s); ++i)
|
||||
{
|
||||
if (keystable[i].code == [keychar characterAtIndex:0])
|
||||
{
|
||||
ev->keyname = keystable[i].name;
|
||||
ev->key = keystable[i].name;
|
||||
ev->string = keystable[i].compose;
|
||||
ev->window = (Ecore_Window)window.ecore_window_data;
|
||||
ev->event_window = ev->window;
|
||||
ecore_event_add(ECORE_EVENT_KEY_UP, ev, NULL, NULL);
|
||||
return pass;
|
||||
}
|
||||
}
|
||||
}
|
||||
ecore_event_add(ECORE_EVENT_KEY_UP, ev, NULL, NULL);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -222,13 +224,6 @@ ecore_cocoa_feed_events(void *anEvent)
|
|||
evDown = calloc(1, sizeof (Ecore_Event_Key));
|
||||
if (!evDown) return pass;
|
||||
|
||||
evUp = calloc(1, sizeof (Ecore_Event_Key));
|
||||
if (!evUp)
|
||||
{
|
||||
free(evDown);
|
||||
return pass;
|
||||
}
|
||||
|
||||
// Turn special key flags on
|
||||
if (flags & NSShiftKeyMask)
|
||||
evDown->key = "Shift_L";
|
||||
|
@ -243,13 +238,22 @@ ecore_cocoa_feed_events(void *anEvent)
|
|||
|
||||
if (evDown->key)
|
||||
{
|
||||
evDown->keyname = evDown->key;
|
||||
evDown->timestamp = time;
|
||||
evDown->string = "";
|
||||
evDown->string = NULL;
|
||||
ecore_event_add(ECORE_EVENT_KEY_DOWN, evDown, NULL, NULL);
|
||||
old_flags = flags;
|
||||
break;
|
||||
}
|
||||
|
||||
free(evDown);
|
||||
|
||||
evUp = calloc(1, sizeof (Ecore_Event_Key));
|
||||
if (!evUp)
|
||||
{
|
||||
return pass;
|
||||
}
|
||||
|
||||
int changed_flags = flags ^ old_flags;
|
||||
|
||||
// Turn special key flags off
|
||||
|
@ -266,8 +270,9 @@ ecore_cocoa_feed_events(void *anEvent)
|
|||
|
||||
if (evUp->key)
|
||||
{
|
||||
evUp->keyname = evDown->key;
|
||||
evUp->timestamp = time;
|
||||
evUp->string = "";
|
||||
evUp->string = NULL;
|
||||
ecore_event_add(ECORE_EVENT_KEY_UP, evUp, NULL, NULL);
|
||||
old_flags = flags;
|
||||
break;
|
||||
|
@ -361,4 +366,3 @@ ecore_cocoa_titlebar_height_get(void)
|
|||
}
|
||||
return height;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue