mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-04-03 07:15:29 -04:00
ime: add functions to enable/disable IME, simplify code that enables IME
We may want to be able to enable/disable IME run-time, even though we have received an ‘enter’ IME event. This enables us to do that. Also add functions to enable/disable IME on a per-terminal instance basis. A terminal may have multiple seats focusing it, and enabling/disabling IME in a terminal instance enables/disables IME on all those seats. Finally, the code to enable IME is simplified; the *only* surface that can ever receive ‘enter’ IME events is the main grid. All other surfaces are sub-surfaces, without their own keyboard focus.
This commit is contained in:
parent
5c17b7f8e7
commit
b59d695b2b
5 changed files with 122 additions and 48 deletions
82
ime.c
82
ime.c
|
|
@ -20,43 +20,16 @@ enter(void *data, struct zwp_text_input_v3 *zwp_text_input_v3,
|
||||||
struct wl_surface *surface)
|
struct wl_surface *surface)
|
||||||
{
|
{
|
||||||
struct seat *seat = data;
|
struct seat *seat = data;
|
||||||
|
|
||||||
LOG_DBG("enter: seat=%s", seat->name);
|
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)) {
|
ime_enable(seat);
|
||||||
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++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -65,11 +38,7 @@ leave(void *data, struct zwp_text_input_v3 *zwp_text_input_v3,
|
||||||
{
|
{
|
||||||
struct seat *seat = data;
|
struct seat *seat = data;
|
||||||
LOG_DBG("leave: seat=%s", seat->name);
|
LOG_DBG("leave: seat=%s", seat->name);
|
||||||
zwp_text_input_v3_disable(seat->wl_text_input);
|
ime_disable(seat);
|
||||||
zwp_text_input_v3_commit(seat->wl_text_input);
|
|
||||||
seat->ime.serial++;
|
|
||||||
|
|
||||||
ime_reset(seat);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -146,7 +115,7 @@ done(void *data, struct zwp_text_input_v3 *zwp_text_input_v3,
|
||||||
|
|
||||||
/* 1. Delete existing pre-edit text */
|
/* 1. Delete existing pre-edit text */
|
||||||
if (term->ime.preedit.cells != NULL) {
|
if (term->ime.preedit.cells != NULL) {
|
||||||
term_reset_ime(term);
|
term_ime_reset(term);
|
||||||
render_refresh(term);
|
render_refresh(term);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -337,6 +306,36 @@ ime_reset(struct seat *seat)
|
||||||
ime_reset_commit(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 = {
|
const struct zwp_text_input_v3_listener text_input_listener = {
|
||||||
.enter = &enter,
|
.enter = &enter,
|
||||||
|
|
@ -349,6 +348,9 @@ const struct zwp_text_input_v3_listener text_input_listener = {
|
||||||
|
|
||||||
#else /* !FOOT_IME_ENABLED */
|
#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_preedit(struct seat *seat) {}
|
||||||
void ime_reset_commit(struct seat *seat) {}
|
void ime_reset_commit(struct seat *seat) {}
|
||||||
void ime_reset(struct seat *seat) {}
|
void ime_reset(struct seat *seat) {}
|
||||||
|
|
|
||||||
3
ime.h
3
ime.h
|
|
@ -10,6 +10,9 @@ extern const struct zwp_text_input_v3_listener text_input_listener;
|
||||||
|
|
||||||
struct seat;
|
struct seat;
|
||||||
|
|
||||||
|
void ime_enable(struct seat *seat);
|
||||||
|
void ime_disable(struct seat *seat);
|
||||||
|
|
||||||
void ime_reset_preedit(struct seat *seat);
|
void ime_reset_preedit(struct seat *seat);
|
||||||
void ime_reset_commit(struct seat *seat);
|
void ime_reset_commit(struct seat *seat);
|
||||||
void ime_reset(struct seat *seat);
|
void ime_reset(struct seat *seat);
|
||||||
|
|
|
||||||
|
|
@ -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_up(struct terminal *term, int rows) {}
|
||||||
void cmd_scrollback_down(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
|
int
|
||||||
main(int argc, const char *const *argv)
|
main(int argc, const char *const *argv)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
76
terminal.c
76
terminal.c
|
|
@ -24,6 +24,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "extract.h"
|
#include "extract.h"
|
||||||
#include "grid.h"
|
#include "grid.h"
|
||||||
|
#include "ime.h"
|
||||||
#include "quirks.h"
|
#include "quirks.h"
|
||||||
#include "reaper.h"
|
#include "reaper.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
|
|
@ -1116,6 +1117,11 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper,
|
||||||
.shutdown_data = shutdown_data,
|
.shutdown_data = shutdown_data,
|
||||||
.foot_exe = xstrdup(foot_exe),
|
.foot_exe = xstrdup(foot_exe),
|
||||||
.cwd = xstrdup(cwd),
|
.cwd = xstrdup(cwd),
|
||||||
|
#if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED
|
||||||
|
.ime = {
|
||||||
|
.enabled = true,
|
||||||
|
},
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
for (size_t i = 0; i < 4; i++) {
|
for (size_t i = 0; i < 4; i++) {
|
||||||
|
|
@ -1403,7 +1409,7 @@ term_destroy(struct terminal *term)
|
||||||
tll_free(term->alt.sixel_images);
|
tll_free(term->alt.sixel_images);
|
||||||
sixel_fini(term);
|
sixel_fini(term);
|
||||||
|
|
||||||
term_reset_ime(term);
|
term_ime_reset(term);
|
||||||
|
|
||||||
free(term->foot_exe);
|
free(term->foot_exe);
|
||||||
free(term->cwd);
|
free(term->cwd);
|
||||||
|
|
@ -1559,6 +1565,10 @@ term_reset(struct terminal *term, bool hard)
|
||||||
sixel_destroy(&it->item);
|
sixel_destroy(&it->item);
|
||||||
tll_free(term->alt.sixel_images);
|
tll_free(term->alt.sixel_images);
|
||||||
|
|
||||||
|
#if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED
|
||||||
|
term_ime_enable(term);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!hard)
|
if (!hard)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -2220,7 +2230,7 @@ term_kbd_focus_out(struct terminal *term)
|
||||||
|
|
||||||
#if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED
|
#if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED
|
||||||
if (term->ime.preedit.cells != NULL) {
|
if (term->ime.preedit.cells != NULL) {
|
||||||
term_reset_ime(term);
|
term_ime_reset(term);
|
||||||
render_refresh(term);
|
render_refresh(term);
|
||||||
}
|
}
|
||||||
#endif
|
#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);
|
return rows_to_text(term, start, end, text, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
term_reset_ime(struct terminal *term)
|
term_ime_is_enabled(const struct terminal *term)
|
||||||
{
|
{
|
||||||
#if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED
|
#if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED
|
||||||
free(term->ime.preedit.cells);
|
return term->ime.enabled;
|
||||||
term->ime.preedit.cells = NULL;
|
#else
|
||||||
term->ime.preedit.count = 0;
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -472,6 +472,7 @@ struct terminal {
|
||||||
|
|
||||||
#if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED
|
#if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED
|
||||||
struct {
|
struct {
|
||||||
|
bool enabled;
|
||||||
struct {
|
struct {
|
||||||
struct cell *cells;
|
struct cell *cells;
|
||||||
int count;
|
int count;
|
||||||
|
|
@ -608,4 +609,7 @@ bool term_scrollback_to_text(
|
||||||
bool term_view_to_text(
|
bool term_view_to_text(
|
||||||
const struct terminal *term, char **text, size_t *len);
|
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);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue