Wayland: Implement text_input_v3 and xkb compose (#11712)

Release Notes:

- N/A

Fixes #9207 
Known Issues:
- [ ] ~~After launching Zed and immediately trying to change input
method, the input panel will appear at Point{0, 0}~~
- [ ] ~~`ime_handle_preedit` should not trigger `write_to_primary`~~
Move to other PR
- [ ] ~~Cursor is visually stuck at the end.~~ Move to other PR
Currently tested with KDE & fcitx5.
This commit is contained in:
Fernando Tagawa 2024-05-16 15:42:43 -03:00 committed by GitHub
parent fdadbc7174
commit 5596a34311
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 281 additions and 5 deletions

View file

@ -2,6 +2,7 @@ use std::any::Any;
use std::cell::{Ref, RefCell, RefMut};
use std::ffi::c_void;
use std::num::NonZeroU32;
use std::ops::Range;
use std::ptr::NonNull;
use std::rc::{Rc, Weak};
use std::sync::Arc;
@ -162,6 +163,11 @@ impl WaylandWindowState {
}
pub(crate) struct WaylandWindow(pub WaylandWindowStatePtr);
pub enum ImeInput {
InsertText(String),
SetMarkedText(String),
DeleteText,
}
impl Drop for WaylandWindow {
fn drop(&mut self) {
@ -425,6 +431,40 @@ impl WaylandWindowStatePtr {
}
}
pub fn handle_ime(&self, ime: ImeInput) {
let mut state = self.state.borrow_mut();
if let Some(mut input_handler) = state.input_handler.take() {
drop(state);
match ime {
ImeInput::InsertText(text) => {
input_handler.replace_text_in_range(None, &text);
}
ImeInput::SetMarkedText(text) => {
input_handler.replace_and_mark_text_in_range(None, &text, None);
}
ImeInput::DeleteText => {
if let Some(marked) = input_handler.marked_text_range() {
input_handler.replace_text_in_range(Some(marked), "");
}
}
}
self.state.borrow_mut().input_handler = Some(input_handler);
}
}
pub fn get_ime_area(&self) -> Option<Bounds<Pixels>> {
let mut state = self.state.borrow_mut();
let mut bounds: Option<Bounds<Pixels>> = None;
if let Some(mut input_handler) = state.input_handler.take() {
drop(state);
if let Some(range) = input_handler.selected_text_range() {
bounds = input_handler.bounds_for_range(range);
}
self.state.borrow_mut().input_handler = Some(input_handler);
}
bounds
}
pub fn set_size_and_scale(
&self,
width: Option<NonZeroU32>,