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

Unified Diff: ui/views/widget/widget.cc

Issue 2651753003: Wires up ShouldDescendIntoChildForEventHandling() for DesktopNativeWidgetAura (Closed)
Patch Set: improve comments Created 3 years, 11 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 | « ui/views/widget/widget.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/views/widget/widget.cc
diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc
index 8b062753e23765729eb07cb7ac267a9ff10fe818..0008141679a270ad77cb56908a7cc1ee321ebc72 100644
--- a/ui/views/widget/widget.cc
+++ b/ui/views/widget/widget.cc
@@ -9,6 +9,7 @@
#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/trace_event/trace_event.h"
+#include "ui/aura/window.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/default_style.h"
#include "ui/base/default_theme_provider.h"
@@ -46,12 +47,12 @@ namespace {
// If |view| has a layer the layer is added to |layers|. Else this recurses
// through the children. This is used to build a list of the layers created by
// views that are direct children of the Widgets layer.
-void BuildRootLayers(View* view, std::vector<ui::Layer*>* layers) {
+void BuildViewsWithLayers(View* view, View::Views* views) {
if (view->layer()) {
- layers->push_back(view->layer());
+ views->push_back(view);
} else {
for (int i = 0; i < view->child_count(); ++i)
- BuildRootLayers(view->child_at(i), layers);
+ BuildViewsWithLayers(view->child_at(i), views);
}
}
@@ -163,10 +164,9 @@ Widget::Widget()
ignore_capture_loss_(false),
last_mouse_event_was_move_(false),
auto_release_capture_(true),
- root_layers_dirty_(false),
+ views_with_layers_dirty_(false),
movement_disabled_(false),
- observer_manager_(this) {
-}
+ observer_manager_(this) {}
Widget::~Widget() {
DestroyRootView();
@@ -914,11 +914,11 @@ void Widget::ReorderNativeViews() {
native_widget_->ReorderNativeViews();
}
-void Widget::UpdateRootLayers() {
+void Widget::LayerTreeChanged() {
// Calculate the layers requires traversing the tree, and since nearly any
// mutation of the tree can trigger this call we delay until absolutely
// necessary.
- root_layers_dirty_ = true;
+ views_with_layers_dirty_ = true;
}
const NativeWidget* Widget::native_widget() const {
@@ -1276,15 +1276,6 @@ bool Widget::ExecuteCommand(int command_id) {
return widget_delegate_->ExecuteWindowsCommand(command_id);
}
-const std::vector<ui::Layer*>& Widget::GetRootLayers() {
- if (root_layers_dirty_) {
- root_layers_dirty_ = false;
- root_layers_.clear();
- BuildRootLayers(GetRootView(), &root_layers_);
- }
- return root_layers_;
-}
-
bool Widget::HasHitTestMask() const {
return widget_delegate_->WidgetHasHitTestMask();
}
@@ -1323,6 +1314,55 @@ bool Widget::SetInitialFocus(ui::WindowShowState show_state) {
return !!focus_manager->GetFocusedView();
}
+bool Widget::ShouldDescendIntoChildForEventHandling(
+ ui::Layer* root_layer,
+ gfx::NativeView child,
+ ui::Layer* child_layer,
+ const gfx::Point& location) {
+ if (widget_delegate_ &&
+ !widget_delegate_->ShouldDescendIntoChildForEventHandling(child,
+ location)) {
+ return false;
+ }
+
+ const View::Views& views_with_layers = GetViewsWithLayers();
+ if (views_with_layers.empty())
+ return true;
+
+ // Don't descend into |child| if there is a view with a Layer that contains
+ // the point and is stacked above |child_layer|.
+ auto child_layer_iter = std::find(root_layer->children().begin(),
+ root_layer->children().end(), child_layer);
+ if (child_layer_iter == root_layer->children().end())
+ return true;
+
+ for (auto iter = views_with_layers.rbegin(); iter != views_with_layers.rend();
+ ++iter) {
+ ui::Layer* layer = (*iter)->layer();
+ DCHECK(layer);
+ if (layer->visible() && layer->bounds().Contains(location)) {
+ auto root_layer_iter = std::find(root_layer->children().begin(),
+ root_layer->children().end(), layer);
+ if (child_layer_iter > root_layer_iter) {
+ // |child| is on top of the remaining layers, no need to continue.
+ return true;
+ }
+
+ // Event targeting uses the visible bounds of the View, which may differ
+ // from the bounds of the layer. Verify the view hosting the layer
+ // actually contains |location|. Use GetVisibleBounds(), which is
+ // effectively what event targetting uses.
+ View* view = *iter;
+ gfx::Rect vis_bounds = view->GetVisibleBounds();
+ gfx::Point point_in_view = location;
+ View::ConvertPointToTarget(GetRootView(), view, &point_in_view);
+ if (vis_bounds.Contains(point_in_view))
+ return false;
+ }
+ }
+ return true;
+}
+
////////////////////////////////////////////////////////////////////////////////
// Widget, ui::EventSource implementation:
ui::EventProcessor* Widget::GetEventProcessor() {
@@ -1492,6 +1532,15 @@ bool Widget::GetSavedWindowPlacement(gfx::Rect* bounds,
return false;
}
+const View::Views& Widget::GetViewsWithLayers() {
+ if (views_with_layers_dirty_) {
+ views_with_layers_dirty_ = false;
+ views_with_layers_.clear();
+ BuildViewsWithLayers(GetRootView(), &views_with_layers_);
+ }
+ return views_with_layers_;
+}
+
namespace internal {
////////////////////////////////////////////////////////////////////////////////
« no previous file with comments | « ui/views/widget/widget.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698