diff --git a/ime.c b/ime.c index 53a908b0..a60e72f5 100644 --- a/ime.c +++ b/ime.c @@ -20,43 +20,16 @@ enter(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, struct wl_surface *surface) { struct seat *seat = data; + LOG_DBG("enter: seat=%s", seat->name); - assert(seat->kbd_focus != NULL); + /* The main grid is the *only* input-receiving surface we have */ + /* TODO: can we receive text_input::enter() _before_ keyboard_enter()? */ + struct terminal UNUSED *term = seat->kbd_focus; + assert(term != NULL); + assert(term_surface_kind(term, surface) == TERM_SURF_GRID); - switch (term_surface_kind(seat->kbd_focus, surface)) { - case TERM_SURF_GRID: - zwp_text_input_v3_enable(seat->wl_text_input); - zwp_text_input_v3_set_content_type( - seat->wl_text_input, - ZWP_TEXT_INPUT_V3_CONTENT_HINT_NONE, - ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_TERMINAL); - - /* TODO: set cursor rectangle */ - zwp_text_input_v3_set_cursor_rectangle(seat->wl_text_input, 0, 0, 15, 15); - break; - - case TERM_SURF_SEARCH: - /* TODO */ - /* FALLTHROUGH */ - - case TERM_SURF_NONE: - case TERM_SURF_SCROLLBACK_INDICATOR: - case TERM_SURF_RENDER_TIMER: - case TERM_SURF_TITLE: - case TERM_SURF_BORDER_LEFT: - case TERM_SURF_BORDER_RIGHT: - case TERM_SURF_BORDER_TOP: - case TERM_SURF_BORDER_BOTTOM: - case TERM_SURF_BUTTON_MINIMIZE: - case TERM_SURF_BUTTON_MAXIMIZE: - case TERM_SURF_BUTTON_CLOSE: - zwp_text_input_v3_disable(seat->wl_text_input); - break; - } - - zwp_text_input_v3_commit(seat->wl_text_input); - seat->ime.serial++; + ime_enable(seat); } static void @@ -65,11 +38,7 @@ leave(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, { struct seat *seat = data; LOG_DBG("leave: seat=%s", seat->name); - zwp_text_input_v3_disable(seat->wl_text_input); - zwp_text_input_v3_commit(seat->wl_text_input); - seat->ime.serial++; - - ime_reset(seat); + ime_disable(seat); } static void @@ -146,7 +115,7 @@ done(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, /* 1. Delete existing pre-edit text */ if (term->ime.preedit.cells != NULL) { - term_reset_ime(term); + term_ime_reset(term); render_refresh(term); } @@ -337,6 +306,36 @@ ime_reset(struct seat *seat) ime_reset_commit(seat); } +void +ime_enable(struct seat *seat) +{ + struct terminal *term = seat->kbd_focus; + assert(term != NULL); + + if (!term->ime.enabled) + return; + + ime_reset(seat); + + zwp_text_input_v3_enable(seat->wl_text_input); + zwp_text_input_v3_set_content_type( + seat->wl_text_input, + ZWP_TEXT_INPUT_V3_CONTENT_HINT_NONE, + ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_TERMINAL); + + zwp_text_input_v3_commit(seat->wl_text_input); + seat->ime.serial++; +} + +void +ime_disable(struct seat *seat) +{ + ime_reset(seat); + + zwp_text_input_v3_disable(seat->wl_text_input); + zwp_text_input_v3_commit(seat->wl_text_input); + seat->ime.serial++; +} const struct zwp_text_input_v3_listener text_input_listener = { .enter = &enter, @@ -349,6 +348,9 @@ const struct zwp_text_input_v3_listener text_input_listener = { #else /* !FOOT_IME_ENABLED */ +void ime_enable(struct seat *seat) {} +void ime_disable(struct seat *seat) {} + void ime_reset_preedit(struct seat *seat) {} void ime_reset_commit(struct seat *seat) {} void ime_reset(struct seat *seat) {} diff --git a/ime.h b/ime.h index d5c96534..7036bbde 100644 --- a/ime.h +++ b/ime.h @@ -10,6 +10,9 @@ extern const struct zwp_text_input_v3_listener text_input_listener; struct seat; +void ime_enable(struct seat *seat); +void ime_disable(struct seat *seat); + void ime_reset_preedit(struct seat *seat); void ime_reset_commit(struct seat *seat); void ime_reset(struct seat *seat); diff --git a/pgo/pgo.c b/pgo/pgo.c index d401e533..0dc08f61 100644 --- a/pgo/pgo.c +++ b/pgo/pgo.c @@ -126,6 +126,9 @@ extract_finish(struct extraction_context *context, char **text, size_t *len) void cmd_scrollback_up(struct terminal *term, int rows) {} void cmd_scrollback_down(struct terminal *term, int rows) {} +void ime_enable(struct seat *seat) {} +void ime_disable(struct seat *seat) {} + int main(int argc, const char *const *argv) { diff --git a/terminal.c b/terminal.c index cfcc2040..80c162bd 100644 --- a/terminal.c +++ b/terminal.c @@ -24,6 +24,7 @@ #include "config.h" #include "extract.h" #include "grid.h" +#include "ime.h" #include "quirks.h" #include "reaper.h" #include "render.h" @@ -1116,6 +1117,11 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper, .shutdown_data = shutdown_data, .foot_exe = xstrdup(foot_exe), .cwd = xstrdup(cwd), +#if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED + .ime = { + .enabled = true, + }, +#endif }; for (size_t i = 0; i < 4; i++) { @@ -1403,7 +1409,7 @@ term_destroy(struct terminal *term) tll_free(term->alt.sixel_images); sixel_fini(term); - term_reset_ime(term); + term_ime_reset(term); free(term->foot_exe); free(term->cwd); @@ -1559,6 +1565,10 @@ term_reset(struct terminal *term, bool hard) sixel_destroy(&it->item); tll_free(term->alt.sixel_images); +#if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED + term_ime_enable(term); +#endif + if (!hard) return; @@ -2220,7 +2230,7 @@ term_kbd_focus_out(struct terminal *term) #if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED if (term->ime.preedit.cells != NULL) { - term_reset_ime(term); + term_ime_reset(term); render_refresh(term); } #endif @@ -2754,12 +2764,64 @@ term_view_to_text(const struct terminal *term, char **text, size_t *len) return rows_to_text(term, start, end, text, len); } -void -term_reset_ime(struct terminal *term) +bool +term_ime_is_enabled(const struct terminal *term) { #if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED - free(term->ime.preedit.cells); - term->ime.preedit.cells = NULL; - term->ime.preedit.count = 0; + return term->ime.enabled; +#else + return false; +#endif +} + +void +term_ime_enable(struct terminal *term) +{ +#if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED + if (term->ime.enabled) + return; + + LOG_DBG("IME enabled"); + + term->ime.enabled = true; + term_ime_reset(term); + + /* IME is per seat - enable on all seat currenly focusing us */ + tll_foreach(term->wl->seats, it) { + if (it->item.kbd_focus == term) + ime_enable(&it->item); + } +#endif +} + +void +term_ime_disable(struct terminal *term) +{ +#if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED + if (!term->ime.enabled) + return; + + LOG_DBG("IME disabled"); + + term->ime.enabled = false; + term_ime_reset(term); + + /* IME is per seat - disable on all seat currenly focusing us */ + tll_foreach(term->wl->seats, it) { + if (it->item.kbd_focus == term) + ime_disable(&it->item); + } +#endif +} + +void +term_ime_reset(struct terminal *term) +{ +#if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED + if (term->ime.preedit.cells != NULL) { + free(term->ime.preedit.cells); + term->ime.preedit.cells = NULL; + term->ime.preedit.count = 0; + } #endif } diff --git a/terminal.h b/terminal.h index bbe7df25..6a634914 100644 --- a/terminal.h +++ b/terminal.h @@ -472,6 +472,7 @@ struct terminal { #if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED struct { + bool enabled; struct { struct cell *cells; int count; @@ -608,4 +609,7 @@ bool term_scrollback_to_text( bool term_view_to_text( const struct terminal *term, char **text, size_t *len); -void term_reset_ime(struct terminal *term); +bool term_ime_is_enabled(const struct terminal *term); +void term_ime_enable(struct terminal *term); +void term_ime_disable(struct terminal *term); +void term_ime_reset(struct terminal *term);