linux: Fix IME panel position while enumerating input methods (#12495)

Release Notes:

- N/A

This updates the IME position every time the selection changes, this is
probably only useful when you enumerate languages with your IME.

TODO:
- ~There is a rare chance that the ime panel is not updated because the
window input handler is None.~
- ~Update IME panel in vim mode.~
- ~Update IME panel when leaving Buffer search input.~

---------

Co-authored-by: Mikayla Maki <mikayla@zed.dev>
This commit is contained in:
Fernando Tagawa 2024-08-28 23:58:40 -03:00 committed by GitHub
parent e6d5f4406f
commit 8e8927db4b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 244 additions and 55 deletions

View file

@ -383,6 +383,8 @@ pub(crate) trait PlatformWindow: HasWindowHandle + HasDisplayHandle {
fn gpu_specs(&self) -> Option<GPUSpecs>;
fn fps(&self) -> Option<f32>;
fn update_ime_position(&self, _bounds: Bounds<Pixels>);
#[cfg(any(test, feature = "test-support"))]
fn as_test(&mut self) -> Option<&mut TestWindow> {
None
@ -526,9 +528,9 @@ impl PlatformInputHandler {
Self { cx, handler }
}
fn selected_text_range(&mut self) -> Option<Range<usize>> {
fn selected_text_range(&mut self, ignore_disabled_input: bool) -> Option<UTF16Selection> {
self.cx
.update(|cx| self.handler.selected_text_range(cx))
.update(|cx| self.handler.selected_text_range(ignore_disabled_input, cx))
.ok()
.flatten()
}
@ -589,6 +591,31 @@ impl PlatformInputHandler {
pub(crate) fn dispatch_input(&mut self, input: &str, cx: &mut WindowContext) {
self.handler.replace_text_in_range(None, input, cx);
}
pub fn selected_bounds(&mut self, cx: &mut WindowContext) -> Option<Bounds<Pixels>> {
let Some(selection) = self.handler.selected_text_range(true, cx) else {
return None;
};
self.handler.bounds_for_range(
if selection.reversed {
selection.range.start..selection.range.start
} else {
selection.range.end..selection.range.end
},
cx,
)
}
}
/// A struct representing a selection in a text buffer, in UTF16 characters.
/// This is different from a range because the head may be before the tail.
pub struct UTF16Selection {
/// The range of text in the document this selection corresponds to
/// in UTF16 characters.
pub range: Range<usize>,
/// Whether the head of this selection is at the start (true), or end (false)
/// of the range
pub reversed: bool,
}
/// Zed's interface for handling text input from the platform's IME system
@ -600,7 +627,11 @@ pub trait InputHandler: 'static {
/// Corresponds to [selectedRange()](https://developer.apple.com/documentation/appkit/nstextinputclient/1438242-selectedrange)
///
/// Return value is in terms of UTF-16 characters, from 0 to the length of the document
fn selected_text_range(&mut self, cx: &mut WindowContext) -> Option<Range<usize>>;
fn selected_text_range(
&mut self,
ignore_disabled_input: bool,
cx: &mut WindowContext,
) -> Option<UTF16Selection>;
/// Get the range of the currently marked text, if any
/// Corresponds to [markedRange()](https://developer.apple.com/documentation/appkit/nstextinputclient/1438250-markedrange)