Emits an IME lost focus event when the window lost focus or closed

This commit is contained in:
pagedown 2022-01-27 10:13:57 +08:00
parent 4d920b182f
commit a987fb81a0
No known key found for this signature in database
GPG Key ID: E921CF18AC8FF6EB
6 changed files with 21 additions and 7 deletions

View File

@ -1343,5 +1343,5 @@ def set_os_window_title(os_window_id: int, title: str) -> None:
pass pass
def update_ime_position_for_window(window_id: int, force: bool = False) -> bool: def update_ime_position_for_window(window_id: int, force: bool = False, lost_focus: bool = False) -> bool:
pass pass

View File

@ -79,6 +79,12 @@ active_window(void) {
return NULL; return NULL;
} }
void
update_ime_focus(OSWindow *osw, bool focused) {
GLFWIMEUpdateEvent ev = { .focused = focused, .type = GLFW_IME_UPDATE_FOCUS };
glfwUpdateIMEState(osw->handle, &ev);
}
void void
update_ime_position(Window* w, Screen *screen) { update_ime_position(Window* w, Screen *screen) {
unsigned int cell_width = global_state.callback_os_window->fonts_data->cell_width, cell_height = global_state.callback_os_window->fonts_data->cell_height; unsigned int cell_width = global_state.callback_os_window->fonts_data->cell_width, cell_height = global_state.callback_os_window->fonts_data->cell_height;

View File

@ -762,7 +762,7 @@ restore_overlay_line(struct SaveOverlayLine *sol) {
debug("Received input from child (%s) while overlay active. Overlay contents: %s\n", sol->func_name, PyUnicode_AsUTF8(sol->overlay_text)); debug("Received input from child (%s) while overlay active. Overlay contents: %s\n", sol->func_name, PyUnicode_AsUTF8(sol->overlay_text));
screen_draw_overlay_text(sol->screen, PyUnicode_AsUTF8(sol->overlay_text)); screen_draw_overlay_text(sol->screen, PyUnicode_AsUTF8(sol->overlay_text));
Py_DECREF(sol->overlay_text); Py_DECREF(sol->overlay_text);
update_ime_position_for_window(sol->screen->window_id, false); update_ime_position_for_window(sol->screen->window_id, false, false);
} }
} }

View File

@ -602,7 +602,7 @@ send_pending_click_to_window_id(id_type timer_id UNUSED, void *data) {
} }
bool bool
update_ime_position_for_window(id_type window_id, bool force) { update_ime_position_for_window(id_type window_id, bool force, bool lost_focus) {
for (size_t o = 0; o < global_state.num_os_windows; o++) { for (size_t o = 0; o < global_state.num_os_windows; o++) {
OSWindow *osw = global_state.os_windows + o; OSWindow *osw = global_state.os_windows + o;
for (size_t t = 0; t < osw->num_tabs; t++) { for (size_t t = 0; t < osw->num_tabs; t++) {
@ -613,7 +613,8 @@ update_ime_position_for_window(id_type window_id, bool force) {
if (window->render_data.screen && (force || osw->is_focused)) { if (window->render_data.screen && (force || osw->is_focused)) {
OSWindow *orig = global_state.callback_os_window; OSWindow *orig = global_state.callback_os_window;
global_state.callback_os_window = osw; global_state.callback_os_window = osw;
update_ime_position(window, window->render_data.screen); if (lost_focus) update_ime_focus(osw, false);
else update_ime_position(window, window->render_data.screen);
global_state.callback_os_window = orig; global_state.callback_os_window = orig;
return true; return true;
} }
@ -652,8 +653,9 @@ update_ime_position_for_window(id_type window_id, bool force) {
PYWRAP1(update_ime_position_for_window) { PYWRAP1(update_ime_position_for_window) {
id_type window_id; id_type window_id;
int force = 0; int force = 0;
PA("K|p", &window_id, &force); int lost_focus = 0;
if (update_ime_position_for_window(window_id, force)) Py_RETURN_TRUE; PA("K|pp", &window_id, &force, &lost_focus);
if (update_ime_position_for_window(window_id, force, lost_focus)) Py_RETURN_TRUE;
Py_RETURN_FALSE; Py_RETURN_FALSE;
} }

View File

@ -335,6 +335,7 @@ void get_platform_dependent_config_values(void *glfw_window);
bool draw_window_title(OSWindow *window, const char *text, color_type fg, color_type bg, uint8_t *output_buf, size_t width, size_t height); bool draw_window_title(OSWindow *window, const char *text, color_type fg, color_type bg, uint8_t *output_buf, size_t width, size_t height);
uint8_t* draw_single_ascii_char(const char ch, size_t *result_width, size_t *result_height); uint8_t* draw_single_ascii_char(const char ch, size_t *result_width, size_t *result_height);
bool is_os_window_fullscreen(OSWindow *); bool is_os_window_fullscreen(OSWindow *);
void update_ime_focus(OSWindow* osw, bool focused);
void update_ime_position(Window* w, Screen *screen); void update_ime_position(Window* w, Screen *screen);
bool update_ime_position_for_window(id_type window_id, bool force); bool update_ime_position_for_window(id_type window_id, bool force, bool lost_focus);
void set_ignore_os_keyboard_processing(bool enabled); void set_ignore_os_keyboard_processing(bool enabled);

View File

@ -689,6 +689,9 @@ class Window:
tab = self.tabref() tab = self.tabref()
if tab is not None: if tab is not None:
tab.relayout_borders() tab.relayout_borders()
else:
# Cancel IME composition after loses focus
update_ime_position_for_window(self.id, True, True)
def title_changed(self, new_title: Optional[str]) -> None: def title_changed(self, new_title: Optional[str]) -> None:
self.child_title = sanitize_title(new_title or self.default_title) self.child_title = sanitize_title(new_title or self.default_title)
@ -1021,6 +1024,8 @@ class Window:
self.call_watchers(self.watchers.on_close, {}) self.call_watchers(self.watchers.on_close, {})
self.destroyed = True self.destroyed = True
if hasattr(self, 'screen'): if hasattr(self, 'screen'):
# Cancel IME composition when window is destroyed
update_ime_position_for_window(self.id, True, True)
# Remove cycles so that screen is de-allocated immediately # Remove cycles so that screen is de-allocated immediately
self.screen.reset_callbacks() self.screen.reset_callbacks()
del self.screen del self.screen