Skip to content

Commit

Permalink
Factor work area insets calculations outside of the shelf
Browse files Browse the repository at this point in the history
Move keyboard bounds and move work area calculations at the same time
to avoid exposing keyboard bounds in WorkAreaInsets.

Bug: 944685
Test: Existing ash_unittests + manually
Change-Id: Id17ec5c37615824fed6368e89fc97fd8c025bde3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1552290
Reviewed-by: Darren Shen <shend@chromium.org>
Reviewed-by: Mitsuru Oshima <oshima@chromium.org>
Reviewed-by: James Cook <jamescook@chromium.org>
Commit-Queue: Aga Wronska <agawronska@chromium.org>
Cr-Commit-Position: refs/heads/master@{#650155}
  • Loading branch information
Aga Wronska authored and Commit Bot committed Apr 12, 2019
1 parent 5bb9b44 commit 4397114
Show file tree
Hide file tree
Showing 21 changed files with 314 additions and 200 deletions.
2 changes: 1 addition & 1 deletion ash/screen_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ gfx::Rect GetDisplayWorkAreaBoundsInParent(aura::Window* window) {
}

gfx::Rect GetDisplayWorkAreaBoundsInParentForLockScreen(aura::Window* window) {
gfx::Rect bounds = Shelf::ForWindow(window)->GetUserWorkAreaBounds();
gfx::Rect bounds = WorkAreaInsets::ForWindow(window)->user_work_area_bounds();
::wm::ConvertRectFromScreen(window->parent(), &bounds);
return bounds;
}
Expand Down
31 changes: 19 additions & 12 deletions ash/shelf/shelf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "ash/shelf/shelf_widget.h"
#include "ash/shell.h"
#include "ash/system/status_area_widget.h"
#include "ash/wm/work_area_insets.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "ui/display/types/display_constants.h"
Expand Down Expand Up @@ -142,10 +143,14 @@ bool Shelf::IsVisible() const {
return shelf_layout_manager_->IsVisible();
}

aura::Window* Shelf::GetWindow() {
const aura::Window* Shelf::GetWindow() const {
return shelf_widget_ ? shelf_widget_->GetNativeWindow() : nullptr;
}

aura::Window* Shelf::GetWindow() {
return const_cast<aura::Window*>(const_cast<const Shelf*>(this)->GetWindow());
}

void Shelf::SetAlignment(ShelfAlignment alignment) {
if (!shelf_widget_)
return;
Expand Down Expand Up @@ -248,11 +253,6 @@ gfx::Rect Shelf::GetIdealBounds() const {
return shelf_layout_manager_->GetIdealBounds();
}

gfx::Rect Shelf::GetUserWorkAreaBounds() const {
return shelf_layout_manager_ ? shelf_layout_manager_->user_work_area_bounds()
: gfx::Rect();
}

gfx::Rect Shelf::GetScreenBoundsOfItemIconForWindow(aura::Window* window) {
if (!shelf_widget_)
return gfx::Rect();
Expand Down Expand Up @@ -293,7 +293,7 @@ TrayBackgroundView* Shelf::GetSystemTrayAnchorView() const {
}

gfx::Rect Shelf::GetSystemTrayAnchorRect() const {
gfx::Rect work_area = GetUserWorkAreaBounds();
gfx::Rect work_area = GetWorkAreaInsets()->user_work_area_bounds();
switch (alignment_) {
case SHELF_ALIGNMENT_BOTTOM:
case SHELF_ALIGNMENT_BOTTOM_LOCKED:
Expand Down Expand Up @@ -322,13 +322,14 @@ void Shelf::SetVirtualKeyboardBoundsForTesting(const gfx::Rect& bounds) {
state.visual_bounds = bounds;
state.occluded_bounds = bounds;
state.displaced_bounds = gfx::Rect();
shelf_layout_manager_->OnKeyboardVisibilityStateChanged(state.is_visible);
shelf_layout_manager_->OnKeyboardVisibleBoundsChanged(state.visual_bounds);
shelf_layout_manager_->OnKeyboardWorkspaceOccludedBoundsChanged(
WorkAreaInsets* work_area_insets = GetWorkAreaInsets();
work_area_insets->OnKeyboardVisibilityStateChanged(state.is_visible);
work_area_insets->OnKeyboardVisibleBoundsChanged(state.visual_bounds);
work_area_insets->OnKeyboardWorkspaceOccludedBoundsChanged(
state.occluded_bounds);
shelf_layout_manager_->OnKeyboardWorkspaceDisplacingBoundsChanged(
work_area_insets->OnKeyboardWorkspaceDisplacingBoundsChanged(
state.displaced_bounds);
shelf_layout_manager_->OnKeyboardAppearanceChanged(state);
work_area_insets->OnKeyboardAppearanceChanged(state);
}

ShelfLockingManager* Shelf::GetShelfLockingManagerForTesting() {
Expand Down Expand Up @@ -373,4 +374,10 @@ void Shelf::OnBackgroundUpdated(ShelfBackgroundType background_type,
observer.OnBackgroundTypeChanged(background_type, change_type);
}

WorkAreaInsets* Shelf::GetWorkAreaInsets() const {
const aura::Window* window = GetWindow();
DCHECK(window);
return WorkAreaInsets::ForWindow(window->GetRootWindow());
}

} // namespace ash
7 changes: 5 additions & 2 deletions ash/shelf/shelf.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class ShelfWidget;
class StatusAreaWidget;
class ShelfObserver;
class TrayBackgroundView;
class WorkAreaInsets;

// Controller for the shelf state. One per display, because each display might
// have different shelf alignment, autohide, etc. Exists for the lifetime of the
Expand Down Expand Up @@ -88,6 +89,7 @@ class ASH_EXPORT Shelf : public ShelfLayoutManagerObserver {
bool IsVisible() const;

// Returns the window showing the shelf.
const aura::Window* GetWindow() const;
aura::Window* GetWindow();

void SetAlignment(ShelfAlignment alignment);
Expand Down Expand Up @@ -123,8 +125,6 @@ class ASH_EXPORT Shelf : public ShelfLayoutManagerObserver {
// Returns the ideal bounds of the shelf assuming it is visible.
gfx::Rect GetIdealBounds() const;

gfx::Rect GetUserWorkAreaBounds() const;

// Returns the screen bounds of the item for the specified window. If there is
// no item for the specified window an empty rect is returned.
gfx::Rect GetScreenBoundsOfItemIconForWindow(aura::Window* window);
Expand Down Expand Up @@ -190,6 +190,9 @@ class ASH_EXPORT Shelf : public ShelfLayoutManagerObserver {
class AutoHideEventHandler;
friend class ShelfLayoutManagerTest;

// Returns work area insets object for the window with this shelf.
WorkAreaInsets* GetWorkAreaInsets() const;

// Layout manager for the shelf container window. Instances are constructed by
// ShelfWidget and lifetimes are managed by the container windows themselves.
ShelfLayoutManager* shelf_layout_manager_ = nullptr;
Expand Down
121 changes: 30 additions & 91 deletions ash/shelf/shelf_layout_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@
#include "ui/display/screen.h"
#include "ui/events/event.h"
#include "ui/events/event_handler.h"
#include "ui/keyboard/keyboard_controller.h"
#include "ui/views/border.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/core/coordinate_conversion.h"
Expand Down Expand Up @@ -130,6 +129,11 @@ wm::WorkspaceWindowState GetShelfWorkspaceWindowState(
return controller->GetWindowState();
}

// Returns shelf's work area inset for given |visibility_state| and |size|.
int GetShelfInset(ShelfVisibilityState visibility_state, int size) {
return visibility_state == SHELF_VISIBLE ? size : 0;
}

} // namespace

// ShelfLayoutManager::UpdateShelfObserver -------------------------------------
Expand Down Expand Up @@ -224,7 +228,6 @@ ShelfLayoutManager::ShelfLayoutManager(ShelfWidget* shelf_widget, Shelf* shelf)
Shell::Get()->activation_client()->AddObserver(this);
Shell::Get()->locale_update_controller()->AddObserver(this);
state_.session_state = Shell::Get()->session_controller()->GetSessionState();
keyboard::KeyboardController::Get()->AddObserver(this);
wallpaper_controller_observer_.Add(Shell::Get()->wallpaper_controller());
display::Screen::GetScreen()->AddObserver(this);
}
Expand All @@ -236,7 +239,6 @@ ShelfLayoutManager::~ShelfLayoutManager() {
for (auto& observer : observers_)
observer.WillDeleteShelfLayoutManager();
display::Screen::GetScreen()->RemoveObserver(this);
keyboard::KeyboardController::Get()->RemoveObserver(this);
Shell::Get()->locale_update_controller()->RemoveObserver(this);
Shell::Get()->RemoveShellObserver(this);
Shell::Get()->lock_state_controller()->RemoveObserver(this);
Expand Down Expand Up @@ -551,7 +553,7 @@ void ShelfLayoutManager::OnShelfAutoHideBehaviorChanged(
UpdateVisibilityState();
}

void ShelfLayoutManager::OnAccessibilityInsetsChanged(
void ShelfLayoutManager::OnUserWorkAreaInsetsChanged(
aura::Window* root_window) {
LayoutShelf();
}
Expand Down Expand Up @@ -639,26 +641,6 @@ void ShelfLayoutManager::OnWindowActivated(ActivationReason reason,
UpdateAutoHideStateNow();
}

void ShelfLayoutManager::OnKeyboardAppearanceChanged(
const keyboard::KeyboardStateDescriptor& state) {
keyboard_occluded_bounds_ = state.occluded_bounds;
keyboard_displaced_bounds_ = state.displaced_bounds;

LayoutShelfAndUpdateBounds();
}

void ShelfLayoutManager::OnKeyboardVisibilityStateChanged(
const bool is_visible) {
// On login screen if keyboard has been just hidden, update bounds just once
// but ignore target_bounds.work_area_insets since shelf overlaps with login
// window.
if (Shell::Get()->session_controller()->IsUserSessionBlocked() &&
!is_visible) {
Shell::Get()->SetDisplayWorkAreaInsets(shelf_widget_->GetNativeWindow(),
gfx::Insets());
}
}

void ShelfLayoutManager::OnLockStateEvent(LockStateObserver::EventType event) {
if (event == EVENT_LOCK_ANIMATION_STARTED) {
// Enter the screen locked state and update the visibility to avoid an odd
Expand Down Expand Up @@ -929,8 +911,12 @@ void ShelfLayoutManager::UpdateBoundsAndOpacity(
// If user session is blocked (login to new user session or add user to
// the existing session - multi-profile) then give 100% of work area only
// if keyboard is not shown.
if (!state_.IsAddingSecondaryUser() || IsKeyboardShown())
insets = target_bounds.work_area_insets;
// TODO(agawronska): Could this be called from WorkAreaInsets?
const WorkAreaInsets* const work_area =
WorkAreaInsets::ForWindow(shelf_widget_->GetNativeWindow());
if (!state_.IsAddingSecondaryUser() || work_area->IsKeyboardShown())
insets = work_area->user_work_area_insets();

Shell::Get()->SetDisplayWorkAreaInsets(shelf_widget_->GetNativeWindow(),
insets);
}
Expand All @@ -949,10 +935,6 @@ void ShelfLayoutManager::UpdateBoundsAndOpacity(
status_widget->Show();
}

bool ShelfLayoutManager::IsKeyboardShown() const {
return !keyboard_displaced_bounds_.IsEmpty();
}

bool ShelfLayoutManager::IsDraggingWindowFromTopOrCaptionArea() const {
// Currently dragging maximized or fullscreen window from the top or the
// caption area is only allowed in tablet mode.
Expand All @@ -979,43 +961,31 @@ void ShelfLayoutManager::StopAnimating() {
GetLayer(shelf_widget_->status_area_widget())->GetAnimator()->StopAnimating();
}

gfx::Rect ShelfLayoutManager::ComputeStableWorkArea() const {
TargetBounds target_bounds;
State state = state_;
state.visibility_state = SHELF_VISIBLE;
return CalculateTargetBounds(state, &target_bounds);
}

bool ShelfLayoutManager::IsShowingStatusAreaWithoutShelf() const {
return state_.is_status_area_visible &&
state_.visibility_state == SHELF_HIDDEN;
}

gfx::Rect ShelfLayoutManager::CalculateTargetBounds(
void ShelfLayoutManager::CalculateTargetBounds(
const State& state,
TargetBounds* target_bounds) const {
const int shelf_size = ShelfConstants::shelf_size();
// By default, show the whole shelf on the screen.
int shelf_in_screen_portion = shelf_size;
const WorkAreaInsets* const work_area =
WorkAreaInsets::ForWindow(shelf_widget_->GetNativeWindow());

if (state.IsShelfAutoHidden()) {
shelf_in_screen_portion = kHiddenShelfInScreenPortion;
} else if (state.visibility_state == SHELF_HIDDEN || IsKeyboardShown()) {
} else if (state.visibility_state == SHELF_HIDDEN ||
work_area->IsKeyboardShown()) {
shelf_in_screen_portion = 0;
}

aura::Window* shelf_window = shelf_widget_->GetNativeWindow();
const WorkAreaInsets* const work_area_insets =
WorkAreaInsets::ForWindow(shelf_window);
const int accessibility_panel_height =
work_area_insets->accessibility_panel_height();
const int docked_magnifier_height =
work_area_insets->docked_magnifier_height();

gfx::Rect available_bounds =
screen_util::GetDisplayBoundsWithShelf(shelf_window);
available_bounds.Inset(
0, accessibility_panel_height + docked_magnifier_height, 0, 0);
screen_util::GetDisplayBoundsWithShelf(shelf_widget_->GetNativeWindow());
available_bounds.Inset(work_area->GetAccessibilityInsets());

int shelf_width = PrimaryAxisValue(available_bounds.width(), shelf_size);
int shelf_height = PrimaryAxisValue(shelf_size, available_bounds.height());
const int shelf_primary_position = SelectValueForShelfAlignment(
Expand Down Expand Up @@ -1047,26 +1017,6 @@ gfx::Rect ShelfLayoutManager::CalculateTargetBounds(
status_origin.set_x(shelf_width - status_size.width());
target_bounds->status_bounds_in_shelf = gfx::Rect(status_origin, status_size);

target_bounds->work_area_insets = SelectValueForShelfAlignment(
gfx::Insets(0, 0, GetWorkAreaInsets(state, shelf_height), 0),
gfx::Insets(0, GetWorkAreaInsets(state, shelf_width), 0, 0),
gfx::Insets(0, 0, 0, GetWorkAreaInsets(state, shelf_width)));

// TODO(varkha): The functionality of managing insets for display areas
// should probably be pushed to a separate component. This would simplify or
// remove entirely the dependency on keyboard and dock.

if (!keyboard_displaced_bounds_.IsEmpty()) {
// Also push in the work area inset for the keyboard if it is visible.
gfx::Insets keyboard_insets(0, 0, keyboard_displaced_bounds_.height(), 0);
target_bounds->work_area_insets += keyboard_insets;
}

// Also push in the work area insets for both the ChromeVox panel and the
// Docked Magnifier.
target_bounds->work_area_insets += gfx::Insets(
accessibility_panel_height + docked_magnifier_height, 0, 0, 0);

bool is_showing_status_area_without_shelf =
state_.is_status_area_visible && state_.visibility_state == SHELF_HIDDEN;
target_bounds->shelf_opacity = ComputeTargetOpacity(state);
Expand All @@ -1079,9 +1029,13 @@ gfx::Rect ShelfLayoutManager::CalculateTargetBounds(
target_bounds->status_opacity = target_bounds->shelf_opacity;
}

if (gesture_drag_status_ == GESTURE_DRAG_IN_PROGRESS) {
if (gesture_drag_status_ == GESTURE_DRAG_IN_PROGRESS)
UpdateShelfTargetBoundsForGesture(target_bounds);
}

target_bounds->shelf_insets = SelectValueForShelfAlignment(
gfx::Insets(0, 0, GetShelfInset(state.visibility_state, shelf_height), 0),
gfx::Insets(0, GetShelfInset(state.visibility_state, shelf_width), 0, 0),
gfx::Insets(0, 0, 0, GetShelfInset(state.visibility_state, shelf_width)));

// This needs to happen after calling UpdateTargetBoundsForGesture(), because
// that can change the size of the shelf.
Expand All @@ -1092,18 +1046,14 @@ gfx::Rect ShelfLayoutManager::CalculateTargetBounds(
shelf_height - status_size.height()),
gfx::Rect(0, 0, target_bounds->shelf_bounds.width(),
shelf_height - status_size.height()));

available_bounds.Subtract(target_bounds->shelf_bounds);
available_bounds.Subtract(keyboard_occluded_bounds_);

aura::Window* root = shelf_window->GetRootWindow();
::wm::ConvertRectToScreen(root, &available_bounds);
return available_bounds;
}

void ShelfLayoutManager::CalculateTargetBoundsAndUpdateWorkArea(
TargetBounds* target_bounds) {
user_work_area_bounds_ = CalculateTargetBounds(state_, target_bounds);
CalculateTargetBounds(state_, target_bounds);
WorkAreaInsets::ForWindow(shelf_widget_->GetNativeWindow())
->SetShelfBoundsAndInsets(target_bounds->shelf_bounds,
target_bounds->shelf_insets);
}

void ShelfLayoutManager::UpdateShelfTargetBoundsForGesture(
Expand Down Expand Up @@ -1354,17 +1304,6 @@ bool ShelfLayoutManager::IsStatusAreaWindow(aura::Window* window) {
return status_window && status_window->Contains(window);
}

int ShelfLayoutManager::GetWorkAreaInsets(const State& state, int size) const {
// The virtual keyboard always hides the shelf (in any orientation).
// Therefore, if the keyboard is shown, there is no need to reduce the work
// area by the size of the shelf.
if (IsKeyboardShown())
return 0;
if (state.visibility_state == SHELF_VISIBLE)
return size;
return 0;
}

void ShelfLayoutManager::UpdateShelfVisibilityAfterLoginUIChange() {
UpdateVisibilityState();
LayoutShelf();
Expand Down
Loading

0 comments on commit 4397114

Please sign in to comment.