mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Auto merge of #20676 - fabricedesre:ime-embedding, r=cbrewster
Notify the embedder when it should display or hide an IME <!-- Please describe your changes on the following line: --> This adds a couple of embedder messages triggered when an editable element is focused or blured. The embedder also gets the type of data to edit so it can display a different keyboard type or a custom input method eg. for color choosing. This is a partial fix for issue #12127 --- <!-- 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 build-geckolib` does not report any errors - [X] `./mach test-tidy` does not report any errors - [ ] These changes fix #__ (github issue number if applicable). <!-- Either: --> - [ ] There are tests for these changes OR - [X] These changes do not require tests because there are no tests for the embedding api :( <!-- 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. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/20676) <!-- Reviewable:end -->
This commit is contained in:
commit
c5f7c9ccf3
8 changed files with 93 additions and 2 deletions
|
@ -8,7 +8,7 @@ use SendableFrameTree;
|
|||
use compositor::CompositingReason;
|
||||
use gfx_traits::Epoch;
|
||||
use ipc_channel::ipc::IpcSender;
|
||||
use msg::constellation_msg::{Key, KeyModifiers, KeyState, PipelineId, TopLevelBrowsingContextId};
|
||||
use msg::constellation_msg::{InputMethodType, Key, KeyModifiers, KeyState, PipelineId, TopLevelBrowsingContextId};
|
||||
use net_traits::image::base::Image;
|
||||
use profile_traits::mem;
|
||||
use profile_traits::time;
|
||||
|
@ -143,6 +143,10 @@ pub enum EmbedderMsg {
|
|||
Panic(TopLevelBrowsingContextId, String, Option<String>),
|
||||
/// Open dialog to select bluetooth device.
|
||||
GetSelectedBluetoothDevice(Vec<String>, IpcSender<Option<String>>),
|
||||
/// Request to present an IME to the user when an editable element is focused.
|
||||
ShowIME(TopLevelBrowsingContextId, InputMethodType),
|
||||
/// Request to hide the IME when the editable element is blurred.
|
||||
HideIME(TopLevelBrowsingContextId),
|
||||
/// Servo has shut down
|
||||
Shutdown,
|
||||
}
|
||||
|
@ -244,6 +248,8 @@ impl Debug for EmbedderMsg {
|
|||
EmbedderMsg::LoadComplete(..) => write!(f, "LoadComplete"),
|
||||
EmbedderMsg::Panic(..) => write!(f, "Panic"),
|
||||
EmbedderMsg::GetSelectedBluetoothDevice(..) => write!(f, "GetSelectedBluetoothDevice"),
|
||||
EmbedderMsg::ShowIME(..) => write!(f, "ShowIME"),
|
||||
EmbedderMsg::HideIME(..) => write!(f, "HideIME"),
|
||||
EmbedderMsg::Shutdown => write!(f, "Shutdown"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1247,6 +1247,14 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
|||
FromScriptMsg::SetFullscreenState(state) => {
|
||||
self.embedder_proxy.send(EmbedderMsg::SetFullscreenState(source_top_ctx_id, state));
|
||||
}
|
||||
FromScriptMsg::ShowIME(kind) => {
|
||||
debug!("constellation got ShowIME message");
|
||||
self.embedder_proxy.send(EmbedderMsg::ShowIME(source_top_ctx_id, kind));
|
||||
}
|
||||
FromScriptMsg::HideIME => {
|
||||
debug!("constellation got HideIME message");
|
||||
self.embedder_proxy.send(EmbedderMsg::HideIME(source_top_ctx_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -401,3 +401,23 @@ pub const TEST_BROWSING_CONTEXT_INDEX: BrowsingContextIndex =
|
|||
#[cfg(feature = "unstable")]
|
||||
pub const TEST_BROWSING_CONTEXT_ID: BrowsingContextId =
|
||||
BrowsingContextId { namespace_id: TEST_NAMESPACE, index: TEST_BROWSING_CONTEXT_INDEX };
|
||||
|
||||
// Used to specify the kind of input method editor appropriate to edit a field.
|
||||
// This is a subset of htmlinputelement::InputType because some variants of InputType
|
||||
// don't make sense in this context.
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub enum InputMethodType {
|
||||
Color,
|
||||
Date,
|
||||
DatetimeLocal,
|
||||
Email,
|
||||
Month,
|
||||
Number,
|
||||
Password,
|
||||
Search,
|
||||
Tel,
|
||||
Text,
|
||||
Time,
|
||||
Url,
|
||||
Week,
|
||||
}
|
||||
|
|
|
@ -812,6 +812,11 @@ impl Document {
|
|||
elem.set_focus_state(false);
|
||||
// FIXME: pass appropriate relatedTarget
|
||||
self.fire_focus_event(FocusEventType::Blur, node, None);
|
||||
|
||||
// Notify the embedder to hide the input method.
|
||||
if elem.input_method_type().is_some() {
|
||||
self.send_to_constellation(ScriptMsg::HideIME);
|
||||
}
|
||||
}
|
||||
|
||||
self.focused.set(self.possibly_focused.get().r());
|
||||
|
@ -826,6 +831,11 @@ impl Document {
|
|||
if focus_type == FocusType::Element {
|
||||
self.send_to_constellation(ScriptMsg::Focus);
|
||||
}
|
||||
|
||||
// Notify the embedder to display an input method.
|
||||
if let Some(kind) = elem.input_method_type() {
|
||||
self.send_to_constellation(ScriptMsg::ShowIME(kind));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -83,6 +83,7 @@ use html5ever::serialize::TraversalScope;
|
|||
use html5ever::serialize::TraversalScope::{ChildrenOnly, IncludeNode};
|
||||
use js::jsapi::Heap;
|
||||
use js::jsval::JSVal;
|
||||
use msg::constellation_msg::InputMethodType;
|
||||
use net_traits::request::CorsSettings;
|
||||
use ref_filter_map::ref_filter_map;
|
||||
use script_layout_interface::message::ReflowGoal;
|
||||
|
@ -1087,6 +1088,22 @@ impl Element {
|
|||
None
|
||||
}
|
||||
|
||||
// Returns the kind of IME control needed for a focusable element, if any.
|
||||
pub fn input_method_type(&self) -> Option<InputMethodType> {
|
||||
if !self.is_focusable_area() {
|
||||
return None;
|
||||
}
|
||||
|
||||
if let Some(input) = self.downcast::<HTMLInputElement>() {
|
||||
input.input_type().as_ime_type()
|
||||
} else if self.is::<HTMLTextAreaElement>() {
|
||||
Some(InputMethodType::Text)
|
||||
} else {
|
||||
// Other focusable elements that are not input fields.
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_focusable_area(&self) -> bool {
|
||||
if self.is_actually_disabled() {
|
||||
return false;
|
||||
|
|
|
@ -40,6 +40,7 @@ use dom::virtualmethods::VirtualMethods;
|
|||
use dom_struct::dom_struct;
|
||||
use html5ever::{LocalName, Prefix};
|
||||
use mime_guess;
|
||||
use msg::constellation_msg::InputMethodType;
|
||||
use net_traits::{CoreResourceMsg, IpcSend};
|
||||
use net_traits::blob_url_store::get_blob_origin;
|
||||
use net_traits::filemanager_thread::{FileManagerThreadMsg, FilterPattern};
|
||||
|
@ -137,6 +138,25 @@ impl InputType {
|
|||
InputType::Week => "week",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_ime_type(&self) -> Option<InputMethodType> {
|
||||
match *self {
|
||||
InputType::Color => Some(InputMethodType::Color),
|
||||
InputType::Date => Some(InputMethodType::Date),
|
||||
InputType::DatetimeLocal => Some(InputMethodType::DatetimeLocal),
|
||||
InputType::Email => Some(InputMethodType::Email),
|
||||
InputType::Month => Some(InputMethodType::Month),
|
||||
InputType::Number => Some(InputMethodType::Number),
|
||||
InputType::Password => Some(InputMethodType::Password),
|
||||
InputType::Search => Some(InputMethodType::Search),
|
||||
InputType::Tel => Some(InputMethodType::Tel),
|
||||
InputType::Text => Some(InputMethodType::Text),
|
||||
InputType::Time => Some(InputMethodType::Time),
|
||||
InputType::Url => Some(InputMethodType::Url),
|
||||
InputType::Week => Some(InputMethodType::Week),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Atom> for InputType {
|
||||
|
|
|
@ -17,7 +17,7 @@ use euclid::{Size2D, TypedSize2D};
|
|||
use gfx_traits::Epoch;
|
||||
use ipc_channel::ipc::{IpcReceiver, IpcSender};
|
||||
use msg::constellation_msg::{BrowsingContextId, HistoryStateId, PipelineId, TraversalDirection};
|
||||
use msg::constellation_msg::{Key, KeyModifiers, KeyState};
|
||||
use msg::constellation_msg::{InputMethodType, Key, KeyModifiers, KeyState};
|
||||
use net_traits::CoreResourceMsg;
|
||||
use net_traits::request::RequestInit;
|
||||
use net_traits::storage_thread::StorageType;
|
||||
|
@ -163,6 +163,10 @@ pub enum ScriptMsg {
|
|||
GetScreenSize(IpcSender<(DeviceUintSize)>),
|
||||
/// Get the available screen size (pixel)
|
||||
GetScreenAvailSize(IpcSender<(DeviceUintSize)>),
|
||||
/// Request to present an IME to the user when an editable element is focused.
|
||||
ShowIME(InputMethodType),
|
||||
/// Request to hide the IME when the editable element is blurred.
|
||||
HideIME,
|
||||
/// Requests that the compositor shut down.
|
||||
Exit,
|
||||
}
|
||||
|
|
|
@ -295,6 +295,12 @@ impl Browser {
|
|||
EmbedderMsg::GetSelectedBluetoothDevice(devices, sender) => {
|
||||
platform_get_selected_devices(devices, sender);
|
||||
}
|
||||
EmbedderMsg::ShowIME(_browser_id, _kind) => {
|
||||
debug!("ShowIME received");
|
||||
}
|
||||
EmbedderMsg::HideIME(_browser_id) => {
|
||||
debug!("HideIME received");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue