// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ash/accessibility/accessibility_panel.h"
#include <memory>
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/utility/wm_util.h"
#include "base/memory/raw_ptr.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/view_type_utils.h"
#include "extensions/common/mojom/view_type.mojom.h"
#include "ui/compositor/layer.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/views/controls/webview/webview.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/core/shadow_types.h"
#include "ui/wm/core/window_animations.h"
namespace ash {
// Monitors the contents of the accessibility panel for relevant changes
class AccessibilityPanel::AccessibilityPanelWebContentsObserver
: public content::WebContentsObserver {
public:
AccessibilityPanelWebContentsObserver(content::WebContents* web_contents,
AccessibilityPanel* panel)
: content::WebContentsObserver(web_contents), panel_(panel) {}
AccessibilityPanelWebContentsObserver(
const AccessibilityPanelWebContentsObserver&) = delete;
AccessibilityPanelWebContentsObserver& operator=(
const AccessibilityPanelWebContentsObserver&) = delete;
~AccessibilityPanelWebContentsObserver() override = default;
// content::WebContentsObserver overrides.
void DidFirstVisuallyNonEmptyPaint() override {
panel_->DidFirstVisuallyNonEmptyPaint();
}
private:
raw_ptr<AccessibilityPanel> panel_;
};
AccessibilityPanel::AccessibilityPanel(content::BrowserContext* browser_context,
const std::string& content_url,
const std::string& widget_name) {
SetOwnedByWidget(true);
views::WebView* web_view = new views::WebView(browser_context);
web_contents_ = web_view->GetWebContents();
web_contents_observer_ =
std::make_unique<AccessibilityPanelWebContentsObserver>(web_contents_,
this);
web_contents_->SetDelegate(this);
extensions::SetViewType(web_contents_,
extensions::mojom::ViewType::kComponent);
web_view->LoadInitialURL(GURL(content_url));
web_view_ = web_view;
widget_ = new views::Widget();
views::Widget::InitParams params(
views::Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET,
views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
// Placing the panel in the accessibility panel container allows ash to manage
// both the window bounds and display work area.
// The AccessibilityPanel is only shown in the primary root window.
ash_util::SetupWidgetInitParamsForContainerInPrimary(
¶ms, ShellWindowId::kShellWindowId_AccessibilityPanelContainer);
params.bounds = display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
params.delegate = this;
params.activatable = views::Widget::InitParams::Activatable::kNo;
params.name = widget_name;
params.shadow_elevation = wm::kShadowElevationInactiveWindow;
widget_->Init(std::move(params));
// We rely on being able to set the bounds of the panel to control when it
// captures input rather than hiding the widget because we need to continue to
// receive key events. crbug.com/1251129.
widget_->GetNativeWindow()->layer()->SetMasksToBounds(true);
}
AccessibilityPanel::~AccessibilityPanel() = default;
void AccessibilityPanel::CloseNow() {
widget_->CloseNow();
}
void AccessibilityPanel::Close() {
// NOTE: Close the widget asynchronously because it's not legal to delete
// a WebView/WebContents during a DidFinishNavigation callback.
widget_->Close();
}
const views::Widget* AccessibilityPanel::GetWidget() const {
return widget_;
}
views::Widget* AccessibilityPanel::GetWidget() {
return widget_;
}
content::WebContents* AccessibilityPanel::GetWebContents() {
return web_contents_;
}
views::View* AccessibilityPanel::GetContentsView() {
return web_view_;
}
bool AccessibilityPanel::HandleContextMenu(
content::RenderFrameHost& render_frame_host,
const content::ContextMenuParams& params) {
// Eat all requests as context menus are disallowed.
return true;
}
void AccessibilityPanel::DidFirstVisuallyNonEmptyPaint() {
widget_->Show();
}
} // namespace ash