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

Unified Diff: ash/system/web_notification/web_notification_tray.cc

Issue 10514008: Add WebNotificationTray (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years, 6 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
Index: ash/system/web_notification/web_notification_tray.cc
diff --git a/ash/system/web_notification/web_notification_tray.cc b/ash/system/web_notification/web_notification_tray.cc
new file mode 100644
index 0000000000000000000000000000000000000000..2029a744a06ec291db79148cd62ecdc475e9fe14
--- /dev/null
+++ b/ash/system/web_notification/web_notification_tray.cc
@@ -0,0 +1,694 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/system/web_notification/web_notification_tray.h"
+
+#include "ash/shell.h"
+#include "ash/system/status_area_widget.h"
+#include "ash/system/status_area_widget.h"
+#include "ash/system/tray/system_tray_bubble_view.h"
+#include "ash/system/tray/tray_constants.h"
+#include "ash/system/tray/tray_views.h"
+#include "grit/ash_strings.h"
+#include "grit/ui_resources.h"
+#include "grit/ui_resources_standard.h"
+#include "ui/aura/event.h"
+#include "ui/aura/window.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/models/simple_menu_model.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/views/controls/button/button.h"
+#include "ui/views/controls/button/menu_button.h"
+#include "ui/views/controls/button/menu_button_listener.h"
+#include "ui/views/controls/label.h"
+#include "ui/views/controls/menu/menu_model_adapter.h"
+#include "ui/views/controls/menu/menu_runner.h"
+#include "ui/views/layout/box_layout.h"
+#include "ui/views/layout/fill_layout.h"
+#include "ui/views/layout/grid_layout.h"
+
+namespace {
+
+const int kIconBorder = 4;
+const int kImageWidth = 40;
+const int kImageHeight = 25;
+const int kWebNotificationBubbleMinHeight = 50;
+const int kWebNotificationBubbleMaxHeight = 400;
+const int kWebNotificationWidth = 400;
+const int kWebNotificationButtonWidth = 32;
+
+const int kTogglePermissionCommand = 0;
+const int kToggleExtensionCommand = 1;
+const int kShowSettingsCommand = 2;
+
+// The image has three icons: 1 notifiaction, 2 notifications, and 3+.
+SkBitmap GetNotificationImage(int notification_count) {
+ SkBitmap image;
+ gfx::Image all = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
+ IDR_AURA_UBER_TRAY_WEB_NOTIFICATON);
+
+ int image_index = notification_count - 1;
+ image_index = std::max(0, std::min(image_index, 2));
+
+ SkIRect region = SkIRect::MakeXYWH(
+ 0, image_index * kImageHeight, kImageWidth, kImageHeight);
+ all.ToSkBitmap()->extractSubset(&image, region);
+ return image;
+}
+
+} // namespace
+
+namespace ash {
+
+namespace internal {
+
+struct WebNotification {
+ WebNotification(const std::string& i,
+ const string16& t,
+ const string16& m,
+ const string16& s,
+ const std::string& e)
+ : id(i),
+ title(t),
+ message(m),
+ display_source(s),
+ extension_id(e) {
+ }
+
+ std::string id;
+ string16 title;
+ string16 message;
+ string16 display_source;
+ std::string extension_id;
+ SkBitmap image;
+};
+
+// A helper class to manage the list of notifications.
+class WebNotificationList {
+ public:
+ typedef std::list<WebNotification> Notifications;
+
+ WebNotificationList() {
+ }
+
+ void AddNotification(const std::string& id,
+ const string16& title,
+ const string16& message,
+ const string16& source,
+ const std::string& extension) {
+ Notifications::iterator iter = GetNotification(id);
+ if (iter != notifications_.end()) {
+ iter->title = title;
+ iter->message = message;
+ iter->display_source = source;
+ iter->extension_id = extension;
+ } else {
+ notifications_.push_back(
+ WebNotification(id, title, message, source, extension));
+ }
+ }
+
+ bool RemoveNotification(const std::string& id) {
+ Notifications::iterator iter = GetNotification(id);
+ if (iter == notifications_.end())
+ return false;
+ notifications_.erase(iter);
+ return true;
+ }
+
+ void RemoveNotificationsBySource(const std::string& id) {
+ Notifications::iterator source_iter = GetNotification(id);
+ if (source_iter == notifications_.end())
+ return;
+ string16 display_source = source_iter->display_source;
+ for (Notifications::iterator loopiter = notifications_.begin();
+ loopiter != notifications_.end(); ) {
+ Notifications::iterator curiter = loopiter++;
+ if (curiter->display_source == display_source)
+ notifications_.erase(curiter);
+ }
+ }
+
+ void RemoveNotificationsByExtension(const std::string& id) {
+ Notifications::iterator source_iter = GetNotification(id);
+ if (source_iter == notifications_.end())
+ return;
+ std::string extension_id = source_iter->extension_id;
+ for (Notifications::iterator loopiter = notifications_.begin();
+ loopiter != notifications_.end(); ) {
+ Notifications::iterator curiter = loopiter++;
+ if (curiter->extension_id == extension_id)
+ notifications_.erase(curiter);
+ }
+ }
+
+ bool SetNotificationImage(const std::string& id,
+ const SkBitmap& image) {
+ Notifications::iterator iter = GetNotification(id);
+ if (iter == notifications_.end())
+ return false;
+ iter->image = image;
+ return true;
+ }
+
+ const Notifications& notifications() const { return notifications_; }
+
+ private:
+ Notifications::iterator GetNotification(const std::string& id) {
+ for (Notifications::iterator iter = notifications_.begin();
+ iter != notifications_.end(); ++iter) {
+ if (iter->id == id)
+ return iter;
+ }
+ return notifications_.end();
+ }
+
+ Notifications notifications_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebNotificationList);
+};
+
+// A simple view for the text (title and message) of a notification.
+class WebNotificationMessageView : public views::View {
+ public:
+ explicit WebNotificationMessageView(const WebNotification& notification) {
+ views::Label* title = new views::Label(notification.title);
+ title->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+ title->SetFont(title->font().DeriveFont(0, gfx::Font::BOLD));
+ views::Label* message = new views::Label(notification.message);
+ message->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+ message->SetMultiLine(true);
+
+ SetLayoutManager(
+ new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1));
+ AddChildView(title);
+ AddChildView(message);
+ }
+
+ virtual ~WebNotificationMessageView() {
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(WebNotificationMessageView);
+};
+
+// A dropdown menu for notifications.
+class WebNotificationMenuModel : public ui::SimpleMenuModel,
+ public ui::SimpleMenuModel::Delegate {
+ public:
+ explicit WebNotificationMenuModel(WebNotificationTray* tray,
+ const WebNotification& notification)
+ : ALLOW_THIS_IN_INITIALIZER_LIST(ui::SimpleMenuModel(this)),
+ tray_(tray),
+ notification_(notification) {
+ // Add 'disable notifications' menu item.
+ if (!notification.extension_id.empty()) {
+ AddItem(kToggleExtensionCommand,
+ GetLabelForCommandId(kToggleExtensionCommand));
+ } else if (!notification.display_source.empty()) {
+ AddItem(kTogglePermissionCommand,
+ GetLabelForCommandId(kTogglePermissionCommand));
+ }
+ // Add settings menu item.
+ if (!notification.display_source.empty()) {
+ AddItem(kShowSettingsCommand,
+ GetLabelForCommandId(kShowSettingsCommand));
+ }
+ }
+
+ virtual ~WebNotificationMenuModel() {
+ }
+
+ // Overridden from ui::SimpleMenuModel:
+ virtual string16 GetLabelForCommandId(int command_id) const OVERRIDE {
+ switch (command_id) {
+ case kToggleExtensionCommand:
+ return l10n_util::GetStringUTF16(
+ IDS_ASH_WEB_NOTFICATION_TRAY_EXTENSIONS_DISABLE);
+ case kTogglePermissionCommand:
+ return l10n_util::GetStringFUTF16(
+ IDS_ASH_WEB_NOTFICATION_TRAY_SITE_DISABLE,
+ notification_.display_source);
+ case kShowSettingsCommand:
+ return l10n_util::GetStringUTF16(
+ IDS_ASH_WEB_NOTFICATION_TRAY_SETTINGS);
+ default:
+ NOTREACHED();
+ }
+ return string16();
+ }
+
+ // Overridden from ui::SimpleMenuModel::Delegate:
+ virtual bool IsCommandIdChecked(int command_id) const OVERRIDE {
+ return false;
+ }
+
+ virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE {
+ return true;
+ }
+
+ virtual bool GetAcceleratorForCommandId(
+ int command_id,
+ ui::Accelerator* accelerator) OVERRIDE {
+ return false;
+ }
+
+ virtual void ExecuteCommand(int command_id) OVERRIDE {
+ switch (command_id) {
+ case kToggleExtensionCommand:
+ tray_->DisableByExtension(notification_.id);
+ break;
+ case kTogglePermissionCommand:
+ tray_->DisableByUrl(notification_.id);
+ break;
+ case kShowSettingsCommand:
+ tray_->ShowSettings(notification_.id);
+ break;
+ default:
+ NOTREACHED();
+ }
+ }
+
+ private:
+ WebNotificationTray* tray_;
+ WebNotification notification_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebNotificationMenuModel);
+};
+
+// The view for a notification entry (icon + message + buttons).
+class WebNotificationView : public views::View,
+ public views::ButtonListener,
+ public views::MenuButtonListener {
+ public:
+ WebNotificationView(WebNotificationTray* tray,
+ const WebNotification& notification)
+ : tray_(tray),
+ notification_(notification),
+ icon_(NULL),
+ menu_button_(NULL),
+ close_button_(NULL) {
+ InitView(tray, notification);
+ }
+
+ virtual ~WebNotificationView() {
+ }
+
+ void InitView(WebNotificationTray* tray,
+ const WebNotification& notification) {
+ set_border(views::Border::CreateSolidSidedBorder(
+ 1, 0, 0, 0, kBorderLightColor));
+ set_background(views::Background::CreateSolidBackground(kBackgroundColor));
+
+ icon_ = new views::ImageView;
+ icon_->SetImage(notification.image);
+
+ WebNotificationMessageView* message_view
+ = new WebNotificationMessageView(notification);
+
+ close_button_ = new views::ImageButton(this);
+ close_button_->SetImage(
+ views::CustomButton::BS_NORMAL,
+ ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
+ IDR_AURA_WINDOW_CLOSE));
+
+ menu_button_ = new views::MenuButton(NULL, string16(), this, true);
+ menu_button_->set_border(NULL);
+
+ views::GridLayout* layout = new views::GridLayout(this);
+ SetLayoutManager(layout);
+
+ views::ColumnSet* columns = layout->AddColumnSet(0);
+
+ columns->AddPaddingColumn(0, kTrayPopupPaddingHorizontal/2);
+
+ // Notification Icon.
+ columns->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER,
+ 0, /* resize percent */
+ views::GridLayout::FIXED,
+ kNotificationIconWidth, kNotificationIconWidth);
+
+ columns->AddPaddingColumn(0, kTrayPopupPaddingHorizontal/2);
+
+ // Notification message text.
+ columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL,
+ 100, /* resize percent */
+ views::GridLayout::USE_PREF, 0, 0);
+
+ columns->AddPaddingColumn(0, kTrayPopupPaddingHorizontal/2);
+
+ // Close and menu buttons.
+ columns->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER,
+ 0, /* resize percent */
+ views::GridLayout::FIXED,
+ kWebNotificationButtonWidth,
+ kWebNotificationButtonWidth);
+
+ columns->AddPaddingColumn(0, kTrayPopupPaddingHorizontal/2);
+
+ // Layout rows
+ layout->AddPaddingRow(0, kTrayPopupPaddingBetweenItems);
+
+ layout->StartRow(0, 0);
+ layout->AddView(icon_, 1, 2);
+ layout->AddView(message_view, 1, 2);
+ layout->AddView(close_button_);
+
+ layout->StartRow(0, 0);
+ layout->SkipColumns(4);
+ layout->AddView(menu_button_);
+
+ layout->AddPaddingRow(0, kTrayPopupPaddingBetweenItems);
+ }
+
+ // Overridden from ButtonListener.
+ virtual void ButtonPressed(views::Button* sender,
+ const views::Event& event) OVERRIDE {
+ if (sender == close_button_)
+ tray_->RemoveNotification(notification_.id);
+ }
+
+ // Overridden from MenuButtonListener.
+ virtual void OnMenuButtonClicked(View* source, const gfx::Point& point) {
+ if (source != menu_button_)
+ return;
+ WebNotificationMenuModel menu_model(tray_, notification_);
+ views::MenuModelAdapter menu_model_adapter(&menu_model);
+ views::MenuRunner menu_runner(menu_model_adapter.CreateMenu());
+
+ gfx::Point screen_location;
+ views::View::ConvertPointToScreen(menu_button_, &screen_location);
+ ignore_result(menu_runner.RunMenuAt(
+ source->GetWidget()->GetTopLevelWidget(),
+ menu_button_,
+ gfx::Rect(screen_location, menu_button_->size()),
+ views::MenuItemView::TOPRIGHT,
+ views::MenuRunner::HAS_MNEMONICS));
+ }
+
+
+ private:
+ WebNotificationTray* tray_;
+ WebNotification notification_;
+ views::ImageView* icon_;
+ views::MenuButton* menu_button_;
+ views::ImageButton* close_button_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebNotificationView);
+};
+
+} // namespace internal
+
+using internal::WebNotificationList;
+using internal::WebNotificationView;
+
+class WebNotificationTray::BubbleContentsView : public views::View {
+ public:
+ explicit BubbleContentsView(WebNotificationTray* tray)
+ : tray_(tray) {
+ SetLayoutManager(new views::FillLayout);
+ set_background(views::Background::CreateSolidBackground(kBackgroundColor));
+
+ scroll_content_ = new views::View;
+ scroll_content_->SetLayoutManager(
+ new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1));
+ scroller_ = new internal::FixedSizedScrollView;
+ scroller_->SetContentsView(scroll_content_);
+
+ AddChildView(scroller_);
+ }
+
+ void Update(const WebNotificationList::Notifications& notifications) {
+ scroll_content_->RemoveAllChildViews(true);
+ for (WebNotificationList::Notifications::const_iterator iter =
+ notifications.begin(); iter != notifications.end(); ++iter) {
+ WebNotificationView* view = new WebNotificationView(tray_, *iter);
+ scroll_content_->AddChildView(view);
+ }
+ scroller_->Layout();
+ SizeToPreferredSize();
+ Layout();
+ PreferredSizeChanged();
+ SchedulePaint();
+ }
+
+ // views::View overrides.
+ virtual gfx::Size GetPreferredSize() {
+ gfx::Size preferred_size = scroll_content_->GetPreferredSize();
+ int height = std::min(
+ std::max(preferred_size.height(), kWebNotificationBubbleMinHeight),
+ kWebNotificationBubbleMaxHeight);
+ preferred_size.set_height(height);
+ return preferred_size;
+ }
+
+ private:
+ WebNotificationTray* tray_;
+ internal::FixedSizedScrollView* scroller_;
+ views::View* scroll_content_;
+
+ DISALLOW_COPY_AND_ASSIGN(BubbleContentsView);
+};
+
+class WebNotificationTray::Bubble
+ : public internal::SystemTrayBubbleView::Host {
+ public:
+ explicit Bubble(WebNotificationTray* tray) : tray_(tray),
+ bubble_view_(NULL),
+ bubble_widget_(NULL),
+ contents_view_(NULL) {
+ views::View* anchor = tray->tray_container();
+ views::BubbleBorder::ArrowLocation arrow_location;
+ int arrow_offset = 0;
+ if (tray_->shelf_alignment() == SHELF_ALIGNMENT_BOTTOM) {
+ arrow_location = views::BubbleBorder::BOTTOM_RIGHT;
+ arrow_offset = anchor->GetContentsBounds().width() / 2;
+ } else if (tray_->shelf_alignment() == SHELF_ALIGNMENT_LEFT) {
+ arrow_location = views::BubbleBorder::LEFT_BOTTOM;
+ } else {
+ arrow_location = views::BubbleBorder::RIGHT_BOTTOM;
+ }
+ bubble_view_ = new internal::SystemTrayBubbleView(
+ anchor, arrow_location, this, false);
+ bubble_view_->SetMaxHeight(kWebNotificationBubbleMaxHeight);
+ bubble_view_->set_bubble_width(kWebNotificationWidth);
+
+ bubble_widget_ = views::BubbleDelegateView::CreateBubble(bubble_view_);
+
+ bubble_view_->SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE);
+ bubble_widget_->non_client_view()->frame_view()->set_background(NULL);
+ bubble_view_->SetBubbleBorder(arrow_offset);
+
+ contents_view_ = new BubbleContentsView(tray);
+ bubble_view_->AddChildView(contents_view_);
+
+ Update();
+ bubble_view_->Show();
+ }
+
+ virtual ~Bubble() {
+ if (bubble_view_)
+ bubble_view_->reset_host();
+ if (bubble_widget_)
+ bubble_widget_->Close();
+ }
+
+ // Overridden from SystemTrayBubbleView::Host.
+ virtual void BubbleViewDestroyed() OVERRIDE {
+ }
+
+ virtual gfx::Rect GetAnchorRect() const OVERRIDE {
+ gfx::Rect anchor_rect = tray_->tray_container()->GetScreenBounds();
+ return anchor_rect;
+ }
+
+ virtual void OnMouseEnteredView() OVERRIDE {
+ }
+
+ virtual void OnMouseExitedView() OVERRIDE {
+ }
+
+ void Update() {
+ contents_view_->Update(tray_->notification_list()->notifications());
+ bubble_view_->Layout();
+ bubble_view_->SchedulePaint();
+ }
+
+ views::Widget* bubble_widget() const { return bubble_widget_; }
+
+ private:
+ WebNotificationTray* tray_;
+ internal::SystemTrayBubbleView* bubble_view_;
+ views::Widget* bubble_widget_;
+ BubbleContentsView* contents_view_;
+};
+
+WebNotificationTray::WebNotificationTray(
+ internal::StatusAreaWidget* status_area_widget)
+ : status_area_widget_(status_area_widget),
+ notification_list_(new WebNotificationList()),
+ tray_container_(NULL),
+ icon_(NULL),
+ delegate_(NULL) {
+ tray_container_ = new views::View;
+ tray_container_->set_border(views::Border::CreateEmptyBorder(
+ kIconBorder, kIconBorder, kIconBorder, kIconBorder));
+ SetShelfAlignment(shelf_alignment());
+
+ icon_ = new views::ImageView;
+ tray_container_->AddChildView(icon_);
+ UpdateIcon(); // Hides the tray initially.
+
+ SetContents(tray_container_);
+
+ Shell::GetInstance()->AddEnvEventFilter(this);
+}
+
+WebNotificationTray::~WebNotificationTray() {
+ Shell::GetInstance()->RemoveEnvEventFilter(this);
+}
+
+void WebNotificationTray::SetDelegate(Delegate* delegate) {
+ DCHECK(!delegate_);
+ delegate_ = delegate;
+}
+
+void WebNotificationTray::AddNotification(const std::string& id,
+ const string16& title,
+ const string16& message,
+ const string16& source,
+ const std::string& extension) {
+ notification_list_->AddNotification(id, title, message, source, extension);
+ UpdateIcon();
+ if (bubble()) {
+ bubble_->Update();
+ } else {
+ status_area_widget_->ShowWebNotificationBubble(
+ internal::StatusAreaWidget::NON_USER_ACTION);
+ }
+}
+
+void WebNotificationTray::RemoveNotification(const std::string& id) {
+ if (!notification_list_->RemoveNotification(id))
+ return;
+ if (delegate_)
+ delegate_->NotificationRemoved(id);
+ UpdateBubbleAndIcon();
+}
+
+void WebNotificationTray::SetNotificationImage(const std::string& id,
+ const SkBitmap& image) {
+ if (!notification_list_->SetNotificationImage(id, image))
+ return;
+ if (bubble())
+ bubble_->Update();
+}
+
+void WebNotificationTray::DisableByExtension(const std::string& id) {
+ notification_list_->RemoveNotificationsByExtension(id);
+ UpdateBubbleAndIcon();
+ if (delegate_)
+ delegate_->DisableExtension(id);
+}
+
+void WebNotificationTray::DisableByUrl(const std::string& id) {
+ notification_list_->RemoveNotificationsBySource(id);
+ UpdateBubbleAndIcon();
+ if (delegate_)
+ delegate_->DisableNotificationsFromSource(id);
+}
+
+void WebNotificationTray::ShowBubble() {
+ if (bubble())
+ return;
+ bubble_.reset(new Bubble(this));
+}
+
+void WebNotificationTray::HideBubble() {
+ bubble_.reset();
+}
+
+void WebNotificationTray::ShowSettings(const std::string& id) {
+ if (delegate_)
+ delegate_->ShowSettings(id);
+}
+
+bool WebNotificationTray::PreHandleKeyEvent(aura::Window* target,
+ aura::KeyEvent* event) {
+ return false;
+}
+
+bool WebNotificationTray::PreHandleMouseEvent(aura::Window* target,
+ aura::MouseEvent* event) {
+ if (event->type() == ui::ET_MOUSE_PRESSED)
+ ProcessLocatedEvent(*event);
+ return false;
+}
+
+ui::TouchStatus WebNotificationTray::PreHandleTouchEvent(aura::Window* target,
+ aura::TouchEvent* event) {
+ if (event->type() == ui::ET_TOUCH_PRESSED)
+ ProcessLocatedEvent(*event);
+ return ui::TOUCH_STATUS_UNKNOWN;
+}
+
+ui::GestureStatus WebNotificationTray::PreHandleGestureEvent(
+ aura::Window* target,
+ aura::GestureEvent* event) {
+ return ui::GESTURE_STATUS_UNKNOWN;
+}
+
+void WebNotificationTray::SetShelfAlignment(ShelfAlignment alignment) {
+ internal::TrayBackgroundView::SetShelfAlignment(alignment);
+ tray_container_->SetLayoutManager(new views::BoxLayout(
+ alignment == SHELF_ALIGNMENT_BOTTOM ?
+ views::BoxLayout::kHorizontal : views::BoxLayout::kVertical,
+ 0, 0, 0));
+}
+
+bool WebNotificationTray::PerformAction(const views::Event& event) {
+ if (bubble()) {
+ status_area_widget_->HideWebNotificationBubble();
+ } else {
+ status_area_widget_->ShowWebNotificationBubble(
+ internal::StatusAreaWidget::USER_ACTION);
+ }
+ return true;
+}
+
+int WebNotificationTray::GetNotificationCount() const {
+ return notification_list()->notifications().size();
+}
+
+void WebNotificationTray::UpdateIcon() {
+ int count = GetNotificationCount();
+ if (count == 0) {
+ SetVisible(false);
+ } else {
+ icon_->SetImage(GetNotificationImage(count));
+ SetVisible(true);
+ }
+ PreferredSizeChanged();
+}
+
+void WebNotificationTray::UpdateBubbleAndIcon() {
+ UpdateIcon();
+ if (!bubble())
+ return;
+ if (GetNotificationCount() == 0)
+ status_area_widget_->HideWebNotificationBubble();
+ else
+ bubble_->Update();
+}
+
+void WebNotificationTray::ProcessLocatedEvent(const aura::LocatedEvent& event) {
+ if (!bubble())
+ return;
+ gfx::Rect bounds =
+ bubble_->bubble_widget()->GetNativeWindow()->GetBoundsInRootWindow();
+ if (!bounds.Contains(event.root_location()))
+ status_area_widget_->HideWebNotificationBubble();
+}
+
+} // namespace ash
« no previous file with comments | « ash/system/web_notification/web_notification_tray.h ('k') | ash/system/web_notification/web_notification_tray_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698