Clip UTF-16 offsets in text for range (#20968)

When launching the Pinyin keyboard, macOS will sometimes try to peek one
character back in the string.

This caused a panic if the preceding character was an emoji. The docs
say
"don't assume the range is valid", so now we don't.

Release Notes:

- (macOS) Fixed a panic when using the Pinyin keyboard with emojis
This commit is contained in:
Conrad Irwin 2024-11-20 22:04:26 -07:00 committed by GitHub
parent 7285cdb955
commit ebaa270baf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 70 additions and 16 deletions

View file

@ -15,7 +15,10 @@ actions!(
SelectAll,
Home,
End,
ShowCharacterPalette
ShowCharacterPalette,
Paste,
Cut,
Copy,
]
);
@ -107,6 +110,28 @@ impl TextInput {
cx.show_character_palette();
}
fn paste(&mut self, _: &Paste, cx: &mut ViewContext<Self>) {
if let Some(text) = cx.read_from_clipboard().and_then(|item| item.text()) {
self.replace_text_in_range(None, &text.replace("\n", " "), cx);
}
}
fn copy(&mut self, _: &Copy, cx: &mut ViewContext<Self>) {
if !self.selected_range.is_empty() {
cx.write_to_clipboard(ClipboardItem::new_string(
(&self.content[self.selected_range.clone()]).to_string(),
));
}
}
fn cut(&mut self, _: &Copy, cx: &mut ViewContext<Self>) {
if !self.selected_range.is_empty() {
cx.write_to_clipboard(ClipboardItem::new_string(
(&self.content[self.selected_range.clone()]).to_string(),
));
self.replace_text_in_range(None, "", cx)
}
}
fn move_to(&mut self, offset: usize, cx: &mut ViewContext<Self>) {
self.selected_range = offset..offset;
cx.notify()
@ -219,9 +244,11 @@ impl ViewInputHandler for TextInput {
fn text_for_range(
&mut self,
range_utf16: Range<usize>,
actual_range: &mut Option<Range<usize>>,
_cx: &mut ViewContext<Self>,
) -> Option<String> {
let range = self.range_from_utf16(&range_utf16);
actual_range.replace(self.range_to_utf16(&range));
Some(self.content[range].to_string())
}
@ -497,6 +524,9 @@ impl Render for TextInput {
.on_action(cx.listener(Self::home))
.on_action(cx.listener(Self::end))
.on_action(cx.listener(Self::show_character_palette))
.on_action(cx.listener(Self::paste))
.on_action(cx.listener(Self::cut))
.on_action(cx.listener(Self::copy))
.on_mouse_down(MouseButton::Left, cx.listener(Self::on_mouse_down))
.on_mouse_up(MouseButton::Left, cx.listener(Self::on_mouse_up))
.on_mouse_up_out(MouseButton::Left, cx.listener(Self::on_mouse_up))
@ -602,6 +632,9 @@ fn main() {
KeyBinding::new("shift-left", SelectLeft, None),
KeyBinding::new("shift-right", SelectRight, None),
KeyBinding::new("cmd-a", SelectAll, None),
KeyBinding::new("cmd-v", Paste, None),
KeyBinding::new("cmd-c", Copy, None),
KeyBinding::new("cmd-x", Cut, None),
KeyBinding::new("home", Home, None),
KeyBinding::new("end", End, None),
KeyBinding::new("ctrl-cmd-space", ShowCharacterPalette, None),