Commit 723b1eed authored by Alan Cutter's avatar Alan Cutter Committed by Commit Bot

Upstream HostedAppButtonContainer container logic into BrowserNonClientFrameView

Subclasses of BrowserNonClientFrameView that contain a HostedAppButtonContainer
child view have duplicate logic outside of creation, colors and layout.

This CL dedupes the logic involved in having a HostedAppButtonContainer
in preparation for adding one to BrowserNonClientFrameViewMac.

Bug: 895690
Change-Id: If2e5d58af58cd72ea9d0902d3a15f3375a9e1585
Reviewed-on: https://chromium-review.googlesource.com/c/1288092Reviewed-by: default avatarBret Sepulveda <bsep@chromium.org>
Commit-Queue: Alan Cutter <alancutter@chromium.org>
Cr-Commit-Position: refs/heads/master@{#601427}
parent aa05092f
......@@ -15,10 +15,12 @@
#include "chrome/browser/ui/layout_constants.h"
#include "chrome/browser/ui/view_ids.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/frame/hosted_app_button_container.h"
#include "chrome/browser/ui/views/tabs/tab_strip.h"
#include "chrome/common/chrome_features.h"
#include "chrome/grit/theme_resources.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/hit_test.h"
#include "ui/base/theme_provider.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/color_palette.h"
......@@ -26,6 +28,7 @@
#include "ui/gfx/paint_vector_icon.h"
#include "ui/gfx/scoped_canvas.h"
#include "ui/views/background.h"
#include "ui/views/window/hit_test_utils.h"
#if defined(OS_WIN)
#include "chrome/browser/ui/views/frame/taskbar_decorator_win.h"
......@@ -256,6 +259,22 @@ void BrowserNonClientFrameView::VisibilityChanged(views::View* starting_from,
OnProfileAvatarChanged(base::FilePath());
}
int BrowserNonClientFrameView::NonClientHitTest(const gfx::Point& point) {
if (hosted_app_button_container_) {
int hosted_app_component =
views::GetHitTestComponent(hosted_app_button_container_, point);
if (hosted_app_component != HTNOWHERE)
return hosted_app_component;
}
return HTNOWHERE;
}
void BrowserNonClientFrameView::ResetWindowControls() {
if (hosted_app_button_container_)
hosted_app_button_container_->UpdateContentSettingViewsVisibility();
}
void BrowserNonClientFrameView::OnSingleTabModeChanged() {
SchedulePaint();
}
......@@ -326,6 +345,11 @@ gfx::ImageSkia BrowserNonClientFrameView::GetFrameOverlayImage(
: gfx::ImageSkia();
}
void BrowserNonClientFrameView::ChildPreferredSizeChanged(views::View* child) {
if (browser_view()->initialized() && child == hosted_app_button_container_)
Layout();
}
void BrowserNonClientFrameView::ActivationChanged(bool active) {
// On Windows, while deactivating the widget, this is called before the
// active HWND has actually been changed. Since we want the state to reflect
......@@ -341,6 +365,9 @@ void BrowserNonClientFrameView::ActivationChanged(bool active) {
set_active_state_override(nullptr);
if (hosted_app_button_container_)
hosted_app_button_container_->SetPaintAsActive(active);
// Changing the activation state may change the visible frame color.
SchedulePaint();
}
......
......@@ -14,6 +14,7 @@
class BrowserFrame;
class BrowserView;
class HostedAppButtonContainer;
// A specialization of the NonClientFrameView object that provides additional
// Browser-specific methods.
......@@ -134,10 +135,16 @@ class BrowserNonClientFrameView : public views::NonClientFrameView,
// views::NonClientFrameView:
using views::NonClientFrameView::ShouldPaintAsActive;
void VisibilityChanged(views::View* starting_from, bool is_visible) override;
int NonClientHitTest(const gfx::Point& point) override;
void ResetWindowControls() override;
// TabStripObserver:
void OnSingleTabModeChanged() override;
HostedAppButtonContainer* hosted_app_button_container_for_testing() {
return hosted_app_button_container_;
}
protected:
// Whether the frame should be painted with theming.
// By default, tabbed browser windows are themed but popup and app windows are
......@@ -157,6 +164,7 @@ class BrowserNonClientFrameView : public views::NonClientFrameView,
ActiveState active_state = kUseCurrent) const;
// views::NonClientFrameView:
void ChildPreferredSizeChanged(views::View* child) override;
void ActivationChanged(bool active) override;
bool DoesIntersectRect(const views::View* target,
const gfx::Rect& rect) const override;
......@@ -169,6 +177,17 @@ class BrowserNonClientFrameView : public views::NonClientFrameView,
void OnProfileHighResAvatarLoaded(
const base::FilePath& profile_path) override;
void set_hosted_app_button_container(
HostedAppButtonContainer* hosted_app_button_container) {
hosted_app_button_container_ = hosted_app_button_container;
}
HostedAppButtonContainer* hosted_app_button_container() {
return hosted_app_button_container_;
}
const HostedAppButtonContainer* hosted_app_button_container() const {
return hosted_app_button_container_;
}
private:
void MaybeObserveTabstrip();
......@@ -189,6 +208,9 @@ class BrowserNonClientFrameView : public views::NonClientFrameView,
// The BrowserView hosted within this View.
BrowserView* browser_view_;
// Menu button and page status icons. Only used by hosted app windows.
HostedAppButtonContainer* hosted_app_button_container_ = nullptr;
ScopedObserver<TabStrip, BrowserNonClientFrameView> tab_strip_observer_;
DISALLOW_COPY_AND_ASSIGN(BrowserNonClientFrameView);
......
......@@ -343,11 +343,9 @@ void BrowserNonClientFrameViewAsh::GetWindowMask(const gfx::Size& size,
}
void BrowserNonClientFrameViewAsh::ResetWindowControls() {
BrowserNonClientFrameView::ResetWindowControls();
caption_button_container_->SetVisible(true);
caption_button_container_->ResetWindowControls();
if (hosted_app_button_container_)
hosted_app_button_container_->UpdateContentSettingViewsVisibility();
}
void BrowserNonClientFrameViewAsh::UpdateWindowIcon() {
......@@ -369,9 +367,6 @@ void BrowserNonClientFrameViewAsh::ActivationChanged(bool active) {
const bool should_paint_as_active = ShouldPaintAsActive();
frame_header_->SetPaintAsActive(should_paint_as_active);
if (hosted_app_button_container_)
hosted_app_button_container_->SetPaintAsActive(should_paint_as_active);
}
///////////////////////////////////////////////////////////////////////////////
......@@ -401,8 +396,8 @@ void BrowserNonClientFrameViewAsh::Layout() {
if (profile_indicator_icon_)
LayoutProfileIndicator();
if (hosted_app_button_container_) {
hosted_app_button_container_->LayoutInContainer(
if (hosted_app_button_container()) {
hosted_app_button_container()->LayoutInContainer(
0, caption_button_container_->x(), 0, painted_height);
}
......@@ -678,9 +673,9 @@ void BrowserNonClientFrameViewAsh::OnImmersiveRevealStarted() {
// temporarily children of the TopContainerView while they're all painting to
// their layers.
browser_view()->top_container()->AddChildViewAt(caption_button_container_, 0);
if (hosted_app_button_container_) {
if (hosted_app_button_container()) {
browser_view()->top_container()->AddChildViewAt(
hosted_app_button_container_, 0);
hosted_app_button_container(), 0);
}
if (back_button_)
browser_view()->top_container()->AddChildViewAt(back_button_, 0);
......@@ -690,8 +685,8 @@ void BrowserNonClientFrameViewAsh::OnImmersiveRevealStarted() {
void BrowserNonClientFrameViewAsh::OnImmersiveRevealEnded() {
AddChildViewAt(caption_button_container_, 0);
if (hosted_app_button_container_)
AddChildViewAt(hosted_app_button_container_, 0);
if (hosted_app_button_container())
AddChildViewAt(hosted_app_button_container(), 0);
if (back_button_)
AddChildViewAt(back_button_, 0);
Layout();
......@@ -701,11 +696,6 @@ void BrowserNonClientFrameViewAsh::OnImmersiveFullscreenExited() {
OnImmersiveRevealEnded();
}
HostedAppButtonContainer*
BrowserNonClientFrameViewAsh::GetHostedAppButtonContainerForTesting() const {
return hosted_app_button_container_;
}
// static
bool BrowserNonClientFrameViewAsh::UsePackagedAppHeaderStyle(
const Browser* browser) {
......@@ -822,9 +812,9 @@ void BrowserNonClientFrameViewAsh::SetUpForHostedApp(
ash::FrameCaptionButton::GetInactiveButtonColorAlphaRatio();
SkColor inactive_color =
SkColorSetA(active_color, 255 * inactive_alpha_ratio);
hosted_app_button_container_ = new HostedAppButtonContainer(
frame(), browser_view(), active_color, inactive_color);
AddChildView(hosted_app_button_container_);
set_hosted_app_button_container(new HostedAppButtonContainer(
frame(), browser_view(), active_color, inactive_color));
AddChildView(hosted_app_button_container());
}
void BrowserNonClientFrameViewAsh::UpdateFrameColors() {
......
......@@ -29,7 +29,6 @@ namespace {
class HostedAppNonClientFrameViewAshTest;
}
class HostedAppButtonContainer;
class ProfileIndicatorIcon;
class TabIconView;
......@@ -132,8 +131,6 @@ class BrowserNonClientFrameViewAsh
void OnImmersiveRevealEnded() override;
void OnImmersiveFullscreenExited() override;
HostedAppButtonContainer* GetHostedAppButtonContainerForTesting() const;
// Returns true if the header should be painted so that it looks the same as
// the header used for packaged apps.
static bool UsePackagedAppHeaderStyle(const Browser* browser);
......@@ -173,7 +170,6 @@ class BrowserNonClientFrameViewAsh
HeaderHeightForSnappedBrowserInSplitView);
friend class HostedAppNonClientFrameViewAshTest;
friend class ImmersiveModeControllerAshHostedAppBrowserTest;
// Returns whether the caption buttons should be visible. They are hidden, for
// example, in overview mode and tablet mode.
......@@ -246,10 +242,6 @@ class BrowserNonClientFrameViewAsh
// A helper for controlling the window frame; only used in !Mash.
std::unique_ptr<ash::AshFrameCaptionController> caption_controller_;
// Container for extra frame buttons shown for hosted app windows.
// Owned by views hierarchy.
HostedAppButtonContainer* hosted_app_button_container_ = nullptr;
// Ash's mojom::SplitViewController.
ash::mojom::SplitViewControllerPtr split_view_controller_;
......
......@@ -714,7 +714,7 @@ class HostedAppNonClientFrameViewAshTest
static_cast<ash::DefaultFrameHeader*>(frame_view->frame_header_.get());
hosted_app_button_container_ =
frame_view->GetHostedAppButtonContainerForTesting();
frame_view->hosted_app_button_container_for_testing();
DCHECK(hosted_app_button_container_);
DCHECK(hosted_app_button_container_->visible());
......
......@@ -36,7 +36,6 @@
#include "ui/strings/grit/ui_strings.h"
#include "ui/views/win/hwnd_util.h"
#include "ui/views/window/client_view.h"
#include "ui/views/window/hit_test_utils.h"
HICON GlassBrowserFrameView::throbber_icons_[
GlassBrowserFrameView::kThrobberIconCount];
......@@ -119,9 +118,9 @@ GlassBrowserFrameView::GlassBrowserFrameView(BrowserFrame* frame,
// HostedAppButtonContainer::UpdateIconsColor() via a delegate interface.
SkColor active_color = GetTitlebarFeatureColor(kActive);
SkColor inactive_color = GetTitlebarFeatureColor(kInactive);
hosted_app_button_container_ = new HostedAppButtonContainer(
frame, browser_view, active_color, inactive_color);
AddChildView(hosted_app_button_container_);
set_hosted_app_button_container(new HostedAppButtonContainer(
frame, browser_view, active_color, inactive_color));
AddChildView(hosted_app_button_container());
}
minimize_button_ =
......@@ -275,6 +274,10 @@ bool HitTestCaptionButton(Windows10CaptionButton* button,
} // namespace
int GlassBrowserFrameView::NonClientHitTest(const gfx::Point& point) {
int super_component = BrowserNonClientFrameView::NonClientHitTest(point);
if (super_component != HTNOWHERE)
return super_component;
// For app windows and popups without a custom titlebar we haven't customized
// the frame at all so Windows can figure it out.
if (!ShouldCustomDrawSystemTitlebar() &&
......@@ -286,15 +289,6 @@ int GlassBrowserFrameView::NonClientHitTest(const gfx::Point& point) {
if (!bounds().Contains(point))
return HTNOWHERE;
if (hosted_app_button_container_) {
// TODO(alancutter): Assign hit test components to all children and refactor
// this entire function call to just be GetHitTestComponent(this, point).
int hosted_app_component =
views::GetHitTestComponent(hosted_app_button_container_, point);
if (hosted_app_component != HTNOWHERE)
return hosted_app_component;
}
int frame_component = frame()->client_view()->NonClientHitTest(point);
// See if we're in the sysmenu region. We still have to check the tabstrip
......@@ -375,12 +369,11 @@ void GlassBrowserFrameView::UpdateWindowTitle() {
}
void GlassBrowserFrameView::ResetWindowControls() {
BrowserNonClientFrameView::ResetWindowControls();
minimize_button_->SetState(views::Button::STATE_NORMAL);
maximize_button_->SetState(views::Button::STATE_NORMAL);
restore_button_->SetState(views::Button::STATE_NORMAL);
close_button_->SetState(views::Button::STATE_NORMAL);
if (hosted_app_button_container_)
hosted_app_button_container_->UpdateContentSettingViewsVisibility();
}
void GlassBrowserFrameView::ButtonPressed(views::Button* sender,
......@@ -418,11 +411,6 @@ const char* GlassBrowserFrameView::GetClassName() const {
return kClassName;
}
void GlassBrowserFrameView::ChildPreferredSizeChanged(views::View* child) {
if (browser_view()->initialized() && child == hosted_app_button_container_)
Layout();
}
void GlassBrowserFrameView::OnPaint(gfx::Canvas* canvas) {
TRACE_EVENT0("views.frame", "GlassBrowserFrameView::OnPaint");
if (ShouldCustomDrawSystemTitlebar())
......@@ -443,13 +431,6 @@ void GlassBrowserFrameView::Layout() {
///////////////////////////////////////////////////////////////////////////////
// GlassBrowserFrameView, private:
void GlassBrowserFrameView::ActivationChanged(bool active) {
BrowserNonClientFrameView::ActivationChanged(active);
if (hosted_app_button_container_)
hosted_app_button_container_->SetPaintAsActive(active);
}
int GlassBrowserFrameView::FrameBorderThickness() const {
return (IsMaximized() || frame()->IsFullscreen())
? 0
......@@ -514,13 +495,13 @@ int GlassBrowserFrameView::TopAreaHeight(bool restored) const {
int GlassBrowserFrameView::TitlebarMaximizedVisualHeight() const {
int maximized_height =
display::win::ScreenWin::GetSystemMetricsInDIP(SM_CYCAPTION);
if (hosted_app_button_container_) {
if (hosted_app_button_container()) {
// Adding 2px of vertical padding puts at least 1 px of space on the top and
// bottom of the element.
constexpr int kVerticalPadding = 2;
maximized_height =
std::max(maximized_height,
hosted_app_button_container_->GetPreferredSize().height() +
hosted_app_button_container()->GetPreferredSize().height() +
kVerticalPadding);
}
return maximized_height;
......@@ -572,7 +553,7 @@ bool GlassBrowserFrameView::IsToolbarVisible() const {
bool GlassBrowserFrameView::ShowCustomIcon() const {
// Hosted app windows don't include the window icon as per UI mocks.
return !hosted_app_button_container_ && ShouldCustomDrawSystemTitlebar() &&
return !hosted_app_button_container() && ShouldCustomDrawSystemTitlebar() &&
browser_view()->ShouldShowWindowIcon();
}
......@@ -706,8 +687,8 @@ void GlassBrowserFrameView::LayoutTitleBar() {
next_leading_x = window_icon_bounds.right() + kIconTitleSpacing;
}
if (hosted_app_button_container_) {
next_trailing_x = hosted_app_button_container_->LayoutInContainer(
if (hosted_app_button_container()) {
next_trailing_x = hosted_app_button_container()->LayoutInContainer(
next_leading_x, next_trailing_x, window_top, titlebar_visual_height);
}
......
......@@ -16,7 +16,6 @@
#include "ui/views/window/non_client_view.h"
class BrowserView;
class HostedAppButtonContainer;
class GlassBrowserFrameView : public BrowserNonClientFrameView,
public views::ButtonListener,
......@@ -71,23 +70,15 @@ class GlassBrowserFrameView : public BrowserNonClientFrameView,
SkColor GetTitlebarColor() const;
HostedAppButtonContainer* hosted_app_button_container_for_testing() {
return hosted_app_button_container_;
}
views::Label* window_title_for_testing() { return window_title_; }
protected:
// views::View:
void ChildPreferredSizeChanged(views::View* child) override;
const char* GetClassName() const override;
void OnPaint(gfx::Canvas* canvas) override;
void Layout() override;
private:
// views::NonClientFrameView:
void ActivationChanged(bool active) override;
// Returns the thickness of the window border for the left, right, and bottom
// edges of the frame. On Windows 10 this is a mostly-transparent handle that
// allows you to resize the window.
......@@ -166,9 +157,6 @@ class GlassBrowserFrameView : public BrowserNonClientFrameView,
TabIconView* window_icon_;
views::Label* window_title_;
// Menu button and page status icons. Only used by hosted app windows.
HostedAppButtonContainer* hosted_app_button_container_ = nullptr;
// Custom-drawn caption buttons. Only used when custom-drawing the titlebar.
Windows10CaptionButton* minimize_button_;
Windows10CaptionButton* maximize_button_;
......
......@@ -122,7 +122,7 @@ class ImmersiveModeControllerAshHostedAppBrowserTest
void VerifyButtonsInImmersiveMode(BrowserNonClientFrameViewAsh* frame_view) {
HostedAppButtonContainer* container =
frame_view->hosted_app_button_container_;
frame_view->hosted_app_button_container_for_testing();
views::test::InkDropHostViewTestApi ink_drop_api(
container->app_menu_button_);
EXPECT_TRUE(container->GetContentSettingContainerForTesting()->layer());
......
......@@ -43,7 +43,6 @@
#include "ui/views/resources/grit/views_resources.h"
#include "ui/views/views_delegate.h"
#include "ui/views/window/frame_background.h"
#include "ui/views/window/hit_test_utils.h"
#include "ui/views/window/window_shape.h"
#if defined(OS_LINUX)
......@@ -176,11 +175,11 @@ OpaqueBrowserFrameView::OpaqueBrowserFrameView(
AddChildView(window_title_);
if (browser_view->IsBrowserTypeHostedApp()) {
hosted_app_button_container_ = new HostedAppButtonContainer(
set_hosted_app_button_container(new HostedAppButtonContainer(
frame, browser_view, GetReadableFrameForegroundColor(kActive),
GetReadableFrameForegroundColor(kInactive));
hosted_app_button_container_->set_id(VIEW_ID_HOSTED_APP_BUTTON_CONTAINER);
AddChildView(hosted_app_button_container_);
GetReadableFrameForegroundColor(kInactive)));
hosted_app_button_container()->set_id(VIEW_ID_HOSTED_APP_BUTTON_CONTAINER);
AddChildView(hosted_app_button_container());
}
}
......@@ -229,6 +228,10 @@ gfx::Rect OpaqueBrowserFrameView::GetWindowBoundsForClientBounds(
}
int OpaqueBrowserFrameView::NonClientHitTest(const gfx::Point& point) {
int super_component = BrowserNonClientFrameView::NonClientHitTest(point);
if (super_component != HTNOWHERE)
return super_component;
if (!bounds().Contains(point))
return HTNOWHERE;
......@@ -264,15 +267,6 @@ int OpaqueBrowserFrameView::NonClientHitTest(const gfx::Point& point) {
minimize_button_->GetMirroredBounds().Contains(point))
return HTMINBUTTON;
if (hosted_app_button_container_) {
// TODO(alancutter): Assign hit test components to all children and refactor
// this entire function call to just be GetHitTestComponent(this, point).
int hosted_app_component =
views::GetHitTestComponent(hosted_app_button_container_, point);
if (hosted_app_component != HTNOWHERE)
return hosted_app_component;
}
views::WidgetDelegate* delegate = frame()->widget_delegate();
if (!delegate) {
LOG(WARNING) << "delegate is null, returning safe default.";
......@@ -301,12 +295,11 @@ void OpaqueBrowserFrameView::GetWindowMask(const gfx::Size& size,
}
void OpaqueBrowserFrameView::ResetWindowControls() {
BrowserNonClientFrameView::ResetWindowControls();
restore_button_->SetState(views::Button::STATE_NORMAL);
minimize_button_->SetState(views::Button::STATE_NORMAL);
maximize_button_->SetState(views::Button::STATE_NORMAL);
// The close button isn't affected by this constraint.
if (hosted_app_button_container_)
hosted_app_button_container_->UpdateContentSettingViewsVisibility();
}
void OpaqueBrowserFrameView::UpdateWindowIcon() {
......@@ -323,12 +316,6 @@ void OpaqueBrowserFrameView::UpdateWindowTitle() {
void OpaqueBrowserFrameView::SizeConstraintsChanged() {}
void OpaqueBrowserFrameView::ActivationChanged(bool active) {
BrowserNonClientFrameView::ActivationChanged(active);
if (hosted_app_button_container_)
hosted_app_button_container_->SetPaintAsActive(active);
}
///////////////////////////////////////////////////////////////////////////////
// OpaqueBrowserFrameView, views::View overrides:
......@@ -336,12 +323,6 @@ const char* OpaqueBrowserFrameView::GetClassName() const {
return kClassName;
}
void OpaqueBrowserFrameView::ChildPreferredSizeChanged(views::View* child) {
BrowserNonClientFrameView::ChildPreferredSizeChanged(child);
if (browser_view()->initialized() && child == hosted_app_button_container_)
Layout();
}
void OpaqueBrowserFrameView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
node_data->role = ax::mojom::Role::kTitleBar;
}
......
......@@ -20,7 +20,6 @@
class BrowserView;
class OpaqueBrowserFrameViewLayout;
class HostedAppButtonContainer;
class OpaqueBrowserFrameViewPlatformSpecific;
class TabIconView;
......@@ -65,11 +64,9 @@ class OpaqueBrowserFrameView : public BrowserNonClientFrameView,
void UpdateWindowIcon() override;
void UpdateWindowTitle() override;
void SizeConstraintsChanged() override;
void ActivationChanged(bool active) override;
// views::View:
const char* GetClassName() const override;
void ChildPreferredSizeChanged(views::View* child) override;
void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
// views::ButtonListener:
......@@ -103,10 +100,6 @@ class OpaqueBrowserFrameView : public BrowserNonClientFrameView,
bool IsFrameCondensed() const override;
bool EverHasVisibleBackgroundTabShapes() const override;
HostedAppButtonContainer* hosted_app_button_container_for_testing() {
return hosted_app_button_container_;
}
protected:
views::ImageButton* minimize_button() const { return minimize_button_; }
views::ImageButton* maximize_button() const { return maximize_button_; }
......@@ -193,8 +186,6 @@ class OpaqueBrowserFrameView : public BrowserNonClientFrameView,
TabIconView* window_icon_;
views::Label* window_title_;
HostedAppButtonContainer* hosted_app_button_container_ = nullptr;
// Background painter for the window frame.
std::unique_ptr<views::FrameBackground> frame_background_;
......
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