Chromium Code Reviews| Index: ash/common/devtools/ash_devtools_dom_agent.cc |
| diff --git a/ash/common/devtools/ash_devtools_dom_agent.cc b/ash/common/devtools/ash_devtools_dom_agent.cc |
| index a41dd36318a07a75cce5fa7734f4c5acb61c74be..af2e0c69a7bba241c25050d91ada7c55e79d48d8 100644 |
| --- a/ash/common/devtools/ash_devtools_dom_agent.cc |
| +++ b/ash/common/devtools/ash_devtools_dom_agent.cc |
| @@ -5,8 +5,14 @@ |
| #include "ash/common/devtools/ash_devtools_dom_agent.h" |
| #include "ash/common/wm_lookup.h" |
| +#include "ash/common/wm_root_window_controller.h" |
| #include "ash/common/wm_window.h" |
| +#include "ash/public/cpp/shell_window_ids.h" |
| #include "components/ui_devtools/devtools_server.h" |
| +#include "third_party/skia/include/core/SkColor.h" |
| +#include "ui/display/display.h" |
| +#include "ui/views/background.h" |
| +#include "ui/views/border.h" |
| namespace ash { |
| namespace devtools { |
| @@ -79,10 +85,22 @@ views::View* FindPreviousSibling(views::View* view) { |
| return view_index == 0 ? nullptr : parent->child_at(view_index - 1); |
| } |
| -} // namespace |
| +SkColor RGBAToSkColor(DOM::RGBA* rgba) { |
| + if (!rgba) |
| + return SkColorSetARGB(0, 0, 0, 0); |
| + // Default alpha value is 0 (not visibile) and need to convert alpha decimal |
| + // percentage value to hex |
| + return SkColorSetARGB(rgba->getA(0) * 255, rgba->getR(), rgba->getG(), |
| + rgba->getB()); |
|
sadrul
2016/12/06 20:48:58
Should we sanity check these values?
Sarmad Hashmi
2016/12/06 22:54:34
Done.
|
| +} |
| -AshDevToolsDOMAgent::AshDevToolsDOMAgent(ash::WmShell* shell) : shell_(shell) { |
| +} // namespace |
| +AshDevToolsDOMAgent::AshDevToolsDOMAgent( |
| + ash::WmShell* shell, |
| + scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner) |
| + : main_thread_task_runner_(main_thread_task_runner), shell_(shell) { |
| DCHECK(shell_); |
| + DCHECK(main_thread_task_runner_); |
| } |
| AshDevToolsDOMAgent::~AshDevToolsDOMAgent() { |
| @@ -100,6 +118,28 @@ ui::devtools::protocol::Response AshDevToolsDOMAgent::getDocument( |
| return ui::devtools::protocol::Response::OK(); |
| } |
| +ui::devtools::protocol::Response AshDevToolsDOMAgent::highlightNode( |
| + std::unique_ptr<ui::devtools::protocol::DOM::HighlightConfig> |
| + highlight_config, |
| + ui::devtools::protocol::Maybe<int> node_id) { |
| + main_thread_task_runner_->PostTask( |
|
sadrul
2016/12/06 20:48:59
Why do you need to PostTask()?
Sarmad Hashmi
2016/12/06 22:54:34
Removed, as discussed.
|
| + FROM_HERE, |
| + base::Bind(&AshDevToolsDOMAgent::HighlightNode, base::Unretained(this), |
| + base::Passed(std::move(highlight_config)), |
| + node_id.fromJust())); |
| + return ui::devtools::protocol::Response::OK(); |
| +} |
| + |
| +ui::devtools::protocol::Response AshDevToolsDOMAgent::hideHighlight() { |
| + if (widget_for_highlighting_ && widget_for_highlighting_->IsVisible()) { |
| + main_thread_task_runner_->PostTask( |
| + FROM_HERE, |
| + base::Bind(&views::Widget::Hide, |
| + base::Unretained(widget_for_highlighting_.get()))); |
| + } |
| + return ui::devtools::protocol::Response::OK(); |
| +} |
| + |
| // Handles removing windows. |
| void AshDevToolsDOMAgent::OnWindowTreeChanging(WmWindow* window, |
| const TreeChangeParams& params) { |
| @@ -223,8 +263,10 @@ std::unique_ptr<DOM::Node> AshDevToolsDOMAgent::BuildTreeForWindow( |
| views::Widget* widget = window->GetInternalWidget(); |
| if (widget) |
| children->addItem(BuildTreeForRootWidget(widget)); |
| - for (ash::WmWindow* child : window->GetChildren()) |
| - children->addItem(BuildTreeForWindow(child)); |
| + for (ash::WmWindow* child : window->GetChildren()) { |
| + if (!IsHighlightingWindow(child)) |
| + children->addItem(BuildTreeForWindow(child)); |
| + } |
| std::unique_ptr<ui::devtools::protocol::DOM::Node> node = |
| BuildNode("Window", GetAttributes(window), std::move(children)); |
| @@ -265,6 +307,9 @@ std::unique_ptr<DOM::Node> AshDevToolsDOMAgent::BuildTreeForView( |
| } |
| void AshDevToolsDOMAgent::AddWindowTree(WmWindow* window) { |
| + if (IsHighlightingWindow(window)) |
| + return; |
| + |
| DCHECK(window_to_node_id_map_.count(window->GetParent())); |
| WmWindow* prev_sibling = FindPreviousSibling(window); |
| frontend()->childNodeInserted( |
| @@ -276,6 +321,9 @@ void AshDevToolsDOMAgent::AddWindowTree(WmWindow* window) { |
| void AshDevToolsDOMAgent::RemoveWindowTree(WmWindow* window, |
| bool remove_observer) { |
| DCHECK(window); |
| + if (IsHighlightingWindow(window)) |
| + return; |
| + |
| if (window->GetInternalWidget()) |
| RemoveWidgetTree(window->GetInternalWidget(), remove_observer); |
| @@ -380,6 +428,11 @@ void AshDevToolsDOMAgent::RemoveViewNode(views::View* view, |
| frontend()->childNodeRemoved(parent_id, node_id); |
| } |
| +void AshDevToolsDOMAgent::DestroyHighlightingWidget() { |
| + DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); |
| + widget_for_highlighting_.reset(); |
| +} |
| + |
| void AshDevToolsDOMAgent::RemoveObservers() { |
| for (auto& pair : window_to_node_id_map_) |
| pair.first->RemoveObserver(this); |
| @@ -391,6 +444,9 @@ void AshDevToolsDOMAgent::RemoveObservers() { |
| void AshDevToolsDOMAgent::Reset() { |
| RemoveObservers(); |
| + main_thread_task_runner_->PostTask( |
| + FROM_HERE, base::Bind(&AshDevToolsDOMAgent::DestroyHighlightingWidget, |
| + base::Unretained(this))); |
| window_to_node_id_map_.clear(); |
| widget_to_node_id_map_.clear(); |
| view_to_node_id_map_.clear(); |
| @@ -400,5 +456,89 @@ void AshDevToolsDOMAgent::Reset() { |
| node_ids = 1; |
| } |
| +AshDevToolsDOMAgent::WindowAndBoundsPair |
| +AshDevToolsDOMAgent::GetNodeWindowAndBounds(int node_id) { |
| + WmWindow* window = GetWindowFromNodeId(node_id); |
| + if (window) |
| + return std::make_pair(window, window->GetBoundsInScreen()); |
| + |
| + views::Widget* widget = GetWidgetFromNodeId(node_id); |
| + if (widget) { |
| + return std::make_pair(WmLookup::Get()->GetWindowForWidget(widget), |
| + widget->GetWindowBoundsInScreen()); |
| + } |
| + |
| + views::View* view = GetViewFromNodeId(node_id); |
| + if (view) { |
| + gfx::Rect bounds = view->GetBoundsInScreen(); |
| + while (view->parent() != nullptr) |
| + view = view->parent(); |
|
sadrul
2016/12/06 20:48:58
Why is this needed?
Sarmad Hashmi
2016/12/06 22:54:34
Sorry, thought an earlier bug I was encountering w
|
| + return std::make_pair( |
| + WmLookup::Get()->GetWindowForWidget(view->GetWidget()), bounds); |
| + } |
| + |
| + return std::make_pair(nullptr, gfx::Rect()); |
| +} |
| + |
| +void AshDevToolsDOMAgent::InitializeHighlightingWidget() { |
| + DCHECK(!widget_for_highlighting_); |
| + widget_for_highlighting_.reset(new views::Widget); |
| + views::Widget::InitParams params; |
| + params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS; |
| + params.activatable = views::Widget::InitParams::ACTIVATABLE_NO; |
| + params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| + params.opacity = views::Widget::InitParams::WindowOpacity::TRANSLUCENT_WINDOW; |
| + params.name = "HighlightingWidget"; |
| + shell_->GetPrimaryRootWindowController() |
| + ->ConfigureWidgetInitParamsForContainer(widget_for_highlighting_.get(), |
| + kShellWindowId_OverlayContainer, |
| + ¶ms); |
| + params.keep_on_top = true; |
| + params.accept_events = false; |
| + widget_for_highlighting_->Init(params); |
| +} |
| + |
| +void AshDevToolsDOMAgent::UpdateHighlight(WindowAndBoundsPair window_and_bounds, |
| + SkColor background, |
| + SkColor border) { |
| + constexpr int kBorderThickness = 1; |
| + views::View* root_view = widget_for_highlighting_->GetRootView(); |
| + root_view->SetBorder(views::CreateSolidBorder(kBorderThickness, border)); |
| + root_view->set_background( |
| + views::Background::CreateSolidBackground(background)); |
| + WmLookup::Get() |
| + ->GetWindowForWidget(widget_for_highlighting_.get()) |
| + ->SetBoundsInScreen(window_and_bounds.second, |
| + window_and_bounds.first->GetDisplayNearestWindow()); |
|
sadrul
2016/12/06 20:48:59
Can you just SetBounds() on |widget_for_highlighti
Sarmad Hashmi
2016/12/06 22:54:34
We need to do SetBoundsInScreen so that we can han
|
| +} |
| + |
| +void AshDevToolsDOMAgent::HighlightNode( |
| + std::unique_ptr<ui::devtools::protocol::DOM::HighlightConfig> |
| + highlight_config, |
| + int node_id) { |
| + DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); |
| + if (!widget_for_highlighting_) |
| + InitializeHighlightingWidget(); |
| + |
| + WindowAndBoundsPair window_and_bounds(GetNodeWindowAndBounds(node_id)); |
| + // Invalid node id provided |
| + if (!window_and_bounds.first) |
| + return; |
| + |
| + SkColor border_color = |
| + RGBAToSkColor(highlight_config->getBorderColor(nullptr)); |
| + SkColor content_color = |
| + RGBAToSkColor(highlight_config->getContentColor(nullptr)); |
| + UpdateHighlight(window_and_bounds, content_color, border_color); |
| + |
| + if (!widget_for_highlighting_->IsVisible()) |
| + widget_for_highlighting_->Show(); |
| +} |
| + |
| +bool AshDevToolsDOMAgent::IsHighlightingWindow(WmWindow* window) { |
| + return widget_for_highlighting_ && |
| + window->GetInternalWidget() == widget_for_highlighting_.get(); |
| +} |
| + |
| } // namespace devtools |
| } // namespace ash |