mirror of
https://github.com/kovidgoyal/kitty.git
synced 2024-09-17 17:47:21 +03:00
Start work on supporting arbitrary unicode keys
This commit is contained in:
parent
f00ec0ff60
commit
a681162326
129
gen-key-constants.py
Normal file
129
gen-key-constants.py
Normal file
@ -0,0 +1,129 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
functional_key_names = ( # {{{
|
||||
'escape',
|
||||
'enter',
|
||||
'tab',
|
||||
'backspace',
|
||||
'insert',
|
||||
'delete',
|
||||
'right',
|
||||
'left',
|
||||
'down',
|
||||
'up',
|
||||
'page_up',
|
||||
'page_down',
|
||||
'home',
|
||||
'end',
|
||||
'caps_lock',
|
||||
'scroll_lock',
|
||||
'num_lock',
|
||||
'print_screen',
|
||||
'pause',
|
||||
'f1',
|
||||
'f2',
|
||||
'f3',
|
||||
'f4',
|
||||
'f5',
|
||||
'f6',
|
||||
'f7',
|
||||
'f8',
|
||||
'f9',
|
||||
'f10',
|
||||
'f11',
|
||||
'f12',
|
||||
'f13',
|
||||
'f14',
|
||||
'f15',
|
||||
'f16',
|
||||
'f17',
|
||||
'f18',
|
||||
'f19',
|
||||
'f20',
|
||||
'f21',
|
||||
'f22',
|
||||
'f23',
|
||||
'f24',
|
||||
'f25',
|
||||
'f26',
|
||||
'f27',
|
||||
'f28',
|
||||
'f29',
|
||||
'f30',
|
||||
'f31',
|
||||
'f32',
|
||||
'f33',
|
||||
'f34',
|
||||
'f35',
|
||||
'kp_0',
|
||||
'kp_1',
|
||||
'kp_2',
|
||||
'kp_3',
|
||||
'kp_4',
|
||||
'kp_5',
|
||||
'kp_6',
|
||||
'kp_7',
|
||||
'kp_8',
|
||||
'kp_9',
|
||||
'kp_decimal',
|
||||
'kp_divide',
|
||||
'kp_multiply',
|
||||
'kp_subtract',
|
||||
'kp_add',
|
||||
'kp_enter',
|
||||
'kp_equal',
|
||||
'left_shift',
|
||||
'left_control',
|
||||
'left_alt',
|
||||
'left_super',
|
||||
'right_shift',
|
||||
'right_control',
|
||||
'right_alt',
|
||||
'right_super',
|
||||
'media_play',
|
||||
'media_pause',
|
||||
'media_play_pause',
|
||||
'media_reverse',
|
||||
'media_stop',
|
||||
'media_fast_forward',
|
||||
'media_rewind',
|
||||
'media_track_next',
|
||||
'media_track_previous',
|
||||
'media_record',
|
||||
'menu',
|
||||
) # }}}
|
||||
start_code = 0xe000
|
||||
last_code = start_code + len(functional_key_names) - 1
|
||||
name_to_code = {n: start_code + i for i, n in enumerate(functional_key_names)}
|
||||
|
||||
|
||||
def generate_glfw_header() -> None:
|
||||
lines = [
|
||||
'/* start functional key names */',
|
||||
'typedef enum {',
|
||||
f' GLFW_FKEY_FIRST = 0x{start_code:x},',
|
||||
]
|
||||
for name, code in name_to_code.items():
|
||||
lines.append(f' GLFW_FKEY_{name.upper()} = 0x{code:x},')
|
||||
lines.append(f' GLFW_FKEY_LAST = 0x{last_code:x}')
|
||||
lines.append('} GLFWFunctionKey;')
|
||||
end_marker = '/* end functional key names */'
|
||||
|
||||
with open('glfw/glfw3.h', 'r+') as f:
|
||||
text = f.read()
|
||||
start = text.index(lines[0])
|
||||
end = text.index(end_marker)
|
||||
ntext = text[:start] + '\n'.join(lines) + '\n' + text[end:]
|
||||
f.seek(0)
|
||||
f.truncate()
|
||||
f.write(ntext)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
generate_glfw_header()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -1070,7 +1070,7 @@ - (void)keyDown:(NSEvent *)event
|
||||
|
||||
- (void)flagsChanged:(NSEvent *)event
|
||||
{
|
||||
int action;
|
||||
int action = GLFW_RELEASE;
|
||||
const unsigned int modifierFlags =
|
||||
[event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;
|
||||
const int key = translateKey([event keyCode], false);
|
||||
@ -1079,13 +1079,18 @@ - (void)flagsChanged:(NSEvent *)event
|
||||
|
||||
if (keyFlag & modifierFlags)
|
||||
{
|
||||
if (window->keys[key] == GLFW_PRESS)
|
||||
int current_action == GLFW_RELEASE;
|
||||
for (unsigned i = 0; i < arraysz(window->activated_keys); i++) {
|
||||
if (window->activated_keys[i] == key) {
|
||||
current_action = window->activated_keys[i].action;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (current_action == GLFW_PRESS)
|
||||
action = GLFW_RELEASE;
|
||||
else
|
||||
action = GLFW_PRESS;
|
||||
}
|
||||
else
|
||||
action = GLFW_RELEASE;
|
||||
|
||||
GLFWkeyevent glfw_keyevent;
|
||||
_glfwInitializeKeyEvent(&glfw_keyevent, key, [event keyCode], action, mods);
|
||||
|
133
glfw/glfw3.h
vendored
133
glfw/glfw3.h
vendored
@ -300,31 +300,6 @@ extern "C" {
|
||||
#define GLFW_VERSION_REVISION 0
|
||||
/*! @} */
|
||||
|
||||
/*! @name Key and button actions
|
||||
* @{ */
|
||||
/*! @brief The key or mouse button was released.
|
||||
*
|
||||
* The key or mouse button was released.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
#define GLFW_RELEASE 0
|
||||
/*! @brief The key or mouse button was pressed.
|
||||
*
|
||||
* The key or mouse button was pressed.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
#define GLFW_PRESS 1
|
||||
/*! @brief The key was held down until it repeated.
|
||||
*
|
||||
* The key was held down until it repeated.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
#define GLFW_REPEAT 2
|
||||
/*! @} */
|
||||
|
||||
/*! @defgroup hat_state Joystick hat states
|
||||
* @brief Joystick hat states.
|
||||
*
|
||||
@ -367,6 +342,103 @@ extern "C" {
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* start functional key names */
|
||||
typedef enum {
|
||||
GLFW_FKEY_FIRST = 0xe000,
|
||||
GLFW_FKEY_ESCAPE = 0xe000,
|
||||
GLFW_FKEY_ENTER = 0xe001,
|
||||
GLFW_FKEY_TAB = 0xe002,
|
||||
GLFW_FKEY_BACKSPACE = 0xe003,
|
||||
GLFW_FKEY_INSERT = 0xe004,
|
||||
GLFW_FKEY_DELETE = 0xe005,
|
||||
GLFW_FKEY_RIGHT = 0xe006,
|
||||
GLFW_FKEY_LEFT = 0xe007,
|
||||
GLFW_FKEY_DOWN = 0xe008,
|
||||
GLFW_FKEY_UP = 0xe009,
|
||||
GLFW_FKEY_PAGE_UP = 0xe00a,
|
||||
GLFW_FKEY_PAGE_DOWN = 0xe00b,
|
||||
GLFW_FKEY_HOME = 0xe00c,
|
||||
GLFW_FKEY_END = 0xe00d,
|
||||
GLFW_FKEY_CAPS_LOCK = 0xe00e,
|
||||
GLFW_FKEY_SCROLL_LOCK = 0xe00f,
|
||||
GLFW_FKEY_NUM_LOCK = 0xe010,
|
||||
GLFW_FKEY_PRINT_SCREEN = 0xe011,
|
||||
GLFW_FKEY_PAUSE = 0xe012,
|
||||
GLFW_FKEY_F1 = 0xe013,
|
||||
GLFW_FKEY_F2 = 0xe014,
|
||||
GLFW_FKEY_F3 = 0xe015,
|
||||
GLFW_FKEY_F4 = 0xe016,
|
||||
GLFW_FKEY_F5 = 0xe017,
|
||||
GLFW_FKEY_F6 = 0xe018,
|
||||
GLFW_FKEY_F7 = 0xe019,
|
||||
GLFW_FKEY_F8 = 0xe01a,
|
||||
GLFW_FKEY_F9 = 0xe01b,
|
||||
GLFW_FKEY_F10 = 0xe01c,
|
||||
GLFW_FKEY_F11 = 0xe01d,
|
||||
GLFW_FKEY_F12 = 0xe01e,
|
||||
GLFW_FKEY_F13 = 0xe01f,
|
||||
GLFW_FKEY_F14 = 0xe020,
|
||||
GLFW_FKEY_F15 = 0xe021,
|
||||
GLFW_FKEY_F16 = 0xe022,
|
||||
GLFW_FKEY_F17 = 0xe023,
|
||||
GLFW_FKEY_F18 = 0xe024,
|
||||
GLFW_FKEY_F19 = 0xe025,
|
||||
GLFW_FKEY_F20 = 0xe026,
|
||||
GLFW_FKEY_F21 = 0xe027,
|
||||
GLFW_FKEY_F22 = 0xe028,
|
||||
GLFW_FKEY_F23 = 0xe029,
|
||||
GLFW_FKEY_F24 = 0xe02a,
|
||||
GLFW_FKEY_F25 = 0xe02b,
|
||||
GLFW_FKEY_F26 = 0xe02c,
|
||||
GLFW_FKEY_F27 = 0xe02d,
|
||||
GLFW_FKEY_F28 = 0xe02e,
|
||||
GLFW_FKEY_F29 = 0xe02f,
|
||||
GLFW_FKEY_F30 = 0xe030,
|
||||
GLFW_FKEY_F31 = 0xe031,
|
||||
GLFW_FKEY_F32 = 0xe032,
|
||||
GLFW_FKEY_F33 = 0xe033,
|
||||
GLFW_FKEY_F34 = 0xe034,
|
||||
GLFW_FKEY_F35 = 0xe035,
|
||||
GLFW_FKEY_KP_0 = 0xe036,
|
||||
GLFW_FKEY_KP_1 = 0xe037,
|
||||
GLFW_FKEY_KP_2 = 0xe038,
|
||||
GLFW_FKEY_KP_3 = 0xe039,
|
||||
GLFW_FKEY_KP_4 = 0xe03a,
|
||||
GLFW_FKEY_KP_5 = 0xe03b,
|
||||
GLFW_FKEY_KP_6 = 0xe03c,
|
||||
GLFW_FKEY_KP_7 = 0xe03d,
|
||||
GLFW_FKEY_KP_8 = 0xe03e,
|
||||
GLFW_FKEY_KP_9 = 0xe03f,
|
||||
GLFW_FKEY_KP_DECIMAL = 0xe040,
|
||||
GLFW_FKEY_KP_DIVIDE = 0xe041,
|
||||
GLFW_FKEY_KP_MULTIPLY = 0xe042,
|
||||
GLFW_FKEY_KP_SUBTRACT = 0xe043,
|
||||
GLFW_FKEY_KP_ADD = 0xe044,
|
||||
GLFW_FKEY_KP_ENTER = 0xe045,
|
||||
GLFW_FKEY_KP_EQUAL = 0xe046,
|
||||
GLFW_FKEY_LEFT_SHIFT = 0xe047,
|
||||
GLFW_FKEY_LEFT_CONTROL = 0xe048,
|
||||
GLFW_FKEY_LEFT_ALT = 0xe049,
|
||||
GLFW_FKEY_LEFT_SUPER = 0xe04a,
|
||||
GLFW_FKEY_RIGHT_SHIFT = 0xe04b,
|
||||
GLFW_FKEY_RIGHT_CONTROL = 0xe04c,
|
||||
GLFW_FKEY_RIGHT_ALT = 0xe04d,
|
||||
GLFW_FKEY_RIGHT_SUPER = 0xe04e,
|
||||
GLFW_FKEY_MEDIA_PLAY = 0xe04f,
|
||||
GLFW_FKEY_MEDIA_PAUSE = 0xe050,
|
||||
GLFW_FKEY_MEDIA_PLAY_PAUSE = 0xe051,
|
||||
GLFW_FKEY_MEDIA_REVERSE = 0xe052,
|
||||
GLFW_FKEY_MEDIA_STOP = 0xe053,
|
||||
GLFW_FKEY_MEDIA_FAST_FORWARD = 0xe054,
|
||||
GLFW_FKEY_MEDIA_REWIND = 0xe055,
|
||||
GLFW_FKEY_MEDIA_TRACK_NEXT = 0xe056,
|
||||
GLFW_FKEY_MEDIA_TRACK_PREVIOUS = 0xe057,
|
||||
GLFW_FKEY_MEDIA_RECORD = 0xe058,
|
||||
GLFW_FKEY_MENU = 0xe059,
|
||||
GLFW_FKEY_LAST = 0xe059
|
||||
} GLFWFunctionKey;
|
||||
/* end functional key names */
|
||||
|
||||
/* The unknown key */
|
||||
#define GLFW_KEY_UNKNOWN -1
|
||||
|
||||
@ -1284,17 +1356,22 @@ typedef struct GLFWwindow GLFWwindow;
|
||||
* @ingroup input
|
||||
*/
|
||||
typedef struct GLFWcursor GLFWcursor;
|
||||
typedef enum {
|
||||
GLFW_RELEASE = 0,
|
||||
GLFW_PRESS = 1,
|
||||
GLFW_REPEAT = 2
|
||||
} GLFWKeyAction;
|
||||
|
||||
typedef struct GLFWkeyevent
|
||||
{
|
||||
// The [keyboard key](@ref keys) that was pressed or released.
|
||||
int key;
|
||||
uint32_t key;
|
||||
|
||||
// The platform-specific identifier of the key.
|
||||
int native_key;
|
||||
|
||||
// The event action. Either `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`.
|
||||
int action;
|
||||
GLFWKeyAction action;
|
||||
|
||||
// Bit field describing which [modifier keys](@ref mods) were held down.
|
||||
int mods;
|
||||
@ -4486,7 +4563,7 @@ GLFWAPI int glfwGetNativeKeyForKey(int key);
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
GLFWAPI int glfwGetKey(GLFWwindow* window, int key);
|
||||
GLFWAPI GLFWKeyAction glfwGetKey(GLFWwindow* window, uint32_t key);
|
||||
|
||||
/*! @brief Returns the last reported state of a mouse button for the specified
|
||||
* window.
|
||||
|
84
glfw/input.c
vendored
84
glfw/input.c
vendored
@ -283,24 +283,61 @@ void _glfwInitializeKeyEvent(GLFWkeyevent *ev, int key, int native_key, int acti
|
||||
ev->ime_state = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
set_key_action(_GLFWwindow *window, uint32_t key, int val, int idx) {
|
||||
const unsigned sz = arraysz(window->activated_keys);
|
||||
if (idx < 0) {
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
if (window->activated_keys[i].key == 0) {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (idx < 0) {
|
||||
idx = sz - 1;
|
||||
memmove(window->activated_keys, window->activated_keys + 1, sizeof(window->activated_keys[0]) * (sz - 1));
|
||||
window->activated_keys[sz - 1].key = key;
|
||||
}
|
||||
}
|
||||
if (val == GLFW_RELEASE) {
|
||||
memset(window->activated_keys + idx, 0, sizeof(window->activated_keys[0]));
|
||||
if (idx < (int)sz - 1) {
|
||||
memmove(window->activated_keys + idx, window->activated_keys + idx + 1, sizeof(window->activated_keys[0]) * (sz - 1 - idx));
|
||||
memset(window->activated_keys + sz - 1, 0, sizeof(window->activated_keys[0]));
|
||||
}
|
||||
} else {
|
||||
window->activated_keys[idx].action = val;
|
||||
}
|
||||
}
|
||||
|
||||
// Notifies shared code of a physical key event
|
||||
//
|
||||
void _glfwInputKeyboard(_GLFWwindow* window, GLFWkeyevent* ev)
|
||||
{
|
||||
if (ev->key >= 0 && ev->key <= GLFW_KEY_LAST)
|
||||
if (ev->key > 0)
|
||||
{
|
||||
bool repeated = false;
|
||||
int idx = -1;
|
||||
int current_action = GLFW_RELEASE;
|
||||
const unsigned sz = arraysz(window->activated_keys);
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
if (window->activated_keys[i].key == ev->key) {
|
||||
idx = i;
|
||||
current_action = window->activated_keys[i].action;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ev->action == GLFW_RELEASE && window->keys[ev->key] == GLFW_RELEASE)
|
||||
if (ev->action == GLFW_RELEASE && current_action == GLFW_RELEASE)
|
||||
return;
|
||||
|
||||
if (ev->action == GLFW_PRESS && window->keys[ev->key] == GLFW_PRESS)
|
||||
if (ev->action == GLFW_PRESS && current_action == GLFW_PRESS)
|
||||
repeated = true;
|
||||
|
||||
if (ev->action == GLFW_RELEASE && window->stickyKeys)
|
||||
window->keys[ev->key] = _GLFW_STICK;
|
||||
set_key_action(window, ev->key, _GLFW_STICK, idx);
|
||||
else
|
||||
window->keys[ev->key] = (char) ev->action;
|
||||
set_key_action(window, ev->key, ev->action, idx);
|
||||
|
||||
if (repeated)
|
||||
ev->action = GLFW_REPEAT;
|
||||
@ -736,13 +773,15 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
||||
|
||||
if (!value)
|
||||
{
|
||||
int i;
|
||||
|
||||
// Release all sticky keys
|
||||
for (i = 0; i <= GLFW_KEY_LAST; i++)
|
||||
for (unsigned i = arraysz(window->activated_keys) - 1; i-- > 0;)
|
||||
{
|
||||
if (window->keys[i] == _GLFW_STICK)
|
||||
window->keys[i] = GLFW_RELEASE;
|
||||
if (window->activated_keys[i].action == _GLFW_STICK) {
|
||||
if (i < arraysz(window->activated_keys) - 1) {
|
||||
memmove(window->activated_keys + i, window->activated_keys + i + 1, sizeof(window->activated_keys[0]) * (arraysz(window->activated_keys) - 1 - i));
|
||||
}
|
||||
memset(window->activated_keys + arraysz(window->activated_keys) - 1, 0, sizeof(window->activated_keys[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -830,27 +869,34 @@ GLFWAPI int glfwGetNativeKeyForKey(int key)
|
||||
return _glfwPlatformGetNativeKeyForKey(key);
|
||||
}
|
||||
|
||||
GLFWAPI int glfwGetKey(GLFWwindow* handle, int key)
|
||||
GLFWAPI GLFWKeyAction glfwGetKey(GLFWwindow* handle, uint32_t key)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE);
|
||||
if (!key) return GLFW_RELEASE;
|
||||
|
||||
if (key < GLFW_KEY_SPACE || key > GLFW_KEY_LAST)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid key %i", key);
|
||||
return GLFW_RELEASE;
|
||||
int current_action = GLFW_RELEASE;
|
||||
const unsigned sz = arraysz(window->activated_keys);
|
||||
int idx = -1;
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
if (window->activated_keys[i].key == key) {
|
||||
idx = i;
|
||||
current_action = window->activated_keys[i].action;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (window->keys[key] == _GLFW_STICK)
|
||||
|
||||
if (current_action == _GLFW_STICK)
|
||||
{
|
||||
// Sticky mode: release key now
|
||||
window->keys[key] = GLFW_RELEASE;
|
||||
return GLFW_PRESS;
|
||||
set_key_action(window, key, GLFW_RELEASE, idx);
|
||||
current_action = GLFW_PRESS;
|
||||
}
|
||||
|
||||
return (int) window->keys[key];
|
||||
return current_action;
|
||||
}
|
||||
|
||||
GLFWAPI int glfwGetMouseButton(GLFWwindow* handle, int button)
|
||||
|
7
glfw/internal.h
vendored
7
glfw/internal.h
vendored
@ -401,6 +401,11 @@ struct _GLFWcontext
|
||||
_GLFWcontextOSMesa osmesa;
|
||||
};
|
||||
|
||||
typedef struct GLFWKeyState {
|
||||
uint32_t key;
|
||||
char action;
|
||||
} GLFWKeyState;
|
||||
|
||||
// Window and context structure
|
||||
//
|
||||
struct _GLFWwindow
|
||||
@ -431,7 +436,7 @@ struct _GLFWwindow
|
||||
bool lockKeyMods;
|
||||
int cursorMode;
|
||||
char mouseButtons[GLFW_MOUSE_BUTTON_LAST + 1];
|
||||
char keys[GLFW_KEY_LAST + 1];
|
||||
GLFWKeyState activated_keys[16];
|
||||
// Virtual cursor position when cursor is disabled
|
||||
double virtualCursorPosX, virtualCursorPosY;
|
||||
bool rawMouseMotion;
|
||||
|
11
glfw/window.c
vendored
11
glfw/window.c
vendored
@ -50,21 +50,20 @@ void _glfwInputWindowFocus(_GLFWwindow* window, bool focused)
|
||||
|
||||
if (!focused)
|
||||
{
|
||||
int key, button;
|
||||
_glfw.focusedWindowId = 0;
|
||||
|
||||
for (key = 0; key <= GLFW_KEY_LAST; key++)
|
||||
for (unsigned i = 0; i < arraysz(window->activated_keys); i++)
|
||||
{
|
||||
if (window->keys[key] == GLFW_PRESS)
|
||||
if (window->activated_keys[i].key > 0 && window->activated_keys[i].action == GLFW_PRESS)
|
||||
{
|
||||
const int native_key = _glfwPlatformGetNativeKeyForKey(key);
|
||||
const int native_key = _glfwPlatformGetNativeKeyForKey(window->activated_keys[i].key);
|
||||
GLFWkeyevent ev;
|
||||
_glfwInitializeKeyEvent(&ev, key, native_key, GLFW_RELEASE, 0);
|
||||
_glfwInitializeKeyEvent(&ev, window->activated_keys[i].key, native_key, GLFW_RELEASE, 0);
|
||||
_glfwInputKeyboard(window, &ev);
|
||||
}
|
||||
}
|
||||
|
||||
for (button = 0; button <= GLFW_MOUSE_BUTTON_LAST; button++)
|
||||
for (int button = 0; button <= GLFW_MOUSE_BUTTON_LAST; button++)
|
||||
{
|
||||
if (window->mouseButtons[button] == GLFW_PRESS)
|
||||
_glfwInputMouseClick(window, button, GLFW_RELEASE, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user