Skip to content

Add Basic IME Support for macOS #3108

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed

Add Basic IME Support for macOS #3108

wants to merge 2 commits into from

Conversation

liuliu
Copy link
Contributor

@liuliu liuliu commented Apr 7, 2020

This PR added basic IME support for macOS. Particularly, a very simple
TextInputClient implementation added to facilitate the inputs.

Screen Shot 2020-04-07 at 4 37 28 PM

Test Plan:

Run the example, add proper font support. Typing Chinese / Japanese in
the input box of the demo. See it now works.

TODO:

Need to position the IME window properly (likely to return reasonable
position in firstRectForCharacterRange:actualRange:).

Need to figure out whether need to add markedText support and how.
It requires to display the markedText, but not sure with imgui, what's
the best way of doing that (I want to avoid taint the input text, so
maybe it is another Text on screen somewhere? But how to do that not
intrusively?).

@ocornut
Copy link
Owner

ocornut commented Apr 8, 2020

Hello,

Need to position the IME window properly (likely to return reasonable
position in firstRectForCharacterRange:actualRange:).

io.ImeSetInputScreenPosFn() will be called to specify the caret position so you may use that to position your rectangle. We could decide to alter this API if more information are needed for correct IME support.

Need to figure out whether need to add markedText support and how.
It requires to display the markedText, but not sure with imgui, what's
the best way of doing that (I want to avoid taint the input text, so
maybe it is another Text on screen somewhere? But how to do that not
intrusively?).

I am not sure what "markedText" is, could you clarify?

Please note that the Docking branch already io.ImeSetInputScreenPosFn` in a "Platform" function will support for multiple windows, so the exact api is fairly work in progress. I think we should backport some of the changes that have been made from Docking branch to Master there.

One unknown, is that the current back-ends organisation would suggest that only imgui_impl_osx.mm would support the new IME support you are working on. It would be great if we can find a way to make this code usable by the SDL and GLFW backends (for exemple, we can imagine that compiling them under OSX would leverage some of the OSX code).

@liuliu
Copy link
Contributor Author

liuliu commented Apr 8, 2020

io.ImeSetInputScreenPosFn() will be called to specify the caret position so you may use that to position your rectangle. We could decide to alter this API if more information are needed for correct IME support.

Will try to fix this later today, not sure how multi-viewport can come into play with a singleton NSTextInputContext though, but seems doable after consulting the other PR for the IME support (#2598).

I am not sure what "markedText" is, could you clarify?

Screen Shot 2020-04-08 at 10 40 08 AM

Note in the screenshot, there is pinyin "di'fang" showing up in the Chrome navigation bar. These are passed to the text input through "markedText" mechanism. It never insertText:replacementRange:, but rather, through setMarkedText:selectedRange:replacementRange: so it can be updated along side the real text. Not sure how imgui handles this for other OSes, or there is any recommended way of doing things in imgui for this.

One unknown, is that the current back-ends organisation would suggest that only imgui_impl_osx.mm would support the new IME support you are working on. It would be great if we can find a way to make this code usable by the SDL and GLFW backends (for exemple, we can imagine that compiling them under OSX would leverage some of the OSX code).

Correct, I am not sure whether SDL or GLFW already intercept and translate these events though. I haven't tried the SDL / GLFW backends on macOS yet. My intention is to have working versions on different platforms with minimal compilation requirement (for example, the macOS version can compile with one line call: https://github.com/liuliu/imgui/blob/raw-macos/compile.sh#L1). I can continue investigate SDL / GLFW once the above two issues resolved and this PR looks more promising to be merged.

@liuliu
Copy link
Contributor Author

liuliu commented Apr 8, 2020

Updated to add logic to follow the input cursor: a41be8c

Screen Shot 2020-04-08 at 11 39 57 AM

It would be nicer if I can get the text input height (not obvious how to do that considering you can push different fonts). xi-editor does that (and a few magic numbers) to make it better looking: https://github.com/xi-editor/xi-mac/blob/bc5dc4f847f00b5cd604efe4015931db558235da/Sources/XiEditor/EditView.swift#L364 That obviously is not fully applicable here since it is all CoreText around and they have one NSTextInputClient per text view.

@liuliu
Copy link
Contributor Author

liuliu commented Apr 8, 2020

Added the update to include line_height in ImeSetInputScreenPosFn: 975f963

It now positioned correctly below the text.

Screen Shot 2020-04-08 at 12 20 51 PM

I can separate that change into a different PR if you prefer.

@ocornut
Copy link
Owner

ocornut commented Apr 9, 2020

I can separate that change into a different PR if you prefer.

Yes that would be good, we can discuss that specifically in a separate PR and it may force me to redesign the API ahead for multi-viewport.

Would passing the entire frame/rectangle of the widget also be useful?
I noticed that SDL abstraction of IME is passing a rectangle, I am not sure what it correspond.
Let me know if you can think of other useful values.

There's something inconsistent, which is that you are polling io.WantTextInput to decide when to display the IME. Under Windows by default we don't decide when it appears (it appears when character input starts), so the initial API was only a pos x/y update via that ImeSetInputScreenPosFn() function, and this was supported way before I added io.WantTextInput (which I added initially for on-screen keyboard on mobile).

Maybe we can redesign that whole API to store fields in io structure and remove the function all-together, and the backend can poll those fields?

@liuliu
Copy link
Contributor Author

liuliu commented Apr 9, 2020

Would passing the entire frame/rectangle of the widget also be useful?
I noticed that SDL abstraction of IME is passing a rectangle, I am not sure what it correspond.
Let me know if you can think of other useful values.

It could be, if it helps me to solve "where to put the markedText" question (#3108 (comment), basically attaching a hover window to show markedText). Let me know what do you think about that (the io.addInputCharacters method is pretty limited and I cannot easily put it in the input box and modify it as we go).

@liuliu
Copy link
Contributor Author

liuliu commented Jun 9, 2020

Hi, please let me know what fixes would required to get this merged. Thanks!

@ocornut
Copy link
Owner

ocornut commented Jan 5, 2022

Hello,

As per #3113 (comment) this PR will currently break but we now have a better API for IME stuff. This PR can probably we reworked to only alter the backend (no change to core needed hopefully).

@liuliu
Copy link
Contributor Author

liuliu commented Jan 11, 2022

@ocornut updated.

@ocornut
Copy link
Owner

ocornut commented Jan 12, 2022

Thank you! Tweaked coding style, added changelog and merged as e6f008d !

@vkedwardli
Copy link

Need to figure out whether need to add markedText support and how.
It requires to display the markedText, but not sure with imgui, what's
the best way of doing that (I want to avoid taint the input text, so
maybe it is another Text on screen somewhere? But how to do that not
intrusively?).

I'm facing the same issue, do you have any recommended way to draw the markedText?
Thanks

ocornut added a commit that referenced this pull request Jan 15, 2024
…87, favor of writing to 'void* ImGuiViewport::PlatformHandleRaw'.

Amend 3a90dc3 (#2589, #2598, #3108, #3113, #3653, #4642)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants