Commit 6c77e2f6 authored by Scott Violet's avatar Scott Violet Committed by Commit Bot

chromeos: makes sure events aren't sent to IME twice

Currently clients of window-service forward KeyEvents to IME. Ash was doing
the same, resulting in KeyEvents destined for remote clients going to IME
twice.

BUG=891489
TEST=none

Change-Id: I315c84399cfb9d8adf39ae9f3eb6c50d222f22c4
Reviewed-on: https://chromium-review.googlesource.com/c/1290194Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Commit-Queue: Scott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#601182}
parent 2a84daa6
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event.h"
#include "services/ws/public/cpp/input_devices/input_device_controller_client.h" #include "services/ws/public/cpp/input_devices/input_device_controller_client.h"
#include "services/ws/public/mojom/window_manager.mojom.h" #include "services/ws/public/mojom/window_manager.mojom.h"
#include "services/ws/window_service.h"
#include "ui/aura/mus/input_method_mus.h" #include "ui/aura/mus/input_method_mus.h"
#include "ui/aura/null_window_targeter.h" #include "ui/aura/null_window_targeter.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
...@@ -205,6 +206,13 @@ void AshWindowTreeHostPlatform::SetTapToClickPaused(bool state) { ...@@ -205,6 +206,13 @@ void AshWindowTreeHostPlatform::SetTapToClickPaused(bool state) {
input_device_controller_client->SetTapToClickPaused(state); input_device_controller_client->SetTapToClickPaused(state);
} }
bool AshWindowTreeHostPlatform::ShouldSendKeyEventToIme() {
// Don't send key events to IME if they are going to go to a remote client.
// Remote clients handle forwarding to IME (as necessary).
aura::Window* target = window()->targeter()->FindTargetForKeyEvent(window());
return !target || !ws::WindowService::HasRemoteClient(target);
}
void AshWindowTreeHostPlatform::SetTextInputState( void AshWindowTreeHostPlatform::SetTextInputState(
ui::mojom::TextInputStatePtr state) { ui::mojom::TextInputStatePtr state) {
ui::PlatformImeController* ime = ui::PlatformImeController* ime =
......
...@@ -62,6 +62,7 @@ class ASH_EXPORT AshWindowTreeHostPlatform ...@@ -62,6 +62,7 @@ class ASH_EXPORT AshWindowTreeHostPlatform
void SetBoundsInPixels(const gfx::Rect& bounds, void SetBoundsInPixels(const gfx::Rect& bounds,
const viz::LocalSurfaceId& local_surface_id) override; const viz::LocalSurfaceId& local_surface_id) override;
void DispatchEvent(ui::Event* event) override; void DispatchEvent(ui::Event* event) override;
bool ShouldSendKeyEventToIme() override;
// aura::InputMethodMusDelegate: // aura::InputMethodMusDelegate:
void SetTextInputState(ui::mojom::TextInputStatePtr state) override; void SetTextInputState(ui::mojom::TextInputStatePtr state) override;
......
...@@ -1089,8 +1089,10 @@ DispatchDetails WindowEventDispatcher::PreDispatchTouchEvent( ...@@ -1089,8 +1089,10 @@ DispatchDetails WindowEventDispatcher::PreDispatchTouchEvent(
DispatchDetails WindowEventDispatcher::PreDispatchKeyEvent( DispatchDetails WindowEventDispatcher::PreDispatchKeyEvent(
ui::KeyEvent* event) { ui::KeyEvent* event) {
if (skip_ime_ || !host_->has_input_method() || if (skip_ime_ || !host_->has_input_method() ||
(event->flags() & ui::EF_IS_SYNTHESIZED)) (event->flags() & ui::EF_IS_SYNTHESIZED) ||
!host_->ShouldSendKeyEventToIme()) {
return DispatchDetails(); return DispatchDetails();
}
DispatchDetails details = host_->GetInputMethod()->DispatchKeyEvent(event); DispatchDetails details = host_->GetInputMethod()->DispatchKeyEvent(event);
event->StopPropagation(); event->StopPropagation();
return details; return details;
......
...@@ -183,7 +183,7 @@ ui::EventTarget* WindowTargeter::FindTargetForEvent(ui::EventTarget* root, ...@@ -183,7 +183,7 @@ ui::EventTarget* WindowTargeter::FindTargetForEvent(ui::EventTarget* root,
ui::Event* event) { ui::Event* event) {
Window* window = static_cast<Window*>(root); Window* window = static_cast<Window*>(root);
Window* target = event->IsKeyEvent() Window* target = event->IsKeyEvent()
? FindTargetForKeyEvent(window, *event->AsKeyEvent()) ? FindTargetForKeyEvent(window)
: FindTargetForNonKeyEvent(window, event); : FindTargetForNonKeyEvent(window, event);
if (target && !window->parent() && if (target && !window->parent() &&
ProcessEventIfTargetsDifferentRootWindow(window, target, event)) { ProcessEventIfTargetsDifferentRootWindow(window, target, event)) {
...@@ -198,6 +198,24 @@ ui::EventTarget* WindowTargeter::FindNextBestTarget( ...@@ -198,6 +198,24 @@ ui::EventTarget* WindowTargeter::FindNextBestTarget(
return nullptr; return nullptr;
} }
Window* WindowTargeter::FindTargetForKeyEvent(Window* window) {
Window* root_window = window->GetRootWindow();
client::FocusClient* focus_client = client::GetFocusClient(root_window);
if (!focus_client)
return window;
Window* focused_window = focus_client->GetFocusedWindow();
if (!focused_window)
return window;
client::EventClient* event_client = client::GetEventClient(root_window);
if (event_client &&
!event_client->CanProcessEventsWithinSubtree(focused_window)) {
focus_client->FocusWindow(nullptr);
return nullptr;
}
return focused_window ? focused_window : window;
}
void WindowTargeter::OnInstalled(Window* window) { void WindowTargeter::OnInstalled(Window* window) {
window_ = window; window_ = window;
UpdateMusIfNecessary(); UpdateMusIfNecessary();
...@@ -321,25 +339,6 @@ void WindowTargeter::UpdateMusIfNecessary() { ...@@ -321,25 +339,6 @@ void WindowTargeter::UpdateMusIfNecessary() {
} }
} }
Window* WindowTargeter::FindTargetForKeyEvent(Window* window,
const ui::KeyEvent& key) {
Window* root_window = window->GetRootWindow();
client::FocusClient* focus_client = client::GetFocusClient(root_window);
if (!focus_client)
return window;
Window* focused_window = focus_client->GetFocusedWindow();
if (!focused_window)
return window;
client::EventClient* event_client = client::GetEventClient(root_window);
if (event_client &&
!event_client->CanProcessEventsWithinSubtree(focused_window)) {
focus_client->FocusWindow(nullptr);
return nullptr;
}
return focused_window ? focused_window : window;
}
Window* WindowTargeter::FindTargetForNonKeyEvent(Window* root_window, Window* WindowTargeter::FindTargetForNonKeyEvent(Window* root_window,
ui::Event* event) { ui::Event* event) {
if (!event->IsLocatedEvent()) if (!event->IsLocatedEvent())
......
...@@ -18,7 +18,6 @@ class Rect; ...@@ -18,7 +18,6 @@ class Rect;
} }
namespace ui { namespace ui {
class KeyEvent;
class LocatedEvent; class LocatedEvent;
} // namespace ui } // namespace ui
...@@ -87,6 +86,8 @@ class AURA_EXPORT WindowTargeter : public ui::EventTargeter { ...@@ -87,6 +86,8 @@ class AURA_EXPORT WindowTargeter : public ui::EventTargeter {
ui::EventTarget* FindNextBestTarget(ui::EventTarget* previous_target, ui::EventTarget* FindNextBestTarget(ui::EventTarget* previous_target,
ui::Event* event) override; ui::Event* event) override;
Window* FindTargetForKeyEvent(Window* root_window);
protected: protected:
aura::Window* window() { return window_; } aura::Window* window() { return window_; }
const aura::Window* window() const { return window_; } const aura::Window* window() const { return window_; }
...@@ -131,7 +132,6 @@ class AURA_EXPORT WindowTargeter : public ui::EventTargeter { ...@@ -131,7 +132,6 @@ class AURA_EXPORT WindowTargeter : public ui::EventTargeter {
void UpdateMusIfNecessary(); void UpdateMusIfNecessary();
Window* FindTargetForKeyEvent(Window* root_window, const ui::KeyEvent& event);
Window* FindTargetForNonKeyEvent(Window* root_window, ui::Event* event); Window* FindTargetForNonKeyEvent(Window* root_window, ui::Event* event);
Window* FindTargetForLocatedEventRecursively(Window* root_window, Window* FindTargetForLocatedEventRecursively(Window* root_window,
ui::LocatedEvent* event); ui::LocatedEvent* event);
......
...@@ -288,6 +288,10 @@ std::unique_ptr<ScopedKeyboardHook> WindowTreeHost::CaptureSystemKeyEvents( ...@@ -288,6 +288,10 @@ std::unique_ptr<ScopedKeyboardHook> WindowTreeHost::CaptureSystemKeyEvents(
return nullptr; return nullptr;
} }
bool WindowTreeHost::ShouldSendKeyEventToIme() {
return true;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// WindowTreeHost, protected: // WindowTreeHost, protected:
......
...@@ -223,6 +223,10 @@ class AURA_EXPORT WindowTreeHost : public ui::internal::InputMethodDelegate, ...@@ -223,6 +223,10 @@ class AURA_EXPORT WindowTreeHost : public ui::internal::InputMethodDelegate,
// Returns a map of KeyboardEvent code to KeyboardEvent key values. // Returns a map of KeyboardEvent code to KeyboardEvent key values.
virtual base::flat_map<std::string, std::string> GetKeyboardLayoutMap() = 0; virtual base::flat_map<std::string, std::string> GetKeyboardLayoutMap() = 0;
// Returns true if KeyEvents should be send to IME. This is called from
// WindowEventDispatcher during event dispatch.
virtual bool ShouldSendKeyEventToIme();
protected: protected:
friend class ScopedKeyboardHook; friend class ScopedKeyboardHook;
friend class TestScreen; // TODO(beng): see if we can remove/consolidate. friend class TestScreen; // TODO(beng): see if we can remove/consolidate.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment