mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Auto merge of #28308 - philip-lamb:phil-ime-textentry, r=jdm
Improve IME messaging to embedder with insertion point index and mult… …iline flag. <!-- Please describe your changes on the following line: --> This improves handling of IME requests in the embedder by passing the location of the insertion point along with the current text, and a boolean flag 'multiline' (true for HTML textarea, false otherwise) which allows the embedder to be more clever about handling of the 'enter' or 'return' keys. Tested and working in an embedding example. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [ ] These changes fix #___ (GitHub issue number if applicable) <!-- Either: --> - [x] There are tests for these changes OR - [ ] These changes do not require tests because ___ <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
This commit is contained in:
commit
94e337f22f
8 changed files with 58 additions and 16 deletions
|
@ -197,7 +197,10 @@ pub enum EmbedderMsg {
|
|||
/// Open interface to request permission specified by prompt.
|
||||
PromptPermission(PermissionPrompt, IpcSender<PermissionRequest>),
|
||||
/// Request to present an IME to the user when an editable element is focused.
|
||||
ShowIME(InputMethodType, Option<String>, DeviceIntRect),
|
||||
/// If the input is text, the second parameter defines the pre-existing string
|
||||
/// text content and the zero-based index into the string locating the insertion point.
|
||||
/// bool is true for multi-line and false otherwise.
|
||||
ShowIME(InputMethodType, Option<(String, i32)>, bool, DeviceIntRect),
|
||||
/// Request to hide the IME when the editable element is blurred.
|
||||
HideIME,
|
||||
/// Servo has shut down
|
||||
|
|
|
@ -1122,16 +1122,29 @@ impl Document {
|
|||
Point2D::new(rect.origin.x.to_px(), rect.origin.y.to_px()),
|
||||
Size2D::new(rect.size.width.to_px(), rect.size.height.to_px()),
|
||||
);
|
||||
let text = if let Some(input) = elem.downcast::<HTMLInputElement>() {
|
||||
Some((&input.Value()).to_string())
|
||||
let (text, multiline) = if let Some(input) = elem.downcast::<HTMLInputElement>() {
|
||||
(
|
||||
Some((
|
||||
(&input.Value()).to_string(),
|
||||
input.GetSelectionEnd().unwrap_or(0) as i32,
|
||||
)),
|
||||
false,
|
||||
)
|
||||
} else if let Some(textarea) = elem.downcast::<HTMLTextAreaElement>() {
|
||||
Some((&textarea.Value()).to_string())
|
||||
(
|
||||
Some((
|
||||
(&textarea.Value()).to_string(),
|
||||
textarea.GetSelectionEnd().unwrap_or(0) as i32,
|
||||
)),
|
||||
true,
|
||||
)
|
||||
} else {
|
||||
None
|
||||
(None, false)
|
||||
};
|
||||
self.send_to_embedder(EmbedderMsg::ShowIME(
|
||||
kind,
|
||||
text,
|
||||
multiline,
|
||||
DeviceIntRect::from_untyped(&rect),
|
||||
));
|
||||
}
|
||||
|
|
|
@ -416,7 +416,8 @@ impl HostTrait for HostCallbacks {
|
|||
fn on_ime_show(
|
||||
&self,
|
||||
_input_type: InputMethodType,
|
||||
_text: Option<String>,
|
||||
_text: Option<(String, i32)>,
|
||||
_multiline: bool,
|
||||
_bounds: DeviceIntRect,
|
||||
) {
|
||||
if let Some(keyboard) = self.keyboard.0 {
|
||||
|
|
|
@ -141,7 +141,13 @@ pub trait HostTrait {
|
|||
/// Servo finished shutting down.
|
||||
fn on_shutdown_complete(&self);
|
||||
/// A text input is focused.
|
||||
fn on_ime_show(&self, input_type: InputMethodType, text: Option<String>, bounds: DeviceIntRect);
|
||||
fn on_ime_show(
|
||||
&self,
|
||||
input_type: InputMethodType,
|
||||
text: Option<(String, i32)>,
|
||||
multiline: bool,
|
||||
bounds: DeviceIntRect,
|
||||
);
|
||||
/// Input lost focus
|
||||
fn on_ime_hide(&self);
|
||||
/// Gets sytem clipboard contents.
|
||||
|
@ -742,10 +748,10 @@ impl ServoGlue {
|
|||
|
||||
let _ = sender.send(result);
|
||||
},
|
||||
EmbedderMsg::ShowIME(kind, text, bounds) => {
|
||||
EmbedderMsg::ShowIME(kind, text, multiline, bounds) => {
|
||||
self.callbacks
|
||||
.host_callbacks
|
||||
.on_ime_show(kind, text, bounds);
|
||||
.on_ime_show(kind, text, multiline, bounds);
|
||||
},
|
||||
EmbedderMsg::HideIME => {
|
||||
self.callbacks.host_callbacks.on_ime_hide();
|
||||
|
|
|
@ -205,7 +205,15 @@ pub struct CHostCallbacks {
|
|||
pub on_history_changed: extern "C" fn(can_go_back: bool, can_go_forward: bool),
|
||||
pub on_animating_changed: extern "C" fn(animating: bool),
|
||||
pub on_shutdown_complete: extern "C" fn(),
|
||||
pub on_ime_show: extern "C" fn(text: *const c_char, x: i32, y: i32, width: i32, height: i32),
|
||||
pub on_ime_show: extern "C" fn(
|
||||
text: *const c_char,
|
||||
text_index: i32,
|
||||
multiline: bool,
|
||||
x: i32,
|
||||
y: i32,
|
||||
width: i32,
|
||||
height: i32,
|
||||
),
|
||||
pub on_ime_hide: extern "C" fn(),
|
||||
pub get_clipboard_contents: extern "C" fn() -> *const c_char,
|
||||
pub set_clipboard_contents: extern "C" fn(contents: *const c_char),
|
||||
|
@ -808,17 +816,21 @@ impl HostTrait for HostCallbacks {
|
|||
fn on_ime_show(
|
||||
&self,
|
||||
_input_type: InputMethodType,
|
||||
text: Option<String>,
|
||||
text: Option<(String, i32)>,
|
||||
multiline: bool,
|
||||
bounds: DeviceIntRect,
|
||||
) {
|
||||
debug!("on_ime_show");
|
||||
let text = text.and_then(|s| CString::new(s).ok());
|
||||
let text_index = text.as_ref().map_or(0, |(_, i)| *i);
|
||||
let text = text.and_then(|(s, _)| CString::new(s).ok());
|
||||
let text_ptr = text
|
||||
.as_ref()
|
||||
.map(|cstr| cstr.as_ptr())
|
||||
.unwrap_or(std::ptr::null());
|
||||
(self.0.on_ime_show)(
|
||||
text_ptr,
|
||||
text_index,
|
||||
multiline,
|
||||
bounds.origin.x,
|
||||
bounds.origin.y,
|
||||
bounds.size.width,
|
||||
|
|
|
@ -530,7 +530,14 @@ impl HostTrait for HostCallbacks {
|
|||
.unwrap();
|
||||
}
|
||||
|
||||
fn on_ime_show(&self, _type: InputEncoding, _text: Option<String>, _rect: DeviceIntRect) {}
|
||||
fn on_ime_show(
|
||||
&self,
|
||||
_type: InputEncoding,
|
||||
_text: Option<(String, i32)>,
|
||||
_multiline: bool,
|
||||
_rect: DeviceIntRect,
|
||||
) {
|
||||
}
|
||||
fn on_ime_hide(&self) {}
|
||||
|
||||
fn get_clipboard_contents(&self) -> Option<String> {
|
||||
|
|
|
@ -487,7 +487,7 @@ where
|
|||
let permission_state = prompt_user(prompt);
|
||||
let _ = sender.send(permission_state);
|
||||
},
|
||||
EmbedderMsg::ShowIME(_kind, _text, _rect) => {
|
||||
EmbedderMsg::ShowIME(_kind, _text, _multiline, _rect) => {
|
||||
debug!("ShowIME received");
|
||||
},
|
||||
EmbedderMsg::HideIME => {
|
||||
|
|
|
@ -66,8 +66,8 @@ void on_panic(const char *cbacktrace) {
|
|||
throw hresult_error(E_FAIL, backtrace);
|
||||
}
|
||||
|
||||
void on_ime_show(const char *text, int32_t x, int32_t y, int32_t width,
|
||||
int32_t height) {
|
||||
void on_ime_show(const char *text, int32_t text_index, bool multiline,
|
||||
int32_t x, int32_t y, int32_t width, int32_t height) {
|
||||
hstring htext = L"";
|
||||
if (text != nullptr) {
|
||||
htext = char2hstring(text);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue