Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(416)

Unified Diff: components/exo/shell_surface.cc

Issue 1819273002: exo: Improved implementation of child surfaces and popups. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix deps Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/exo/shell_surface.h ('k') | components/exo/shell_surface_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/exo/shell_surface.cc
diff --git a/components/exo/shell_surface.cc b/components/exo/shell_surface.cc
index 544eb5a6f66e9058c273285e303a25f675d5f37e..72e30856ddd9db8852af1442d9198b4ea03040ca 100644
--- a/components/exo/shell_surface.cc
+++ b/components/exo/shell_surface.cc
@@ -19,6 +19,7 @@
#include "ui/base/hit_test.h"
#include "ui/gfx/path.h"
#include "ui/views/widget/widget.h"
+#include "ui/wm/core/window_util.h"
#include "ui/wm/public/activation_client.h"
DECLARE_WINDOW_PROPERTY_TYPE(std::string*)
@@ -60,32 +61,20 @@ class CustomWindowTargeter : public aura::WindowTargeter {
// Overridden from aura::WindowTargeter:
bool EventLocationInsideBounds(aura::Window* window,
const ui::LocatedEvent& event) const override {
- return PointInsideBounds(window, event.location());
- }
-
- private:
- bool PointInsideBounds(const aura::Window* window,
- const gfx::Point& point) const {
Surface* surface = ShellSurface::GetMainSurface(window);
if (!surface)
return false;
- gfx::Point local_point = point;
- if (window->parent()) {
+ gfx::Point local_point = event.location();
+ if (window->parent())
aura::Window::ConvertPointToTarget(window->parent(), window,
&local_point);
- }
-
- // If point is inside a child window then it's also inside the parent.
- for (const aura::Window* child : window->children()) {
- if (PointInsideBounds(child, local_point))
- return true;
- }
aura::Window::ConvertPointToTarget(window, surface, &local_point);
return surface->HitTestRect(gfx::Rect(local_point, gfx::Size(1, 1)));
}
+ private:
DISALLOW_COPY_AND_ASSIGN(CustomWindowTargeter);
};
@@ -113,10 +102,13 @@ DEFINE_LOCAL_WINDOW_PROPERTY_KEY(Surface*, kMainSurfaceKey, nullptr)
ShellSurface::ShellSurface(Surface* surface,
ShellSurface* parent,
- const gfx::Rect& initial_bounds)
- : surface_(surface),
+ const gfx::Rect& initial_bounds,
+ bool activatable)
+ : widget_(nullptr),
+ surface_(surface),
parent_(parent ? parent->GetWidget()->GetNativeWindow() : nullptr),
- initial_bounds_(initial_bounds) {
+ initial_bounds_(initial_bounds),
+ activatable_(activatable) {
ash::Shell::GetInstance()->activation_client()->AddObserver(this);
surface_->SetSurfaceDelegate(this);
surface_->AddSurfaceObserver(this);
@@ -127,7 +119,7 @@ ShellSurface::ShellSurface(Surface* surface,
}
ShellSurface::ShellSurface(Surface* surface)
- : ShellSurface(surface, nullptr, gfx::Rect()) {}
+ : ShellSurface(surface, nullptr, gfx::Rect(), true) {}
ShellSurface::~ShellSurface() {
ash::Shell::GetInstance()->activation_client()->RemoveObserver(this);
@@ -149,11 +141,17 @@ void ShellSurface::SetParent(ShellSurface* parent) {
TRACE_EVENT1("exo", "ShellSurface::SetParent", "parent",
parent ? base::UTF16ToASCII(parent->title_) : "null");
- if (parent_)
+ if (parent_) {
parent_->RemoveObserver(this);
+ if (widget_)
+ wm::RemoveTransientChild(parent_, widget_->GetNativeWindow());
+ }
parent_ = parent ? parent->GetWidget()->GetNativeWindow() : nullptr;
- if (parent_)
+ if (parent_) {
parent_->AddObserver(this);
+ if (widget_)
+ wm::AddTransientChild(parent_, widget_->GetNativeWindow());
+ }
}
void ShellSurface::Maximize() {
@@ -284,14 +282,11 @@ void ShellSurface::OnSurfaceCommit() {
if (widget_) {
// Update surface bounds and widget size.
- gfx::Point origin;
- views::View::ConvertPointToWidget(this, &origin);
- // Use |geometry_| if set, otherwise use the visual bounds of the surface.
- gfx::Rect geometry =
- geometry_.IsEmpty() ? surface_->GetVisibleBounds() : geometry_;
- surface_->SetBounds(gfx::Rect(origin - geometry.OffsetFromOrigin(),
- surface_->layer()->size()));
- widget_->SetSize(geometry.size());
+ gfx::Rect visible_bounds = GetVisibleBounds();
+ surface_->SetBounds(
+ gfx::Rect(gfx::Point() - visible_bounds.OffsetFromOrigin(),
+ surface_->layer()->size()));
+ widget_->SetSize(visible_bounds.size());
// Show widget if not already visible.
if (!widget_->IsClosed() && !widget_->IsVisible())
@@ -332,12 +327,17 @@ base::string16 ShellSurface::GetWindowTitle() const {
return title_;
}
+void ShellSurface::WindowClosing() {
+ SetEnabled(false);
+ widget_ = nullptr;
+}
+
views::Widget* ShellSurface::GetWidget() {
- return widget_.get();
+ return widget_;
}
const views::Widget* ShellSurface::GetWidget() const {
- return widget_.get();
+ return widget_;
}
views::View* ShellSurface::GetContentsView() {
@@ -403,6 +403,8 @@ void ShellSurface::OnWindowActivated(
aura::client::ActivationChangeObserver::ActivationReason reason,
aura::Window* gained_active,
aura::Window* lost_active) {
+ DCHECK(activatable_);
+
if (!widget_)
return;
@@ -421,26 +423,28 @@ void ShellSurface::CreateShellSurfaceWidget() {
views::Widget::InitParams params;
params.type = views::Widget::InitParams::TYPE_WINDOW;
- params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ params.ownership = views::Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET;
params.delegate = this;
params.shadow_type = views::Widget::InitParams::SHADOW_TYPE_NONE;
params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
params.show_state = ui::SHOW_STATE_NORMAL;
- gfx::Point position(initial_bounds_.origin());
- if (parent_) {
- params.child = true;
- params.parent = parent_;
- aura::Window::ConvertPointToTarget(GetMainSurface(parent_), parent_,
- &position);
- } else {
- params.parent =
- ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(),
- ash::kShellWindowId_DefaultContainer);
+ params.parent = ash::Shell::GetContainer(
+ ash::Shell::GetPrimaryRootWindow(), ash::kShellWindowId_DefaultContainer);
+ if (!initial_bounds_.IsEmpty()) {
+ gfx::Point position(initial_bounds_.origin());
+ if (parent_) {
+ aura::Window::ConvertPointToTarget(GetMainSurface(parent_), params.parent,
+ &position);
+ }
+ params.bounds = gfx::Rect(position + GetVisibleBounds().OffsetFromOrigin(),
+ initial_bounds_.size());
}
- params.bounds = gfx::Rect(position, initial_bounds_.size());
- widget_.reset(new ShellSurfaceWidget(this));
+ params.activatable = activatable_ ? views::Widget::InitParams::ACTIVATABLE_YES
+ : views::Widget::InitParams::ACTIVATABLE_NO;
+
+ // Note: NativeWidget owns this widget.
+ widget_ = new ShellSurfaceWidget(this);
widget_->Init(params);
- widget_->GetNativeWindow()->set_owned_by_parent(false);
widget_->GetNativeWindow()->SetName("ExoShellSurface");
widget_->GetNativeWindow()->AddChild(surface_);
widget_->GetNativeWindow()->SetEventTargeter(
@@ -451,9 +455,16 @@ void ShellSurface::CreateShellSurfaceWidget() {
// Start tracking window state changes.
ash::wm::GetWindowState(widget_->GetNativeWindow())->AddObserver(this);
- // The position of a top-level shell surface is managed by Ash.
- ash::wm::GetWindowState(widget_->GetNativeWindow())
- ->set_window_position_managed(true);
+ // Make shell surface a transient child if |parent_| has been set.
+ if (parent_)
+ wm::AddTransientChild(parent_, widget_->GetNativeWindow());
+
+ // Ash manages the position of a top-level shell surfaces unless
+ // |initial_bounds_| has been set.
+ if (initial_bounds_.IsEmpty()) {
+ ash::wm::GetWindowState(widget_->GetNativeWindow())
+ ->set_window_position_managed(true);
+ }
}
void ShellSurface::Configure() {
@@ -468,4 +479,9 @@ void ShellSurface::Configure() {
widget_->IsActive());
}
+gfx::Rect ShellSurface::GetVisibleBounds() const {
+ // Use |geometry_| if set, otherwise use the visual bounds of the surface.
+ return geometry_.IsEmpty() ? surface_->GetVisibleBounds() : geometry_;
+}
+
} // namespace exo
« no previous file with comments | « components/exo/shell_surface.h ('k') | components/exo/shell_surface_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698