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

Unified Diff: mojo/services/public/cpp/view_manager/lib/view.cc

Issue 782693004: Update mojo sdk to rev f6c8ec07c01deebc13178d516225fd12695c3dc2 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: hack mojo_system_impl gypi for android :| Created 6 years 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
Index: mojo/services/public/cpp/view_manager/lib/view.cc
diff --git a/mojo/services/public/cpp/view_manager/lib/view.cc b/mojo/services/public/cpp/view_manager/lib/view.cc
index 1ed7a62b638711fde4fdf8ea60ecc4a02b16ac94..0880958b0d7ca4c06e49e57cc67ec9395b94b7ca 100644
--- a/mojo/services/public/cpp/view_manager/lib/view.cc
+++ b/mojo/services/public/cpp/view_manager/lib/view.cc
@@ -4,10 +4,13 @@
#include "mojo/services/public/cpp/view_manager/view.h"
+#include <set>
+
#include "mojo/public/cpp/application/service_provider_impl.h"
#include "mojo/services/public/cpp/view_manager/lib/view_manager_client_impl.h"
#include "mojo/services/public/cpp/view_manager/lib/view_private.h"
#include "mojo/services/public/cpp/view_manager/view_observer.h"
+#include "mojo/services/public/cpp/view_manager/view_tracker.h"
namespace mojo {
@@ -225,7 +228,7 @@ void View::SetVisible(bool value) {
static_cast<ViewManagerClientImpl*>(manager_)->SetVisible(id_, value);
FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewVisibilityChanging(this));
visible_ = value;
- FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewVisibilityChanged(this));
+ NotifyViewVisibilityChanged(this);
}
void View::SetSharedProperty(const std::string& name,
@@ -503,4 +506,52 @@ void View::LocalSetDrawn(bool value) {
FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewDrawnChanged(this));
}
+void View::NotifyViewVisibilityChanged(View* target) {
+ if (!NotifyViewVisibilityChangedDown(target)) {
+ return; // |this| has been deleted.
+ }
+ NotifyViewVisibilityChangedUp(target);
+}
+
+bool View::NotifyViewVisibilityChangedAtReceiver(View* target) {
+ // |this| may be deleted during a call to OnViewVisibilityChanged() on one
+ // of the observers. We create an local observer for that. In that case we
+ // exit without further access to any members.
+ ViewTracker tracker;
+ tracker.Add(this);
+ FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewVisibilityChanged(target));
+ return tracker.Contains(this);
+}
+
+bool View::NotifyViewVisibilityChangedDown(View* target) {
+ if (!NotifyViewVisibilityChangedAtReceiver(target))
+ return false; // |this| was deleted.
+ std::set<const View*> child_already_processed;
+ bool child_destroyed = false;
+ do {
+ child_destroyed = false;
+ for (View::Children::const_iterator it = children_.begin();
+ it != children_.end(); ++it) {
+ if (!child_already_processed.insert(*it).second)
+ continue;
+ if (!(*it)->NotifyViewVisibilityChangedDown(target)) {
+ // |*it| was deleted, |it| is invalid and |children_| has changed. We
+ // exit the current for-loop and enter a new one.
+ child_destroyed = true;
+ break;
+ }
+ }
+ } while (child_destroyed);
+ return true;
+}
+
+void View::NotifyViewVisibilityChangedUp(View* target) {
+ // Start with the parent as we already notified |this|
+ // in NotifyViewVisibilityChangedDown.
+ for (View* view = parent(); view; view = view->parent()) {
+ bool ret = view->NotifyViewVisibilityChangedAtReceiver(target);
+ DCHECK(ret);
+ }
+}
+
} // namespace mojo

Powered by Google App Engine
This is Rietveld 408576698