Make mac notifications less janky: group the animation together so that they slide in a group, and make the animation duration shorter.
Remove some unnecessary repositionings.

BUG=49245
TEST=notifications on mac

Review URL: http://codereview.chromium.org/3259009

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@58036 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/cocoa/notifications/balloon_controller.mm b/chrome/browser/cocoa/notifications/balloon_controller.mm
index 82a7ca1..55ee041 100644
--- a/chrome/browser/cocoa/notifications/balloon_controller.mm
+++ b/chrome/browser/cocoa/notifications/balloon_controller.mm
@@ -89,7 +89,15 @@
   [shelf_ addSubview:closeButton_];
   [self updateTrackingRect];
 
-  [self repositionToBalloon];
+  // Set the initial position without animating (the balloon should not
+  // yet be visible).
+  DCHECK(![[self window] isVisible]);
+  NSRect balloon_frame = NSMakeRect(balloon_->GetPosition().x(),
+                                    balloon_->GetPosition().y(),
+                                    [self desiredTotalWidth],
+                                    [self desiredTotalHeight]);
+  [[self window] setFrame:balloon_frame
+                  display:NO];
 }
 
 - (void)updateTrackingRect {
diff --git a/chrome/browser/cocoa/notifications/balloon_view_bridge.mm b/chrome/browser/cocoa/notifications/balloon_view_bridge.mm
index a1be94b6..7f6aa7cb 100644
--- a/chrome/browser/cocoa/notifications/balloon_view_bridge.mm
+++ b/chrome/browser/cocoa/notifications/balloon_view_bridge.mm
@@ -31,7 +31,7 @@
 
 void BalloonViewBridge::Show(Balloon* balloon) {
   controller_ = [[BalloonController alloc] initWithBalloon:balloon];
-  [controller_ repositionToBalloon];
+  [controller_ setShouldCascadeWindows:NO];
   [controller_ showWindow:nil];
 }
 
diff --git a/chrome/browser/notifications/balloon_collection.cc b/chrome/browser/notifications/balloon_collection.cc
index 3b66a07..ebbe566f 100644
--- a/chrome/browser/notifications/balloon_collection.cc
+++ b/chrome/browser/notifications/balloon_collection.cc
@@ -62,7 +62,6 @@
   if (balloons_.size() > 0)
     new_balloon->set_offset(balloons_[balloons_.size() - 1]->offset());
 #endif
-
   balloons_.push_back(new_balloon);
   PositionBalloons(false);
 
@@ -151,7 +150,7 @@
     space_change_listener_->OnBalloonSpaceChanged();
 }
 
-void BalloonCollectionImpl::PositionBalloons(bool reposition) {
+void BalloonCollectionImpl::PositionBalloonsInternal(bool reposition) {
   layout_.RefreshSystemMetrics();
   gfx::Point origin = layout_.GetLayoutOrigin();
   for (Balloons::iterator it = balloons_.begin(); it != balloons_.end(); ++it) {
diff --git a/chrome/browser/notifications/balloon_collection_impl.h b/chrome/browser/notifications/balloon_collection_impl.h
index d1307355..dc9975e 100644
--- a/chrome/browser/notifications/balloon_collection_impl.h
+++ b/chrome/browser/notifications/balloon_collection_impl.h
@@ -139,8 +139,12 @@
   int count() const { return balloons_.size(); }
 
   // Adjusts the positions of the balloons (e.g., when one is closed).
+  // Implemented by each platform for specific UI requirements.
   void PositionBalloons(bool is_reposition);
 
+  // Cross-platform internal implementation for PositionBalloons.
+  void PositionBalloonsInternal(bool is_reposition);
+
 #if defined(OS_MACOSX)
   // Get the work area on Mac OS, without inverting the coordinates.
   static gfx::Rect GetMacWorkArea();
diff --git a/chrome/browser/notifications/balloon_collection_linux.cc b/chrome/browser/notifications/balloon_collection_linux.cc
index a499292..f15c713 100644
--- a/chrome/browser/notifications/balloon_collection_linux.cc
+++ b/chrome/browser/notifications/balloon_collection_linux.cc
@@ -30,6 +30,10 @@
   return 5;
 }
 
+void BalloonCollectionImpl::PositionBalloons(bool reposition) {
+  PositionBalloonsInternal(reposition);
+}
+
 void BalloonCollectionImpl::DidProcessEvent(GdkEvent* event) {
   switch (event->type) {
     case GDK_MOTION_NOTIFY:
diff --git a/chrome/browser/notifications/balloon_collection_mac.mm b/chrome/browser/notifications/balloon_collection_mac.mm
index f4d44056..e3ac1794 100644
--- a/chrome/browser/notifications/balloon_collection_mac.mm
+++ b/chrome/browser/notifications/balloon_collection_mac.mm
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/notifications/balloon_collection_impl.h"
 
+#import <Cocoa/Cocoa.h>
+
 #include "chrome/browser/cocoa/notifications/balloon_view_bridge.h"
 
 Balloon* BalloonCollectionImpl::MakeBalloon(const Notification& notification,
@@ -33,6 +35,14 @@
   return 0;
 }
 
+void BalloonCollectionImpl::PositionBalloons(bool reposition) {
+  // Use an animation context so that all the balloons animate together.
+  [NSAnimationContext beginGrouping];
+  [[NSAnimationContext currentContext] setDuration:0.1f];
+  PositionBalloonsInternal(reposition);
+  [NSAnimationContext endGrouping];
+}
+
 // static
 BalloonCollection* BalloonCollection::Create() {
   return new BalloonCollectionImpl();
diff --git a/chrome/browser/notifications/balloon_collection_win.cc b/chrome/browser/notifications/balloon_collection_win.cc
index b5c2351..8915662 100644
--- a/chrome/browser/notifications/balloon_collection_win.cc
+++ b/chrome/browser/notifications/balloon_collection_win.cc
@@ -29,6 +29,10 @@
   return 0;
 }
 
+void BalloonCollectionImpl::PositionBalloons(bool reposition) {
+  PositionBalloonsInternal(reposition);
+}
+
 void BalloonCollectionImpl::DidProcessMessage(const MSG& msg) {
   switch (msg.message) {
     case WM_MOUSEMOVE: