Import glfw from upstream, key handling on macOS works again
This commit is contained in:
parent
7a3534baf8
commit
b59d7dda11
@ -69,6 +69,7 @@ static void changeToResourcesDirectory(void)
|
|||||||
static void createKeyTables(void)
|
static void createKeyTables(void)
|
||||||
{
|
{
|
||||||
int scancode;
|
int scancode;
|
||||||
|
_glfw.ns.debug_keyboard = getenv("GLFW_DEBUG_KEYBOARD") != NULL;
|
||||||
|
|
||||||
memset(_glfw.ns.keycodes, -1, sizeof(_glfw.ns.keycodes));
|
memset(_glfw.ns.keycodes, -1, sizeof(_glfw.ns.keycodes));
|
||||||
memset(_glfw.ns.scancodes, -1, sizeof(_glfw.ns.scancodes));
|
memset(_glfw.ns.scancodes, -1, sizeof(_glfw.ns.scancodes));
|
||||||
@ -371,4 +372,3 @@ const char* _glfwPlatformGetVersionString(void)
|
|||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
3
glfw/cocoa_platform.h
vendored
3
glfw/cocoa_platform.h
vendored
@ -114,6 +114,8 @@ typedef struct _GLFWlibraryNS
|
|||||||
id listener;
|
id listener;
|
||||||
|
|
||||||
char keyName[64];
|
char keyName[64];
|
||||||
|
char text[256];
|
||||||
|
GLFWbool debug_keyboard;
|
||||||
short int keycodes[256];
|
short int keycodes[256];
|
||||||
short int scancodes[GLFW_KEY_LAST + 1];
|
short int scancodes[GLFW_KEY_LAST + 1];
|
||||||
char* clipboardString;
|
char* clipboardString;
|
||||||
@ -166,4 +168,3 @@ void _glfwInitTimerNS(void);
|
|||||||
void _glfwPollMonitorsNS(void);
|
void _glfwPollMonitorsNS(void);
|
||||||
void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
||||||
void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor);
|
void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor);
|
||||||
|
|
||||||
|
|||||||
@ -183,10 +183,112 @@ static int translateFlags(NSUInteger flags)
|
|||||||
return mods;
|
return mods;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define debug_key(...) if (_glfw.ns.debug_keyboard) NSLog(__VA_ARGS__)
|
||||||
|
|
||||||
|
static inline const char*
|
||||||
|
format_mods(int mods) {
|
||||||
|
static char buf[128];
|
||||||
|
char *p = buf, *s;
|
||||||
|
#define pr(x) p += snprintf(p, sizeof(buf) - (p - buf) - 1, x)
|
||||||
|
pr("mods: ");
|
||||||
|
s = p;
|
||||||
|
if (mods & GLFW_MOD_CONTROL) pr("ctrl+");
|
||||||
|
if (mods & GLFW_MOD_ALT) pr("alt+");
|
||||||
|
if (mods & GLFW_MOD_SHIFT) pr("shift+");
|
||||||
|
if (mods & GLFW_MOD_SUPER) pr("super+");
|
||||||
|
if (mods & GLFW_MOD_CAPS_LOCK) pr("capslock+");
|
||||||
|
if (mods & GLFW_MOD_NUM_LOCK) pr("numlock+");
|
||||||
|
if (p == s) pr("none");
|
||||||
|
else p--;
|
||||||
|
pr(" ");
|
||||||
|
#undef pr
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const char*
|
||||||
|
format_text(const char *src) {
|
||||||
|
static char buf[256];
|
||||||
|
char *p = buf;
|
||||||
|
if (!src[0]) return "<none>";
|
||||||
|
while (*src) {
|
||||||
|
p += snprintf(p, sizeof(buf) - (p - buf), "%x ", (unsigned char)*(src++));
|
||||||
|
}
|
||||||
|
if (p != buf) *(--p) = 0;
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char*
|
||||||
|
safe_name_for_scancode(unsigned int scancode) {
|
||||||
|
const char *ans = _glfwPlatformGetScancodeName(scancode);
|
||||||
|
if (!ans) return "<noname>";
|
||||||
|
if ((1 <= ans[0] && ans[0] <= 31) || ans[0] == 127) ans = "<cc>";
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Translates a macOS keycode to a GLFW keycode
|
// Translates a macOS keycode to a GLFW keycode
|
||||||
//
|
//
|
||||||
static int translateKey(unsigned int key)
|
static int translateKey(unsigned int key, GLFWbool apply_keymap)
|
||||||
{
|
{
|
||||||
|
if (apply_keymap) {
|
||||||
|
// Look for the effective key name after applying any keyboard layouts/mappings
|
||||||
|
const char *name = _glfwPlatformGetScancodeName(key);
|
||||||
|
if (name && name[1] == 0) {
|
||||||
|
// Single letter key name
|
||||||
|
switch(name[0]) {
|
||||||
|
#define K(ch, name) case ch: return GLFW_KEY_##name
|
||||||
|
K('A', A); K('a', A);
|
||||||
|
K('B', B); K('b', B);
|
||||||
|
K('C', C); K('c', C);
|
||||||
|
K('D', D); K('d', D);
|
||||||
|
K('E', E); K('e', E);
|
||||||
|
K('F', F); K('f', F);
|
||||||
|
K('G', G); K('g', G);
|
||||||
|
K('H', H); K('h', H);
|
||||||
|
K('I', I); K('i', I);
|
||||||
|
K('J', J); K('j', J);
|
||||||
|
K('K', K); K('k', K);
|
||||||
|
K('L', L); K('l', L);
|
||||||
|
K('M', M); K('m', M);
|
||||||
|
K('N', N); K('n', N);
|
||||||
|
K('O', O); K('o', O);
|
||||||
|
K('P', P); K('p', P);
|
||||||
|
K('Q', Q); K('q', Q);
|
||||||
|
K('R', R); K('r', R);
|
||||||
|
K('S', S); K('s', S);
|
||||||
|
K('T', T); K('t', T);
|
||||||
|
K('U', U); K('u', U);
|
||||||
|
K('V', V); K('v', V);
|
||||||
|
K('W', W); K('w', W);
|
||||||
|
K('X', X); K('x', X);
|
||||||
|
K('Y', Y); K('y', Y);
|
||||||
|
K('Z', Z); K('z', Z);
|
||||||
|
K('0', 0);
|
||||||
|
K('1', 1);
|
||||||
|
K('2', 2);
|
||||||
|
K('3', 3);
|
||||||
|
K('5', 5);
|
||||||
|
K('6', 6);
|
||||||
|
K('7', 7);
|
||||||
|
K('8', 8);
|
||||||
|
K('9', 9);
|
||||||
|
K('\'', APOSTROPHE);
|
||||||
|
K(',', COMMA);
|
||||||
|
K('.', PERIOD);
|
||||||
|
K('/', SLASH);
|
||||||
|
K('-', MINUS);
|
||||||
|
K('=', EQUAL);
|
||||||
|
K(';', SEMICOLON);
|
||||||
|
K('[', LEFT_BRACKET);
|
||||||
|
K(']', RIGHT_BRACKET);
|
||||||
|
K('`', GRAVE_ACCENT);
|
||||||
|
K('\\', BACKSLASH);
|
||||||
|
#undef K
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (key >= sizeof(_glfw.ns.keycodes) / sizeof(_glfw.ns.keycodes[0]))
|
if (key >= sizeof(_glfw.ns.keycodes) / sizeof(_glfw.ns.keycodes[0]))
|
||||||
return GLFW_KEY_UNKNOWN;
|
return GLFW_KEY_UNKNOWN;
|
||||||
|
|
||||||
@ -619,12 +721,17 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
|
|
||||||
- (void)keyDown:(NSEvent *)event
|
- (void)keyDown:(NSEvent *)event
|
||||||
{
|
{
|
||||||
const int key = translateKey([event keyCode]);
|
const unsigned int scancode = [event keyCode];
|
||||||
|
const int key = translateKey(scancode, GLFW_TRUE);
|
||||||
const int mods = translateFlags([event modifierFlags]);
|
const int mods = translateFlags([event modifierFlags]);
|
||||||
|
_glfw.ns.text[0] = 0;
|
||||||
_glfwInputKey(window, key, [event keyCode], GLFW_PRESS, mods);
|
// this will call insertText with the text for this event, if any
|
||||||
|
|
||||||
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
|
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
|
||||||
|
if ((1 <= _glfw.ns.text[0] && _glfw.ns.text[0] <= 31) || (unsigned)_glfw.ns.text[0] == 127) _glfw.ns.text[0] = 0; // dont send text for ascii control codes
|
||||||
|
debug_key(@"scancode: 0x%x (%s) mods: %stext: %s glfw_key: %s\n",
|
||||||
|
scancode, safe_name_for_scancode(scancode), format_mods(mods),
|
||||||
|
format_text(_glfw.ns.text), _glfwGetKeyName(key));
|
||||||
|
_glfwInputKeyboard(window, key, scancode, GLFW_PRESS, mods, _glfw.ns.text, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)flagsChanged:(NSEvent *)event
|
- (void)flagsChanged:(NSEvent *)event
|
||||||
@ -632,7 +739,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
int action;
|
int action;
|
||||||
const unsigned int modifierFlags =
|
const unsigned int modifierFlags =
|
||||||
[event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;
|
[event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;
|
||||||
const int key = translateKey([event keyCode]);
|
const int key = translateKey([event keyCode], GLFW_FALSE);
|
||||||
const int mods = translateFlags(modifierFlags);
|
const int mods = translateFlags(modifierFlags);
|
||||||
const NSUInteger keyFlag = translateKeyToModifierFlag(key);
|
const NSUInteger keyFlag = translateKeyToModifierFlag(key);
|
||||||
|
|
||||||
@ -646,14 +753,14 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
else
|
else
|
||||||
action = GLFW_RELEASE;
|
action = GLFW_RELEASE;
|
||||||
|
|
||||||
_glfwInputKey(window, key, [event keyCode], action, mods);
|
_glfwInputKeyboard(window, key, [event keyCode], action, mods, "", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)keyUp:(NSEvent *)event
|
- (void)keyUp:(NSEvent *)event
|
||||||
{
|
{
|
||||||
const int key = translateKey([event keyCode]);
|
const int key = translateKey([event keyCode], GLFW_TRUE);
|
||||||
const int mods = translateFlags([event modifierFlags]);
|
const int mods = translateFlags([event modifierFlags]);
|
||||||
_glfwInputKey(window, key, [event keyCode], GLFW_RELEASE, mods);
|
_glfwInputKeyboard(window, key, [event keyCode], GLFW_RELEASE, mods, "", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)scrollWheel:(NSEvent *)event
|
- (void)scrollWheel:(NSEvent *)event
|
||||||
@ -788,25 +895,12 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
- (void)insertText:(id)string replacementRange:(NSRange)replacementRange
|
- (void)insertText:(id)string replacementRange:(NSRange)replacementRange
|
||||||
{
|
{
|
||||||
NSString* characters;
|
NSString* characters;
|
||||||
NSEvent* event = [NSApp currentEvent];
|
|
||||||
const int mods = translateFlags([event modifierFlags]);
|
|
||||||
const int plain = !(mods & GLFW_MOD_SUPER);
|
|
||||||
|
|
||||||
if ([string isKindOfClass:[NSAttributedString class]])
|
if ([string isKindOfClass:[NSAttributedString class]])
|
||||||
characters = [string string];
|
characters = [string string];
|
||||||
else
|
else
|
||||||
characters = (NSString*) string;
|
characters = (NSString*) string;
|
||||||
|
snprintf(_glfw.ns.text, sizeof(_glfw.ns.text), "%s", [characters UTF8String]);
|
||||||
NSUInteger i, length = [characters length];
|
_glfw.ns.text[sizeof(_glfw.ns.text) - 1] = 0;
|
||||||
|
|
||||||
for (i = 0; i < length; i++)
|
|
||||||
{
|
|
||||||
const unichar codepoint = [characters characterAtIndex:i];
|
|
||||||
if ((codepoint & 0xff00) == 0xf700)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
_glfwInputChar(window, codepoint, mods, plain);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)doCommandBySelector:(SEL)selector
|
- (void)doCommandBySelector:(SEL)selector
|
||||||
|
|||||||
2
glfw/xkb_glfw.c
vendored
2
glfw/xkb_glfw.c
vendored
@ -376,7 +376,7 @@ glfw_xkb_handle_key_event(_GLFWwindow *window, _GLFWXKBData *xkb, xkb_keycode_t
|
|||||||
if ( ((GLFW_MOD_CONTROL | GLFW_MOD_ALT | GLFW_MOD_SUPER) & xkb->modifiers) == 0) xkb_state_key_get_utf8(xkb->state, code_for_sym, text, sizeof(text));
|
if ( ((GLFW_MOD_CONTROL | GLFW_MOD_ALT | GLFW_MOD_SUPER) & xkb->modifiers) == 0) xkb_state_key_get_utf8(xkb->state, code_for_sym, text, sizeof(text));
|
||||||
text_type = "text";
|
text_type = "text";
|
||||||
}
|
}
|
||||||
if (text[0] <= 31 || text[0] == 127) text[0] = 0; // dont send text for ascii control codes
|
if ((1 <= text[0] && text[0] <= 31) || text[0] == 127) text[0] = 0; // dont send text for ascii control codes
|
||||||
if (text[0]) { debug("%s: %s ", text_type, text); }
|
if (text[0]) { debug("%s: %s ", text_type, text); }
|
||||||
}
|
}
|
||||||
int glfw_keycode = glfw_key_for_sym(glfw_sym);
|
int glfw_keycode = glfw_key_for_sym(glfw_sym);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user