mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-04 04:06:06 -05:00
ime: track IME focus independently from keyboard focus
Replace the seat->ime.focused boolean with a terminal instace pointer, seat->ime_focus. Set and reset this on ime::enter() and ime::leave() events, and use this instead of seat->kbd_focus on all other IME events. This fixes two issues: a) buggy compositors that sometimes sends an IME enter event without first having sent a keyboard enter event. b) seats may be IME capable while still lacking the keyboard capability. Such seats will *always* see IME enter events without a corresponding keyboard enter event.
This commit is contained in:
parent
d852178540
commit
96f23b4c64
4 changed files with 21 additions and 14 deletions
|
|
@ -72,6 +72,7 @@
|
|||
* Graphical corruption when viewport is at the top of the scrollback,
|
||||
and the output is scrolling.
|
||||
* Improved text reflow of logical lines with trailing empty cells ([#1055][1055])
|
||||
* IME focus is now tracked independently from keyboard focus.
|
||||
|
||||
[1055]: https://codeberg.org/dnkl/foot/issues/1055
|
||||
|
||||
|
|
|
|||
28
ime.c
28
ime.c
|
|
@ -56,12 +56,18 @@ enter(void *data, struct zwp_text_input_v3 *zwp_text_input_v3,
|
|||
struct wl_surface *surface)
|
||||
{
|
||||
struct seat *seat = data;
|
||||
struct wl_window *win = wl_surface_get_user_data(surface);
|
||||
struct terminal *term = win->term;
|
||||
|
||||
LOG_DBG("enter: seat=%s", seat->name);
|
||||
LOG_DBG("enter: seat=%s, term=%p", seat->name, (const void *)term);
|
||||
|
||||
if (seat->kbd_focus != term) {
|
||||
LOG_WARN("compositor sent ime::enter() event before the "
|
||||
"corresponding keyboard_enter() event");
|
||||
}
|
||||
|
||||
/* The main grid is the *only* input-receiving surface we have */
|
||||
xassert(seat->kbd_focus != NULL);
|
||||
seat->ime.focused = true;
|
||||
seat->ime_focus = term;
|
||||
ime_enable(seat);
|
||||
}
|
||||
|
||||
|
|
@ -73,7 +79,7 @@ leave(void *data, struct zwp_text_input_v3 *zwp_text_input_v3,
|
|||
LOG_DBG("leave: seat=%s", seat->name);
|
||||
|
||||
ime_disable(seat);
|
||||
seat->ime.focused = false;
|
||||
seat->ime_focus = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -138,7 +144,7 @@ done(void *data, struct zwp_text_input_v3 *zwp_text_input_v3,
|
|||
|
||||
LOG_DBG("done: serial=%u", serial);
|
||||
struct seat *seat = data;
|
||||
struct terminal *term = seat->kbd_focus;
|
||||
struct terminal *term = seat->ime_focus;
|
||||
|
||||
if (seat->ime.serial != serial) {
|
||||
LOG_DBG("IME serial mismatch: expected=0x%08x, got 0x%08x",
|
||||
|
|
@ -364,10 +370,10 @@ ime_send_cursor_rect(struct seat *seat)
|
|||
if (unlikely(seat->wayl->text_input_manager == NULL))
|
||||
return;
|
||||
|
||||
if (!seat->ime.focused)
|
||||
if (seat->ime_focus == NULL)
|
||||
return;
|
||||
|
||||
struct terminal *term = seat->kbd_focus;
|
||||
struct terminal *term = seat->ime_focus;
|
||||
|
||||
if (!term->ime_enabled)
|
||||
return;
|
||||
|
|
@ -399,10 +405,10 @@ ime_enable(struct seat *seat)
|
|||
if (unlikely(seat->wayl->text_input_manager == NULL))
|
||||
return;
|
||||
|
||||
if (!seat->ime.focused)
|
||||
if (seat->ime_focus == NULL)
|
||||
return;
|
||||
|
||||
struct terminal *term = seat->kbd_focus;
|
||||
struct terminal *term = seat->ime_focus;
|
||||
if (term == NULL)
|
||||
return;
|
||||
|
||||
|
|
@ -437,7 +443,7 @@ ime_disable(struct seat *seat)
|
|||
if (unlikely(seat->wayl->text_input_manager == NULL))
|
||||
return;
|
||||
|
||||
if (!seat->ime.focused)
|
||||
if (seat->ime_focus == NULL)
|
||||
return;
|
||||
|
||||
ime_reset_pending(seat);
|
||||
|
|
@ -451,7 +457,7 @@ ime_disable(struct seat *seat)
|
|||
void
|
||||
ime_update_cursor_rect(struct seat *seat)
|
||||
{
|
||||
struct terminal *term = seat->kbd_focus;
|
||||
struct terminal *term = seat->ime_focus;
|
||||
|
||||
/* Set in render_ime_preedit() */
|
||||
if (seat->ime.preedit.cells != NULL)
|
||||
|
|
|
|||
4
render.c
4
render.c
|
|
@ -3576,7 +3576,7 @@ frame_callback(void *data, struct wl_callback *wl_callback, uint32_t callback_da
|
|||
grid_render(term);
|
||||
|
||||
tll_foreach(term->wl->seats, it) {
|
||||
if (it->item.kbd_focus == term)
|
||||
if (it->item.ime_focus == term)
|
||||
ime_update_cursor_rect(&it->item);
|
||||
}
|
||||
|
||||
|
|
@ -4058,7 +4058,7 @@ fdm_hook_refresh_pending_terminals(struct fdm *fdm, void *data)
|
|||
grid_render(term);
|
||||
|
||||
tll_foreach(term->wl->seats, it) {
|
||||
if (it->item.kbd_focus == term)
|
||||
if (it->item.ime_focus == term)
|
||||
ime_update_cursor_rect(&it->item);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ struct seat {
|
|||
/* Focused terminals */
|
||||
struct terminal *kbd_focus;
|
||||
struct terminal *mouse_focus;
|
||||
struct terminal *ime_focus;
|
||||
|
||||
/* Keyboard state */
|
||||
struct wl_keyboard *wl_keyboard;
|
||||
|
|
@ -202,7 +203,6 @@ struct seat {
|
|||
} pending;
|
||||
} surrounding;
|
||||
|
||||
bool focused;
|
||||
uint32_t serial;
|
||||
} ime;
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue