Move the key handler to C
This commit is contained in:
parent
a4d71bcf5c
commit
c5e989bc94
@ -6,16 +6,13 @@ from gettext import gettext as _
|
|||||||
from weakref import WeakValueDictionary
|
from weakref import WeakValueDictionary
|
||||||
|
|
||||||
from .config import MINIMUM_FONT_SIZE
|
from .config import MINIMUM_FONT_SIZE
|
||||||
from .constants import (
|
from .constants import cell_size, set_boss, viewport_size, wakeup
|
||||||
MODIFIER_KEYS, cell_size, set_boss, viewport_size, wakeup
|
|
||||||
)
|
|
||||||
from .fast_data_types import (
|
from .fast_data_types import (
|
||||||
GLFW_KEY_DOWN, GLFW_KEY_UP, GLFW_PRESS, GLFW_REPEAT, ChildMonitor,
|
GLFW_KEY_DOWN, GLFW_KEY_UP, ChildMonitor, destroy_global_data,
|
||||||
destroy_global_data, destroy_sprite_map, glfw_post_empty_event,
|
destroy_sprite_map, glfw_post_empty_event, layout_sprite_map
|
||||||
layout_sprite_map
|
|
||||||
)
|
)
|
||||||
from .fonts.render import render_cell_wrapper, set_font_family
|
from .fonts.render import render_cell_wrapper, set_font_family
|
||||||
from .keys import get_key_map, get_sent_data, get_shortcut, interpret_key_event
|
from .keys import get_key_map, get_sent_data, get_shortcut
|
||||||
from .session import create_session
|
from .session import create_session
|
||||||
from .tabs import SpecialWindow, TabManager
|
from .tabs import SpecialWindow, TabManager
|
||||||
from .utils import (
|
from .utils import (
|
||||||
@ -72,7 +69,6 @@ class Boss:
|
|||||||
self.opts, self.args = opts, args
|
self.opts, self.args = opts, args
|
||||||
self.glfw_window = glfw_window
|
self.glfw_window = glfw_window
|
||||||
glfw_window.framebuffer_size_callback = self.on_window_resize
|
glfw_window.framebuffer_size_callback = self.on_window_resize
|
||||||
glfw_window.key_callback = self.on_key
|
|
||||||
glfw_window.window_focus_callback = self.on_focus
|
glfw_window.window_focus_callback = self.on_focus
|
||||||
load_shader_programs()
|
load_shader_programs()
|
||||||
self.tab_manager = TabManager(opts, args)
|
self.tab_manager = TabManager(opts, args)
|
||||||
@ -171,35 +167,34 @@ class Boss:
|
|||||||
if t is not None:
|
if t is not None:
|
||||||
return t.active_window
|
return t.active_window
|
||||||
|
|
||||||
def on_key(self, window, key, scancode, action, mods):
|
def dispatch_special_key(self, key, scancode, action, mods):
|
||||||
func = None
|
# Handles shortcuts, return True if the key was consumed
|
||||||
if action == GLFW_PRESS or action == GLFW_REPEAT:
|
func = get_shortcut(self.opts.keymap, mods, key, scancode)
|
||||||
func = get_shortcut(self.opts.keymap, mods, key, scancode)
|
if func is not None:
|
||||||
if func is not None:
|
f = getattr(self, func, None)
|
||||||
f = getattr(self, func, None)
|
if f is not None:
|
||||||
if f is not None:
|
passthrough = f()
|
||||||
passthrough = f()
|
if not passthrough:
|
||||||
if not passthrough:
|
return True
|
||||||
return
|
|
||||||
tab = self.active_tab
|
tab = self.active_tab
|
||||||
if tab is None:
|
if tab is None:
|
||||||
return
|
return False
|
||||||
window = self.active_window
|
window = self.active_window
|
||||||
if window is None:
|
if window is None:
|
||||||
return
|
return False
|
||||||
if func is not None:
|
if func is not None:
|
||||||
f = getattr(tab, func, getattr(window, func, None))
|
f = getattr(tab, func, getattr(window, func, None))
|
||||||
if f is not None:
|
if f is not None:
|
||||||
passthrough = f()
|
passthrough = f()
|
||||||
if not passthrough:
|
if not passthrough:
|
||||||
return
|
return True
|
||||||
if window.screen.scrolled_by and key not in MODIFIER_KEYS and action == GLFW_PRESS:
|
|
||||||
window.scroll_end()
|
|
||||||
data = get_sent_data(
|
data = get_sent_data(
|
||||||
self.opts.send_text_map, key, scancode, mods, window, action
|
self.opts.send_text_map, key, scancode, mods, window, action
|
||||||
) or interpret_key_event(key, scancode, mods, window, action)
|
)
|
||||||
if data:
|
if data:
|
||||||
window.write_to_child(data)
|
window.write_to_child(data)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def on_focus(self, window, focused):
|
def on_focus(self, window, focused):
|
||||||
self.window_is_focused = focused
|
self.window_is_focused = focused
|
||||||
|
|||||||
@ -8,10 +8,7 @@ import ctypes
|
|||||||
import sys
|
import sys
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
from .fast_data_types import (
|
from .fast_data_types import set_boss as set_c_boss
|
||||||
GLFW_KEY_LEFT_SHIFT, GLFW_KEY_RIGHT_SHIFT, GLFW_KEY_LEFT_ALT,
|
|
||||||
GLFW_KEY_RIGHT_ALT, GLFW_KEY_LEFT_CONTROL, GLFW_KEY_RIGHT_CONTROL,
|
|
||||||
GLFW_KEY_LEFT_SUPER, GLFW_KEY_RIGHT_SUPER, set_boss as set_c_boss)
|
|
||||||
|
|
||||||
appname = 'kitty'
|
appname = 'kitty'
|
||||||
version = (0, 3, 0)
|
version = (0, 3, 0)
|
||||||
@ -78,8 +75,3 @@ if ctypes.sizeof(GLfloat) != 4:
|
|||||||
raise RuntimeError('float size is not 4')
|
raise RuntimeError('float size is not 4')
|
||||||
if ctypes.sizeof(GLint) != 4:
|
if ctypes.sizeof(GLint) != 4:
|
||||||
raise RuntimeError('int size is not 4')
|
raise RuntimeError('int size is not 4')
|
||||||
|
|
||||||
MODIFIER_KEYS = (
|
|
||||||
GLFW_KEY_LEFT_SHIFT, GLFW_KEY_RIGHT_SHIFT, GLFW_KEY_LEFT_ALT,
|
|
||||||
GLFW_KEY_RIGHT_ALT, GLFW_KEY_LEFT_CONTROL, GLFW_KEY_RIGHT_CONTROL,
|
|
||||||
GLFW_KEY_LEFT_SUPER, GLFW_KEY_RIGHT_SUPER)
|
|
||||||
|
|||||||
@ -319,3 +319,4 @@ void mouse_event(int, int);
|
|||||||
void scroll_event(double, double);
|
void scroll_event(double, double);
|
||||||
void set_special_key_combo(int glfw_key, int mods);
|
void set_special_key_combo(int glfw_key, int mods);
|
||||||
void on_text_input(unsigned int codepoint, int mods);
|
void on_text_input(unsigned int codepoint, int mods);
|
||||||
|
void on_key_input(int key, int scancode, int action, int mods);
|
||||||
|
|||||||
11
kitty/glfw.c
11
kitty/glfw.c
@ -36,7 +36,7 @@ typedef struct {
|
|||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
|
|
||||||
GLFWwindow *window;
|
GLFWwindow *window;
|
||||||
PyObject *framebuffer_size_callback, *key_callback, *window_focus_callback;
|
PyObject *framebuffer_size_callback, *window_focus_callback;
|
||||||
GLFWcursor *standard_cursor, *click_cursor, *arrow_cursor;
|
GLFWcursor *standard_cursor, *click_cursor, *arrow_cursor;
|
||||||
} WindowWrapper;
|
} WindowWrapper;
|
||||||
|
|
||||||
@ -63,8 +63,10 @@ char_mods_callback(GLFWwindow UNUSED *w, unsigned int codepoint, int mods) {
|
|||||||
static void
|
static void
|
||||||
key_callback(GLFWwindow UNUSED *w, int key, int scancode, int action, int mods) {
|
key_callback(GLFWwindow UNUSED *w, int key, int scancode, int action, int mods) {
|
||||||
global_state.cursor_blink_zero_time = monotonic();
|
global_state.cursor_blink_zero_time = monotonic();
|
||||||
if (key >= 0 && key <= GLFW_KEY_LAST) global_state.is_key_pressed[key] = action == GLFW_RELEASE ? false : true;
|
if (key >= 0 && key <= GLFW_KEY_LAST) {
|
||||||
WINDOW_CALLBACK(key_callback, "iiii", key, scancode, action, mods);
|
global_state.is_key_pressed[key] = action == GLFW_RELEASE ? false : true;
|
||||||
|
on_key_input(key, scancode, action, mods);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -259,7 +261,7 @@ glfw_init_hint_string(PyObject UNUSED *self, PyObject *args) {
|
|||||||
static void
|
static void
|
||||||
dealloc(WindowWrapper* self) {
|
dealloc(WindowWrapper* self) {
|
||||||
the_window = NULL;
|
the_window = NULL;
|
||||||
Py_CLEAR(self->framebuffer_size_callback); Py_CLEAR(self->key_callback); Py_CLEAR(self->window_focus_callback);
|
Py_CLEAR(self->framebuffer_size_callback); Py_CLEAR(self->window_focus_callback);
|
||||||
if (self->window != NULL) glfwDestroyWindow(self->window);
|
if (self->window != NULL) glfwDestroyWindow(self->window);
|
||||||
Py_TYPE(self)->tp_free((PyObject*)self);
|
Py_TYPE(self)->tp_free((PyObject*)self);
|
||||||
}
|
}
|
||||||
@ -446,7 +448,6 @@ static PyMethodDef methods[] = {
|
|||||||
static PyMemberDef members[] = {
|
static PyMemberDef members[] = {
|
||||||
#define CBE(name) {#name, T_OBJECT_EX, offsetof(WindowWrapper, name), 0, #name}
|
#define CBE(name) {#name, T_OBJECT_EX, offsetof(WindowWrapper, name), 0, #name}
|
||||||
CBE(framebuffer_size_callback),
|
CBE(framebuffer_size_callback),
|
||||||
CBE(key_callback),
|
|
||||||
CBE(window_focus_callback),
|
CBE(window_focus_callback),
|
||||||
{NULL}
|
{NULL}
|
||||||
#undef CBE
|
#undef CBE
|
||||||
|
|||||||
123
kitty/keys.c
123
kitty/keys.c
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "keys.h"
|
#include "keys.h"
|
||||||
#include "state.h"
|
#include "state.h"
|
||||||
|
#include "screen.h"
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
const uint8_t*
|
const uint8_t*
|
||||||
@ -24,10 +25,15 @@ key_to_bytes(int glfw_key, bool smkx, bool extended, int mods, int action) {
|
|||||||
return key_bytes[key];
|
return key_bytes[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SPECIAL_INDEX(key) ((key & 0x7f) | ( (mods & 0xF) << 7))
|
||||||
|
|
||||||
void
|
void
|
||||||
set_special_key_combo(int glfw_key, int mods) {
|
set_special_key_combo(int glfw_key, int mods) {
|
||||||
int k = (glfw_key & 0x7f) | ( (mods & 0xF) << 7);
|
uint16_t key = key_map[glfw_key];
|
||||||
needs_special_handling[k] = true;
|
if (key != UINT8_MAX) {
|
||||||
|
key = SPECIAL_INDEX(key);
|
||||||
|
needs_special_handling[key] = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Window*
|
static inline Window*
|
||||||
@ -56,6 +62,119 @@ on_text_input(unsigned int codepoint, int mods) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
is_modifier_key(int key) {
|
||||||
|
switch(key) {
|
||||||
|
case GLFW_KEY_LEFT_SHIFT:
|
||||||
|
case GLFW_KEY_RIGHT_SHIFT:
|
||||||
|
case GLFW_KEY_LEFT_ALT:
|
||||||
|
case GLFW_KEY_RIGHT_ALT:
|
||||||
|
case GLFW_KEY_LEFT_CONTROL:
|
||||||
|
case GLFW_KEY_RIGHT_CONTROL:
|
||||||
|
case GLFW_KEY_LEFT_SUPER:
|
||||||
|
case GLFW_KEY_RIGHT_SUPER:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
get_localized_key(int key, int scancode) {
|
||||||
|
const char *name = glfwGetKeyName(key, scancode);
|
||||||
|
if (name == NULL || name[1] != 0) return key;
|
||||||
|
switch(name[0]) {
|
||||||
|
#define K(ch, name) case ch: return GLFW_KEY_##name
|
||||||
|
// key names {{{
|
||||||
|
K('A', A);
|
||||||
|
K('B', B);
|
||||||
|
K('C', C);
|
||||||
|
K('D', D);
|
||||||
|
K('E', E);
|
||||||
|
K('F', F);
|
||||||
|
K('G', G);
|
||||||
|
K('H', H);
|
||||||
|
K('I', I);
|
||||||
|
K('J', J);
|
||||||
|
K('K', K);
|
||||||
|
K('L', L);
|
||||||
|
K('M', M);
|
||||||
|
K('N', N);
|
||||||
|
K('O', O);
|
||||||
|
K('P', P);
|
||||||
|
K('Q', Q);
|
||||||
|
K('S', S);
|
||||||
|
K('T', T);
|
||||||
|
K('U', U);
|
||||||
|
K('V', V);
|
||||||
|
K('W', W);
|
||||||
|
K('X', X);
|
||||||
|
K('Y', Y);
|
||||||
|
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(';', SEMICOLON);
|
||||||
|
K('=', EQUAL);
|
||||||
|
K('[', LEFT_BRACKET);
|
||||||
|
K(']', RIGHT_BRACKET);
|
||||||
|
K('`', GRAVE_ACCENT);
|
||||||
|
K('\\', BACKSLASH);
|
||||||
|
// }}}
|
||||||
|
#undef K
|
||||||
|
default:
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
on_key_input(int key, int scancode, int action, int mods) {
|
||||||
|
Window *w = active_window();
|
||||||
|
if (!w) return;
|
||||||
|
Screen *screen = w->render_data.screen;
|
||||||
|
if (screen->scrolled_by && action == GLFW_PRESS && !is_modifier_key(key)) {
|
||||||
|
screen_history_scroll(screen, SCROLL_FULL, false); // scroll back to bottom
|
||||||
|
}
|
||||||
|
int lkey = get_localized_key(key, scancode);
|
||||||
|
if (action == GLFW_PRESS || action == GLFW_REPEAT) {
|
||||||
|
uint16_t qkey = key_map[lkey];
|
||||||
|
bool special = false;
|
||||||
|
if (qkey != UINT8_MAX) {
|
||||||
|
qkey = SPECIAL_INDEX(qkey);
|
||||||
|
special = needs_special_handling[qkey];
|
||||||
|
}
|
||||||
|
/* printf("key: %s mods: %d special: %d\n", key_name(lkey), mods, special); */
|
||||||
|
if (special) {
|
||||||
|
PyObject *ret = PyObject_CallMethod(global_state.boss, "dispatch_special_key", "iiii", lkey, scancode, action, mods);
|
||||||
|
if (ret == NULL) { PyErr_Print(); }
|
||||||
|
else {
|
||||||
|
bool consumed = ret == Py_True ? true : false;
|
||||||
|
Py_DECREF(ret);
|
||||||
|
if (consumed) return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
action == GLFW_PRESS ||
|
||||||
|
(action == GLFW_REPEAT && screen->modes.mDECARM) ||
|
||||||
|
screen->modes.mEXTENDED_KEYBOARD
|
||||||
|
) {
|
||||||
|
const uint8_t *data = key_to_bytes(lkey, screen->modes.mDECCKM, screen->modes.mEXTENDED_KEYBOARD, mods, action);
|
||||||
|
if (data) schedule_write_to_child(w->id, (char*)(data + 1), *data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define PYWRAP1(name) static PyObject* py##name(PyObject UNUSED *self, PyObject *args)
|
#define PYWRAP1(name) static PyObject* py##name(PyObject UNUSED *self, PyObject *args)
|
||||||
#define PA(fmt, ...) if(!PyArg_ParseTuple(args, fmt, __VA_ARGS__)) return NULL;
|
#define PA(fmt, ...) if(!PyArg_ParseTuple(args, fmt, __VA_ARGS__)) return NULL;
|
||||||
#define M(name, arg_type) {#name, (PyCFunction)py##name, arg_type, NULL}
|
#define M(name, arg_type) {#name, (PyCFunction)py##name, arg_type, NULL}
|
||||||
|
|||||||
7990
kitty/keys.h
7990
kitty/keys.h
File diff suppressed because it is too large
Load Diff
@ -111,32 +111,6 @@ def keyboard_mode_name(screen):
|
|||||||
return 'application' if screen.cursor_key_mode else 'normal'
|
return 'application' if screen.cursor_key_mode else 'normal'
|
||||||
|
|
||||||
|
|
||||||
valid_localized_key_names = {
|
|
||||||
k: getattr(defines, 'GLFW_KEY_' + k)
|
|
||||||
for k in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
|
|
||||||
}
|
|
||||||
|
|
||||||
for name, ch in {
|
|
||||||
'APOSTROPHE': "'",
|
|
||||||
'COMMA': ',',
|
|
||||||
'PERIOD': '.',
|
|
||||||
'SLASH': '/',
|
|
||||||
'MINUS': '-',
|
|
||||||
'SEMICOLON': ';',
|
|
||||||
'EQUAL': '=',
|
|
||||||
'LEFT_BRACKET': '[',
|
|
||||||
'RIGHT_BRACKET': ']',
|
|
||||||
'GRAVE_ACCENT': '`',
|
|
||||||
'BACKSLASH': '\\'
|
|
||||||
}.items():
|
|
||||||
valid_localized_key_names[ch] = getattr(defines, 'GLFW_KEY_' + name)
|
|
||||||
|
|
||||||
|
|
||||||
def get_localized_key(key, scancode):
|
|
||||||
name = defines.glfw_get_key_name(key, scancode)
|
|
||||||
return valid_localized_key_names.get((name or '').upper(), key)
|
|
||||||
|
|
||||||
|
|
||||||
action_map = {
|
action_map = {
|
||||||
defines.GLFW_PRESS: 'p',
|
defines.GLFW_PRESS: 'p',
|
||||||
defines.GLFW_RELEASE: 'r',
|
defines.GLFW_RELEASE: 'r',
|
||||||
@ -182,26 +156,23 @@ def key_to_bytes(key, smkx, extended, mods, action):
|
|||||||
return bytes(data)
|
return bytes(data)
|
||||||
|
|
||||||
|
|
||||||
def interpret_key_event(key, scancode, mods, window, action, get_localized_key=get_localized_key):
|
def interpret_key_event(key, scancode, mods, window, action):
|
||||||
screen = window.screen
|
screen = window.screen
|
||||||
if (
|
if (
|
||||||
action == defines.GLFW_PRESS or
|
action == defines.GLFW_PRESS or
|
||||||
(action == defines.GLFW_REPEAT and screen.auto_repeat_enabled) or
|
(action == defines.GLFW_REPEAT and screen.auto_repeat_enabled) or
|
||||||
screen.extended_keyboard
|
screen.extended_keyboard
|
||||||
):
|
):
|
||||||
key = get_localized_key(key, scancode)
|
|
||||||
return defines.key_to_bytes(key, screen.cursor_key_mode, screen.extended_keyboard, mods, action)
|
return defines.key_to_bytes(key, screen.cursor_key_mode, screen.extended_keyboard, mods, action)
|
||||||
return b''
|
return b''
|
||||||
|
|
||||||
|
|
||||||
def get_shortcut(keymap, mods, key, scancode):
|
def get_shortcut(keymap, mods, key, scancode):
|
||||||
key = get_localized_key(key, scancode)
|
|
||||||
return keymap.get((mods & 0b1111, key))
|
return keymap.get((mods & 0b1111, key))
|
||||||
|
|
||||||
|
|
||||||
def get_sent_data(send_text_map, key, scancode, mods, window, action):
|
def get_sent_data(send_text_map, key, scancode, mods, window, action):
|
||||||
if action in (defines.GLFW_PRESS, defines.GLFW_REPEAT):
|
if action in (defines.GLFW_PRESS, defines.GLFW_REPEAT):
|
||||||
key = get_localized_key(key, scancode)
|
|
||||||
m = keyboard_mode_name(window.screen)
|
m = keyboard_mode_name(window.screen)
|
||||||
keymap = send_text_map[m]
|
keymap = send_text_map[m]
|
||||||
return keymap.get((mods & 0b1111, key))
|
return keymap.get((mods & 0b1111, key))
|
||||||
@ -215,6 +186,7 @@ def generate_key_table():
|
|||||||
w = partial(print, file=f)
|
w = partial(print, file=f)
|
||||||
w('// auto-generated from keys.py, do not edit!')
|
w('// auto-generated from keys.py, do not edit!')
|
||||||
w('#pragma once')
|
w('#pragma once')
|
||||||
|
w('#include <stddef.h>')
|
||||||
w('#include <stdint.h>')
|
w('#include <stdint.h>')
|
||||||
w('#include <stdbool.h>')
|
w('#include <stdbool.h>')
|
||||||
w('#include <limits.h>')
|
w('#include <limits.h>')
|
||||||
@ -222,7 +194,11 @@ def generate_key_table():
|
|||||||
number_of_keys = defines.GLFW_KEY_LAST + 1
|
number_of_keys = defines.GLFW_KEY_LAST + 1
|
||||||
w('static const uint8_t key_map[%d] = {' % number_of_keys)
|
w('static const uint8_t key_map[%d] = {' % number_of_keys)
|
||||||
key_count = 0
|
key_count = 0
|
||||||
keys = {v: k for k, v in vars(defines).items() if k.startswith('GLFW_KEY_') and k not in 'GLFW_KEY_LAST GLFW_KEY_UNKNOWN'}
|
|
||||||
|
def key_name(k):
|
||||||
|
return k[len('GLFW_KEY_'):]
|
||||||
|
|
||||||
|
keys = {v: k for k, v in vars(defines).items() if k.startswith('GLFW_KEY_') and k not in {'GLFW_KEY_LAST', 'GLFW_KEY_UNKNOWN'}}
|
||||||
key_rmap = []
|
key_rmap = []
|
||||||
for i in range(number_of_keys):
|
for i in range(number_of_keys):
|
||||||
k = keys.get(i)
|
k = keys.get(i)
|
||||||
@ -235,6 +211,12 @@ def generate_key_table():
|
|||||||
if key_count > 128:
|
if key_count > 128:
|
||||||
raise OverflowError('Too many keys')
|
raise OverflowError('Too many keys')
|
||||||
w('};\n')
|
w('};\n')
|
||||||
|
w('static inline const char* key_name(int key) { switch(key) {')
|
||||||
|
for i in range(number_of_keys):
|
||||||
|
k = keys.get(i)
|
||||||
|
if k is not None:
|
||||||
|
w('case %d: return "%s";' % (i, key_name(k)))
|
||||||
|
w('default: return NULL; }}\n')
|
||||||
number_entries = 128 * 256
|
number_entries = 128 * 256
|
||||||
inits = []
|
inits = []
|
||||||
longest = 0
|
longest = 0
|
||||||
@ -275,6 +257,6 @@ def generate_key_table():
|
|||||||
else:
|
else:
|
||||||
b, k, mods, smkx, extended = b
|
b, k, mods, smkx, extended = b
|
||||||
b = bytearray(b)
|
b = bytearray(b)
|
||||||
name = '+'.join([k for k, v in all_mods.items() if v & mods] + [k.rpartition('_')[2]])
|
name = '+'.join([k for k, v in all_mods.items() if v & mods] + [key_name(k)])
|
||||||
w('{0x%x, ' % len(b) + ', '.join(map(str, b)) + '}, //', name, 'smkx:', smkx, 'extended:', extended)
|
w('{0x%x, ' % len(b) + ', '.join(map(str, b)) + '}, //', name, 'smkx:', smkx, 'extended:', extended)
|
||||||
w('};')
|
w('};')
|
||||||
|
|||||||
@ -15,12 +15,6 @@
|
|||||||
static MouseShape mouse_cursor_shape = BEAM;
|
static MouseShape mouse_cursor_shape = BEAM;
|
||||||
typedef enum MouseActions { PRESS, RELEASE, DRAG, MOVE } MouseAction;
|
typedef enum MouseActions { PRESS, RELEASE, DRAG, MOVE } MouseAction;
|
||||||
|
|
||||||
#define call_boss(name, ...) { \
|
|
||||||
PyObject *cret_ = PyObject_CallMethod(global_state.boss, #name, __VA_ARGS__); \
|
|
||||||
if (cret_ == NULL) { PyErr_Print(); } \
|
|
||||||
else Py_DECREF(cret_); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SHIFT_INDICATOR (1 << 2)
|
#define SHIFT_INDICATOR (1 << 2)
|
||||||
#define ALT_INDICATOR (1 << 3)
|
#define ALT_INDICATOR (1 << 3)
|
||||||
#define CONTROL_INDICATOR (1 << 4)
|
#define CONTROL_INDICATOR (1 << 4)
|
||||||
|
|||||||
@ -127,7 +127,7 @@ color_as_int(PyObject *color) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define dict_iter(d) { \
|
#define dict_iter(d) { \
|
||||||
PyObject *key, *value; Py_ssize_t pos; \
|
PyObject *key, *value; Py_ssize_t pos = 0; \
|
||||||
while (PyDict_Next(d, &pos, &key, &value))
|
while (PyDict_Next(d, &pos, &key, &value))
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
|||||||
@ -78,6 +78,12 @@ typedef struct {
|
|||||||
extern GlobalState global_state;
|
extern GlobalState global_state;
|
||||||
bool drag_scroll(Window *);
|
bool drag_scroll(Window *);
|
||||||
|
|
||||||
|
#define call_boss(name, ...) { \
|
||||||
|
PyObject *cret_ = PyObject_CallMethod(global_state.boss, #name, __VA_ARGS__); \
|
||||||
|
if (cret_ == NULL) { PyErr_Print(); } \
|
||||||
|
else Py_DECREF(cret_); \
|
||||||
|
}
|
||||||
|
|
||||||
#define EXTERNAL_FUNC(name, ret, ...) typedef ret (*name##_func)(__VA_ARGS__); extern name##_func name
|
#define EXTERNAL_FUNC(name, ret, ...) typedef ret (*name##_func)(__VA_ARGS__); extern name##_func name
|
||||||
#define EXTERNAL_FUNC0(name, ret) typedef ret (*name##_func)(); extern name##_func name
|
#define EXTERNAL_FUNC0(name, ret) typedef ret (*name##_func)(); extern name##_func name
|
||||||
EXTERNAL_FUNC0(draw_borders, void);
|
EXTERNAL_FUNC0(draw_borders, void);
|
||||||
|
|||||||
@ -39,7 +39,6 @@ class TestParser(BaseTest):
|
|||||||
mods,
|
mods,
|
||||||
w,
|
w,
|
||||||
defines.GLFW_PRESS,
|
defines.GLFW_PRESS,
|
||||||
get_localized_key=lambda k, s: k
|
|
||||||
)
|
)
|
||||||
self.ae(b'\033' + expected.encode('ascii'), actual)
|
self.ae(b'\033' + expected.encode('ascii'), actual)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user