summaryrefslogtreecommitdiff
path: root/chromium/ui/views/view.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ui/views/view.cc')
-rw-r--r--chromium/ui/views/view.cc55
1 files changed, 36 insertions, 19 deletions
diff --git a/chromium/ui/views/view.cc b/chromium/ui/views/view.cc
index 00b654c8e4f..186b6c5f5cd 100644
--- a/chromium/ui/views/view.cc
+++ b/chromium/ui/views/view.cc
@@ -192,6 +192,13 @@ View::~View() {
if (parent_)
parent_->RemoveChildView(this);
+ // Need to remove layout manager before deleting children because if we do not
+ // it is possible for layout-related calls (e.g. CalculatePreferredSize()) to
+ // be called on this view during one of the callbacks below. Since most
+ // layout managers access child view properties, this would result in a
+ // use-after-free error.
+ layout_manager_.reset();
+
{
internal::ScopedChildrenLock lock(this);
for (auto* child : children_) {
@@ -511,8 +518,10 @@ void View::SetVisible(bool visible) {
// Notify the parent.
if (parent_) {
parent_->ChildVisibilityChanged(this);
- parent_->NotifyAccessibilityEvent(ax::mojom::Event::kChildrenChanged,
- true);
+ if (!view_accessibility_ || !view_accessibility_->IsIgnored()) {
+ parent_->NotifyAccessibilityEvent(ax::mojom::Event::kChildrenChanged,
+ true);
+ }
}
// This notifies all sub-views recursively.
@@ -1973,7 +1982,13 @@ void View::OnFocus() {
// TODO(beng): Investigate whether it's possible for us to move this to
// Focus().
// Notify assistive technologies of the focus change.
- NotifyAccessibilityEvent(ax::mojom::Event::kFocus, true);
+ AXVirtualView* focused_virtual_child =
+ view_accessibility_ ? view_accessibility_->FocusedVirtualChild()
+ : nullptr;
+ if (focused_virtual_child)
+ focused_virtual_child->NotifyAccessibilityEvent(ax::mojom::Event::kFocus);
+ else
+ NotifyAccessibilityEvent(ax::mojom::Event::kFocus, true);
}
void View::OnBlur() {}
@@ -2288,7 +2303,7 @@ void View::AddChildViewAtImpl(View* view, int index) {
ViewHierarchyChangedDetails details(true, this, view, parent);
for (View* v = this; v; v = v->parent_)
- v->ViewHierarchyChangedImpl(false, details);
+ v->ViewHierarchyChangedImpl(details);
view->PropagateAddNotifications(details, widget && widget != old_widget);
@@ -2378,9 +2393,13 @@ void View::PropagateRemoveNotifications(View* old_parent,
}
}
+ // When a view is removed from a hierarchy, UnregisterAccelerators() is called
+ // for the removed view and all descendant views in post-order.
+ UnregisterAccelerators(true);
+
ViewHierarchyChangedDetails details(false, old_parent, this, new_parent);
for (View* v = this; v; v = v->parent_)
- v->ViewHierarchyChangedImpl(true, details);
+ v->ViewHierarchyChangedImpl(details);
if (is_removed_from_widget) {
RemovedFromWidget();
@@ -2391,12 +2410,22 @@ void View::PropagateRemoveNotifications(View* old_parent,
void View::PropagateAddNotifications(const ViewHierarchyChangedDetails& details,
bool is_added_to_widget) {
+ // When a view is added to a Widget hierarchy, RegisterPendingAccelerators()
+ // will be called for the added view and all its descendants in pre-order.
+ // This means that descendant views will register their accelerators after
+ // their parents. This allows children to override accelerators registered by
+ // their parents as accelerators registered later take priority over those
+ // registered earlier.
+ if (GetFocusManager())
+ RegisterPendingAccelerators();
+
{
internal::ScopedChildrenLock lock(this);
for (auto* child : children_)
child->PropagateAddNotifications(details, is_added_to_widget);
}
- ViewHierarchyChangedImpl(true, details);
+
+ ViewHierarchyChangedImpl(details);
if (is_added_to_widget) {
AddedToWidget();
for (ViewObserver& observer : observers_)
@@ -2414,21 +2443,9 @@ void View::PropagateNativeViewHierarchyChanged() {
}
void View::ViewHierarchyChangedImpl(
- bool register_accelerators,
const ViewHierarchyChangedDetails& details) {
- if (register_accelerators) {
- if (details.is_add) {
- // If you get this registration, you are part of a subtree that has been
- // added to the view hierarchy.
- if (GetFocusManager())
- RegisterPendingAccelerators();
- } else {
- if (details.child == this)
- UnregisterAccelerators(true);
- }
- }
-
ViewHierarchyChanged(details);
+
for (ViewObserver& observer : observers_)
observer.OnViewHierarchyChanged(this, details);