From b8a74e89cf4548deaf2b5f059a7b96ffa13a8680 Mon Sep 17 00:00:00 2001 From: Philip Lamb Date: Mon, 29 Mar 2021 17:55:54 +1300 Subject: [PATCH 1/2] Improve IME messaging to embedder with insertion point index and multiline flag. --- components/embedder_traits/lib.rs | 5 ++++- components/script/dom/document.rs | 21 +++++++++++++++---- ports/libmlservo/src/lib.rs | 3 ++- ports/libsimpleservo/api/src/lib.rs | 12 ++++++++--- ports/libsimpleservo/capi/src/lib.rs | 18 +++++++++++++--- ports/libsimpleservo/jniapi/src/lib.rs | 9 +++++++- ports/winit/browser.rs | 2 +- .../hololens/ServoApp/ServoControl/Servo.cpp | 2 +- 8 files changed, 57 insertions(+), 15 deletions(-) diff --git a/components/embedder_traits/lib.rs b/components/embedder_traits/lib.rs index e004756d4a2..c6f372dec19 100644 --- a/components/embedder_traits/lib.rs +++ b/components/embedder_traits/lib.rs @@ -197,7 +197,10 @@ pub enum EmbedderMsg { /// Open interface to request permission specified by prompt. PromptPermission(PermissionPrompt, IpcSender), /// Request to present an IME to the user when an editable element is focused. - ShowIME(InputMethodType, Option, 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 diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 8ae80be66a1..a28b82218ce 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -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::() { - Some((&input.Value()).to_string()) + let (text, multiline) = if let Some(input) = elem.downcast::() { + ( + Some(( + (&input.Value()).to_string(), + input.GetSelectionEnd().unwrap_or(0) as i32, + )), + false, + ) } else if let Some(textarea) = elem.downcast::() { - 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), )); } diff --git a/ports/libmlservo/src/lib.rs b/ports/libmlservo/src/lib.rs index 53bb610c99c..8cebe784837 100644 --- a/ports/libmlservo/src/lib.rs +++ b/ports/libmlservo/src/lib.rs @@ -416,7 +416,8 @@ impl HostTrait for HostCallbacks { fn on_ime_show( &self, _input_type: InputMethodType, - _text: Option, + _text: Option<(String, i32)>, + _multiline: bool, _bounds: DeviceIntRect, ) { if let Some(keyboard) = self.keyboard.0 { diff --git a/ports/libsimpleservo/api/src/lib.rs b/ports/libsimpleservo/api/src/lib.rs index 3088160513b..d6fbf01907f 100644 --- a/ports/libsimpleservo/api/src/lib.rs +++ b/ports/libsimpleservo/api/src/lib.rs @@ -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, 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(); diff --git a/ports/libsimpleservo/capi/src/lib.rs b/ports/libsimpleservo/capi/src/lib.rs index 7ff2c328e16..2fe7e2c8250 100644 --- a/ports/libsimpleservo/capi/src/lib.rs +++ b/ports/libsimpleservo/capi/src/lib.rs @@ -204,7 +204,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), @@ -803,17 +811,21 @@ impl HostTrait for HostCallbacks { fn on_ime_show( &self, _input_type: InputMethodType, - text: Option, + 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, diff --git a/ports/libsimpleservo/jniapi/src/lib.rs b/ports/libsimpleservo/jniapi/src/lib.rs index c11a57b4e45..8223964cc11 100644 --- a/ports/libsimpleservo/jniapi/src/lib.rs +++ b/ports/libsimpleservo/jniapi/src/lib.rs @@ -530,7 +530,14 @@ impl HostTrait for HostCallbacks { .unwrap(); } - fn on_ime_show(&self, _type: InputEncoding, _text: Option, _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 { diff --git a/ports/winit/browser.rs b/ports/winit/browser.rs index ba8c4a72e30..1098c0bbfbc 100644 --- a/ports/winit/browser.rs +++ b/ports/winit/browser.rs @@ -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 => { diff --git a/support/hololens/ServoApp/ServoControl/Servo.cpp b/support/hololens/ServoApp/ServoControl/Servo.cpp index 33b675b98e2..01967566bd8 100644 --- a/support/hololens/ServoApp/ServoControl/Servo.cpp +++ b/support/hololens/ServoApp/ServoControl/Servo.cpp @@ -66,7 +66,7 @@ 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, +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) { From 45a89bcb9525a467f28ea4027078d134c992dc78 Mon Sep 17 00:00:00 2001 From: Philip Lamb Date: Tue, 30 Mar 2021 13:45:07 +1300 Subject: [PATCH 2/2] clang-fmt --- support/hololens/ServoApp/ServoControl/Servo.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/support/hololens/ServoApp/ServoControl/Servo.cpp b/support/hololens/ServoApp/ServoControl/Servo.cpp index 01967566bd8..fdf707d25b3 100644 --- a/support/hololens/ServoApp/ServoControl/Servo.cpp +++ b/support/hololens/ServoApp/ServoControl/Servo.cpp @@ -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 text_index, bool multiline, 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);