| Index: chrome/browser/notifications/balloon_collection_impl.cc
|
| diff --git a/chrome/browser/notifications/balloon_collection_impl.cc b/chrome/browser/notifications/balloon_collection_impl.cc
|
| index 9d234c222aa41ebe7753061c00b7ec4f1c3bccbc..79db2a99bb509c63ab001a4a2ef1656dec12ecc4 100644
|
| --- a/chrome/browser/notifications/balloon_collection_impl.cc
|
| +++ b/chrome/browser/notifications/balloon_collection_impl.cc
|
| @@ -10,7 +10,13 @@
|
| #include "chrome/browser/notifications/balloon.h"
|
| #include "chrome/browser/notifications/balloon_host.h"
|
| #include "chrome/browser/notifications/notification.h"
|
| +#include "chrome/browser/ui/browser.h"
|
| +#include "chrome/browser/ui/panels/panel_manager.h"
|
| +#include "chrome/browser/ui/panels/panel.h"
|
| #include "chrome/browser/ui/window_sizer.h"
|
| +#include "chrome/common/chrome_notification_types.h"
|
| +#include "content/public/browser/notification_registrar.h"
|
| +#include "content/public/browser/notification_service.h"
|
| #include "ui/gfx/rect.h"
|
| #include "ui/gfx/size.h"
|
|
|
| @@ -35,6 +41,12 @@ BalloonCollectionImpl::BalloonCollectionImpl()
|
| added_as_message_loop_observer_(false)
|
| #endif
|
| {
|
| + registrar_.Add(this, chrome::NOTIFICATION_BROWSER_WINDOW_READY,
|
| + content::NotificationService::AllSources());
|
| + registrar_.Add(this, chrome::NOTIFICATION_BROWSER_CLOSED,
|
| + content::NotificationService::AllSources());
|
| + registrar_.Add(this, chrome::NOTIFICATION_PANEL_CHANGED_BOUNDS,
|
| + content::NotificationService::AllSources());
|
|
|
| SetPositionPreference(BalloonCollection::DEFAULT_POSITION);
|
| }
|
| @@ -153,6 +165,27 @@ const BalloonCollection::Balloons& BalloonCollectionImpl::GetActiveBalloons() {
|
| return base_.balloons();
|
| }
|
|
|
| +void BalloonCollectionImpl::Observe(
|
| + int type,
|
| + const content::NotificationSource& source,
|
| + const content::NotificationDetails& details) {
|
| + switch (type) {
|
| + case chrome::NOTIFICATION_BROWSER_WINDOW_READY:
|
| + case chrome::NOTIFICATION_BROWSER_CLOSED: {
|
| + Browser* browser = content::Source<Browser>(source).ptr();
|
| + if (browser->is_type_panel())
|
| + PositionBalloons(true);
|
| + break;
|
| + }
|
| + case chrome::NOTIFICATION_PANEL_CHANGED_BOUNDS:
|
| + PositionBalloons(true);
|
| + break;
|
| + default:
|
| + NOTREACHED();
|
| + break;
|
| + }
|
| +}
|
| +
|
| void BalloonCollectionImpl::PositionBalloonsInternal(bool reposition) {
|
| const Balloons& balloons = base_.balloons();
|
|
|
| @@ -231,7 +264,10 @@ void BalloonCollectionImpl::HandleMouseMoveEvent() {
|
| }
|
| #endif
|
|
|
| -BalloonCollectionImpl::Layout::Layout() : placement_(INVALID) {
|
| +BalloonCollectionImpl::Layout::Layout()
|
| + : placement_(INVALID),
|
| + bottom_left_offset_to_move_above_panels_(0),
|
| + bottom_right_offset_to_move_above_panels_(0) {
|
| RefreshSystemMetrics();
|
| }
|
|
|
| @@ -258,11 +294,17 @@ gfx::Point BalloonCollectionImpl::Layout::GetLayoutOrigin() const {
|
| break;
|
| case VERTICALLY_FROM_BOTTOM_LEFT:
|
| x = work_area_.x() + HorizontalEdgeMargin();
|
| - y = work_area_.bottom() - VerticalEdgeMargin();
|
| + // For this placement, balloon needs to stay on top of left-most panels
|
| + // to avoid overlapping.
|
| + y = work_area_.bottom() - VerticalEdgeMargin() -
|
| + bottom_left_offset_to_move_above_panels_;
|
| break;
|
| case VERTICALLY_FROM_BOTTOM_RIGHT:
|
| x = work_area_.right() - HorizontalEdgeMargin();
|
| - y = work_area_.bottom() - VerticalEdgeMargin();
|
| + // For this placement, balloon needs to stay on top of right-most panels
|
| + // to avoid overlapping.
|
| + y = work_area_.bottom() - VerticalEdgeMargin() -
|
| + bottom_right_offset_to_move_above_panels_;
|
| break;
|
| default:
|
| NOTREACHED();
|
| @@ -363,6 +405,37 @@ gfx::Size BalloonCollectionImpl::Layout::ConstrainToSizeLimits(
|
| std::min(max_balloon_height(), size.height())));
|
| }
|
|
|
| +void BalloonCollectionImpl::Layout::ComputeOffsetsToMoveAbovePanels() {
|
| + const PanelManager::Panels& panels = PanelManager::GetInstance()->panels();
|
| +
|
| + // For balloons that are aligned vertically from bottom-right corner, the
|
| + // offset is the maximum height of the right-most panels that could overlap
|
| + // with the balloons.
|
| + bottom_right_offset_to_move_above_panels_ = 0;
|
| + for (PanelManager::Panels::const_iterator iter = panels.begin();
|
| + iter != panels.end(); ++iter) {
|
| + if ((*iter)->GetBounds().right() <=
|
| + work_area_.right() - max_balloon_width())
|
| + break;
|
| + int current_height = (*iter)->GetBounds().height();
|
| + if (current_height > bottom_right_offset_to_move_above_panels_)
|
| + bottom_right_offset_to_move_above_panels_ = current_height;
|
| + }
|
| +
|
| + // For balloons that are aligned vertically from bottom-left corner, the
|
| + // offset is the maximum height of the left-most panels that could overlap
|
| + // with the balloons.
|
| + bottom_left_offset_to_move_above_panels_ = 0;
|
| + for (PanelManager::Panels::const_reverse_iterator iter = panels.rbegin();
|
| + iter != panels.rend(); ++iter) {
|
| + if ((*iter)->GetBounds().x() > work_area_.x() + max_balloon_width())
|
| + break;
|
| + int current_height = (*iter)->GetBounds().height();
|
| + if (current_height > bottom_left_offset_to_move_above_panels_)
|
| + bottom_left_offset_to_move_above_panels_ = current_height;
|
| + }
|
| +}
|
| +
|
| bool BalloonCollectionImpl::Layout::RefreshSystemMetrics() {
|
| bool changed = false;
|
|
|
| @@ -379,5 +452,7 @@ bool BalloonCollectionImpl::Layout::RefreshSystemMetrics() {
|
| changed = true;
|
| }
|
|
|
| + ComputeOffsetsToMoveAbovePanels();
|
| +
|
| return changed;
|
| }
|
|
|