blob: 14a8d757f1fab07b811eb0c401e63b0067071eea [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/common/wm/workspace/workspace_layout_manager.h"
#include <string>
#include <utility>
#include "ash/common/session/session_state_delegate.h"
#include "ash/common/shelf/shelf_constants.h"
#include "ash/common/shelf/shelf_layout_manager.h"
#include "ash/common/shelf/wm_shelf.h"
#include "ash/common/shell_observer.h"
#include "ash/common/test/ash_test.h"
#include "ash/common/wm/fullscreen_window_finder.h"
#include "ash/common/wm/maximize_mode/workspace_backdrop_delegate.h"
#include "ash/common/wm/window_state.h"
#include "ash/common/wm/wm_event.h"
#include "ash/common/wm/wm_screen_util.h"
#include "ash/common/wm/workspace/workspace_window_resizer.h"
#include "ash/common/wm_lookup.h"
#include "ash/common/wm_root_window_controller.h"
#include "ash/common/wm_shell.h"
#include "ash/common/wm_window.h"
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/shell.h"
#include "base/command_line.h"
#include "ui/base/ui_base_switches.h"
#include "ui/base/ui_base_types.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/keyboard/keyboard_controller.h"
#include "ui/keyboard/keyboard_ui.h"
#include "ui/keyboard/keyboard_util.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
#include "ui/wm/core/window_util.h"
namespace ash {
namespace {
WorkspaceLayoutManager* GetWorkspaceLayoutManager(WmWindow* container) {
return static_cast<WorkspaceLayoutManager*>(container->GetLayoutManager());
}
} // namespace
// TODO: this is a duplicate of that in ash/common, and should move once
// keyboard is refactored to work in mash.
class WorkspaceLayoutManagerKeyboardTest : public AshTest {
public:
WorkspaceLayoutManagerKeyboardTest() : layout_manager_(nullptr) {}
~WorkspaceLayoutManagerKeyboardTest() override {}
void SetUp() override {
AshTest::SetUp();
UpdateDisplay("800x600");
WmWindow* default_container =
WmShell::Get()->GetPrimaryRootWindowController()->GetContainer(
kShellWindowId_DefaultContainer);
layout_manager_ = GetWorkspaceLayoutManager(default_container);
}
void ShowKeyboard() {
layout_manager_->OnKeyboardBoundsChanging(keyboard_bounds_);
restore_work_area_insets_ =
display::Screen::GetScreen()->GetPrimaryDisplay().GetWorkAreaInsets();
WmShell::Get()->SetDisplayWorkAreaInsets(
WmShell::Get()->GetPrimaryRootWindow(),
gfx::Insets(0, 0, keyboard_bounds_.height(), 0));
}
void HideKeyboard() {
WmShell::Get()->SetDisplayWorkAreaInsets(
WmShell::Get()->GetPrimaryRootWindow(), restore_work_area_insets_);
layout_manager_->OnKeyboardBoundsChanging(gfx::Rect());
}
// Initializes the keyboard bounds using the bottom half of the work area.
void InitKeyboardBounds() {
gfx::Rect work_area(
display::Screen::GetScreen()->GetPrimaryDisplay().work_area());
keyboard_bounds_.SetRect(work_area.x(),
work_area.y() + work_area.height() / 2,
work_area.width(), work_area.height() / 2);
}
void EnableNewVKMode() {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (!command_line->HasSwitch(::switches::kUseNewVirtualKeyboardBehavior))
command_line->AppendSwitch(::switches::kUseNewVirtualKeyboardBehavior);
}
const gfx::Rect& keyboard_bounds() const { return keyboard_bounds_; }
private:
gfx::Insets restore_work_area_insets_;
gfx::Rect keyboard_bounds_;
WorkspaceLayoutManager* layout_manager_;
DISALLOW_COPY_AND_ASSIGN(WorkspaceLayoutManagerKeyboardTest);
};
TEST_F(WorkspaceLayoutManagerKeyboardTest, ChangeWorkAreaInNonStickyMode) {
keyboard::SetAccessibilityKeyboardEnabled(true);
InitKeyboardBounds();
Shell::GetInstance()->CreateKeyboard();
keyboard::KeyboardController* kb_controller =
keyboard::KeyboardController::GetInstance();
gfx::Rect work_area(
display::Screen::GetScreen()->GetPrimaryDisplay().work_area());
gfx::Rect orig_window_bounds(0, 100, work_area.width(),
work_area.height() - 100);
std::unique_ptr<WindowOwner> window_owner(
CreateToplevelTestWindow(orig_window_bounds));
WmWindow* window = window_owner->window();
window->Activate();
EXPECT_EQ(orig_window_bounds, window->GetBounds());
// Open keyboard in non-sticky mode.
kb_controller->ShowKeyboard(false);
kb_controller->ui()->GetKeyboardWindow()->SetBounds(
keyboard::FullWidthKeyboardBoundsFromRootBounds(
WmShell::Get()->GetPrimaryRootWindow()->GetBounds(), 100));
int shift =
work_area.height() - kb_controller->GetContainerWindow()->bounds().y();
gfx::Rect changed_window_bounds(orig_window_bounds);
changed_window_bounds.Offset(0, -shift);
// Window should be shifted up.
EXPECT_EQ(changed_window_bounds, window->GetBounds());
kb_controller->HideKeyboard(
keyboard::KeyboardController::HIDE_REASON_AUTOMATIC);
EXPECT_EQ(orig_window_bounds, window->GetBounds());
// Open keyboard in sticky mode.
kb_controller->ShowKeyboard(true);
// Window should be shifted up.
EXPECT_EQ(changed_window_bounds, window->GetBounds());
kb_controller->HideKeyboard(
keyboard::KeyboardController::HIDE_REASON_AUTOMATIC);
EXPECT_EQ(orig_window_bounds, window->GetBounds());
}
// When kAshUseNewVKWindowBehavior flag enabled, do not change accessibility
// keyboard work area in non-sticky mode.
TEST_F(WorkspaceLayoutManagerKeyboardTest,
IgnoreWorkAreaChangeinNonStickyMode) {
// Append flag to ignore work area change in non-sticky mode.
EnableNewVKMode();
keyboard::SetAccessibilityKeyboardEnabled(true);
InitKeyboardBounds();
Shell::GetInstance()->CreateKeyboard();
keyboard::KeyboardController* kb_controller =
keyboard::KeyboardController::GetInstance();
gfx::Rect work_area(
display::Screen::GetScreen()->GetPrimaryDisplay().work_area());
gfx::Rect orig_window_bounds(0, 100, work_area.width(),
work_area.height() - 100);
std::unique_ptr<WindowOwner> window_owner(
CreateToplevelTestWindow(orig_window_bounds));
WmWindow* window = window_owner->window();
window->Activate();
EXPECT_EQ(orig_window_bounds, window->GetBounds());
// Open keyboard in non-sticky mode.
kb_controller->ShowKeyboard(false);
kb_controller->ui()->GetKeyboardWindow()->SetBounds(
keyboard::FullWidthKeyboardBoundsFromRootBounds(
WmShell::Get()->GetPrimaryRootWindow()->GetBounds(), 100));
// Window should not be shifted up.
EXPECT_EQ(orig_window_bounds, window->GetBounds());
kb_controller->HideKeyboard(
keyboard::KeyboardController::HIDE_REASON_AUTOMATIC);
EXPECT_EQ(orig_window_bounds, window->GetBounds());
// Open keyboard in sticky mode.
kb_controller->ShowKeyboard(true);
int shift =
work_area.height() - kb_controller->GetContainerWindow()->bounds().y();
gfx::Rect changed_window_bounds(orig_window_bounds);
changed_window_bounds.Offset(0, -shift);
// Window should be shifted up.
EXPECT_EQ(changed_window_bounds, window->GetBounds());
kb_controller->HideKeyboard(
keyboard::KeyboardController::HIDE_REASON_AUTOMATIC);
EXPECT_EQ(orig_window_bounds, window->GetBounds());
}
} // namespace ash