Wayland: Add support for the text input protocol

Fixes #3410
This commit is contained in:
Kovid Goyal 2021-03-24 11:14:14 +05:30
parent 67445a22d3
commit 317ecbc9fa
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 57 additions and 17 deletions

View File

@ -144,6 +144,8 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
- Wayland: Fix key repeat being stopped by the release of an unrelated key
(:iss:`2191`)
- Wayland: Add support for the text input protocol (:iss:`3410`)
- Add an option, :opt:`detect_urls` to control whether kitty will detect URLs
when the mouse moves over them (:pull:`3118`)

67
glfw/wl_text_input.c vendored
View File

@ -13,50 +13,73 @@
static struct zwp_text_input_v3* text_input;
static struct zwp_text_input_manager_v3* text_input_manager;
static void commit(void) { if (text_input) zwp_text_input_v3_commit (text_input); }
static void
text_input_enter(void *data UNUSED, struct zwp_text_input_v3 *text_input UNUSED, struct wl_surface *surface UNUSED) {
debug("text-input: enter event\n");
if (text_input) {
zwp_text_input_v3_enable(text_input);
zwp_text_input_v3_set_content_type(text_input, ZWP_TEXT_INPUT_V3_CONTENT_HINT_NONE, ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_TERMINAL);
commit();
}
}
static void
text_input_leave(void *data UNUSED, struct zwp_text_input_v3 *text_input UNUSED, struct wl_surface *surface UNUSED) {
debug("text-input: leave event\n");
if (text_input) {
zwp_text_input_v3_disable(text_input);
commit();
}
}
static inline void
send_text(const char *text, GLFWIMEState ime_state) {
_GLFWwindow *w = _glfwFocusedWindow();
if (w && w->callbacks.keyboard) {
GLFWkeyevent fake_ev = {.action = GLFW_PRESS};
fake_ev.text = text;
fake_ev.ime_state = ime_state;
w->callbacks.keyboard((GLFWwindow*) w, &fake_ev);
}
}
static void
text_input_preedit_string(
void *data UNUSED,
struct zwp_text_input_v3 *text_input UNUSED,
const char *text UNUSED,
int32_t cursor_begin UNUSED,
int32_t cursor_end UNUSED
const char *text,
int32_t cursor_begin,
int32_t cursor_end
) {
debug("text-input: preedit_string event: text: %s cursor_begin: %d cursor_end: %d\n", text, cursor_begin, cursor_end);
send_text(text, GLFW_IME_PREEDIT_CHANGED);
}
static void
text_input_commit_string(void *data UNUSED, struct zwp_text_input_v3 *text_input UNUSED, const char *text UNUSED) {
text_input_commit_string(void *data UNUSED, struct zwp_text_input_v3 *text_input UNUSED, const char *text) {
debug("text-input: commit_string event: text: %s\n", text);
send_text(text, GLFW_IME_COMMIT_TEXT);
}
static void
text_input_delete_surrounding_text(
void *data UNUSED,
struct zwp_text_input_v3 *zwp_text_input_v3 UNUSED,
uint32_t before_length UNUSED,
uint32_t after_length UNUSED) {
uint32_t before_length,
uint32_t after_length) {
debug("text-input: delete_surrounding_text event: before_length: %u after_length: %u\n", before_length, after_length);
}
static void
text_input_done(void *data UNUSED, struct zwp_text_input_v3 *zwp_text_input_v3 UNUSED, uint32_t serial UNUSED) {
debug("text-input: done event: serial: %u\n", serial);
}
void
_glfwWaylandBindTextInput(struct wl_registry* registry, uint32_t name) {
if (!text_input_manager) {
text_input_manager =
wl_registry_bind(registry, name,
&zwp_text_input_manager_v3_interface,
1);
}
if (!text_input_manager) text_input_manager = wl_registry_bind(registry, name, &zwp_text_input_manager_v3_interface, 1);
}
void
@ -84,3 +107,23 @@ _glfwWaylandDestroyTextInput(void) {
if (text_input_manager) zwp_text_input_manager_v3_destroy(text_input_manager);
text_input = NULL; text_input_manager = NULL;
}
void
_glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) {
if (!text_input) return;
switch(ev->type) {
case GLFW_IME_UPDATE_FOCUS:
debug("\ntext-input: updating IME focus state, focused: %d\n", ev->focused);
if (ev->focused) zwp_text_input_v3_enable(text_input); else zwp_text_input_v3_disable(text_input);
commit();
break;
case GLFW_IME_UPDATE_CURSOR_POSITION: {
const int scale = w->wl.scale;
const int left = ev->cursor.left / scale, top = ev->cursor.top / scale, width = ev->cursor.width / scale, height = ev->cursor.height / scale;
debug("\ntext-input: updating cursor position: left=%d top=%d width=%d height=%d\n", left, top, width, height);
zwp_text_input_v3_set_cursor_rectangle(text_input, left, top, width, height);
commit();
}
break;
}
}

5
glfw/wl_window.c vendored
View File

@ -2104,11 +2104,6 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
return err;
}
void
_glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) {
glfw_xkb_update_ime_state(w, &_glfw.wl.xkb, ev);
}
static void
frame_handle_redraw(void *data, struct wl_callback *callback, uint32_t time UNUSED) {
_GLFWwindow* window = (_GLFWwindow*) data;