Commit 094d56c5 authored by yilkal's avatar yilkal Committed by Commit Bot

Hide virtual keyboard when parent access widget is shown.

This CL hides virtual keyboard when parent access widget is being
shown. It achieves this by doing the following:
1. Hide virtual keyboard when parent access widget is shown.
2. Prevent views::Textfield from calling views::Textfield::
   ShowVirtualKeyboardIfEnabled() by making changes in
   ParentAccessView::AccessCodeInput and AccessibleInputField.

Bug: 938705
Change-Id: I5199a8a6290e2cf47602b0ef130b4aa5c05b7ad9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1784337Reviewed-by: default avatarDarren Shen <shend@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarMitsuru Oshima <oshima@chromium.org>
Reviewed-by: default avatarAga Wronska <agawronska@chromium.org>
Commit-Queue: Yilkal Abe <yilkal@chromium.org>
Cr-Commit-Position: refs/heads/master@{#693893}
parent ddcb7d8d
...@@ -177,6 +177,15 @@ class AccessibleInputField : public views::Textfield { ...@@ -177,6 +177,15 @@ class AccessibleInputField : public views::Textfield {
return parent() ? parent()->GetSelectedViewForGroup(group) : nullptr; return parent() ? parent()->GetSelectedViewForGroup(group) : nullptr;
} }
void OnGestureEvent(ui::GestureEvent* event) override {
if (event->type() == ui::ET_GESTURE_TAP_DOWN) {
RequestFocusWithPointer(event->details().primary_pointer_type());
return;
}
views::Textfield::OnGestureEvent(event);
}
private: private:
base::string16 accessible_description_; base::string16 accessible_description_;
...@@ -239,6 +248,22 @@ class ParentAccessView::AccessCodeInput : public views::View, ...@@ -239,6 +248,22 @@ class ParentAccessView::AccessCodeInput : public views::View,
base::RepeatingCallback<void(bool complete, bool last_field_active)>; base::RepeatingCallback<void(bool complete, bool last_field_active)>;
using OnEnter = base::RepeatingClosure; using OnEnter = base::RepeatingClosure;
class TestApi {
public:
explicit TestApi(ParentAccessView::AccessCodeInput* access_code_input)
: access_code_input_(access_code_input) {}
~TestApi() = default;
views::Textfield* GetInputTextField(int index) {
DCHECK_LT(static_cast<size_t>(index),
access_code_input_->input_fields_.size());
return access_code_input_->input_fields_[index];
}
private:
ParentAccessView::AccessCodeInput* access_code_input_;
};
// Builds the view for an access code that consists out of |length| digits. // Builds the view for an access code that consists out of |length| digits.
// |on_input_change| will be called upon access code digit insertion, deletion // |on_input_change| will be called upon access code digit insertion, deletion
// or change. True will be passed if the current code is complete (all digits // or change. True will be passed if the current code is complete (all digits
...@@ -378,8 +403,10 @@ class ParentAccessView::AccessCodeInput : public views::View, ...@@ -378,8 +403,10 @@ class ParentAccessView::AccessCodeInput : public views::View,
bool HandleMouseEvent(views::Textfield* sender, bool HandleMouseEvent(views::Textfield* sender,
const ui::MouseEvent& mouse_event) override { const ui::MouseEvent& mouse_event) override {
if (!mouse_event.IsOnlyLeftMouseButton()) if (!(mouse_event.IsOnlyLeftMouseButton() ||
mouse_event.IsOnlyRightMouseButton())) {
return false; return false;
}
// Move focus to the field that was selected with mouse input. // Move focus to the field that was selected with mouse input.
for (size_t i = 0; i < input_fields_.size(); ++i) { for (size_t i = 0; i < input_fields_.size(); ++i) {
...@@ -467,34 +494,39 @@ ParentAccessView::TestApi::TestApi(ParentAccessView* view) : view_(view) { ...@@ -467,34 +494,39 @@ ParentAccessView::TestApi::TestApi(ParentAccessView* view) : view_(view) {
ParentAccessView::TestApi::~TestApi() = default; ParentAccessView::TestApi::~TestApi() = default;
LoginButton* ParentAccessView::TestApi::back_button() const { LoginButton* ParentAccessView::TestApi::back_button() {
return view_->back_button_; return view_->back_button_;
} }
views::Label* ParentAccessView::TestApi::title_label() const { views::Label* ParentAccessView::TestApi::title_label() {
return view_->title_label_; return view_->title_label_;
} }
views::Label* ParentAccessView::TestApi::description_label() const { views::Label* ParentAccessView::TestApi::description_label() {
return view_->description_label_; return view_->description_label_;
} }
views::View* ParentAccessView::TestApi::access_code_view() const { views::View* ParentAccessView::TestApi::access_code_view() {
return view_->access_code_view_; return view_->access_code_view_;
} }
views::LabelButton* ParentAccessView::TestApi::help_button() const { views::LabelButton* ParentAccessView::TestApi::help_button() {
return view_->help_button_; return view_->help_button_;
} }
ArrowButtonView* ParentAccessView::TestApi::submit_button() const { ArrowButtonView* ParentAccessView::TestApi::submit_button() {
return view_->submit_button_; return view_->submit_button_;
} }
LoginPinView* ParentAccessView::TestApi::pin_keyboard_view() const { LoginPinView* ParentAccessView::TestApi::pin_keyboard_view() {
return view_->pin_keyboard_view_; return view_->pin_keyboard_view_;
} }
views::Textfield* ParentAccessView::TestApi::GetInputTextField(int index) {
return ParentAccessView::AccessCodeInput::TestApi(view_->access_code_view_)
.GetInputTextField(index);
}
ParentAccessView::State ParentAccessView::TestApi::state() const { ParentAccessView::State ParentAccessView::TestApi::state() const {
return view_->state_; return view_->state_;
} }
...@@ -520,7 +552,6 @@ ParentAccessView::ParentAccessView(const AccountId& account_id, ...@@ -520,7 +552,6 @@ ParentAccessView::ParentAccessView(const AccountId& account_id,
request_reason_(reason), request_reason_(reason),
validation_time_(validation_time) { validation_time_(validation_time) {
DCHECK(callbacks.on_finished); DCHECK(callbacks.on_finished);
// Main view contains all other views aligned vertically and centered. // Main view contains all other views aligned vertically and centered.
auto layout = std::make_unique<views::BoxLayout>( auto layout = std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kVertical, views::BoxLayout::Orientation::kVertical,
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
namespace views { namespace views {
class Label; class Label;
class LabelButton; class LabelButton;
class Textfield;
} // namespace views } // namespace views
namespace ash { namespace ash {
...@@ -50,13 +51,15 @@ class ASH_EXPORT ParentAccessView : public views::DialogDelegateView, ...@@ -50,13 +51,15 @@ class ASH_EXPORT ParentAccessView : public views::DialogDelegateView,
explicit TestApi(ParentAccessView* view); explicit TestApi(ParentAccessView* view);
~TestApi(); ~TestApi();
LoginButton* back_button() const; LoginButton* back_button();
views::Label* title_label() const; views::Label* title_label();
views::Label* description_label() const; views::Label* description_label();
views::View* access_code_view() const; views::View* access_code_view();
views::LabelButton* help_button() const; views::LabelButton* help_button();
ArrowButtonView* submit_button() const; ArrowButtonView* submit_button();
LoginPinView* pin_keyboard_view() const; LoginPinView* pin_keyboard_view();
views::Textfield* GetInputTextField(int index);
State state() const; State state() const;
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include "ash/keyboard/keyboard_controller_impl.h"
#include "ash/login/mock_login_screen_client.h" #include "ash/login/mock_login_screen_client.h"
#include "ash/login/ui/arrow_button_view.h" #include "ash/login/ui/arrow_button_view.h"
#include "ash/login/ui/login_button.h" #include "ash/login/ui/login_button.h"
...@@ -35,6 +36,7 @@ ...@@ -35,6 +36,7 @@
#include "ui/events/test/event_generator.h" #include "ui/events/test/event_generator.h"
#include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/point.h"
#include "ui/views/controls/button/label_button.h" #include "ui/views/controls/button/label_button.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/widget/widget.h" #include "ui/views/widget/widget.h"
namespace ash { namespace ash {
...@@ -629,6 +631,35 @@ TEST_F(ParentAccessWidgetTest, WidgetResizingInTabletMode) { ...@@ -629,6 +631,35 @@ TEST_F(ParentAccessWidgetTest, WidgetResizingInTabletMode) {
EXPECT_EQ(kClamshellModeSize, view->size()); EXPECT_EQ(kClamshellModeSize, view->size());
EXPECT_EQ(kClamshellModeSize, widget_size()); EXPECT_EQ(kClamshellModeSize, widget_size());
EXPECT_EQ(user_work_area_center(), widget_center()); EXPECT_EQ(user_work_area_center(), widget_center());
widget->Destroy();
}
TEST_F(ParentAccessViewTest, VirtualKeyboardHidden) {
// Enable and show virtual keyboard.
auto* keyboard_controller = Shell::Get()->keyboard_controller();
ASSERT_NE(keyboard_controller, nullptr);
keyboard_controller->SetEnableFlag(
keyboard::KeyboardEnableFlag::kCommandLineEnabled);
// Show widget.
ShowWidget(ParentAccessRequestReason::kUnlockTimeLimits);
auto* view = ParentAccessWidget::TestApi(ParentAccessWidget::Get())
.parent_access_view();
ParentAccessView::TestApi test_api(view);
views::Textfield* text_field = test_api.GetInputTextField(0);
ui::GestureEvent event(
text_field->x(), text_field->y(), 0, base::TimeTicks::Now(),
ui::GestureEventDetails(ui::EventType::ET_GESTURE_TAP_DOWN));
text_field->OnGestureEvent(&event);
base::RunLoop().RunUntilIdle();
// Even if we have pressed the text input field, virtual keyboard shouldn't
// show.
EXPECT_FALSE(keyboard_controller->IsKeyboardVisible());
DismissWidget();
} }
} // namespace ash } // namespace ash
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <utility> #include <utility>
#include "ash/keyboard/keyboard_controller_impl.h"
#include "ash/login/ui/parent_access_view.h" #include "ash/login/ui/parent_access_view.h"
#include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/shell_window_ids.h"
#include "ash/session/session_controller_impl.h" #include "ash/session/session_controller_impl.h"
...@@ -119,6 +120,10 @@ void ParentAccessWidget::Show() { ...@@ -119,6 +120,10 @@ void ParentAccessWidget::Show() {
DCHECK(widget_); DCHECK(widget_);
widget_->Show(); widget_->Show();
auto* keyboard_controller = Shell::Get()->keyboard_controller();
if (keyboard_controller && keyboard_controller->IsKeyboardEnabled())
keyboard_controller->HideKeyboard(HideReason::kSystem);
} }
void ParentAccessWidget::OnExit(bool success) { void ParentAccessWidget::OnExit(bool success) {
......
...@@ -913,28 +913,6 @@ bool Textfield::CanHandleAccelerators() const { ...@@ -913,28 +913,6 @@ bool Textfield::CanHandleAccelerators() const {
return GetRenderText()->focused() && View::CanHandleAccelerators(); return GetRenderText()->focused() && View::CanHandleAccelerators();
} }
void Textfield::RequestFocusWithPointer(ui::EventPointerType pointer_type) {
if (HasFocus())
return;
switch (pointer_type) {
case ui::EventPointerType::POINTER_TYPE_MOUSE:
focus_reason_ = ui::TextInputClient::FOCUS_REASON_MOUSE;
break;
case ui::EventPointerType::POINTER_TYPE_PEN:
focus_reason_ = ui::TextInputClient::FOCUS_REASON_PEN;
break;
case ui::EventPointerType::POINTER_TYPE_TOUCH:
focus_reason_ = ui::TextInputClient::FOCUS_REASON_TOUCH;
break;
default:
focus_reason_ = ui::TextInputClient::FOCUS_REASON_OTHER;
break;
}
View::RequestFocus();
}
void Textfield::AboutToRequestFocusFromTabTraversal(bool reverse) { void Textfield::AboutToRequestFocusFromTabTraversal(bool reverse) {
SelectAll(PlatformStyle::kTextfieldScrollsToStartOnFocusChange); SelectAll(PlatformStyle::kTextfieldScrollsToStartOnFocusChange);
} }
...@@ -2094,6 +2072,28 @@ bool Textfield::ShouldShowPlaceholderText() const { ...@@ -2094,6 +2072,28 @@ bool Textfield::ShouldShowPlaceholderText() const {
return GetText().empty() && !GetPlaceholderText().empty(); return GetText().empty() && !GetPlaceholderText().empty();
} }
void Textfield::RequestFocusWithPointer(ui::EventPointerType pointer_type) {
if (HasFocus())
return;
switch (pointer_type) {
case ui::EventPointerType::POINTER_TYPE_MOUSE:
focus_reason_ = ui::TextInputClient::FOCUS_REASON_MOUSE;
break;
case ui::EventPointerType::POINTER_TYPE_PEN:
focus_reason_ = ui::TextInputClient::FOCUS_REASON_PEN;
break;
case ui::EventPointerType::POINTER_TYPE_TOUCH:
focus_reason_ = ui::TextInputClient::FOCUS_REASON_TOUCH;
break;
default:
focus_reason_ = ui::TextInputClient::FOCUS_REASON_OTHER;
break;
}
View::RequestFocus();
}
views::PropertyChangedSubscription Textfield::AddTextChangedCallback( views::PropertyChangedSubscription Textfield::AddTextChangedCallback(
views::PropertyChangedCallback callback) { views::PropertyChangedCallback callback) {
return AddPropertyChangedCallback(&model_ + kTextfieldText, return AddPropertyChangedCallback(&model_ + kTextfieldText,
......
...@@ -416,6 +416,11 @@ class VIEWS_EXPORT Textfield : public View, ...@@ -416,6 +416,11 @@ class VIEWS_EXPORT Textfield : public View,
// override this to customize when the placeholder text is shown. // override this to customize when the placeholder text is shown.
virtual bool ShouldShowPlaceholderText() const; virtual bool ShouldShowPlaceholderText() const;
protected:
// Like RequestFocus, but explicitly states that the focus is triggered by
// a pointer event.
void RequestFocusWithPointer(ui::EventPointerType pointer_type);
private: private:
friend class TextfieldTestApi; friend class TextfieldTestApi;
...@@ -524,10 +529,6 @@ class VIEWS_EXPORT Textfield : public View, ...@@ -524,10 +529,6 @@ class VIEWS_EXPORT Textfield : public View,
// Textfield::GetCaretBlinkMs(). // Textfield::GetCaretBlinkMs().
void OnCursorBlinkTimerFired(); void OnCursorBlinkTimerFired();
// Like RequestFocus, but explicitly states that the focus is triggered by
// a pointer event.
void RequestFocusWithPointer(ui::EventPointerType pointer_type);
// Returns the color to use for the FocusRing, if one is present. // Returns the color to use for the FocusRing, if one is present.
SkColor GetFocusRingColor() const; SkColor GetFocusRingColor() const;
......
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