macOS: Fix IME action when deleting last char (#13385)

张小白 created

Closes #12862 


https://github.com/zed-industries/zed/assets/14981363/170b1206-5894-4b90-bd5c-79761073d8f2


Release Notes:

- Fixed deleting the last character during IME composition would
mistakenly delete other characters.(#12862)

Change summary

crates/gpui/src/platform/mac/window.rs | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)

Detailed changes

crates/gpui/src/platform/mac/window.rs 🔗

@@ -344,6 +344,7 @@ struct MacWindowState {
     // Whether the next left-mouse click is also the focusing click.
     first_mouse: bool,
     fullscreen_restore_bounds: Bounds<Pixels>,
+    ime_composing: bool,
 }
 
 impl MacWindowState {
@@ -623,6 +624,7 @@ impl MacWindow {
                 external_files_dragged: false,
                 first_mouse: false,
                 fullscreen_restore_bounds: Bounds::default(),
+                ime_composing: false,
             })));
 
             (*native_window).set_ivar(
@@ -1234,6 +1236,7 @@ extern "C" fn handle_key_event(this: &Object, native_event: id, key_equivalent:
         let mut lock = window_state.lock();
         let previous_keydown_inserted_text = lock.previous_keydown_inserted_text.take();
         let mut last_inserts = lock.last_ime_inputs.take().unwrap();
+        let ime_composing = std::mem::take(&mut lock.ime_composing);
 
         let mut callback = lock.event_callback.take();
         drop(lock);
@@ -1248,7 +1251,8 @@ extern "C" fn handle_key_event(this: &Object, native_event: id, key_equivalent:
         let is_composing =
             with_input_handler(this, |input_handler| input_handler.marked_text_range())
                 .flatten()
-                .is_some();
+                .is_some()
+                || ime_composing;
 
         if let Some((text, range)) = last_insert {
             if !is_composing {
@@ -1922,6 +1926,7 @@ fn send_to_input_handler(window: &Object, ime: ImeInput) {
                     input_handler.replace_text_in_range(range, &text)
                 }
                 ImeInput::SetMarkedText(text, range, marked_range) => {
+                    lock.ime_composing = true;
                     drop(lock);
                     input_handler.replace_and_mark_text_in_range(range, &text, marked_range)
                 }