blob: 7a137e2784b2adcf1aa607d6367d60decfd5ceea [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/ui_devtools/views/window_element.h"
#include "components/ui_devtools/Protocol.h"
#include "components/ui_devtools/ui_element_delegate.h"
#include "components/ui_devtools/views/element_utility.h"
#include "ui/aura/window.h"
#include "ui/wm/core/window_util.h"
namespace ui_devtools {
namespace {
int GetIndexOfChildInParent(aura::Window* window) {
const aura::Window::Windows& siblings = window->parent()->children();
auto it = std::find(siblings.begin(), siblings.end(), window);
DCHECK(it != siblings.end());
return std::distance(siblings.begin(), it);
}
} // namespace
WindowElement::WindowElement(aura::Window* window,
UIElementDelegate* ui_element_delegate,
UIElement* parent)
: UIElement(UIElementType::WINDOW, ui_element_delegate, parent),
window_(window) {
if (window)
window_->AddObserver(this);
}
WindowElement::~WindowElement() {
if (window_)
window_->RemoveObserver(this);
}
// Handles removing window_.
void WindowElement::OnWindowHierarchyChanging(
const aura::WindowObserver::HierarchyChangeParams& params) {
if (params.target == window_) {
parent()->RemoveChild(this);
delete this;
}
}
// Handles adding window_.
void WindowElement::OnWindowHierarchyChanged(
const aura::WindowObserver::HierarchyChangeParams& params) {
if (window_ == params.new_parent && params.receiver == params.new_parent) {
AddChild(new WindowElement(params.target, delegate(), this));
}
}
void WindowElement::OnWindowStackingChanged(aura::Window* window) {
DCHECK_EQ(window_, window);
parent()->ReorderChild(this, GetIndexOfChildInParent(window));
}
void WindowElement::OnWindowBoundsChanged(aura::Window* window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds,
ui::PropertyChangeReason reason) {
DCHECK_EQ(window_, window);
delegate()->OnUIElementBoundsChanged(this);
}
std::vector<UIElement::ClassProperties>
WindowElement::GetCustomPropertiesForMatchedStyle() const {
std::vector<UIElement::ClassProperties> ret;
std::vector<UIElement::UIProperty> cur_properties;
ui::Layer* layer = window_->layer();
if (layer) {
AppendLayerPropertiesMatchedStyle(layer, &cur_properties);
ret.emplace_back("Layer", cur_properties);
cur_properties.clear();
}
gfx::Rect bounds;
GetBounds(&bounds);
cur_properties.emplace_back("x", base::NumberToString(bounds.x()));
cur_properties.emplace_back("y", base::NumberToString(bounds.y()));
cur_properties.emplace_back("width", base::NumberToString(bounds.width()));
cur_properties.emplace_back("height", base::NumberToString(bounds.height()));
std::string state_str =
aura::Window::OcclusionStateToString(window_->occlusion_state());
// change OcclusionState::UNKNOWN to UNKNOWN
state_str = state_str.substr(state_str.find("::") + 2);
cur_properties.emplace_back("occlusion-state", state_str);
cur_properties.emplace_back("surface",
window_->GetSurfaceId().is_valid()
? window_->GetSurfaceId().ToString()
: "none");
cur_properties.emplace_back("capture",
window_->HasCapture() ? "true" : "false");
cur_properties.emplace_back(
"is-activatable", wm::CanActivateWindow(window_) ? "true" : "false");
ret.emplace_back("Window", cur_properties);
return ret;
}
void WindowElement::GetBounds(gfx::Rect* bounds) const {
*bounds = window_->bounds();
}
void WindowElement::SetBounds(const gfx::Rect& bounds) {
window_->SetBounds(bounds);
}
void WindowElement::GetVisible(bool* visible) const {
*visible = window_->IsVisible();
}
void WindowElement::SetVisible(bool visible) {
if (visible)
window_->Show();
else
window_->Hide();
}
std::vector<std::string> WindowElement::GetAttributes() const {
return {"name", window_->GetName(), "active",
::wm::IsActiveWindow(window_) ? "true" : "false"};
}
std::pair<gfx::NativeWindow, gfx::Rect>
WindowElement::GetNodeWindowAndScreenBounds() const {
return std::make_pair(static_cast<aura::Window*>(window_),
window_->GetBoundsInScreen());
}
// static
aura::Window* WindowElement::From(const UIElement* element) {
DCHECK_EQ(UIElementType::WINDOW, element->type());
return static_cast<const WindowElement*>(element)->window_;
}
template <>
int UIElement::FindUIElementIdForBackendElement<aura::Window>(
aura::Window* element) const {
if (type_ == UIElementType::WINDOW &&
UIElement::GetBackingElement<aura::Window, WindowElement>(this) ==
element) {
return node_id_;
}
for (auto* child : children_) {
int ui_element_id = child->FindUIElementIdForBackendElement(element);
if (ui_element_id)
return ui_element_id;
}
return 0;
}
void WindowElement::InitSources() {
if (window_->layer()) {
AddSource("ui/compositor/layer.h", 0);
}
AddSource("ui/aura/window.h", 0);
}
} // namespace ui_devtools