diff --git a/glfw/cocoa_window.m b/glfw/cocoa_window.m index ef604eb60..3f8feab49 100644 --- a/glfw/cocoa_window.m +++ b/glfw/cocoa_window.m @@ -1482,12 +1482,12 @@ void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) { cellWidth:(CGFloat)cellWidth cellHeight:(CGFloat)cellHeight { - (void) which; + if (which != GLFW_IME_UPDATE_CURSOR_POSITION) return; left /= window->ns.xscale; top /= window->ns.yscale; cellWidth /= window->ns.xscale; cellHeight /= window->ns.yscale; - debug_key("updateIMEState: %f, %f, %f, %f\n", left, top, cellWidth, cellHeight); + debug_key("updateIMEState: left=%f, top=%f, width=%f, height=%f\n", left, top, cellWidth, cellHeight); const NSRect frame = [window->ns.view frame]; const NSRect rectInView = NSMakeRect(left, frame.size.height - top - cellHeight, diff --git a/kitty/fast_data_types.pyi b/kitty/fast_data_types.pyi index 32ff71453..430cc8310 100644 --- a/kitty/fast_data_types.pyi +++ b/kitty/fast_data_types.pyi @@ -1325,3 +1325,7 @@ def send_data_to_peer(peer_id: int, data: Union[str, bytes]) -> None: def set_os_window_title(os_window_id: int, title: str) -> None: pass + + +def update_ime_position_for_window(window_id: int) -> bool: + pass diff --git a/kitty/glfw.c b/kitty/glfw.c index 208d9614a..01471c565 100644 --- a/kitty/glfw.c +++ b/kitty/glfw.c @@ -382,6 +382,11 @@ window_focus_callback(GLFWwindow *w, int focused) { WINDOW_CALLBACK(on_focus, "O", focused ? Py_True : Py_False); GLFWIMEUpdateEvent ev = { .type = GLFW_IME_UPDATE_FOCUS, .focused = focused }; glfwUpdateIMEState(global_state.callback_os_window->handle, &ev); + if (focused) { + Tab *tab = global_state.callback_os_window->tabs + global_state.callback_os_window->active_tab; + Window *window = tab->windows + tab->active_window; + if (window->render_data.screen) update_ime_position(window, window->render_data.screen); + } } request_tick_callback(); global_state.callback_os_window = NULL; diff --git a/kitty/state.c b/kitty/state.c index 1fcca635e..90f176aba 100644 --- a/kitty/state.c +++ b/kitty/state.c @@ -569,6 +569,29 @@ send_pending_click_to_window_id(id_type timer_id UNUSED, void *data) { } } +static bool +update_ime_position_for_window(id_type window_id) { + for (size_t o = 0; o < global_state.num_os_windows; o++) { + OSWindow *osw = global_state.os_windows + o; + for (size_t t = 0; t < osw->num_tabs; t++) { + Tab *qtab = osw->tabs + t; + for (size_t w = 0; w < qtab->num_windows; w++) { + Window *window = qtab->windows + w; + if (window->id == window_id) { + if (window->render_data.screen) { + OSWindow *orig = global_state.callback_os_window; + global_state.callback_os_window = osw; + update_ime_position(window, window->render_data.screen); + global_state.callback_os_window = orig; + } + return true; + } + } + } + } + return false; +} + // Python API {{{ #define PYWRAP0(name) static PyObject* py##name(PYNOARG) @@ -593,6 +616,13 @@ send_pending_click_to_window_id(id_type timer_id UNUSED, void *data) { PyObject *key, *value; Py_ssize_t pos = 0; \ while (PyDict_Next(d, &pos, &key, &value)) +PYWRAP1(update_ime_position_for_window) { + id_type window_id; + PA("K", &window_id); + if (update_ime_position_for_window(window_id)) Py_RETURN_TRUE; + Py_RETURN_FALSE; +} + PYWRAP0(next_window_id) { return PyLong_FromUnsignedLongLong(global_state.window_id_counter + 1); } @@ -1128,6 +1158,7 @@ static PyMethodDef module_methods[] = { MW(set_in_sequence_mode, METH_O), MW(resolve_key_mods, METH_VARARGS), MW(handle_for_window_id, METH_VARARGS), + MW(update_ime_position_for_window, METH_VARARGS), MW(pt_to_px, METH_VARARGS), MW(add_tab, METH_O), MW(add_window, METH_VARARGS), diff --git a/kitty/window.py b/kitty/window.py index 231ba0a18..cc429ba48 100644 --- a/kitty/window.py +++ b/kitty/window.py @@ -31,7 +31,8 @@ from .fast_data_types import ( get_options, init_cell_program, mark_os_window_dirty, mouse_selection, move_cursor_to_mouse_if_in_prompt, pt_to_px, set_clipboard_string, set_titlebar_color, set_window_padding, set_window_render_data, - update_window_title, update_window_visibility, viewport_for_window + update_ime_position_for_window, update_window_title, + update_window_visibility, viewport_for_window ) from .keys import keyboard_mode_name, mod_mask from .notify import NotificationCommand, handle_notification_cmd @@ -564,6 +565,7 @@ class Window: if not self.pty_resized_once: self.pty_resized_once = True self.child.mark_terminal_ready() + update_ime_position_for_window(self.id) self.last_reported_pty_size = current_pty_size else: mark_os_window_dirty(self.os_window_id)