macOS: Ensure IME position is correct on startup

This commit is contained in:
Kovid Goyal 2021-11-12 09:18:34 +05:30
parent a060bf7223
commit ffa755c723
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
5 changed files with 45 additions and 3 deletions

View File

@ -1482,12 +1482,12 @@ - (void)updateIMEStateFor:(GLFWIMEUpdateType)which
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,

View File

@ -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

View File

@ -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;

View File

@ -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),

View File

@ -31,7 +31,8 @@
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 @@ def set_geometry(self, new_geometry: WindowGeometry) -> None:
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)