rust-windowing / winit

Window handling library in pure Rust
https://docs.rs/winit/
Apache License 2.0
4.76k stars 892 forks source link

IME and the MacOS Character Viewer #3342

Open HolgerGottChristensen opened 9 months ago

HolgerGottChristensen commented 9 months ago

I have an application based on winit 0.29.7. On MacOS you can open the character viewer using the fn/๐ŸŒ key.

Screenshot 2023-12-30 at 18 07 14

This seem to be the preferred way of inserting symbols and emojis into text fields in an application. When I double click one of the characters (which inserts it into other applications), no events are sent from winit.

https://github.com/rust-windowing/winit/assets/11473146/af7daf52-b795-4b56-8fec-0074e2b55cd7

I have experimented more with winit, and it seems that it has to do with the IME implementation. When I enable IME it still does not send events, but when IME has started, for example by typing the ยจ character, I can then insert emojis by double clicking on the character viewer.

https://github.com/rust-windowing/winit/assets/11473146/7aefb8ca-2d02-4cf4-90e6-8f0ee68ae215

When I end the IME for example by typing e, the events of the character viewer stops being sent again.

I looked into the MacOS implementation of winit. The events from MacOS are sent through the insertText:replacementRange: event handler in the file src/platform_impl/macos/view.rs file.

I have tried debugging the issue, and inserting a dbg in the method:

Screenshot 2023-12-30 at 18 29 56

When clicking the character viewer, the following is printed, when IME is not started:

TRACE [winit::platform_impl::platform::view] Triggered `insertText:replacementRange:`
[src/platform_impl/macos/view.rs:398] &string = "๐Ÿ˜€"
TRACE [winit::platform_impl::platform::view] Triggered `hasMarkedText`
TRACE [winit::platform_impl::platform::view] Completed `hasMarkedText`
[src/platform_impl/macos/view.rs:398] unsafe { self.hasMarkedText() } = false
[src/platform_impl/macos/view.rs:398] self.is_ime_enabled() = false
[src/platform_impl/macos/view.rs:398] !is_control = true
TRACE [winit::platform_impl::platform::view] Triggered `hasMarkedText`
TRACE [winit::platform_impl::platform::view] Completed `hasMarkedText`
TRACE [winit::platform_impl::platform::view] Completed `insertText:replacementRange:`

When IME is started(by pressing ยจ), it prints the following:

TRACE [winit::platform_impl::platform::view] Triggered `insertText:replacementRange:`
[src/platform_impl/macos/view.rs:396] &string = "๐Ÿ˜€"
TRACE [winit::platform_impl::platform::view] Triggered `hasMarkedText`
TRACE [winit::platform_impl::platform::view] Completed `hasMarkedText`
[src/platform_impl/macos/view.rs:396] unsafe { self.hasMarkedText() } = true
[src/platform_impl/macos/view.rs:396] self.is_ime_enabled() = true
[src/platform_impl/macos/view.rs:396] !is_control = true
TRACE [winit::platform_impl::platform::view] Triggered `hasMarkedText`
TRACE [winit::platform_impl::platform::view] Completed `hasMarkedText`
TRACE [winit::platform_impl::platform::view] Completed `insertText:replacementRange:`

and sends the events:

WindowEvent { window_id: WindowId(WindowId(5735737648)), event: Ime(Preedit("", None)) }
WindowEvent { window_id: WindowId(WindowId(5735737648)), event: Ime(Commit("๐Ÿ˜€")) }

If anything is missing I will try my best to provide it.

madsmtm commented 9 months ago

has to do with the IME implementation

Very likely.

Thanks for the detailed investigation, I don't have the time to conjure up a fix this week, but might take a stab at it later (especially if reminded).

HolgerGottChristensen commented 8 months ago

@madsmtm Here is your friendly reminder ๐Ÿ˜ƒ

9mm commented 4 months ago

Emojis definitely would be nice to have natively supported in popup

andrewhannebrink commented 2 months ago

I love alacritty. If this issue gets fixed it would be a near perfect experience.

chardskarth commented 3 days ago

@madsmtm here's another friendly reminder. :D

If I knew rust, I'd pick this up myself because both alacritty & neovide is working best for me right now.