1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
ash / keyboard / ui / container_full_width_behavior.cc [blame]
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/keyboard/ui/container_full_width_behavior.h"
#include "ui/aura/window.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/display/screen.h"
#include "ui/gfx/geometry/transform.h"
#include "ui/wm/core/window_animations.h"
namespace keyboard {
// The virtual keyboard show/hide animation durations.
constexpr auto kShowAnimationDuration = base::Milliseconds(200);
constexpr auto kHideAnimationDuration = base::Milliseconds(100);
// The height of the area from the bottom of the keyboard where the user can
// swipe up to access the shelf. Manually calculated to be slightly below
// the virtual keyboard's space bar to avoid accidental trigger.
constexpr int kSwipeUpGestureAreaHeight = 8;
ContainerFullWidthBehavior::ContainerFullWidthBehavior(Delegate* delegate)
: ContainerBehavior(delegate) {}
ContainerFullWidthBehavior::~ContainerFullWidthBehavior() = default;
ContainerType ContainerFullWidthBehavior::GetType() const {
return ContainerType::kFullWidth;
}
void ContainerFullWidthBehavior::DoHidingAnimation(
aura::Window* container,
::wm::ScopedHidingAnimationSettings* animation_settings) {
animation_settings->layer_animation_settings()->SetTransitionDuration(
kHideAnimationDuration);
gfx::Transform transform;
transform.Translate(0, kFullWidthKeyboardAnimationDistance);
container->SetTransform(transform);
container->layer()->SetOpacity(0.f);
}
void ContainerFullWidthBehavior::DoShowingAnimation(
aura::Window* container,
ui::ScopedLayerAnimationSettings* animation_settings) {
animation_settings->SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN);
animation_settings->SetTransitionDuration(kShowAnimationDuration);
container->SetTransform(gfx::Transform());
container->layer()->SetOpacity(1.0);
}
void ContainerFullWidthBehavior::InitializeShowAnimationStartingState(
aura::Window* container) {
SetCanonicalBounds(container, container->GetRootWindow()->bounds());
gfx::Transform transform;
transform.Translate(0, kFullWidthKeyboardAnimationDistance);
container->SetTransform(transform);
container->layer()->SetOpacity(kAnimationStartOrAfterHideOpacity);
}
gfx::Rect ContainerFullWidthBehavior::AdjustSetBoundsRequest(
const gfx::Rect& display_bounds,
const gfx::Rect& requested_bounds_in_screen_coords) {
gfx::Rect new_bounds;
// Honors only the height of the request bounds
const int keyboard_height = requested_bounds_in_screen_coords.height();
new_bounds.set_y(display_bounds.bottom() - keyboard_height);
new_bounds.set_height(keyboard_height);
// If shelf is positioned on the left side of screen, x is not 0. In
// FULL_WIDTH mode, the virtual keyboard should always align with the left
// edge of the screen. So manually set x to the left side of the screen.
new_bounds.set_x(display_bounds.x());
new_bounds.set_width(display_bounds.width());
return new_bounds;
}
bool ContainerFullWidthBehavior::IsOverscrollAllowed() const {
// TODO(blakeo): The locked keyboard is essentially its own behavior type and
// should be refactored as such. Then this will simply return 'true'.
return delegate_ && !delegate_->IsKeyboardLocked();
}
void ContainerFullWidthBehavior::SavePosition(const gfx::Rect& keyboard_bounds,
const gfx::Size& screen_size) {
// No-op. Nothing to save.
}
bool ContainerFullWidthBehavior::HandlePointerEvent(
const ui::LocatedEvent& event,
const display::Display& current_display) {
// No-op. Nothing special to do for pointer events.
return false;
}
bool ContainerFullWidthBehavior::HandleGestureEvent(
const ui::GestureEvent& event,
const gfx::Rect& bounds_in_screen) {
if (!display::Screen::GetScreen()->InTabletMode()) {
return false;
}
if (event.type() == ui::EventType::kGestureScrollBegin) {
// Check that the user is swiping upwards near the bottom of the keyboard.
// The coordinates of the |event| is relative to the window.
const auto details = event.details();
if (std::abs(details.scroll_y_hint()) > std::abs(details.scroll_x_hint()) &&
details.scroll_y_hint() < 0 &&
event.y() > bounds_in_screen.height() - kSwipeUpGestureAreaHeight) {
delegate_->TransferGestureEventToShelf(event);
return true;
}
}
return false;
}
void ContainerFullWidthBehavior::SetCanonicalBounds(
aura::Window* container,
const gfx::Rect& display_bounds) {
const gfx::Rect new_keyboard_bounds =
AdjustSetBoundsRequest(display_bounds, container->bounds());
container->SetBounds(new_keyboard_bounds);
}
bool ContainerFullWidthBehavior::TextBlurHidesKeyboard() const {
return !delegate_->IsKeyboardLocked();
}
void ContainerFullWidthBehavior::SetOccludedBounds(
const gfx::Rect& occluded_bounds_in_window) {
occluded_bounds_in_window_ = occluded_bounds_in_window;
}
gfx::Rect ContainerFullWidthBehavior::GetOccludedBounds(
const gfx::Rect& visual_bounds_in_window) const {
DCHECK(visual_bounds_in_window.Contains(occluded_bounds_in_window_));
return occluded_bounds_in_window_.IsEmpty() ? visual_bounds_in_window
: occluded_bounds_in_window_;
}
bool ContainerFullWidthBehavior::OccludedBoundsAffectWorkspaceLayout() const {
return delegate_->IsKeyboardLocked();
}
void ContainerFullWidthBehavior::SetDraggableArea(const gfx::Rect& rect) {
// Allow extension to call this function but does nothing here.
}
void ContainerFullWidthBehavior::SetAreaToRemainOnScreen(
const gfx::Rect& bounds) {
// Allow extension to call this function but does nothing here.
}
} // namespace keyboard