Skip to content

app: improve IME composition handling - #171

Open
qianniancn wants to merge 3 commits into
gioui:mainfrom
qianniancn:ime-windows-composition
Open

app: improve IME composition handling#171
qianniancn wants to merge 3 commits into
gioui:mainfrom
qianniancn:ime-windows-composition

Conversation

@qianniancn

Copy link
Copy Markdown
Contributor

Place the Windows IME candidate window under the active composition text.

Also avoid cancelling IME composition when a snippet update only expands
around matching text.

Fixes: https://todo.sr.ht/~eliasnaur/gio/697

qiannian added 2 commits July 8, 2026 15:53
SnippetCmd can grow to include surrounding text while an IME
composition is active. If the selection has not moved and the old
snippet still matches the new one, don't cancel the platform
composition.

Signed-off-by: qiannian <qianniancn@gmail.com>
Send the editor's visible composition bounds with SelectionCmd and use
them as the CFS_EXCLUDE rectangle for ImmSetCandidateWindow. That puts
the candidate list below the text being composed, instead of just under
the caret.

Handle RESULTSTR and COMPSTR as separate IME updates. Cursor-only
updates move the IME cursor without replacing text in the editor.

Fixes: https://todo.sr.ht/~eliasnaur/gio/697
Signed-off-by: qiannian <qianniancn@gmail.com>

@whereswaldon whereswaldon left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much for working on this. I have a couple requests, but they aren't very complex:

  1. The implementation of the windows IME event handling feels like it could be made easier to comprehend by a refactor focusing on returning early from each category of message. I may have misunderstood the constraints on the implementation though, so feel free to correct me if my requests there aren't possible/practical.
  2. The way that the editor is now updating the IME state seems too expensive to do every frame; I'd like to more precisely do that work only when we must.

Overall, I think this is looking really promising. Thanks again.

Comment thread app/os_windows.go
Comment thread app/os_windows.go Outdated
Comment thread widget/editor.go
Comment thread app/os_windows.go
Signed-off-by: qiannian <qianniancn@gmail.com>
@qianniancn
qianniancn requested a review from whereswaldon July 21, 2026 15:36
@whereswaldon
whereswaldon force-pushed the main branch 2 times, most recently from 4d8d111 to 23e823d Compare July 23, 2026 09:40

@whereswaldon whereswaldon left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, this is now merged.

To git.sr.ht:~eliasnaur/gio
   18034696..c7e3d6c1  main -> main

There is still an open comment I'd like to discuss with @eliasnaur , so I'm not going to close out the PR just yet.

Comment thread widget/editor.go
Comment thread widget/editor_test.go
Comment thread widget/editor_test.go
Comment on lines +1165 to +1170
e.text.regions = nil
change()
e.updateIMEState(gtx)
if len(e.text.regions) == 0 {
t.Fatalf("%s: changed IME state did not traverse text regions", name)
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dislike using e.text.regions to detect whether or not we've handled the IME change. It's using an implementation detail to detect a side-effect of the change we actually care about. That being said, right now we can't easily mock the input.Source within the gtx so that we could directly detect the expected key.SelectionCmd. @eliasnaur, This feels like an important hole in our ability to test widgets. Am I missing a strategy for checking whether a widget issued a command, or are tests essentially unable to observe that?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This concern is not blocking the acceptance of this PR, for the record. I just want to discuss it with @eliasnaur, and this situation is a good motivating example.

Comment thread app/os_windows.go
Comment thread app/os_windows.go
Comment thread widget/editor.go
@qianniancn

Copy link
Copy Markdown
Contributor Author

Thanks for merging this. I agree that using e.text.regions in the test is a bit awkward. I couldn’t find a way to observe key.SelectionCmd directly. Is there a better pattern for this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants