#include "content/browser/renderer_host/virtual_keyboard_controller_win.h"
#include "base/trace_event/trace_event.h"
#include "content/browser/renderer_host/render_widget_host_view_aura.h"
#include "ui/base/ime/input_method.h"
#include "ui/base/ime/mojom/text_input_state.mojom.h"
#include "ui/base/ime/virtual_keyboard_controller.h"
#include "ui/events/event_utils.h"
#include "ui/gfx/geometry/rect.h"
namespace content {
VirtualKeyboardControllerWin::VirtualKeyboardControllerWin(
RenderWidgetHostViewAura* host_view,
ui::InputMethod* input_method)
: host_view_(host_view), input_method_(input_method) {
host_view_->SetInsets(gfx::Insets());
}
VirtualKeyboardControllerWin::~VirtualKeyboardControllerWin() {
if (observers_registered_) {
if (auto* controller = input_method_->GetVirtualKeyboardController())
controller->RemoveObserver(this);
}
}
void VirtualKeyboardControllerWin::HideAndNotifyKeyboardInset() {
if (auto* controller = input_method_->GetVirtualKeyboardController()) {
if (virtual_keyboard_shown_) {
controller->DismissVirtualKeyboard();
OnKeyboardHidden();
}
}
}
void VirtualKeyboardControllerWin::OnKeyboardVisible(
const gfx::Rect& keyboard_rect) {
TRACE_EVENT0("vk", "VirtualKeyboardControllerWin::OnKeyboardVisible");
virtual_keyboard_shown_ = true;
if (host_view_->GetVirtualKeyboardMode() !=
ui::mojom::VirtualKeyboardMode::kOverlaysContent) {
host_view_->SetInsets(gfx::Insets::TLBR(
0, 0, keyboard_rect.IsEmpty() ? 0 : keyboard_rect.height(), 0));
} else {
host_view_->NotifyVirtualKeyboardOverlayRect(keyboard_rect);
}
}
void VirtualKeyboardControllerWin::OnKeyboardHidden() {
TRACE_EVENT0("vk", "VirtualKeyboardControllerWin::OnKeyboardHidden");
virtual_keyboard_shown_ = false;
if (host_view_->GetVirtualKeyboardMode() !=
ui::mojom::VirtualKeyboardMode::kOverlaysContent) {
host_view_->SetInsets(gfx::Insets());
} else {
host_view_->NotifyVirtualKeyboardOverlayRect(gfx::Rect());
}
}
void VirtualKeyboardControllerWin::ShowVirtualKeyboard() {
TRACE_EVENT0("vk", "VirtualKeyboardControllerWin::ShowVirtualKeyboard");
if (auto* controller = input_method_->GetVirtualKeyboardController()) {
if (!virtual_keyboard_shown_) {
virtual_keyboard_shown_ = true;
input_method_->SetVirtualKeyboardVisibilityIfEnabled(true);
}
}
}
void VirtualKeyboardControllerWin::HideVirtualKeyboard() {
TRACE_EVENT0("vk", "VirtualKeyboardControllerWin::HideVirtualKeyboard");
if (auto* controller = input_method_->GetVirtualKeyboardController()) {
if (virtual_keyboard_shown_) {
virtual_keyboard_shown_ = false;
controller->DismissVirtualKeyboard();
}
}
}
void VirtualKeyboardControllerWin::UpdateTextInputState(
const ui::mojom::TextInputState* state) {
auto* controller = input_method_->GetVirtualKeyboardController();
is_manual_policy_ =
state->vk_policy == ui::mojom::VirtualKeyboardPolicy::MANUAL;
if (!controller ||
!(IsPointerTypeValidForVirtualKeyboard() || is_manual_policy_) ||
!host_view_->host()->GetView() || !host_view_->host()->delegate()) {
return;
}
if (!observers_registered_) {
controller->AddObserver(this);
observers_registered_ = true;
}
if (state->show_ime_if_needed &&
state->vk_policy == ui::mojom::VirtualKeyboardPolicy::AUTO) {
ShowVirtualKeyboard();
return;
}
if (is_manual_policy_) {
switch (state->last_vk_visibility_request) {
case ui::mojom::VirtualKeyboardVisibilityRequest::SHOW:
if (host_view_->FocusedFrameHasStickyActivation())
ShowVirtualKeyboard();
break;
case ui::mojom::VirtualKeyboardVisibilityRequest::HIDE:
HideVirtualKeyboard();
break;
default:
break;
}
}
}
void VirtualKeyboardControllerWin::FocusedNodeChanged(bool is_editable) {
if (!is_editable) {
HideVirtualKeyboard();
return;
}
}
bool VirtualKeyboardControllerWin::IsPointerTypeValidForVirtualKeyboard()
const {
return (host_view_->GetLastPointerType() == ui::EventPointerType::kTouch ||
host_view_->GetLastPointerType() == ui::EventPointerType::kPen);
}
}