Skip to content

Commit

Permalink
Auto merge of #27250 - paulrouget:unfocus, r=jdm
Browse files Browse the repository at this point in the history
Unfocus input when virtual keyboard is dismissed

Fix #27181
  • Loading branch information
bors-servo committed Jul 13, 2020
2 parents 9fe92ec + 6252d36 commit 9bbe9c8
Show file tree
Hide file tree
Showing 11 changed files with 91 additions and 2 deletions.
3 changes: 3 additions & 0 deletions components/compositing/lib.rs
Expand Up @@ -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 {
Expand Down Expand Up @@ -140,6 +142,7 @@ impl fmt::Debug for ConstellationMsg {
ExitFullScreen(..) => "ExitFullScreen",
MediaSessionAction(..) => "MediaSessionAction",
ChangeBrowserVisibility(..) => "ChangeBrowserVisibility",
IMEDismissed => "IMEDismissed",
};
write!(formatter, "ConstellationMsg::{}", variant)
}
Expand Down
3 changes: 3 additions & 0 deletions components/compositing/windowing.rs
Expand Up @@ -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 {
Expand Down Expand Up @@ -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"),
}
}
}
Expand Down
36 changes: 36 additions & 0 deletions components/constellation/constellation.rs
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down
7 changes: 7 additions & 0 deletions components/script/dom/document.rs
Expand Up @@ -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,
Expand Down
12 changes: 10 additions & 2 deletions components/script/script_thread.rs
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions components/script_traits/lib.rs
Expand Up @@ -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.
Expand Down
10 changes: 10 additions & 0 deletions components/servo/lib.rs
Expand Up @@ -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();
},
Expand Down
5 changes: 5 additions & 0 deletions ports/libsimpleservo/api/src/lib.rs
Expand Up @@ -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,
Expand Down
8 changes: 8 additions & 0 deletions ports/libsimpleservo/capi/src/lib.rs
Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions support/hololens/ServoApp/ServoControl/Servo.h
Expand Up @@ -88,6 +88,7 @@ class Servo {
void ContextMenuClosed(CContextMenuResult res, unsigned int idx) {
on_context_menu_closed(res, idx);
}
void IMEDismissed() { ime_dismissed(); }

private:
ServoDelegate &mDelegate;
Expand Down
6 changes: 6 additions & 0 deletions support/hololens/ServoApp/ServoControl/ServoControl.cpp
Expand Up @@ -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);
Expand Down

0 comments on commit 9bbe9c8

Please sign in to comment.