mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Unfocus input when virtual keyboard is dismissed
This commit is contained in:
parent
967a70bd60
commit
6252d36a14
11 changed files with 91 additions and 2 deletions
|
@ -109,6 +109,8 @@ pub enum ConstellationMsg {
|
|||
MediaSessionAction(MediaSessionActionType),
|
||||
/// Toggle browser visibility.
|
||||
ChangeBrowserVisibility(TopLevelBrowsingContextId, bool),
|
||||
/// Virtual keyboard was dismissed
|
||||
IMEDismissed,
|
||||
}
|
||||
|
||||
impl fmt::Debug for ConstellationMsg {
|
||||
|
@ -140,6 +142,7 @@ impl fmt::Debug for ConstellationMsg {
|
|||
ExitFullScreen(..) => "ExitFullScreen",
|
||||
MediaSessionAction(..) => "MediaSessionAction",
|
||||
ChangeBrowserVisibility(..) => "ChangeBrowserVisibility",
|
||||
IMEDismissed => "IMEDismissed",
|
||||
};
|
||||
write!(formatter, "ConstellationMsg::{}", variant)
|
||||
}
|
||||
|
|
|
@ -102,6 +102,8 @@ pub enum WindowEvent {
|
|||
MediaSessionAction(MediaSessionActionType),
|
||||
/// Set browser visibility. A hidden browser will not tick the animations.
|
||||
ChangeBrowserVisibility(TopLevelBrowsingContextId, bool),
|
||||
/// Virtual keyboard was dismissed
|
||||
IMEDismissed,
|
||||
}
|
||||
|
||||
impl Debug for WindowEvent {
|
||||
|
@ -134,6 +136,7 @@ impl Debug for WindowEvent {
|
|||
WindowEvent::ExitFullScreen(..) => write!(f, "ExitFullScreen"),
|
||||
WindowEvent::MediaSessionAction(..) => write!(f, "MediaSessionAction"),
|
||||
WindowEvent::ChangeBrowserVisibility(..) => write!(f, "ChangeBrowserVisibility"),
|
||||
WindowEvent::IMEDismissed => write!(f, "IMEDismissed"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1470,6 +1470,9 @@ where
|
|||
FromCompositorMsg::Keyboard(key_event) => {
|
||||
self.handle_key_msg(key_event);
|
||||
},
|
||||
FromCompositorMsg::IMEDismissed => {
|
||||
self.handle_ime_dismissed();
|
||||
},
|
||||
// Perform a navigation previously requested by script, if approved by the embedder.
|
||||
// If there is already a pending page (self.pending_changes), it will not be overridden;
|
||||
// However, if the id is not encompassed by another change, it will be.
|
||||
|
@ -4074,6 +4077,39 @@ where
|
|||
session_history.replace_history_state(pipeline_id, history_state_id, url);
|
||||
}
|
||||
|
||||
fn handle_ime_dismissed(&mut self) {
|
||||
// Send to the focused browsing contexts' current pipeline.
|
||||
let focused_browsing_context_id = self
|
||||
.active_browser_id
|
||||
.and_then(|browser_id| self.browsers.get(&browser_id))
|
||||
.map(|browser| browser.focused_browsing_context_id);
|
||||
if let Some(browsing_context_id) = focused_browsing_context_id {
|
||||
let pipeline_id = match self.browsing_contexts.get(&browsing_context_id) {
|
||||
Some(ctx) => ctx.pipeline_id,
|
||||
None => {
|
||||
return warn!(
|
||||
"Got IME dismissed event for nonexistent browsing context {}.",
|
||||
browsing_context_id,
|
||||
);
|
||||
},
|
||||
};
|
||||
let msg =
|
||||
ConstellationControlMsg::SendEvent(pipeline_id, CompositorEvent::IMEDismissedEvent);
|
||||
let result = match self.pipelines.get(&pipeline_id) {
|
||||
Some(pipeline) => pipeline.event_loop.send(msg),
|
||||
None => {
|
||||
return debug!(
|
||||
"Pipeline {:?} got IME dismissed event after closure.",
|
||||
pipeline_id
|
||||
);
|
||||
},
|
||||
};
|
||||
if let Err(e) = result {
|
||||
self.handle_send_error(pipeline_id, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_key_msg(&mut self, event: KeyboardEvent) {
|
||||
// Send to the focused browsing contexts' current pipeline. If it
|
||||
// doesn't exist, fall back to sending to the compositor.
|
||||
|
|
|
@ -1722,6 +1722,13 @@ impl Document {
|
|||
self.window.reflow(ReflowGoal::Full, ReflowReason::KeyEvent);
|
||||
}
|
||||
|
||||
pub fn ime_dismissed(&self) {
|
||||
self.request_focus(
|
||||
self.GetBody().as_ref().map(|e| &*e.upcast()),
|
||||
FocusType::Element,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn dispatch_composition_event(
|
||||
&self,
|
||||
composition_event: ::keyboard_types::CompositionEvent,
|
||||
|
|
|
@ -129,8 +129,8 @@ use profile_traits::time::{self as profile_time, profile, ProfilerCategory};
|
|||
use script_layout_interface::message::{self, LayoutThreadInit, Msg, ReflowGoal};
|
||||
use script_traits::webdriver_msg::WebDriverScriptCommand;
|
||||
use script_traits::CompositorEvent::{
|
||||
CompositionEvent, KeyboardEvent, MouseButtonEvent, MouseMoveEvent, ResizeEvent, TouchEvent,
|
||||
WheelEvent,
|
||||
CompositionEvent, IMEDismissedEvent, KeyboardEvent, MouseButtonEvent, MouseMoveEvent,
|
||||
ResizeEvent, TouchEvent, WheelEvent,
|
||||
};
|
||||
use script_traits::{
|
||||
AnimationTickType, CompositorEvent, ConstellationControlMsg, DiscardBrowsingContext,
|
||||
|
@ -3583,6 +3583,14 @@ impl ScriptThread {
|
|||
document.dispatch_key_event(key_event);
|
||||
},
|
||||
|
||||
IMEDismissedEvent => {
|
||||
let document = match self.documents.borrow().find_document(pipeline_id) {
|
||||
Some(document) => document,
|
||||
None => return warn!("Message sent to closed pipeline {}.", pipeline_id),
|
||||
};
|
||||
document.ime_dismissed();
|
||||
},
|
||||
|
||||
CompositionEvent(composition_event) => {
|
||||
let document = match self.documents.borrow().find_document(pipeline_id) {
|
||||
Some(document) => document,
|
||||
|
|
|
@ -570,6 +570,8 @@ pub enum CompositorEvent {
|
|||
KeyboardEvent(KeyboardEvent),
|
||||
/// An event from the IME is dispatched.
|
||||
CompositionEvent(CompositionEvent),
|
||||
/// Virtual keyboard was dismissed
|
||||
IMEDismissedEvent,
|
||||
}
|
||||
|
||||
/// Requests a TimerEvent-Message be sent after the given duration.
|
||||
|
|
|
@ -663,6 +663,16 @@ where
|
|||
}
|
||||
},
|
||||
|
||||
WindowEvent::IMEDismissed => {
|
||||
let msg = ConstellationMsg::IMEDismissed;
|
||||
if let Err(e) = self.constellation_chan.send(msg) {
|
||||
warn!(
|
||||
"Sending IMEDismissed event to constellation failed ({:?}).",
|
||||
e
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
WindowEvent::Quit => {
|
||||
self.compositor.maybe_start_shutting_down();
|
||||
},
|
||||
|
|
|
@ -560,6 +560,11 @@ impl ServoGlue {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn ime_dismissed(&mut self) -> Result<(), &'static str> {
|
||||
info!("ime_dismissed");
|
||||
self.process_event(WindowEvent::IMEDismissed)
|
||||
}
|
||||
|
||||
pub fn on_context_menu_closed(
|
||||
&mut self,
|
||||
result: ContextMenuResult,
|
||||
|
|
|
@ -766,6 +766,14 @@ pub extern "C" fn change_visibility(visible: bool) {
|
|||
});
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ime_dismissed() {
|
||||
catch_any_panic(|| {
|
||||
debug!("ime_dismissed");
|
||||
call(|s| s.ime_dismissed());
|
||||
});
|
||||
}
|
||||
|
||||
pub struct WakeupCallback(extern "C" fn());
|
||||
|
||||
impl WakeupCallback {
|
||||
|
|
|
@ -88,6 +88,7 @@ public:
|
|||
void ContextMenuClosed(CContextMenuResult res, unsigned int idx) {
|
||||
on_context_menu_closed(res, idx);
|
||||
}
|
||||
void IMEDismissed() { ime_dismissed(); }
|
||||
|
||||
private:
|
||||
ServoDelegate &mDelegate;
|
||||
|
|
|
@ -91,6 +91,12 @@ void ServoControl::OnLoaded(IInspectable const &, RoutedEventArgs const &) {
|
|||
|
||||
void ServoControl::InitializeTextController() {
|
||||
mInputPane = Windows::UI::ViewManagement::InputPane::GetForCurrentView();
|
||||
mInputPane->Hiding([=](const auto &, const auto &) {
|
||||
if (mLooping) {
|
||||
RunOnGLThread([=] { mServo->IMEDismissed(); });
|
||||
}
|
||||
});
|
||||
|
||||
auto manager = CoreTextServicesManager::GetForCurrentView();
|
||||
mEditContext = manager.CreateEditContext();
|
||||
mEditContext->InputPaneDisplayPolicy(CoreTextInputPaneDisplayPolicy::Manual);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue