Commit a0294c54 authored by Peter Kasting's avatar Peter Kasting Committed by Commit Bot

Simplify/clean up ArcCustomTabView.

Bug: none
Change-Id: Iced87f066a842db371a7936ecff0644caac2e7b3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2218680
Auto-Submit: Peter Kasting <pkasting@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Commit-Queue: Peter Kasting <pkasting@chromium.org>
Cr-Commit-Position: refs/heads/master@{#773794}
parent d5e14e19
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include "components/exo/surface.h" #include "components/exo/surface.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/aura/window_targeter.h" #include "ui/aura/window_targeter.h"
#include "ui/views/controls/native/native_view_host.h"
#include "ui/views/layout/fill_layout.h" #include "ui/views/layout/fill_layout.h"
#include "ui/views/widget/widget.h" #include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h" #include "ui/views/widget/widget_delegate.h"
...@@ -46,11 +45,10 @@ std::unique_ptr<ArcCustomTab> ArcCustomTab::Create(aura::Window* arc_app_window, ...@@ -46,11 +45,10 @@ std::unique_ptr<ArcCustomTab> ArcCustomTab::Create(aura::Window* arc_app_window,
return nullptr; return nullptr;
} }
auto* parent = widget->widget_delegate()->GetContentsView(); auto* parent = widget->widget_delegate()->GetContentsView();
parent->SetLayoutManager(std::make_unique<views::FillLayout>());
auto view = std::make_unique<ArcCustomTabView>(arc_app_window, surface_id, auto view = std::make_unique<ArcCustomTabView>(arc_app_window, surface_id,
top_margin); top_margin);
parent->AddChildView(view.get()); parent->AddChildView(view.get());
parent->SetLayoutManager(std::make_unique<views::FillLayout>());
parent->Layout();
return std::move(view); return std::move(view);
} }
...@@ -58,136 +56,92 @@ std::unique_ptr<ArcCustomTab> ArcCustomTab::Create(aura::Window* arc_app_window, ...@@ -58,136 +56,92 @@ std::unique_ptr<ArcCustomTab> ArcCustomTab::Create(aura::Window* arc_app_window,
ArcCustomTabView::ArcCustomTabView(aura::Window* arc_app_window, ArcCustomTabView::ArcCustomTabView(aura::Window* arc_app_window,
int32_t surface_id, int32_t surface_id,
int32_t top_margin) int32_t top_margin)
: host_(new views::NativeViewHost()), : arc_app_window_(arc_app_window),
arc_app_window_(arc_app_window),
surface_id_(surface_id), surface_id_(surface_id),
top_margin_(top_margin) { top_margin_(top_margin) {
AddChildView(host_);
arc_app_window_->AddObserver(this);
set_owned_by_client(); set_owned_by_client();
other_windows_observer_.Add(arc_app_window_);
} }
ArcCustomTabView::~ArcCustomTabView() { ArcCustomTabView::~ArcCustomTabView() = default;
for (auto* window : observed_surfaces_)
window->RemoveObserver(this);
arc_app_window_->RemoveObserver(this);
if (surface_window_)
surface_window_->RemoveObserver(this);
if (native_view_container_)
native_view_container_->RemoveObserver(this);
}
void ArcCustomTabView::Attach(gfx::NativeView view) { void ArcCustomTabView::Attach(gfx::NativeView view) {
DCHECK(view); DCHECK(view);
DCHECK(!host_->native_view()); DCHECK(!GetHostView());
host_->Attach(view); host_->Attach(view);
native_view_container_ = host_->GetNativeViewContainer(); aura::Window* const container = host_->GetNativeViewContainer();
native_view_container_->SetEventTargeter( container->SetEventTargeter(std::make_unique<aura::WindowTargeter>());
std::make_unique<aura::WindowTargeter>()); other_windows_observer_.Add(container);
native_view_container_->parent()->StackChildAtTop(native_view_container_); EnsureWindowOrders();
native_view_container_->AddObserver(this); UpdateSurfaceIfNecessary();
} }
gfx::NativeView ArcCustomTabView::GetHostView() { gfx::NativeView ArcCustomTabView::GetHostView() {
return host_->native_view(); return host_->native_view();
} }
void ArcCustomTabView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
if (previous_bounds.size() != size()) {
InvalidateLayout();
host_->InvalidateLayout();
}
}
void ArcCustomTabView::Layout() {
exo::Surface* surface = FindSurface();
if (!surface)
return;
DCHECK(observed_surfaces_.empty());
aura::Window* surface_window = surface->window();
if (surface_window_ != surface_window) {
if (surface_window_)
surface_window_->RemoveObserver(this);
surface_window->AddObserver(this);
surface_window_ = surface_window;
}
gfx::Point topleft(0, top_margin_),
bottomright(surface_window->bounds().width(),
surface_window->bounds().height());
ConvertPointFromWindow(surface_window, &topleft);
ConvertPointFromWindow(surface_window, &bottomright);
gfx::Rect bounds(topleft, gfx::Size(bottomright.x() - topleft.x(),
bottomright.y() - topleft.y()));
host_->SetBoundsRect(bounds);
}
void ArcCustomTabView::OnWindowHierarchyChanged( void ArcCustomTabView::OnWindowHierarchyChanged(
const HierarchyChangeParams& params) { const HierarchyChangeParams& params) {
if (params.receiver == arc_app_window_) { if ((params.receiver == arc_app_window_) &&
auto* surface = exo::Surface::AsSurface(params.target); exo::Surface::AsSurface(params.target) && params.new_parent)
if (surface && params.new_parent != nullptr) { UpdateSurfaceIfNecessary();
// Call Layout() aggressively without checking the surface ID to start
// observing surface ID updates in case it's not set yet.
Layout();
}
}
} }
void ArcCustomTabView::OnWindowBoundsChanged(aura::Window* window, void ArcCustomTabView::OnWindowBoundsChanged(aura::Window* window,
const gfx::Rect& old_bounds, const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds, const gfx::Rect& new_bounds,
ui::PropertyChangeReason reason) { ui::PropertyChangeReason reason) {
if (window == surface_window_ && old_bounds.size() != new_bounds.size()) { if (surface_window_observer_.IsObserving(window) &&
InvalidateLayout(); old_bounds.size() != new_bounds.size())
host_->InvalidateLayout(); OnSurfaceBoundsMaybeChanged(window);
}
} }
void ArcCustomTabView::OnWindowPropertyChanged(aura::Window* window, void ArcCustomTabView::OnWindowPropertyChanged(aura::Window* window,
const void* key, const void* key,
intptr_t old) { intptr_t old) {
if (observed_surfaces_.contains(window)) { if (surfaces_observer_.IsObserving(window) && key == exo::kClientSurfaceIdKey)
if (key == exo::kClientSurfaceIdKey) { UpdateSurfaceIfNecessary();
// Client surface ID was updated. Try to find the surface again.
Layout();
}
}
} }
void ArcCustomTabView::OnWindowStackingChanged(aura::Window* window) { void ArcCustomTabView::OnWindowStackingChanged(aura::Window* window) {
if (window != host_->GetNativeViewContainer() || reorder_scheduled_) if (window == host_->GetNativeViewContainer() &&
return; !weak_ptr_factory_.HasWeakPtrs()) {
reorder_scheduled_ = true; // Reordering should happen asynchronously -- some entity (like
// Reordering should happen asynchronously -- some entity (like // views::WindowReorderer) changes the window orders, and then ensures layer
// views::WindowReorderer) changes the window orders, and then ensures layer // orders later. Changing order here synchronously leads to inconsistent
// orders later. Changing order here synchronously leads to inconsistent // window/layer ordering and causes weird graphical effects.
// window/layer ordering and causes weird graphical effects. // TODO(hashimoto): fix the views ordering and remove this handling.
// TODO(hashimoto): fix the views ordering and remove this handling. base::SequencedTaskRunnerHandle::Get()->PostTask(
base::SequencedTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&ArcCustomTabView::EnsureWindowOrders,
FROM_HERE, base::BindOnce(&ArcCustomTabView::EnsureWindowOrders, weak_ptr_factory_.GetWeakPtr()));
weak_ptr_factory_.GetWeakPtr())); }
} }
void ArcCustomTabView::OnWindowDestroying(aura::Window* window) { void ArcCustomTabView::OnWindowDestroying(aura::Window* window) {
if (observed_surfaces_.contains(window)) { if (surfaces_observer_.IsObserving(window))
window->RemoveObserver(this); surfaces_observer_.Remove(window);
observed_surfaces_.erase(window); if (surface_window_observer_.IsObserving(window))
} surface_window_observer_.Remove(window);
if (window == surface_window_) { if (other_windows_observer_.IsObserving(window))
window->RemoveObserver(this); other_windows_observer_.Remove(window);
surface_window_ = nullptr; }
}
if (window == native_view_container_) { void ArcCustomTabView::OnSurfaceBoundsMaybeChanged(
window->RemoveObserver(this); aura::Window* surface_window) {
native_view_container_ = nullptr; DCHECK(surface_window);
} gfx::Point origin(0, top_margin_);
gfx::Point bottom_right(surface_window->bounds().width(),
surface_window->bounds().height());
ConvertPointFromWindow(surface_window, &origin);
ConvertPointFromWindow(surface_window, &bottom_right);
host_->SetBounds(origin.x(), origin.y(), bottom_right.x() - origin.x(),
bottom_right.y() - origin.y());
} }
void ArcCustomTabView::EnsureWindowOrders() { void ArcCustomTabView::EnsureWindowOrders() {
reorder_scheduled_ = false; aura::Window* const container = host_->GetNativeViewContainer();
if (native_view_container_) if (container)
native_view_container_->parent()->StackChildAtTop(native_view_container_); container->parent()->StackChildAtTop(container);
} }
void ArcCustomTabView::ConvertPointFromWindow(aura::Window* window, void ArcCustomTabView::ConvertPointFromWindow(aura::Window* window,
...@@ -197,28 +151,31 @@ void ArcCustomTabView::ConvertPointFromWindow(aura::Window* window, ...@@ -197,28 +151,31 @@ void ArcCustomTabView::ConvertPointFromWindow(aura::Window* window,
views::View::ConvertPointFromWidget(parent(), point); views::View::ConvertPointFromWidget(parent(), point);
} }
exo::Surface* ArcCustomTabView::FindSurface() { void ArcCustomTabView::UpdateSurfaceIfNecessary() {
std::vector<exo::Surface*> surfaces; std::vector<exo::Surface*> surfaces;
EnumerateSurfaces(arc_app_window_, &surfaces); EnumerateSurfaces(arc_app_window_, &surfaces);
// Try to find the surface. // Try to find the surface.
for (auto* surface : surfaces) { const auto it = std::find_if(surfaces.cbegin(), surfaces.cend(),
if (surface->GetClientSurfaceId() == surface_id_) { [id = surface_id_](const auto* surface) {
// Stop observing surfaces for ID updates. return surface->GetClientSurfaceId() == id;
for (auto* window : observed_surfaces_) });
window->RemoveObserver(this); if (it == surfaces.cend()) {
observed_surfaces_.clear(); for (auto* surface : surfaces) {
return surface; if (!surface->GetClientSurfaceId() &&
!surfaces_observer_.IsObserving(surface->window()))
surfaces_observer_.Add(surface->window());
} }
} } else {
// Surface not found. Start observing surfaces for ID updates. surfaces_observer_.RemoveAll();
for (auto* surface : surfaces) {
if (surface->GetClientSurfaceId() == 0) { auto* const window = (*it)->window();
if (observed_surfaces_.insert(surface->window()).second) if (!surface_window_observer_.IsObserving(window)) {
surface->window()->AddObserver(this); surface_window_observer_.RemoveAll();
surface_window_observer_.Add(window);
OnSurfaceBoundsMaybeChanged(window);
} }
} }
return nullptr;
} }
} // namespace ash } // namespace ash
...@@ -8,19 +8,12 @@ ...@@ -8,19 +8,12 @@
#include <memory> #include <memory>
#include "ash/public/cpp/arc_custom_tab.h" #include "ash/public/cpp/arc_custom_tab.h"
#include "base/containers/flat_set.h" #include "base/scoped_observer.h"
#include "base/macros.h" #include "ui/aura/window.h"
#include "ui/aura/window_observer.h" #include "ui/aura/window_observer.h"
#include "ui/views/controls/native/native_view_host.h"
#include "ui/views/view.h" #include "ui/views/view.h"
namespace exo {
class Surface;
}
namespace views {
class NativeViewHost;
}
namespace ash { namespace ash {
// A view-based implementation of ArcCustomTab which works in the classic // A view-based implementation of ArcCustomTab which works in the classic
...@@ -32,6 +25,8 @@ class ArcCustomTabView : public ArcCustomTab, ...@@ -32,6 +25,8 @@ class ArcCustomTabView : public ArcCustomTab,
ArcCustomTabView(aura::Window* arc_app_window, ArcCustomTabView(aura::Window* arc_app_window,
int32_t surface_id, int32_t surface_id,
int32_t top_margin); int32_t top_margin);
ArcCustomTabView(const ArcCustomTabView&) = delete;
ArcCustomTabView& operator=(const ArcCustomTabView&) = delete;
~ArcCustomTabView() override; ~ArcCustomTabView() override;
private: private:
...@@ -39,10 +34,6 @@ class ArcCustomTabView : public ArcCustomTab, ...@@ -39,10 +34,6 @@ class ArcCustomTabView : public ArcCustomTab,
void Attach(gfx::NativeView view) override; void Attach(gfx::NativeView view) override;
gfx::NativeView GetHostView() override; gfx::NativeView GetHostView() override;
// views::View:
void OnBoundsChanged(const gfx::Rect& previous_bounds) override;
void Layout() override;
// aura::WindowObserver: // aura::WindowObserver:
void OnWindowHierarchyChanged(const HierarchyChangeParams& params) override; void OnWindowHierarchyChanged(const HierarchyChangeParams& params) override;
void OnWindowBoundsChanged(aura::Window* window, void OnWindowBoundsChanged(aura::Window* window,
...@@ -55,27 +46,29 @@ class ArcCustomTabView : public ArcCustomTab, ...@@ -55,27 +46,29 @@ class ArcCustomTabView : public ArcCustomTab,
void OnWindowStackingChanged(aura::Window* window) override; void OnWindowStackingChanged(aura::Window* window) override;
void OnWindowDestroying(aura::Window* window) override; void OnWindowDestroying(aura::Window* window) override;
// Updates |host_|'s bounds to deal with changes in the bounds of the
// associated |surface_window|.
void OnSurfaceBoundsMaybeChanged(aura::Window* surface_window);
// Ensures the window/layer orders for the NativeViewHost. // Ensures the window/layer orders for the NativeViewHost.
void EnsureWindowOrders(); void EnsureWindowOrders();
// Converts the point from the given window to this view. // Converts the point from the given window to this view.
void ConvertPointFromWindow(aura::Window* window, gfx::Point* point); void ConvertPointFromWindow(aura::Window* window, gfx::Point* point);
// Tries to find the surface. // Looks for the surface with |surface_id_|, and handles resultant changes.
exo::Surface* FindSurface(); void UpdateSurfaceIfNecessary();
views::NativeViewHost* const host_; views::NativeViewHost* const host_ =
AddChildView(std::make_unique<views::NativeViewHost>());
aura::Window* const arc_app_window_; aura::Window* const arc_app_window_;
const int32_t surface_id_, top_margin_; const int32_t surface_id_, top_margin_;
aura::Window* surface_window_ = nullptr; ScopedObserver<aura::Window, aura::WindowObserver> surfaces_observer_{this};
base::flat_set<aura::Window*> observed_surfaces_; ScopedObserver<aura::Window, aura::WindowObserver> surface_window_observer_{
aura::Window* native_view_container_ = nullptr; this};
ScopedObserver<aura::Window, aura::WindowObserver> other_windows_observer_{
bool reorder_scheduled_ = false; this};
base::WeakPtrFactory<ArcCustomTabView> weak_ptr_factory_{this}; base::WeakPtrFactory<ArcCustomTabView> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(ArcCustomTabView);
}; };
} // namespace ash } // namespace ash
......
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