Commit e975a3e7 authored by Evan Stade's avatar Evan Stade Committed by Commit Bot

OopAsh: share frame hit test implementation with classic Ash.

This cl places the responsibility of determing the hit test component
on individual Views, which gets rid of some ash/ dependencies and
reduces code duplication.

The one behavioral change in classic Ash is that padding parts of
the hosted app button container (e.g. the medium sized space between
the menu button and the minimize button) are now HTCAPTION, i.e. can
be used to drag the frame rather than do nothing.

Bug: 854704
Change-Id: Ia290a42652a9acbf9b4b01c86941e8d2bdcadc48
Reviewed-on: https://chromium-review.googlesource.com/1145545Reviewed-by: default avatarScott Violet <sky@chromium.org>
Commit-Queue: Evan Stade <estade@chromium.org>
Cr-Commit-Position: refs/heads/master@{#577915}
parent 2d43ed4c
......@@ -278,8 +278,6 @@ component("ash") {
"frame/default_frame_header.h",
"frame/detached_title_area_renderer.cc",
"frame/detached_title_area_renderer.h",
"frame/frame_border_hit_test.cc",
"frame/frame_border_hit_test.h",
"frame/frame_header.cc",
"frame/frame_header.h",
"frame/frame_header_util.cc",
......
......@@ -10,6 +10,7 @@
#include "ash/strings/grit/ash_strings.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/hit_test.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/events/event_sink.h"
......@@ -18,7 +19,7 @@
namespace ash {
FrameBackButton::FrameBackButton()
: FrameCaptionButton(this, CAPTION_BUTTON_ICON_BACK) {
: FrameCaptionButton(this, CAPTION_BUTTON_ICON_BACK, HTMENU) {
SetPreferredSize(GetAshLayoutSize(AshLayoutSize::kNonBrowserCaption));
SetAccessibleName(
l10n_util::GetStringUTF16(IDS_ASH_WINDOW_CONTROL_ACCNAME_BACK));
......
......@@ -5,6 +5,7 @@
#include "ash/frame/caption_buttons/frame_caption_button.h"
#include "ash/public/cpp/ash_constants.h"
#include "ui/base/hit_test.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/gfx/animation/throb_animation.h"
#include "ui/gfx/canvas.h"
......@@ -16,6 +17,7 @@
#include "ui/views/animation/ink_drop_impl.h"
#include "ui/views/animation/ink_drop_mask.h"
#include "ui/views/animation/ink_drop_ripple.h"
#include "ui/views/view_properties.h"
namespace ash {
......@@ -68,7 +70,8 @@ gfx::Insets GetInkdropInsets(const gfx::Size& button_size) {
const char FrameCaptionButton::kViewClassName[] = "FrameCaptionButton";
FrameCaptionButton::FrameCaptionButton(views::ButtonListener* listener,
CaptionButtonIcon icon)
CaptionButtonIcon icon,
int hit_test_type)
: Button(listener),
icon_(icon),
background_color_(SK_ColorWHITE),
......@@ -76,6 +79,8 @@ FrameCaptionButton::FrameCaptionButton(views::ButtonListener* listener,
paint_as_active_(false),
alpha_(255),
swap_images_animation_(new gfx::SlideAnimation(this)) {
SetProperty(views::kHitTestComponentKey, hit_test_type);
set_animate_on_state_change(true);
swap_images_animation_->Reset(1);
......
......@@ -33,7 +33,9 @@ class ASH_EXPORT FrameCaptionButton : public views::Button {
static const char kViewClassName[];
FrameCaptionButton(views::ButtonListener* listener, CaptionButtonIcon icon);
FrameCaptionButton(views::ButtonListener* listener,
CaptionButtonIcon icon,
int hit_test_type);
~FrameCaptionButton() override;
// Gets the color to use for a frame caption button while a theme color is
......
......@@ -94,15 +94,6 @@ float HidePositionStartValue() {
static_cast<float>(kHidePositionDelayMs) / kHideAnimationDurationMs;
}
// Converts |point| from |src| to |dst| and hittests against |dst|.
bool ConvertPointToViewAndHitTest(const views::View* src,
const views::View* dst,
const gfx::Point& point) {
gfx::Point converted(point);
views::View::ConvertPointToTarget(src, dst, &converted);
return dst->HitTestPoint(converted);
}
// Bounds animation values to the range 0.0 - 1.0. Allows for mapping of offset
// animations to the expected range so that gfx::Tween::CalculateValue() can be
// used.
......@@ -199,12 +190,13 @@ FrameCaptionButtonContainerView::FrameCaptionButtonContainerView(
}
// Insert the buttons left to right.
menu_button_ = new FrameCaptionButton(this, CAPTION_BUTTON_ICON_MENU);
menu_button_ = new FrameCaptionButton(this, CAPTION_BUTTON_ICON_MENU, HTMENU);
menu_button_->SetAccessibleName(
l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MENU));
AddChildView(menu_button_);
minimize_button_ = new FrameCaptionButton(this, CAPTION_BUTTON_ICON_MINIMIZE);
minimize_button_ =
new FrameCaptionButton(this, CAPTION_BUTTON_ICON_MINIMIZE, HTMINBUTTON);
minimize_button_->SetAccessibleName(
l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MINIMIZE));
AddChildView(minimize_button_);
......@@ -214,7 +206,8 @@ FrameCaptionButtonContainerView::FrameCaptionButtonContainerView(
l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MAXIMIZE));
AddChildView(size_button_);
close_button_ = new FrameCaptionButton(this, CAPTION_BUTTON_ICON_CLOSE);
close_button_ =
new FrameCaptionButton(this, CAPTION_BUTTON_ICON_CLOSE, HTCLOSE);
close_button_->SetAccessibleName(
l10n_util::GetStringUTF16(IDS_APP_ACCNAME_CLOSE));
AddChildView(close_button_);
......@@ -269,24 +262,6 @@ void FrameCaptionButtonContainerView::ResetWindowControls() {
SetButtonsToNormal(ANIMATE_NO);
}
int FrameCaptionButtonContainerView::NonClientHitTest(
const gfx::Point& point) const {
if (close_button_->visible() &&
ConvertPointToViewAndHitTest(this, close_button_, point)) {
return HTCLOSE;
} else if (size_button_->visible() &&
ConvertPointToViewAndHitTest(this, size_button_, point)) {
return HTMAXBUTTON;
} else if (minimize_button_->visible() &&
ConvertPointToViewAndHitTest(this, minimize_button_, point)) {
return HTMINBUTTON;
} else if (menu_button_->visible() &&
ConvertPointToViewAndHitTest(this, menu_button_, point)) {
return HTMENU;
}
return HTNOWHERE;
}
void FrameCaptionButtonContainerView::UpdateCaptionButtonState(bool animate) {
bool size_button_visible =
(model_->IsVisible(CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE) ||
......
......@@ -93,11 +93,6 @@ class ASH_EXPORT FrameCaptionButtonContainerView
// Tell the window controls to reset themselves to the normal state.
void ResetWindowControls();
// Determines the window HT* code for the caption button at |point|. Returns
// HTNOWHERE if |point| is not over any of the caption buttons. |point| must
// be in the coordinates of the FrameCaptionButtonContainerView.
int NonClientHitTest(const gfx::Point& point) const;
// Updates the caption buttons' state based on the caption button model's
// state. A parent view should relayout to reflect the change in states.
void UpdateCaptionButtonState(bool animate);
......
......@@ -13,6 +13,7 @@
#include "base/i18n/rtl.h"
#include "base/metrics/user_metrics.h"
#include "ui/aura/window.h"
#include "ui/base/hit_test.h"
#include "ui/gfx/geometry/vector2d.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/core/coordinate_conversion.h"
......@@ -48,7 +49,9 @@ bool HitTestButton(const FrameCaptionButton* button,
FrameSizeButton::FrameSizeButton(views::ButtonListener* listener,
views::Widget* frame,
FrameSizeButtonDelegate* delegate)
: FrameCaptionButton(listener, CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE),
: FrameCaptionButton(listener,
CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE,
HTMAXBUTTON),
frame_(frame),
delegate_(delegate),
set_buttons_to_snap_mode_delay_ms_(kSetButtonsToSnapModeDelayMs),
......
......@@ -11,9 +11,9 @@
#include "ash/frame/caption_buttons/frame_caption_button.h"
#include "ash/frame/caption_buttons/frame_caption_button_container_view.h"
#include "ash/frame/default_frame_header.h"
#include "ash/frame/frame_border_hit_test.h"
#include "ash/frame/header_view.h"
#include "ash/public/cpp/ash_constants.h"
#include "ash/public/cpp/frame_border_hit_test.h"
#include "ash/public/cpp/immersive/immersive_fullscreen_controller.h"
#include "ash/public/cpp/immersive/immersive_fullscreen_controller_delegate.h"
#include "ash/public/cpp/window_properties.h"
......@@ -353,9 +353,7 @@ gfx::Rect CustomFrameViewAsh::GetWindowBoundsForClientBounds(
}
int CustomFrameViewAsh::NonClientHitTest(const gfx::Point& point) {
return FrameBorderNonClientHitTest(this, header_view_->GetBackButton(),
header_view_->caption_button_container(),
point);
return FrameBorderNonClientHitTest(this, point);
}
void CustomFrameViewAsh::GetWindowMask(const gfx::Size& size,
......
......@@ -494,6 +494,7 @@ TEST_F(CustomFrameViewAshTest, BackButton) {
// back key sequence.
generator->MoveMouseTo(
header_view->GetBackButton()->GetBoundsInScreen().CenterPoint());
generator->ClickLeftButton();
EXPECT_EQ(1, target_back_press.accelerator_count());
EXPECT_EQ(1, target_back_release.accelerator_count());
......
......@@ -46,6 +46,8 @@ component("cpp") {
"ash_typography.h",
"ash_view_ids.h",
"config.h",
"frame_border_hit_test.cc",
"frame_border_hit_test.h",
"immersive/immersive_context.cc",
"immersive/immersive_context.h",
"immersive/immersive_focus_watcher.h",
......
......@@ -2,27 +2,24 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/frame/frame_border_hit_test.h"
#include "ash/public/cpp/frame_border_hit_test.h"
#include "ash/frame/caption_buttons/frame_caption_button_container_view.h"
#include "ash/public/cpp/ash_constants.h"
#include "ash/shell_port.h"
#include "ui/aura/env.h"
#include "ui/base/hit_test.h"
#include "ui/views/view_properties.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
#include "ui/views/window/non_client_view.h"
namespace ash {
int FrameBorderNonClientHitTest(
views::NonClientFrameView* view,
const views::View* back_button,
const FrameCaptionButtonContainerView* caption_button_container,
const gfx::Point& point_in_widget) {
int FrameBorderNonClientHitTest(views::NonClientFrameView* view,
const gfx::Point& point_in_widget) {
gfx::Rect expanded_bounds = view->bounds();
int outside_bounds = kResizeOutsideBoundsSize;
if (ShellPort::Get()->IsTouchDown())
if (aura::Env::GetInstance()->is_touch_down())
outside_bounds *= kResizeOutsideBoundsScaleForTouch;
expanded_bounds.Inset(-outside_bounds, -outside_bounds);
......@@ -31,12 +28,12 @@ int FrameBorderNonClientHitTest(
// Check the frame first, as we allow a small area overlapping the contents
// to be used for resize handles.
views::Widget* frame = view->GetWidget();
bool can_ever_resize = frame->widget_delegate()->CanResize();
views::Widget* widget = view->GetWidget();
bool can_ever_resize = widget->widget_delegate()->CanResize();
// Don't allow overlapping resize handles when the window is maximized or
// fullscreen, as it can't be resized in those states.
int resize_border = kResizeInsideBoundsSize;
if (frame->IsMaximized() || frame->IsFullscreen()) {
if (widget->IsMaximized() || widget->IsFullscreen()) {
resize_border = 0;
can_ever_resize = false;
}
......@@ -47,27 +44,27 @@ int FrameBorderNonClientHitTest(
return frame_component;
int client_component =
frame->client_view()->NonClientHitTest(point_in_widget);
widget->client_view()->NonClientHitTest(point_in_widget);
if (client_component != HTNOWHERE)
return client_component;
if (caption_button_container->visible()) {
gfx::Point point_in_caption_button_container(point_in_widget);
views::View::ConvertPointFromWidget(caption_button_container,
&point_in_caption_button_container);
int caption_button_component = caption_button_container->NonClientHitTest(
point_in_caption_button_container);
if (caption_button_component != HTNOWHERE)
return caption_button_component;
// Check if it intersects with children (frame caption button, back button,
// etc.).
gfx::Point point_in_non_client_view(point_in_widget);
views::View::ConvertPointFromWidget(widget->non_client_view(),
&point_in_non_client_view);
for (views::View* target_view =
widget->non_client_view()->GetEventHandlerForPoint(
point_in_non_client_view);
target_view; target_view = target_view->parent()) {
int target_component =
target_view->GetProperty(views::kHitTestComponentKey);
if (target_component != HTNOWHERE)
return target_component;
if (target_view == widget->non_client_view())
break;
}
if (back_button) {
gfx::Point point_in_back_button(point_in_widget);
views::View::ConvertPointFromWidget(back_button, &point_in_back_button);
// Using HTMENU as a placeholder to pass through the event to button.
if (back_button->GetLocalBounds().Contains(point_in_back_button))
return HTMENU;
}
// Caption is a safe default.
return HTCAPTION;
}
......
......@@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_FRAME_FRAME_BORDER_HIT_TEST_H_
#define ASH_FRAME_FRAME_BORDER_HIT_TEST_H_
#ifndef ASH_PUBLIC_CPP_FRAME_BORDER_HIT_TEST_H_
#define ASH_PUBLIC_CPP_FRAME_BORDER_HIT_TEST_H_
#include "ash/ash_export.h"
#include "ash/public/cpp/ash_public_export.h"
namespace gfx {
class Point;
......@@ -13,20 +13,15 @@ class Point;
namespace views {
class NonClientFrameView;
class View;
}
} // namespace views
namespace ash {
class FrameCaptionButtonContainerView;
// Returns the HitTestCompat for the specified point.
ASH_EXPORT int FrameBorderNonClientHitTest(
ASH_PUBLIC_EXPORT int FrameBorderNonClientHitTest(
views::NonClientFrameView* view,
const views::View* back_button,
const FrameCaptionButtonContainerView* caption_button_container,
const gfx::Point& point_in_widget);
} // namespace ash
#endif // ASH_FRAME_FRAME_BORDER_HIT_TEST_H_
#endif // ASH_PUBLIC_CPP_FRAME_BORDER_HIT_TEST_H_
......@@ -6,8 +6,8 @@
#include "ash/frame/caption_buttons/frame_caption_button_container_view.h"
#include "ash/frame/default_frame_header.h"
#include "ash/frame/frame_border_hit_test.h"
#include "ash/public/cpp/ash_constants.h"
#include "ash/public/cpp/frame_border_hit_test.h"
#include "ash/shell.h"
#include "ash/wm/resize_handle_window_targeter.h"
#include "ash/wm/window_util.h"
......@@ -123,8 +123,7 @@ gfx::Rect PanelFrameView::GetWindowBoundsForClientBounds(
int PanelFrameView::NonClientHitTest(const gfx::Point& point) {
if (!frame_header_)
return HTNOWHERE;
return FrameBorderNonClientHitTest(this, nullptr, caption_button_container_,
point);
return FrameBorderNonClientHitTest(this, point);
}
void PanelFrameView::OnPaint(gfx::Canvas* canvas) {
......
......@@ -9,13 +9,13 @@
#include "ash/frame/caption_buttons/frame_back_button.h" // mash-ok
#include "ash/frame/caption_buttons/frame_caption_button_container_view.h" // mash-ok
#include "ash/frame/default_frame_header.h" // mash-ok
#include "ash/frame/frame_border_hit_test.h" // mash-ok
#include "ash/frame/frame_header_util.h" // mash-ok
#include "ash/public/cpp/app_list/app_list_features.h"
#include "ash/public/cpp/app_types.h"
#include "ash/public/cpp/ash_constants.h"
#include "ash/public/cpp/ash_layout_constants.h"
#include "ash/public/cpp/ash_switches.h"
#include "ash/public/cpp/frame_border_hit_test.h"
#include "ash/public/cpp/window_properties.h"
#include "ash/public/interfaces/constants.mojom.h"
#include "ash/public/interfaces/window_state_type.mojom.h"
......@@ -450,19 +450,7 @@ gfx::Rect BrowserNonClientFrameViewAsh::GetWindowBoundsForClientBounds(
}
int BrowserNonClientFrameViewAsh::NonClientHitTest(const gfx::Point& point) {
if (hosted_app_button_container_) {
gfx::Point client_point(point);
View::ConvertPointToTarget(this, hosted_app_button_container_,
&client_point);
if (hosted_app_button_container_->HitTestPoint(client_point))
return HTCLIENT;
}
// TODO(sky): figure out how this interaction should work.
const int hit_test =
IsMash() ? HTCLIENT
: ash::FrameBorderNonClientHitTest(
this, back_button_, caption_button_container_, point);
int hit_test = ash::FrameBorderNonClientHitTest(this, point);
// When the window is restored we want a large click target above the tabs
// to drag the window, so redirect clicks in the tab's shadow to caption.
......@@ -470,9 +458,10 @@ int BrowserNonClientFrameViewAsh::NonClientHitTest(const gfx::Point& point) {
!frame()->IsFullscreen()) {
gfx::Point client_point(point);
View::ConvertPointToTarget(this, frame()->client_view(), &client_point);
gfx::Rect tabstrip_bounds(browser_view()->tabstrip()->bounds());
gfx::Rect tabstrip_shadow_bounds(browser_view()->tabstrip()->bounds());
constexpr int kTabShadowHeight = 4;
if (client_point.y() < tabstrip_bounds.y() + kTabShadowHeight)
tabstrip_shadow_bounds.set_height(kTabShadowHeight);
if (tabstrip_shadow_bounds.Contains(client_point))
return HTCAPTION;
}
......
......@@ -17,6 +17,7 @@
#include "chrome/browser/ui/views/location_bar/content_setting_image_view.h"
#include "chrome/browser/ui/views/page_action/page_action_icon_container_view.h"
#include "chrome/browser/ui/views/toolbar/browser_actions_container.h"
#include "ui/base/hit_test.h"
#include "ui/compositor/layer_animation_element.h"
#include "ui/compositor/layer_animation_sequence.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
......@@ -27,6 +28,7 @@
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/layout/layout_provider.h"
#include "ui/views/view_properties.h"
#include "ui/views/widget/native_widget_aura.h"
namespace {
......@@ -181,6 +183,8 @@ HostedAppButtonContainer::ContentSettingsContainer::ContentSettingsContainer(
image_view->SetBorder(views::CreateEmptyBorder(
gfx::Insets(kContentSettingIconInteriorPadding)));
image_view->disable_animation();
image_view->SetProperty(views::kHitTestComponentKey,
static_cast<int>(HTCLIENT));
content_setting_views_.push_back(image_view.get());
AddChildView(image_view.release());
}
......@@ -222,8 +226,16 @@ HostedAppButtonContainer::HostedAppButtonContainer(
layout.set_cross_axis_alignment(
views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER);
content_settings_container_->SetProperty(views::kHitTestComponentKey,
static_cast<int>(HTCLIENT));
AddChildView(content_settings_container_);
page_action_icon_container_view_->SetProperty(views::kHitTestComponentKey,
static_cast<int>(HTCLIENT));
AddChildView(page_action_icon_container_view_);
browser_actions_container_->SetProperty(views::kHitTestComponentKey,
static_cast<int>(HTCLIENT));
AddChildView(browser_actions_container_);
AddChildView(app_menu_button_);
......
......@@ -13,16 +13,20 @@
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/toolbar/app_menu.h"
#include "chrome/grit/generated_resources.h"
#include "ui/base/hit_test.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/views/border.h"
#include "ui/views/controls/button/menu_button.h"
#include "ui/views/view_properties.h"
constexpr int kMenuHighlightFadeDurationMs = 800;
HostedAppMenuButton::HostedAppMenuButton(BrowserView* browser_view)
: AppMenuButton(this), browser_view_(browser_view) {
SetProperty(views::kHitTestComponentKey, static_cast<int>(HTMENU));
SetInkDropMode(InkDropMode::ON);
// Disable focus ring for consistency with sibling buttons and AppMenuButton.
SetFocusPainter(nullptr);
......
......@@ -44,6 +44,9 @@ BrowserNonClientFrameViewAshTest.FrameMinSizeIsUpdated*
-HostedAppNonClientFrameViewAshTest.*
-HomeLauncherBrowserNonClientFrameViewAshTest.*
BrowserNonClientFrameViewAshTest.NonClientHitTest*
BrowserNonClientFrameViewAshTest.AvatarMenuButtonHitTest*
# Fix immersive fullscreen mode in mash. https://crbug.com/844748.
-ImmersiveModeBrowserViewTest.TestCaptionButtonsReceiveEventsInAppImmersiveMode*
-ImmersiveModeBrowserViewTest.TestCaptionButtonsReceiveEventsInBrowserImmersiveMode*
......
......@@ -4,6 +4,7 @@
#include "ui/views/view_properties.h"
#include "ui/base/hit_test.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/views/bubble/bubble_dialog_delegate.h"
......@@ -19,6 +20,7 @@ DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(VIEWS_EXPORT,
namespace views {
DEFINE_UI_CLASS_PROPERTY_KEY(int, kHitTestComponentKey, HTNOWHERE);
DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(gfx::Insets, kMarginsKey, nullptr);
DEFINE_UI_CLASS_PROPERTY_KEY(views::BubbleDialogDelegateView*,
kAnchoredDialogKey,
......
......@@ -16,6 +16,10 @@ namespace views {
class BubbleDialogDelegateView;
// The hit test component (e.g. HTCLIENT) for a View in a window frame. Defaults
// to HTNOWHERE.
VIEWS_EXPORT extern const ui::ClassProperty<int>* const kHitTestComponentKey;
// A property to store margins around the outer perimeter of the view. Margins
// are outside the bounds of the view. This is used by various layout managers
// to position views with the proper spacing between them.
......
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