fix(input): correct IME candidate popup positioning by clamping composition range - #222
Open
cnaron wants to merge 1 commit into
Open
fix(input): correct IME candidate popup positioning by clamping composition range#222cnaron wants to merge 1 commit into
cnaron wants to merge 1 commit into
Conversation
…sition range When composing text using an IME (e.g. CJK Pinyin), macOS NSTextInputClient calls firstRectForCharacterRange synchronously right after setMarkedText. At this point in time, the layout (self.last_layout) has not yet been updated for the newly inserted composition text. As a result: 1. range.end can exceed layout.len(). Previously, layout.position_for_index(range.end)? failed and returned None. 2. On macOS, first_rect_for_character_range maps None to (0, 0) in Cocoa screen coordinates, causing the IME candidate window to jump to the bottom-left corner of the screen. Fix this by: - Clamping start_idx and end_idx to layout.len() so position_for_index safely resolves to the current insertion caret position. - Falling back to bounds.origin if last_layout is not yet available instead of returning None. - Ensuring character bounds are correctly sized with a minimum width of 2px.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When typing with an input method editor (such as Chinese Pinyin, Japanese, or other CJK IMEs) on macOS, the candidate selection window frequently pops up at the bottom-left corner of the screen
(0, 0)instead of following the text insertion caret.Root Cause
During IME composition:
NSTextInputClientcallsfirstRectForCharacterRange:synchronously right aftersetMarkedText:selectedRange:replacementRange:.TextLayoutfor the newly inserted/replaced composition text, soself.last_layoutonly reflects the text before the current composition step.range.endcan exceedlayout.len(). Previously,layout.position_for_index(range.end)?failed and returnedNone.crates/gpui_macos/src/window.rs,first_rect_for_character_rangemapsNonetoNSRect::new(NSPoint::new(0., 0.), NSSize::new(0., 0.))(the bottom-left of the display).Solution
start_idxandend_idxtolayout.len()so thatposition_for_indexsafely resolves to the valid insertion point even if layout has not refreshed yet.last_layoutis not available, return a fallback caret rect anchored atbounds.origininstead of returningNone.(end.x - start.x).max(px(2.0))with properline_height.Tested on macOS with Chinese Pinyin IME; candidate window now consistently follows the insertion caret.