Commit c6255851 authored by Zach Helfinstein's avatar Zach Helfinstein Committed by Commit Bot

Revert "Revert "Generalize AccessibilityPanel sizing""

This reverts commit e8e8d46d.

Bug: 864796
Change-Id: Ia0325f4dc26e3acf1536f28b39e0505238110a19
Reviewed-on: https://chromium-review.googlesource.com/1176077Reviewed-by: default avatarRobert Sesek <rsesek@chromium.org>
Reviewed-by: default avatarDavid Tseng <dtseng@chromium.org>
Commit-Queue: Zach Helfinstein <zhelfins@chromium.org>
Cr-Commit-Position: refs/heads/master@{#583731}
parent aec41dcb
......@@ -222,6 +222,18 @@ void ShowAccessibilityNotification(A11yNotificationType type) {
message_center->AddNotification(std::move(notification));
}
AccessibilityPanelLayoutManager* GetLayoutManager() {
// The accessibility panel is only shown on the primary display.
aura::Window* root = Shell::GetPrimaryRootWindow();
aura::Window* container =
Shell::GetContainer(root, kShellWindowId_AccessibilityPanelContainer);
// TODO(jamescook): Avoid this cast by moving ash::AccessibilityObserver
// ownership to this class and notifying it on accessibility panel fullscreen
// updates.
return static_cast<AccessibilityPanelLayoutManager*>(
container->layout_manager());
}
} // namespace
AccessibilityController::AccessibilityController(
......@@ -700,17 +712,15 @@ void AccessibilityController::SetCaretBounds(
accessibility_highlight_controller_->SetCaretBounds(bounds_in_screen);
}
void AccessibilityController::SetAccessibilityPanelFullscreen(bool fullscreen) {
// The accessibility panel is only shown on the primary display.
aura::Window* root = Shell::GetPrimaryRootWindow();
aura::Window* container =
Shell::GetContainer(root, kShellWindowId_AccessibilityPanelContainer);
// TODO(jamescook): Avoid this cast by moving ash::AccessibilityObserver
// ownership to this class and notifying it on ChromeVox fullscreen updates.
AccessibilityPanelLayoutManager* layout =
static_cast<AccessibilityPanelLayoutManager*>(
container->layout_manager());
layout->SetPanelFullscreen(fullscreen);
void AccessibilityController::SetAccessibilityPanelAlwaysVisible(
bool always_visible) {
GetLayoutManager()->SetAlwaysVisible(always_visible);
}
void AccessibilityController::SetAccessibilityPanelBounds(
const gfx::Rect& bounds,
mojom::AccessibilityPanelState state) {
GetLayoutManager()->SetPanelBounds(bounds, state);
}
void AccessibilityController::OnSigninScreenPrefServiceInitialized(
......
......@@ -163,7 +163,10 @@ class ASH_EXPORT AccessibilityController
void BrailleDisplayStateChanged(bool connected) override;
void SetFocusHighlightRect(const gfx::Rect& bounds_in_screen) override;
void SetCaretBounds(const gfx::Rect& bounds_in_screen) override;
void SetAccessibilityPanelFullscreen(bool fullscreen) override;
void SetAccessibilityPanelAlwaysVisible(bool always_visible) override;
void SetAccessibilityPanelBounds(
const gfx::Rect& bounds,
mojom::AccessibilityPanelState state) override;
void SetSelectToSpeakState(mojom::SelectToSpeakState state) override;
// SessionObserver:
......
......@@ -26,11 +26,20 @@ AccessibilityPanelLayoutManager::~AccessibilityPanelLayoutManager() {
display::Screen::GetScreen()->RemoveObserver(this);
}
void AccessibilityPanelLayoutManager::SetPanelFullscreen(bool fullscreen) {
panel_fullscreen_ = fullscreen;
void AccessibilityPanelLayoutManager::SetAlwaysVisible(bool always_visible) {
always_visible_ = always_visible;
UpdateWindowBounds();
}
void AccessibilityPanelLayoutManager::SetPanelBounds(
const gfx::Rect& bounds,
mojom::AccessibilityPanelState state) {
panel_bounds_ = bounds;
panel_state_ = state;
UpdateWindowBounds();
UpdateWorkArea();
}
void AccessibilityPanelLayoutManager::OnWindowAddedToLayout(
aura::Window* child) {
panel_window_ = child;
......@@ -90,29 +99,44 @@ void AccessibilityPanelLayoutManager::UpdateWindowBounds() {
RootWindowController* root_controller =
RootWindowController::ForWindow(root_window);
// By default the panel sits at the top of the screen.
DCHECK(panel_window_->bounds().origin().IsOrigin());
gfx::Rect bounds(0, 0, root_window->bounds().width(), kPanelHeight);
gfx::Rect bounds = panel_bounds_;
// The panel can make itself fill the screen (including covering the shelf).
if (panel_fullscreen_)
bounds.set_height(root_window->bounds().height());
if (panel_state_ == mojom::AccessibilityPanelState::FULLSCREEN) {
bounds = root_window->bounds();
} else if (panel_state_ == mojom::AccessibilityPanelState::FULL_WIDTH) {
bounds.set_x(0);
bounds.set_width(root_window->bounds().width());
}
// If a fullscreen browser window is open, give the panel a height of 0
// unless it's active.
if (root_controller->GetWindowForFullscreenMode() &&
// unless it's active or always_visible_ is true.
if (!always_visible_ && root_controller->GetWindowForFullscreenMode() &&
!::wm::IsActiveWindow(panel_window_)) {
bounds.set_height(0);
}
// Make sure the ChromeVox panel is always below the Docked Magnifier viewport
// so it shows up and gets magnified.
bounds.Offset(0, root_controller->shelf()->GetDockedMagnifierHeight());
// Make sure the accessibility panel is always below the Docked Magnifier
// viewport so it shows up and gets magnified.
int magnifier_height = root_controller->shelf()->GetDockedMagnifierHeight();
if (bounds.y() < magnifier_height)
bounds.Offset(0, magnifier_height);
// Make sure the accessibility panel doesn't go offscreen when the Docked
// Magnifier is on.
int screen_height = root_window->bounds().height();
int available_height = screen_height - magnifier_height;
if (bounds.height() > available_height)
bounds.set_height(available_height);
panel_window_->SetBounds(bounds);
}
void AccessibilityPanelLayoutManager::UpdateWorkArea() {
if (panel_window_ && panel_window_->bounds().y() != 0)
return;
if (panel_state_ == mojom::AccessibilityPanelState::FULLSCREEN)
return;
Shell::GetPrimaryRootWindowController()->shelf()->SetAccessibilityPanelHeight(
panel_window_ ? panel_window_->bounds().height() : 0);
}
......
......@@ -6,10 +6,12 @@
#define ASH_ACCESSIBILITY_ACCESSIBILITY_PANEL_LAYOUT_MANAGER_H_
#include "ash/ash_export.h"
#include "ash/public/interfaces/accessibility_controller.mojom.h"
#include "ash/shell_observer.h"
#include "base/macros.h"
#include "ui/aura/layout_manager.h"
#include "ui/display/display_observer.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/wm/public/activation_change_observer.h"
namespace aura {
......@@ -30,13 +32,15 @@ class ASH_EXPORT AccessibilityPanelLayoutManager
public ash::ShellObserver {
public:
// Height of the panel in DIPs. Public for test.
static constexpr int kPanelHeight = 35;
static constexpr int kDefaultPanelHeight = 35;
AccessibilityPanelLayoutManager();
~AccessibilityPanelLayoutManager() override;
// Sets whether the panel covers the entire display.
void SetPanelFullscreen(bool fullscreen);
// Controls the panel's visibility and location.
void SetAlwaysVisible(bool always_visible);
void SetPanelBounds(const gfx::Rect& bounds,
mojom::AccessibilityPanelState state);
// aura::LayoutManager:
void OnWindowResized() override {}
......@@ -75,8 +79,15 @@ class ASH_EXPORT AccessibilityPanelLayoutManager
// The panel being managed (e.g. the ChromeVoxPanel's native aura window).
aura::Window* panel_window_ = nullptr;
// Whether the panel itself is filling the display.
bool panel_fullscreen_ = false;
// Window bounds when not in fullscreen
gfx::Rect panel_bounds_ = gfx::Rect(0, 0, 0, 0);
// Determines whether panel is hidden when browser is in fullscreen.
bool always_visible_ = false;
// Determines how the panel_bounds_ are used when displaying the panel.
mojom::AccessibilityPanelState panel_state_ =
mojom::AccessibilityPanelState::BOUNDED;
DISALLOW_COPY_AND_ASSIGN(AccessibilityPanelLayoutManager);
};
......
......@@ -17,7 +17,8 @@ namespace ash {
namespace {
// Shorten the name for better line wrapping.
constexpr int kPanelHeight = AccessibilityPanelLayoutManager::kPanelHeight;
constexpr int kDefaultPanelHeight =
AccessibilityPanelLayoutManager::kDefaultPanelHeight;
AccessibilityPanelLayoutManager* GetLayoutManager() {
aura::Window* container =
......@@ -74,27 +75,6 @@ TEST_F(AccessibilityPanelLayoutManagerTest, Shutdown) {
// Ash should not crash if the window is still open at shutdown.
}
TEST_F(AccessibilityPanelLayoutManagerTest, InitialBounds) {
display::Screen* screen = display::Screen::GetScreen();
gfx::Rect initial_work_area = screen->GetPrimaryDisplay().work_area();
// Simulate Chrome creating the ChromeVox window, but don't show it yet.
std::unique_ptr<views::Widget> widget = CreateChromeVoxPanel();
// The layout manager has not adjusted the work area yet.
EXPECT_EQ(screen->GetPrimaryDisplay().work_area(), initial_work_area);
// Showing the panel causes the layout manager to adjust the panel bounds and
// the display work area.
widget->Show();
gfx::Rect expected_bounds(0, 0, screen->GetPrimaryDisplay().bounds().width(),
kPanelHeight);
EXPECT_EQ(widget->GetNativeWindow()->bounds(), expected_bounds);
gfx::Rect expected_work_area = initial_work_area;
expected_work_area.Inset(0, kPanelHeight, 0, 0);
EXPECT_EQ(screen->GetPrimaryDisplay().work_area(), expected_work_area);
}
TEST_F(AccessibilityPanelLayoutManagerTest, PanelFullscreen) {
AccessibilityPanelLayoutManager* layout_manager = GetLayoutManager();
display::Screen* screen = display::Screen::GetScreen();
......@@ -102,38 +82,56 @@ TEST_F(AccessibilityPanelLayoutManagerTest, PanelFullscreen) {
std::unique_ptr<views::Widget> widget = CreateChromeVoxPanel();
widget->Show();
layout_manager->SetPanelBounds(gfx::Rect(0, 0, 0, kDefaultPanelHeight),
mojom::AccessibilityPanelState::FULL_WIDTH);
gfx::Rect expected_work_area = screen->GetPrimaryDisplay().work_area();
// When the panel is fullscreen it fills the display and does not change the
// work area.
layout_manager->SetPanelFullscreen(true);
layout_manager->SetPanelBounds(gfx::Rect(),
mojom::AccessibilityPanelState::FULLSCREEN);
EXPECT_EQ(widget->GetNativeWindow()->bounds(),
screen->GetPrimaryDisplay().bounds());
EXPECT_EQ(screen->GetPrimaryDisplay().work_area(), expected_work_area);
// Restoring the panel to default size restores the bounds and does not change
// the work area.
layout_manager->SetPanelFullscreen(false);
layout_manager->SetPanelBounds(gfx::Rect(0, 0, 0, kDefaultPanelHeight),
mojom::AccessibilityPanelState::FULL_WIDTH);
gfx::Rect expected_bounds(0, 0, screen->GetPrimaryDisplay().bounds().width(),
kPanelHeight);
kDefaultPanelHeight);
EXPECT_EQ(widget->GetNativeWindow()->bounds(), expected_bounds);
EXPECT_EQ(screen->GetPrimaryDisplay().work_area(), expected_work_area);
}
TEST_F(AccessibilityPanelLayoutManagerTest, SetBounds) {
std::unique_ptr<views::Widget> widget = CreateChromeVoxPanel();
widget->Show();
gfx::Rect bounds(0, 0, 100, 100);
GetLayoutManager()->SetPanelBounds(bounds,
mojom::AccessibilityPanelState::BOUNDED);
EXPECT_EQ(widget->GetNativeWindow()->bounds(), bounds);
}
TEST_F(AccessibilityPanelLayoutManagerTest, DisplayBoundsChange) {
std::unique_ptr<views::Widget> widget = CreateChromeVoxPanel();
widget->Show();
GetLayoutManager()->SetPanelBounds(
gfx::Rect(0, 0, 0, kDefaultPanelHeight),
mojom::AccessibilityPanelState::FULL_WIDTH);
// When the display resolution changes the panel still sits at the top of the
// screen.
UpdateDisplay("1234,567");
display::Screen* screen = display::Screen::GetScreen();
gfx::Rect expected_bounds(0, 0, screen->GetPrimaryDisplay().bounds().width(),
kPanelHeight);
kDefaultPanelHeight);
EXPECT_EQ(widget->GetNativeWindow()->bounds(), expected_bounds);
gfx::Rect expected_work_area = screen->GetPrimaryDisplay().bounds();
expected_work_area.Inset(0, kPanelHeight, 0, kShelfSize);
expected_work_area.Inset(0, kDefaultPanelHeight, 0, kShelfSize);
EXPECT_EQ(screen->GetPrimaryDisplay().work_area(), expected_work_area);
}
......
......@@ -36,6 +36,17 @@ enum AccessibilityAlert {
WINDOW_OVERVIEW_MODE_ENTERED
};
enum AccessibilityPanelState {
// Window bounds are set explicitly.
BOUNDED,
// Width of panel matches screen width, y_coord and height are set by bounds.
FULL_WIDTH,
// Panel occupies the full screen. Bounds are ignored.
FULLSCREEN
};
enum SelectToSpeakState {
// Select to Speak is not actively selecting text or speaking.
kSelectToSpeakStateInactive,
......@@ -70,9 +81,14 @@ interface AccessibilityController {
// Setting off-screen or empty bounds suppresses the highlight.
SetCaretBounds(gfx.mojom.Rect bounds_in_screen);
// Sets whether the accessibility panel is filling the entire screen (e.g. to
// show the expanded UI for the ChromeVox spoken feedback extension).
SetAccessibilityPanelFullscreen(bool fullscreen);
// Sets whether the accessibility panel should always be visible, regardless
// of whether the window is fullscreen.
SetAccessibilityPanelAlwaysVisible(bool always_visible);
// Sets the bounds for the accessibility panel. Overrides current
// configuration (i.e. fullscreen, full-width).
SetAccessibilityPanelBounds(gfx.mojom.Rect bounds,
AccessibilityPanelState state);
// Sets the current Select-to-Speak state. This should be used by the Select-
// to-Speak extension to inform ash of its updated state.
......
......@@ -18,6 +18,16 @@ const char kDisableSpokenFeedbackURLFragment[] = "close";
const char kFocusURLFragment[] = "focus";
const char kFullscreenURLFragment[] = "fullscreen";
const char kWidgetName[] = "ChromeVoxPanel";
const int kPanelHeight = 35;
ash::mojom::AccessibilityControllerPtr GetAccessibilityController() {
// Connect to the accessibility mojo interface in ash.
ash::mojom::AccessibilityControllerPtr accessibility_controller;
content::ServiceManagerConnection::GetForProcess()
->GetConnector()
->BindInterface(ash::mojom::kServiceName, &accessibility_controller);
return accessibility_controller;
}
} // namespace
......@@ -54,6 +64,8 @@ ChromeVoxPanel::ChromeVoxPanel(content::BrowserContext* browser_context)
: AccessibilityPanel(browser_context, GetUrlForContent(), kWidgetName) {
web_contents_observer_.reset(
new ChromeVoxPanelWebContentsObserver(GetWebContents(), this));
SetAccessibilityPanelFullscreen(false);
}
ChromeVoxPanel::~ChromeVoxPanel() {}
......@@ -76,12 +88,10 @@ void ChromeVoxPanel::Focus() {
}
void ChromeVoxPanel::SetAccessibilityPanelFullscreen(bool fullscreen) {
// Connect to the accessibility mojo interface in ash.
ash::mojom::AccessibilityControllerPtr accessibility_controller;
content::ServiceManagerConnection::GetForProcess()
->GetConnector()
->BindInterface(ash::mojom::kServiceName, &accessibility_controller);
accessibility_controller->SetAccessibilityPanelFullscreen(fullscreen);
gfx::Rect bounds(0, 0, 0, kPanelHeight);
auto state = fullscreen ? ash::mojom::AccessibilityPanelState::FULLSCREEN
: ash::mojom::AccessibilityPanelState::FULL_WIDTH;
GetAccessibilityController()->SetAccessibilityPanelBounds(bounds, state);
}
std::string ChromeVoxPanel::GetUrlForContent() {
......
......@@ -38,7 +38,10 @@ class TestAccessibilityController : ash::mojom::AccessibilityController {
void BrailleDisplayStateChanged(bool connected) override {}
void SetFocusHighlightRect(const gfx::Rect& bounds_in_screen) override {}
void SetCaretBounds(const gfx::Rect& bounds_in_screen) override {}
void SetAccessibilityPanelFullscreen(bool fullscreen) override {}
void SetAccessibilityPanelAlwaysVisible(bool always_visible) override {}
void SetAccessibilityPanelBounds(
const gfx::Rect& bounds,
ash::mojom::AccessibilityPanelState state) override {}
void SetSelectToSpeakState(ash::mojom::SelectToSpeakState state) override {}
bool was_client_set() const { return was_client_set_; }
......
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