summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/app/chromium_strings.grd17
-rw-r--r--chrome/app/generated_resources.grd11
-rw-r--r--chrome/app/google_chrome_strings.grd17
-rw-r--r--chrome/browser/background/background_mode_manager.cc15
-rw-r--r--chrome/browser/extensions/api/system_indicator/system_indicator_manager.cc86
-rw-r--r--chrome/browser/media/media_stream_capture_indicator.cc35
-rw-r--r--chrome/browser/media/media_stream_capture_indicator.h9
-rw-r--r--chrome/browser/status_icons/status_icon.cc3
-rw-r--r--chrome/browser/status_icons/status_icon.h11
-rw-r--r--chrome/browser/status_icons/status_tray.cc6
-rw-r--r--chrome/browser/status_icons/status_tray.h13
-rw-r--r--chrome/browser/status_icons/status_tray_unittest.cc30
-rw-r--r--chrome/browser/ui/cocoa/notifications/message_center_tray_bridge.mm5
-rw-r--r--chrome/browser/ui/cocoa/status_icons/status_tray_mac.h5
-rw-r--r--chrome/browser/ui/cocoa/status_icons/status_tray_mac.mm9
-rw-r--r--chrome/browser/ui/gtk/status_icons/status_tray_gtk.cc9
-rw-r--r--chrome/browser/ui/gtk/status_icons/status_tray_gtk.h5
-rw-r--r--chrome/browser/ui/gtk/status_icons/status_tray_gtk_unittest.cc12
-rw-r--r--chrome/browser/ui/libgtk2ui/app_indicator_icon.cc123
-rw-r--r--chrome/browser/ui/libgtk2ui/app_indicator_icon.h10
-rw-r--r--chrome/browser/ui/libgtk2ui/gtk2_ui.cc8
-rw-r--r--chrome/browser/ui/libgtk2ui/gtk2_ui.h4
-rw-r--r--chrome/browser/ui/views/message_center/web_notification_tray.cc40
-rw-r--r--chrome/browser/ui/views/message_center/web_notification_tray.h2
-rw-r--r--chrome/browser/ui/views/message_center/web_notification_tray_win.cc9
-rw-r--r--chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.cc15
-rw-r--r--chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.h6
-rw-r--r--chrome/browser/ui/views/status_icons/status_tray_linux.cc7
-rw-r--r--chrome/browser/ui/views/status_icons/status_tray_linux.h5
-rw-r--r--chrome/browser/ui/views/status_icons/status_tray_win.cc14
-rw-r--r--chrome/browser/ui/views/status_icons/status_tray_win.h5
-rw-r--r--chrome/browser/ui/views/status_icons/status_tray_win_unittest.cc20
-rw-r--r--ui/base/strings/ui_strings.grd6
-rw-r--r--ui/linux_ui/OWNERS1
-rw-r--r--ui/linux_ui/linux_ui.h4
-rw-r--r--ui/linux_ui/status_icon_linux.h2
36 files changed, 346 insertions, 233 deletions
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd
index 4416ca6..4668d4b 100644
--- a/chrome/app/chromium_strings.grd
+++ b/chrome/app/chromium_strings.grd
@@ -1005,6 +1005,23 @@ Signing in anyway will merge Chromium information like bookmarks, history, and o
You can see all your notifications from Chromium apps, extensions, and websites here.
</message>
</if>
+ <message name="IDS_MESSAGE_CENTER_TOOLTIP" desc="Tooltip for notification tray icon without unread notifications">
+ Chromium - Notifications
+ </message>
+ <message name="IDS_MESSAGE_CENTER_TOOLTIP_UNREAD" desc="Tooltip for notification tray icon with unread notifications">
+ Chromium - Notifications (<ph name="QUANTITY">$1<ex>3</ex></ph> unread)
+ </message>
+
+ <!-- MediaStream capture status tray icon -->
+ <message name="IDS_MEDIA_STREAM_STATUS_TRAY_TEXT_AUDIO_AND_VIDEO" desc="Tool tip for the capture status tray icon when microphone and camera are being used">
+ Chromium is using your camera and microphone.
+ </message>
+ <message name="IDS_MEDIA_STREAM_STATUS_TRAY_TEXT_AUDIO_ONLY" desc="Tool tip for the capture status tray icon when microphone is being used">
+ Chromium is using your microphone.
+ </message>
+ <message name="IDS_MEDIA_STREAM_STATUS_TRAY_TEXT_VIDEO_ONLY" desc="Tool tip for the capture status tray icon when camera is being used">
+ Chromium is using your camera.
+ </message>
</messages>
</release>
</grit>
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index d12eb0d..bb002dd 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -15094,17 +15094,6 @@ Some features may be unavailable. Please check that the profile exists and you
Deny
</message>
- <!-- MediaStream capture status tray icon -->
- <message name="IDS_MEDIA_STREAM_STATUS_TRAY_TEXT_AUDIO_AND_VIDEO" desc="Tool tip for the capture status tray icon when microphone and camera are being used">
- <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> is using your camera and microphone.
- </message>
- <message name="IDS_MEDIA_STREAM_STATUS_TRAY_TEXT_AUDIO_ONLY" desc="Tool tip for the capture status tray icon when microphone is being used">
- <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> is using your microphone.
- </message>
- <message name="IDS_MEDIA_STREAM_STATUS_TRAY_TEXT_VIDEO_ONLY" desc="Tool tip for the capture status tray icon when camera is being used">
- <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> is using your camera.
- </message>
-
<!-- Quota messages -->
<if expr="is_android">
<message name="IDS_REQUEST_QUOTA_INFOBAR_QUESTION" desc="Mobile: For Android device. Question asked on the info bar whenever webapp requests new (larger) quota to persistently store data on the device (e.g. for persistent-type filesystem).">
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd
index b9db382..6824d4c 100644
--- a/chrome/app/google_chrome_strings.grd
+++ b/chrome/app/google_chrome_strings.grd
@@ -930,6 +930,23 @@ Signing in anyway will merge Chrome information like bookmarks, history, and oth
You can see all your notifications from Chrome apps, extensions, and websites here.
</message>
</if>
+ <message name="IDS_MESSAGE_CENTER_TOOLTIP" desc="Tooltip for notification tray icon without unread notifications">
+ Chrome - Notifications
+ </message>
+ <message name="IDS_MESSAGE_CENTER_TOOLTIP_UNREAD" desc="Tooltip for notification tray icon with unread notifications">
+ Chrome - Notifications (<ph name="QUANTITY">$1<ex>3</ex></ph> unread)
+ </message>
+
+ <!-- MediaStream capture status tray icon -->
+ <message name="IDS_MEDIA_STREAM_STATUS_TRAY_TEXT_AUDIO_AND_VIDEO" desc="Tool tip for the capture status tray icon when microphone and camera are being used">
+ Google Chrome is using your camera and microphone.
+ </message>
+ <message name="IDS_MEDIA_STREAM_STATUS_TRAY_TEXT_AUDIO_ONLY" desc="Tool tip for the capture status tray icon when microphone is being used">
+ Google Chrome is using your microphone.
+ </message>
+ <message name="IDS_MEDIA_STREAM_STATUS_TRAY_TEXT_VIDEO_ONLY" desc="Tool tip for the capture status tray icon when camera is being used">
+ Google Chrome is using your camera.
+ </message>
</messages>
</release>
</grit>
diff --git a/chrome/browser/background/background_mode_manager.cc b/chrome/browser/background/background_mode_manager.cc
index b925aba..579f031 100644
--- a/chrome/browser/background/background_mode_manager.cc
+++ b/chrome/browser/background/background_mode_manager.cc
@@ -665,17 +665,16 @@ void BackgroundModeManager::CreateStatusTrayIcon() {
if (!status_tray_ || status_icon_)
return;
- status_icon_ =
- status_tray_->CreateStatusIcon(StatusTray::BACKGROUND_MODE_ICON);
- if (!status_icon_)
- return;
-
- // Set the image and add ourselves as a click observer on it.
// TODO(rlp): Status tray icon should have submenus for each profile.
gfx::ImageSkia* image_skia = ui::ResourceBundle::GetSharedInstance().
GetImageSkiaNamed(IDR_STATUS_TRAY_ICON);
- status_icon_->SetImage(*image_skia);
- status_icon_->SetToolTip(l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
+
+ status_icon_ = status_tray_->CreateStatusIcon(
+ StatusTray::BACKGROUND_MODE_ICON,
+ *image_skia,
+ l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
+ if (!status_icon_)
+ return;
UpdateStatusTrayIconContextMenu();
}
diff --git a/chrome/browser/extensions/api/system_indicator/system_indicator_manager.cc b/chrome/browser/extensions/api/system_indicator/system_indicator_manager.cc
index 4297abe..a7601f0 100644
--- a/chrome/browser/extensions/api/system_indicator/system_indicator_manager.cc
+++ b/chrome/browser/extensions/api/system_indicator/system_indicator_manager.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/extensions/api/system_indicator/system_indicator_manager.h"
#include "base/memory/linked_ptr.h"
+#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/event_names.h"
#include "chrome/browser/extensions/event_router.h"
@@ -30,11 +31,10 @@ namespace extensions {
class ExtensionIndicatorIcon : public StatusIconObserver,
public ExtensionActionIconFactory::Observer {
public:
- ExtensionIndicatorIcon(const Extension* extension,
- const ExtensionAction* action,
- Profile* profile,
- StatusTray* status_tray,
- StatusIcon* status_icon);
+ static ExtensionIndicatorIcon* Create(const Extension* extension,
+ const ExtensionAction* action,
+ Profile* profile,
+ StatusTray* status_tray);
virtual ~ExtensionIndicatorIcon();
// StatusIconObserver implementation.
@@ -44,6 +44,11 @@ class ExtensionIndicatorIcon : public StatusIconObserver,
virtual void OnIconUpdated() OVERRIDE;
private:
+ ExtensionIndicatorIcon(const Extension* extension,
+ const ExtensionAction* action,
+ Profile* profile,
+ StatusTray* status_tray);
+
const extensions::Extension* extension_;
StatusTray* status_tray_;
StatusIcon* icon_;
@@ -51,23 +56,27 @@ class ExtensionIndicatorIcon : public StatusIconObserver,
ExtensionActionIconFactory icon_factory_;
};
-ExtensionIndicatorIcon::ExtensionIndicatorIcon(const Extension* extension,
- const ExtensionAction* action,
- Profile* profile,
- StatusTray* status_tray,
- StatusIcon* status_icon)
- : extension_(extension),
- status_tray_(status_tray),
- icon_(status_icon),
- profile_(profile),
- icon_factory_(profile, extension, action, this) {
- icon_->AddObserver(this);
- OnIconUpdated();
+ExtensionIndicatorIcon* ExtensionIndicatorIcon::Create(
+ const Extension* extension,
+ const ExtensionAction* action,
+ Profile* profile,
+ StatusTray* status_tray) {
+ scoped_ptr<ExtensionIndicatorIcon> extension_icon(
+ new ExtensionIndicatorIcon(extension, action, profile, status_tray));
+
+ // Check if a status icon was successfully created.
+ if (extension_icon->icon_)
+ return extension_icon.release();
+
+ // We could not create a status icon.
+ return NULL;
}
ExtensionIndicatorIcon::~ExtensionIndicatorIcon() {
- icon_->RemoveObserver(this);
- status_tray_->RemoveStatusIcon(icon_);
+ if (icon_) {
+ icon_->RemoveObserver(this);
+ status_tray_->RemoveStatusIcon(icon_);
+ }
}
void ExtensionIndicatorIcon::OnStatusIconClicked() {
@@ -89,10 +98,30 @@ void ExtensionIndicatorIcon::OnIconUpdated() {
icon_factory_.GetIcon(ExtensionAction::kDefaultTabId).AsImageSkia());
}
+ExtensionIndicatorIcon::ExtensionIndicatorIcon(const Extension* extension,
+ const ExtensionAction* action,
+ Profile* profile,
+ StatusTray* status_tray)
+ : extension_(extension),
+ status_tray_(status_tray),
+ icon_(NULL),
+ profile_(profile),
+ icon_factory_(profile, extension, action, this) {
+ // Get the icon image and tool tip for the status icon. The extension name is
+ // used as the tool tip.
+ gfx::ImageSkia icon_image =
+ icon_factory_.GetIcon(ExtensionAction::kDefaultTabId).AsImageSkia();
+ string16 tool_tip = UTF8ToUTF16(extension_->name());
+
+ icon_ = status_tray_->CreateStatusIcon(
+ StatusTray::OTHER_ICON, icon_image, tool_tip);
+ if (icon_)
+ icon_->AddObserver(this);
+}
+
SystemIndicatorManager::SystemIndicatorManager(Profile* profile,
StatusTray* status_tray)
- : profile_(profile),
- status_tray_(status_tray) {
+ : profile_(profile), status_tray_(status_tray) {
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
content::Source<Profile>(profile_->GetOriginalProfile()));
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_SYSTEM_INDICATOR_UPDATED,
@@ -167,17 +196,10 @@ void SystemIndicatorManager::CreateOrUpdateIndicator(
return;
}
- StatusIcon* indicator_icon =
- status_tray_->CreateStatusIcon(StatusTray::OTHER_ICON);
- if (indicator_icon != NULL) {
- ExtensionIndicatorIcon* status_icon = new ExtensionIndicatorIcon(
- extension,
- extension_action,
- profile_,
- status_tray_,
- indicator_icon);
- system_indicators_[extension->id()] = make_linked_ptr(status_icon);
- }
+ ExtensionIndicatorIcon* extension_icon = ExtensionIndicatorIcon::Create(
+ extension, extension_action, profile_, status_tray_);
+ if (extension_icon)
+ system_indicators_[extension->id()] = make_linked_ptr(extension_icon);
}
void SystemIndicatorManager::RemoveIndicator(const std::string& extension_id) {
diff --git a/chrome/browser/media/media_stream_capture_indicator.cc b/chrome/browser/media/media_stream_capture_indicator.cc
index 456fc9d..50e4ea7 100644
--- a/chrome/browser/media/media_stream_capture_indicator.cc
+++ b/chrome/browser/media/media_stream_capture_indicator.cc
@@ -366,7 +366,8 @@ void MediaStreamCaptureIndicator::UnregisterWebContents(
UpdateNotificationUserInterface();
}
-void MediaStreamCaptureIndicator::MaybeCreateStatusTrayIcon() {
+void MediaStreamCaptureIndicator::MaybeCreateStatusTrayIcon(bool audio,
+ bool video) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (status_icon_)
return;
@@ -379,10 +380,16 @@ void MediaStreamCaptureIndicator::MaybeCreateStatusTrayIcon() {
if (!status_tray)
return;
- status_icon_ =
- status_tray->CreateStatusIcon(StatusTray::MEDIA_STREAM_CAPTURE_ICON);
-
EnsureStatusTrayIconResources();
+
+ gfx::ImageSkia image;
+ string16 tool_tip;
+ GetStatusTrayIconInfo(audio, video, &image, &tool_tip);
+ DCHECK(!image.isNull());
+ DCHECK(!tool_tip.empty());
+
+ status_icon_ = status_tray->CreateStatusIcon(
+ StatusTray::MEDIA_STREAM_CAPTURE_ICON, image, tool_tip);
}
void MediaStreamCaptureIndicator::EnsureStatusTrayIconResources() {
@@ -481,32 +488,32 @@ void MediaStreamCaptureIndicator::UpdateNotificationUserInterface() {
}
// The icon will take the ownership of the passed context menu.
- MaybeCreateStatusTrayIcon();
+ MaybeCreateStatusTrayIcon(audio, video);
if (status_icon_) {
status_icon_->SetContextMenu(menu.release());
- UpdateStatusTrayIconDisplay(audio, video);
}
}
-void MediaStreamCaptureIndicator::UpdateStatusTrayIconDisplay(
- bool audio, bool video) {
+void MediaStreamCaptureIndicator::GetStatusTrayIconInfo(bool audio,
+ bool video,
+ gfx::ImageSkia* image,
+ string16* tool_tip) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(audio || video);
- DCHECK(status_icon_);
+
int message_id = 0;
if (audio && video) {
message_id = IDS_MEDIA_STREAM_STATUS_TRAY_TEXT_AUDIO_AND_VIDEO;
- status_icon_->SetImage(*camera_image_);
+ *image = *camera_image_;
} else if (audio && !video) {
message_id = IDS_MEDIA_STREAM_STATUS_TRAY_TEXT_AUDIO_ONLY;
- status_icon_->SetImage(*mic_image_);
+ *image = *mic_image_;
} else if (!audio && video) {
message_id = IDS_MEDIA_STREAM_STATUS_TRAY_TEXT_VIDEO_ONLY;
- status_icon_->SetImage(*camera_image_);
+ *image = *camera_image_;
}
- status_icon_->SetToolTip(l10n_util::GetStringFUTF16(
- message_id, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)));
+ *tool_tip = l10n_util::GetStringUTF16(message_id);
}
void MediaStreamCaptureIndicator::OnStopScreenCapture(
diff --git a/chrome/browser/media/media_stream_capture_indicator.h b/chrome/browser/media/media_stream_capture_indicator.h
index 4c311cf..9fc861e 100644
--- a/chrome/browser/media/media_stream_capture_indicator.h
+++ b/chrome/browser/media/media_stream_capture_indicator.h
@@ -84,9 +84,14 @@ class MediaStreamCaptureIndicator
// Helpers to create and destroy status tray icon. Called from
// UpdateNotificationUserInterface().
void EnsureStatusTrayIconResources();
- void MaybeCreateStatusTrayIcon();
+ void MaybeCreateStatusTrayIcon(bool audio, bool video);
void MaybeDestroyStatusTrayIcon();
- void UpdateStatusTrayIconDisplay(bool audio, bool video);
+
+ // Gets the status icon image and the string to use as the tooltip.
+ void GetStatusTrayIconInfo(bool audio,
+ bool video,
+ gfx::ImageSkia* image,
+ string16* tool_tip);
// Callback for ScreenCaptureNotificationUI.
void OnStopScreenCapture(const base::Closure& stop);
diff --git a/chrome/browser/status_icons/status_icon.cc b/chrome/browser/status_icons/status_icon.cc
index 79efafc..00270d2 100644
--- a/chrome/browser/status_icons/status_icon.cc
+++ b/chrome/browser/status_icons/status_icon.cc
@@ -29,9 +29,6 @@ void StatusIcon::DispatchClickEvent() {
FOR_EACH_OBSERVER(StatusIconObserver, observers_, OnStatusIconClicked());
}
-void StatusIcon::SetClickActionLabel(const string16& label) {
-}
-
#if defined(OS_WIN)
void StatusIcon::DispatchBalloonClickEvent() {
FOR_EACH_OBSERVER(StatusIconObserver, observers_, OnBalloonClicked());
diff --git a/chrome/browser/status_icons/status_icon.h b/chrome/browser/status_icons/status_icon.h
index 6110c64..ccc8c2e 100644
--- a/chrome/browser/status_icons/status_icon.h
+++ b/chrome/browser/status_icons/status_icon.h
@@ -31,15 +31,12 @@ class StatusIcon {
// Sets the image associated with this status icon when pressed.
virtual void SetPressedImage(const gfx::ImageSkia& image) = 0;
- // Sets the hover text for this status icon.
+ // Sets the hover text for this status icon. This is also used as the label
+ // for the menu item which is created as a replacement for the status icon
+ // click action on platforms that do not support custom click actions for the
+ // status icon (e.g. Ubuntu Unity).
virtual void SetToolTip(const string16& tool_tip) = 0;
- // Sets the label for the menu item which is created as a replacement for the
- // status icon click action on platforms that do not support custom click
- // actions for the status icon (e.g. Ubuntu Unity). Since only a few platforms
- // would need this, the default action is to ignore the call.
- virtual void SetClickActionLabel(const string16& label);
-
// Displays a notification balloon with the specified contents.
// Depending on the platform it might not appear by the icon tray.
virtual void DisplayBalloon(const gfx::ImageSkia& icon,
diff --git a/chrome/browser/status_icons/status_tray.cc b/chrome/browser/status_icons/status_tray.cc
index aaa7a57..bdd11da 100644
--- a/chrome/browser/status_icons/status_tray.cc
+++ b/chrome/browser/status_icons/status_tray.cc
@@ -11,8 +11,10 @@
StatusTray::~StatusTray() {
}
-StatusIcon* StatusTray::CreateStatusIcon(StatusIconType type) {
- StatusIcon* icon = CreatePlatformStatusIcon(type);
+StatusIcon* StatusTray::CreateStatusIcon(StatusIconType type,
+ const gfx::ImageSkia& image,
+ const string16& tool_tip) {
+ StatusIcon* icon = CreatePlatformStatusIcon(type, image, tool_tip);
if (icon)
status_icons_.push_back(icon);
return icon;
diff --git a/chrome/browser/status_icons/status_tray.h b/chrome/browser/status_icons/status_tray.h
index e4f240d..1c4be06 100644
--- a/chrome/browser/status_icons/status_tray.h
+++ b/chrome/browser/status_icons/status_tray.h
@@ -8,6 +8,11 @@
#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_vector.h"
+#include "base/strings/string16.h"
+
+namespace gfx {
+class ImageSkia;
+}
class StatusIcon;
@@ -32,7 +37,9 @@ class StatusTray {
// Creates a new StatusIcon. The StatusTray retains ownership of the
// StatusIcon. Returns NULL if the StatusIcon could not be created.
- StatusIcon* CreateStatusIcon(StatusIconType type);
+ StatusIcon* CreateStatusIcon(StatusIconType type,
+ const gfx::ImageSkia& image,
+ const string16& tool_tip);
// Removes |icon| from this status tray.
void RemoveStatusIcon(StatusIcon* icon);
@@ -43,7 +50,9 @@ class StatusTray {
StatusTray();
// Factory method for creating a status icon for this platform.
- virtual StatusIcon* CreatePlatformStatusIcon(StatusIconType type) = 0;
+ virtual StatusIcon* CreatePlatformStatusIcon(StatusIconType type,
+ const gfx::ImageSkia& image,
+ const string16& tool_tip) = 0;
// Returns the list of active status icons so subclasses can operate on them.
const StatusIcons& status_icons() const { return status_icons_; }
diff --git a/chrome/browser/status_icons/status_tray_unittest.cc b/chrome/browser/status_icons/status_tray_unittest.cc
index a71fa9a..238d8b7 100644
--- a/chrome/browser/status_icons/status_tray_unittest.cc
+++ b/chrome/browser/status_icons/status_tray_unittest.cc
@@ -7,10 +7,10 @@
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/status_icons/status_icon.h"
#include "chrome/browser/status_icons/status_tray.h"
-#include "testing/gmock/include/gmock/gmock.h"
+#include "grit/chrome_unscaled_resources.h"
#include "testing/gtest/include/gtest/gtest.h"
-
-using testing::Return;
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/image/image_skia.h"
class MockStatusIcon : public StatusIcon {
virtual void SetImage(const gfx::ImageSkia& image) OVERRIDE {}
@@ -24,9 +24,12 @@ class MockStatusIcon : public StatusIcon {
class TestStatusTray : public StatusTray {
public:
- MOCK_METHOD1(CreatePlatformStatusIcon,
- StatusIcon*(StatusTray::StatusIconType type));
- MOCK_METHOD1(UpdatePlatformContextMenu, void(ui::MenuModel*));
+ virtual StatusIcon* CreatePlatformStatusIcon(
+ StatusIconType type,
+ const gfx::ImageSkia& image,
+ const string16& tool_tip) OVERRIDE {
+ return new MockStatusIcon();
+ }
const StatusIcons& GetStatusIconsForTest() const { return status_icons(); }
};
@@ -34,17 +37,20 @@ class TestStatusTray : public StatusTray {
TEST(StatusTrayTest, Create) {
// Check for creation and leaks.
TestStatusTray tray;
- EXPECT_CALL(tray, CreatePlatformStatusIcon(StatusTray::OTHER_ICON)).WillOnce(
- Return(new MockStatusIcon()));
- tray.CreateStatusIcon(StatusTray::OTHER_ICON);
+ ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+ gfx::ImageSkia* image = rb.GetImageSkiaNamed(IDR_STATUS_TRAY_ICON);
+ tray.CreateStatusIcon(
+ StatusTray::OTHER_ICON, *image, ASCIIToUTF16("tool tip"));
+ EXPECT_EQ(1U, tray.GetStatusIconsForTest().size());
}
// Make sure that removing an icon removes it from the list.
TEST(StatusTrayTest, CreateRemove) {
TestStatusTray tray;
- EXPECT_CALL(tray, CreatePlatformStatusIcon(StatusTray::OTHER_ICON)).WillOnce(
- Return(new MockStatusIcon()));
- StatusIcon* icon = tray.CreateStatusIcon(StatusTray::OTHER_ICON);
+ ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+ gfx::ImageSkia* image = rb.GetImageSkiaNamed(IDR_STATUS_TRAY_ICON);
+ StatusIcon* icon = tray.CreateStatusIcon(
+ StatusTray::OTHER_ICON, *image, ASCIIToUTF16("tool tip"));
EXPECT_EQ(1U, tray.GetStatusIconsForTest().size());
tray.RemoveStatusIcon(icon);
EXPECT_EQ(0U, tray.GetStatusIconsForTest().size());
diff --git a/chrome/browser/ui/cocoa/notifications/message_center_tray_bridge.mm b/chrome/browser/ui/cocoa/notifications/message_center_tray_bridge.mm
index 405aabf..ff4bac5 100644
--- a/chrome/browser/ui/cocoa/notifications/message_center_tray_bridge.mm
+++ b/chrome/browser/ui/cocoa/notifications/message_center_tray_bridge.mm
@@ -100,15 +100,14 @@ void MessageCenterTrayBridge::UpdateStatusItem() {
size_t unread_count = message_center_->UnreadNotificationCount();
[status_item_view_ setUnreadCount:unread_count];
- string16 product_name = l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME);
if (unread_count > 0) {
string16 unread_count_string = base::FormatNumber(unread_count);
[status_item_view_ setToolTip:
l10n_util::GetNSStringF(IDS_MESSAGE_CENTER_TOOLTIP_UNREAD,
- product_name, unread_count_string)];
+ unread_count_string)];
} else {
[status_item_view_ setToolTip:
- l10n_util::GetNSStringF(IDS_MESSAGE_CENTER_TOOLTIP, product_name)];
+ l10n_util::GetNSString(IDS_MESSAGE_CENTER_TOOLTIP)];
}
}
diff --git a/chrome/browser/ui/cocoa/status_icons/status_tray_mac.h b/chrome/browser/ui/cocoa/status_icons/status_tray_mac.h
index 2bb19c4..7325d86 100644
--- a/chrome/browser/ui/cocoa/status_icons/status_tray_mac.h
+++ b/chrome/browser/ui/cocoa/status_icons/status_tray_mac.h
@@ -14,7 +14,10 @@ class StatusTrayMac : public StatusTray {
protected:
// Factory method for creating a status icon.
- virtual StatusIcon* CreatePlatformStatusIcon(StatusIconType type) OVERRIDE;
+ virtual StatusIcon* CreatePlatformStatusIcon(
+ StatusIconType type,
+ const gfx::ImageSkia& image,
+ const string16& tool_tip) OVERRIDE;
private:
DISALLOW_COPY_AND_ASSIGN(StatusTrayMac);
diff --git a/chrome/browser/ui/cocoa/status_icons/status_tray_mac.mm b/chrome/browser/ui/cocoa/status_icons/status_tray_mac.mm
index 7a4324d..50dc797 100644
--- a/chrome/browser/ui/cocoa/status_icons/status_tray_mac.mm
+++ b/chrome/browser/ui/cocoa/status_icons/status_tray_mac.mm
@@ -13,6 +13,11 @@ StatusTray* StatusTray::Create() {
StatusTrayMac::StatusTrayMac() {
}
-StatusIcon* StatusTrayMac::CreatePlatformStatusIcon(StatusIconType type) {
- return new StatusIconMac();
+StatusIcon* StatusTrayMac::CreatePlatformStatusIcon(StatusIconType type,
+ const gfx::ImageSkia& image,
+ const string16& tool_tip) {
+ StatusIcon* icon = new StatusIconMac();
+ icon->SetImage(image);
+ icon->SetToolTip(tool_tip);
+ return icon;
}
diff --git a/chrome/browser/ui/gtk/status_icons/status_tray_gtk.cc b/chrome/browser/ui/gtk/status_icons/status_tray_gtk.cc
index ecff525..a86f48f 100644
--- a/chrome/browser/ui/gtk/status_icons/status_tray_gtk.cc
+++ b/chrome/browser/ui/gtk/status_icons/status_tray_gtk.cc
@@ -12,8 +12,13 @@ StatusTrayGtk::StatusTrayGtk() {
StatusTrayGtk::~StatusTrayGtk() {
}
-StatusIcon* StatusTrayGtk::CreatePlatformStatusIcon(StatusIconType type) {
- return new StatusIconGtk();
+StatusIcon* StatusTrayGtk::CreatePlatformStatusIcon(StatusIconType type,
+ const gfx::ImageSkia& image,
+ const string16& tool_tip) {
+ StatusIcon* icon = new StatusIconGtk();
+ icon->SetImage(image);
+ icon->SetToolTip(tool_tip);
+ return icon;
}
StatusTray* StatusTray::Create() {
diff --git a/chrome/browser/ui/gtk/status_icons/status_tray_gtk.h b/chrome/browser/ui/gtk/status_icons/status_tray_gtk.h
index 3e010d7..d24d386 100644
--- a/chrome/browser/ui/gtk/status_icons/status_tray_gtk.h
+++ b/chrome/browser/ui/gtk/status_icons/status_tray_gtk.h
@@ -15,7 +15,10 @@ class StatusTrayGtk : public StatusTray {
protected:
// Overriden from StatusTray:
- virtual StatusIcon* CreatePlatformStatusIcon(StatusIconType type) OVERRIDE;
+ virtual StatusIcon* CreatePlatformStatusIcon(
+ StatusIconType type,
+ const gfx::ImageSkia& image,
+ const string16& tool_tip) OVERRIDE;
private:
DISALLOW_COPY_AND_ASSIGN(StatusTrayGtk);
diff --git a/chrome/browser/ui/gtk/status_icons/status_tray_gtk_unittest.cc b/chrome/browser/ui/gtk/status_icons/status_tray_gtk_unittest.cc
index 3cf40d0..3ca1df2 100644
--- a/chrome/browser/ui/gtk/status_icons/status_tray_gtk_unittest.cc
+++ b/chrome/browser/ui/gtk/status_icons/status_tray_gtk_unittest.cc
@@ -13,6 +13,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/models/simple_menu_model.h"
#include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/image/image_skia.h"
namespace {
@@ -29,12 +30,11 @@ TEST(StatusTrayGtkTest, CreateTray) {
TEST(StatusTrayGtkTest, CreateIcon) {
// Create an icon, set the images and tooltip, then shut it down.
StatusTrayGtk tray;
- StatusIcon* icon = tray.CreateStatusIcon(StatusTray::OTHER_ICON);
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
gfx::ImageSkia* image = rb.GetImageSkiaNamed(IDR_STATUS_TRAY_ICON);
- icon->SetImage(*image);
+ StatusIcon* icon = tray.CreateStatusIcon(
+ StatusTray::OTHER_ICON, *image, ASCIIToUTF16("tool tip"));
icon->SetPressedImage(*image);
- icon->SetToolTip(ASCIIToUTF16("tool tip"));
ui::SimpleMenuModel* menu = new ui::SimpleMenuModel(NULL);
menu->AddItem(0, ASCIIToUTF16("foo"));
icon->SetContextMenu(menu);
@@ -43,8 +43,10 @@ TEST(StatusTrayGtkTest, CreateIcon) {
TEST(StatusTrayGtkTest, ClickOnIcon) {
// Create an icon, send a fake click event, make sure observer is called.
StatusTrayGtk tray;
- StatusIconGtk* icon = static_cast<StatusIconGtk*>(
- tray.CreateStatusIcon(StatusTray::OTHER_ICON));
+ ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+ gfx::ImageSkia* image = rb.GetImageSkiaNamed(IDR_STATUS_TRAY_ICON);
+ StatusIconGtk* icon = static_cast<StatusIconGtk*>(tray.CreateStatusIcon(
+ StatusTray::OTHER_ICON, *image, ASCIIToUTF16("tool tip")));
MockStatusIconObserver observer;
icon->AddObserver(&observer);
EXPECT_CALL(observer, OnStatusIconClicked());
diff --git a/chrome/browser/ui/libgtk2ui/app_indicator_icon.cc b/chrome/browser/ui/libgtk2ui/app_indicator_icon.cc
index ff4b79f..73a4aff 100644
--- a/chrome/browser/ui/libgtk2ui/app_indicator_icon.cc
+++ b/chrome/browser/ui/libgtk2ui/app_indicator_icon.cc
@@ -124,7 +124,9 @@ void EnsureMethodsLoaded() {
namespace libgtk2ui {
-AppIndicatorIcon::AppIndicatorIcon(std::string id)
+AppIndicatorIcon::AppIndicatorIcon(std::string id,
+ const gfx::ImageSkia& image,
+ const string16& tool_tip)
: id_(id),
icon_(NULL),
gtk_menu_(NULL),
@@ -133,6 +135,8 @@ AppIndicatorIcon::AppIndicatorIcon(std::string id)
block_activation_(false),
has_click_action_replacement_(false) {
EnsureMethodsLoaded();
+ tool_tip_ = UTF16ToUTF8(tool_tip);
+ SetImage(image);
}
AppIndicatorIcon::~AppIndicatorIcon() {
if (icon_) {
@@ -154,22 +158,25 @@ bool AppIndicatorIcon::CouldOpen() {
}
void AppIndicatorIcon::SetImage(const gfx::ImageSkia& image) {
- if (opened) {
- ++icon_change_count_;
- gfx::ImageSkia safe_image = gfx::ImageSkia(image);
- safe_image.MakeThreadSafe();
- base::PostTaskAndReplyWithResult(
- content::BrowserThread::GetBlockingPool()
- ->GetTaskRunnerWithShutdownBehavior(
- base::SequencedWorkerPool::SKIP_ON_SHUTDOWN).get(),
- FROM_HERE,
- base::Bind(&AppIndicatorIcon::CreateTempImageFile,
- safe_image,
- icon_change_count_,
- id_),
- base::Bind(&AppIndicatorIcon::SetImageFromFile,
- base::Unretained(this)));
- }
+ if (!opened)
+ return;
+
+ ++icon_change_count_;
+
+ // We create a deep copy of the image since it may have been freed by the time
+ // it's accessed in the other thread.
+ scoped_ptr<gfx::ImageSkia> safe_image(image.DeepCopy());
+ base::PostTaskAndReplyWithResult(
+ content::BrowserThread::GetBlockingPool()
+ ->GetTaskRunnerWithShutdownBehavior(
+ base::SequencedWorkerPool::SKIP_ON_SHUTDOWN).get(),
+ FROM_HERE,
+ base::Bind(&AppIndicatorIcon::CreateTempImageFile,
+ safe_image.release(),
+ icon_change_count_,
+ id_),
+ base::Bind(&AppIndicatorIcon::SetImageFromFile,
+ base::Unretained(this)));
}
void AppIndicatorIcon::SetPressedImage(const gfx::ImageSkia& image) {
@@ -178,27 +185,22 @@ void AppIndicatorIcon::SetPressedImage(const gfx::ImageSkia& image) {
}
void AppIndicatorIcon::SetToolTip(const string16& tool_tip) {
- // App-indicators don't support tool-tips. Ignore call.
-}
-
-void AppIndicatorIcon::SetClickActionLabel(const string16& label) {
- click_action_label_ = UTF16ToUTF8(label);
+ DCHECK(!tool_tip_.empty());
+ tool_tip_ = UTF16ToUTF8(tool_tip);
- // If the menu item has already been created, then find the menu item and
- // change it's label.
- if (has_click_action_replacement_) {
+ // We can set the click action label only if the icon exists. Also we only
+ // need to update the label if it is shown and it's only shown if we are sure
+ // that there is a click action or if there is no menu.
+ if (icon_ && (delegate()->HasClickAction() || menu_model_ == NULL)) {
GList* children = gtk_container_get_children(GTK_CONTAINER(gtk_menu_));
for (GList* child = children; child; child = g_list_next(child))
if (g_object_get_data(G_OBJECT(child->data), "click-action-item") !=
NULL) {
gtk_menu_item_set_label(GTK_MENU_ITEM(child->data),
- click_action_label_.c_str());
+ tool_tip_.c_str());
break;
}
g_list_free(children);
- } else if (icon_) {
- CreateClickActionReplacement();
- app_indicator_set_menu(icon_, GTK_MENU(gtk_menu_));
}
}
@@ -208,13 +210,12 @@ void AppIndicatorIcon::UpdatePlatformContextMenu(ui::MenuModel* model) {
if (gtk_menu_) {
DestroyMenu();
- has_click_action_replacement_ = false;
}
menu_model_ = model;
- // If icon doesn't exist now it's okay, the menu will be set later along with
- // the image. Both an icon and a menu are required to show an app indicator.
- if (model && icon_)
+ // The icon is created asynchronously so it might not exist when the menu is
+ // set.
+ if (icon_)
SetMenu();
}
@@ -234,12 +235,8 @@ void AppIndicatorIcon::SetImageFromFile(base::FilePath icon_file_path) {
APP_INDICATOR_CATEGORY_APPLICATION_STATUS,
icon_dir.c_str());
app_indicator_set_status(icon_, APP_INDICATOR_STATUS_ACTIVE);
- if (menu_model_) {
- SetMenu();
- } else if (!click_action_label_.empty()) {
- CreateClickActionReplacement();
- app_indicator_set_menu(icon_, GTK_MENU(gtk_menu_));
- }
+
+ SetMenu();
} else {
// Currently we are creating a new temp directory every time the icon is
// set. So we need to set the directory each time.
@@ -256,40 +253,38 @@ void AppIndicatorIcon::SetImageFromFile(base::FilePath icon_file_path) {
void AppIndicatorIcon::SetMenu() {
gtk_menu_ = gtk_menu_new();
- BuildSubmenuFromModel(menu_model_,
- gtk_menu_,
- G_CALLBACK(OnMenuItemActivatedThunk),
- &block_activation_,
- this);
- if (!click_action_label_.empty())
+
+ if (delegate()->HasClickAction() || menu_model_ == NULL) {
CreateClickActionReplacement();
- UpdateMenu();
- menu_model_->MenuWillShow();
+ if (menu_model_) {
+ // Add separator before the other menu items.
+ GtkWidget* menu_item = gtk_separator_menu_item_new();
+ gtk_widget_show(menu_item);
+ gtk_menu_shell_append(GTK_MENU_SHELL(gtk_menu_), menu_item);
+ }
+ }
+ if (menu_model_) {
+ BuildSubmenuFromModel(menu_model_,
+ gtk_menu_,
+ G_CALLBACK(OnMenuItemActivatedThunk),
+ &block_activation_,
+ this);
+ UpdateMenu();
+ menu_model_->MenuWillShow();
+ }
app_indicator_set_menu(icon_, GTK_MENU(gtk_menu_));
}
void AppIndicatorIcon::CreateClickActionReplacement() {
- GtkWidget* menu_item = NULL;
-
- // If a menu doesn't exist create one just for the click action replacement.
- if (!gtk_menu_) {
- gtk_menu_ = gtk_menu_new();
- } else {
- // Add separator before the other menu items.
- menu_item = gtk_separator_menu_item_new();
- gtk_widget_show(menu_item);
- gtk_menu_shell_prepend(GTK_MENU_SHELL(gtk_menu_), menu_item);
- }
+ DCHECK(!tool_tip_.empty());
// Add "click replacement menu item".
- menu_item = gtk_menu_item_new_with_mnemonic(click_action_label_.c_str());
+ GtkWidget* menu_item = gtk_menu_item_new_with_mnemonic(tool_tip_.c_str());
g_object_set_data(
G_OBJECT(menu_item), "click-action-item", GINT_TO_POINTER(1));
g_signal_connect(menu_item, "activate", G_CALLBACK(OnClickThunk), this);
gtk_widget_show(menu_item);
gtk_menu_shell_prepend(GTK_MENU_SHELL(gtk_menu_), menu_item);
-
- has_click_action_replacement_ = true;
}
void AppIndicatorIcon::DestroyMenu() {
@@ -300,11 +295,13 @@ void AppIndicatorIcon::DestroyMenu() {
menu_model_ = NULL;
}
-base::FilePath AppIndicatorIcon::CreateTempImageFile(gfx::ImageSkia image,
+base::FilePath AppIndicatorIcon::CreateTempImageFile(gfx::ImageSkia* image_ptr,
int icon_change_count,
std::string id) {
+ scoped_ptr<gfx::ImageSkia> image(image_ptr);
+
scoped_refptr<base::RefCountedMemory> png_data =
- gfx::Image(image).As1xPNGBytes();
+ gfx::Image(*image.get()).As1xPNGBytes();
if (png_data->size() == 0) {
// If the bitmap could not be encoded to PNG format, skip it.
LOG(WARNING) << "Could not encode icon";
diff --git a/chrome/browser/ui/libgtk2ui/app_indicator_icon.h b/chrome/browser/ui/libgtk2ui/app_indicator_icon.h
index 33bfd5e..db1198d 100644
--- a/chrome/browser/ui/libgtk2ui/app_indicator_icon.h
+++ b/chrome/browser/ui/libgtk2ui/app_indicator_icon.h
@@ -6,6 +6,7 @@
#define CHROME_BROWSER_UI_LIBGTK2UI_APP_INDICATOR_ICON_H_
#include "base/files/file_path.h"
+#include "base/memory/scoped_ptr.h"
#include "chrome/browser/ui/libgtk2ui/gtk2_signal.h"
#include "ui/linux_ui/status_icon_linux.h"
@@ -22,7 +23,9 @@ class AppIndicatorIcon : public StatusIconLinux {
public:
// The id uniquely identifies the new status icon from other chrome status
// icons.
- explicit AppIndicatorIcon(std::string id);
+ explicit AppIndicatorIcon(std::string id,
+ const gfx::ImageSkia& image,
+ const string16& tool_tip);
virtual ~AppIndicatorIcon();
// Indicates whether libappindicator so could be opened.
@@ -32,7 +35,6 @@ class AppIndicatorIcon : public StatusIconLinux {
virtual void SetImage(const gfx::ImageSkia& image) OVERRIDE;
virtual void SetPressedImage(const gfx::ImageSkia& image) OVERRIDE;
virtual void SetToolTip(const string16& tool_tip) OVERRIDE;
- virtual void SetClickActionLabel(const string16& label) OVERRIDE;
protected:
// Overridden from StatusIcon.
@@ -49,7 +51,7 @@ class AppIndicatorIcon : public StatusIconLinux {
void CreateClickActionReplacement();
void DestroyMenu();
- static base::FilePath CreateTempImageFile(gfx::ImageSkia image,
+ static base::FilePath CreateTempImageFile(gfx::ImageSkia* image,
int icon_change_count,
std::string id);
static void DeletePath(base::FilePath icon_file_path);
@@ -64,7 +66,7 @@ class AppIndicatorIcon : public StatusIconLinux {
CHROMEGTK_CALLBACK_0(AppIndicatorIcon, void, OnMenuItemActivated);
std::string id_;
- std::string click_action_label_;
+ std::string tool_tip_;
// Gtk status icon wrapper
AppIndicator* icon_;
diff --git a/chrome/browser/ui/libgtk2ui/gtk2_ui.cc b/chrome/browser/ui/libgtk2ui/gtk2_ui.cc
index 4167edc..1376db2 100644
--- a/chrome/browser/ui/libgtk2ui/gtk2_ui.cc
+++ b/chrome/browser/ui/libgtk2ui/gtk2_ui.cc
@@ -395,11 +395,15 @@ bool Gtk2UI::IsStatusIconSupported() const {
return AppIndicatorIcon::CouldOpen();
}
-scoped_ptr<StatusIconLinux> Gtk2UI::CreateLinuxStatusIcon() const {
+scoped_ptr<StatusIconLinux> Gtk2UI::CreateLinuxStatusIcon(
+ const gfx::ImageSkia& image,
+ const string16& tool_tip) const {
if (AppIndicatorIcon::CouldOpen()) {
++indicators_count;
return scoped_ptr<StatusIconLinux>(new AppIndicatorIcon(
- base::StringPrintf("%s%d", kAppIndicatorIdPrefix, indicators_count)));
+ base::StringPrintf("%s%d", kAppIndicatorIdPrefix, indicators_count),
+ image,
+ tool_tip));
} else {
return scoped_ptr<StatusIconLinux>();
}
diff --git a/chrome/browser/ui/libgtk2ui/gtk2_ui.h b/chrome/browser/ui/libgtk2ui/gtk2_ui.h
index 69a7dde..af57462 100644
--- a/chrome/browser/ui/libgtk2ui/gtk2_ui.h
+++ b/chrome/browser/ui/libgtk2ui/gtk2_ui.h
@@ -48,7 +48,9 @@ class Gtk2UI : public ui::LinuxUI {
virtual void SetDownloadCount(int count) const OVERRIDE;
virtual void SetProgressFraction(float percentage) const OVERRIDE;
virtual bool IsStatusIconSupported() const OVERRIDE;
- virtual scoped_ptr<StatusIconLinux> CreateLinuxStatusIcon() const OVERRIDE;
+ virtual scoped_ptr<StatusIconLinux> CreateLinuxStatusIcon(
+ const gfx::ImageSkia& image,
+ const string16& tool_tip) const OVERRIDE;
private:
typedef std::map<int, SkColor> ColorMap;
diff --git a/chrome/browser/ui/views/message_center/web_notification_tray.cc b/chrome/browser/ui/views/message_center/web_notification_tray.cc
index f3371d9..00eadd5 100644
--- a/chrome/browser/ui/views/message_center/web_notification_tray.cc
+++ b/chrome/browser/ui/views/message_center/web_notification_tray.cc
@@ -200,20 +200,22 @@ void WebNotificationTray::UpdateStatusIcon() {
should_update_tray_content_ = false;
int unread_notifications = message_center()->UnreadNotificationCount();
- StatusIcon* status_icon = GetStatusIcon();
- if (!status_icon)
- return;
-
- status_icon->SetImage(GetIcon(unread_notifications));
- string16 product_name(l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME));
+ string16 tool_tip;
if (unread_notifications > 0) {
string16 str_unread_count = base::FormatNumber(unread_notifications);
- status_icon->SetToolTip(l10n_util::GetStringFUTF16(
- IDS_MESSAGE_CENTER_TOOLTIP_UNREAD, product_name, str_unread_count));
+ tool_tip = l10n_util::GetStringFUTF16(IDS_MESSAGE_CENTER_TOOLTIP_UNREAD,
+ str_unread_count);
+ } else {
+ tool_tip = l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_TOOLTIP);
+ }
+ gfx::ImageSkia icon_image = GetIcon(unread_notifications);
+
+ if (status_icon_ == NULL) {
+ CreateStatusIcon(icon_image, tool_tip);
} else {
- status_icon->SetToolTip(
- l10n_util::GetStringFUTF16(IDS_MESSAGE_CENTER_TOOLTIP, product_name));
+ status_icon_->SetImage(icon_image);
+ status_icon_->SetToolTip(tool_tip);
}
}
@@ -267,24 +269,22 @@ PositionInfo WebNotificationTray::GetPositionInfo() {
return pos_info;
}
-StatusIcon* WebNotificationTray::GetStatusIcon() {
+void WebNotificationTray::CreateStatusIcon(const gfx::ImageSkia& image,
+ const string16& tool_tip) {
if (status_icon_)
- return status_icon_;
+ return;
StatusTray* status_tray = g_browser_process->status_tray();
if (!status_tray)
- return NULL;
+ return;
- StatusIcon* status_icon =
- status_tray->CreateStatusIcon(StatusTray::NOTIFICATION_TRAY_ICON);
- if (!status_icon)
- return NULL;
+ status_icon_ = status_tray->CreateStatusIcon(
+ StatusTray::NOTIFICATION_TRAY_ICON, image, tool_tip);
+ if (!status_icon_)
+ return;
- status_icon_ = status_icon;
status_icon_->AddObserver(this);
AddQuietModeMenu(status_icon_);
-
- return status_icon_;
}
void WebNotificationTray::DestroyStatusIcon() {
diff --git a/chrome/browser/ui/views/message_center/web_notification_tray.h b/chrome/browser/ui/views/message_center/web_notification_tray.h
index 8d4010d..1bc6fa4 100644
--- a/chrome/browser/ui/views/message_center/web_notification_tray.h
+++ b/chrome/browser/ui/views/message_center/web_notification_tray.h
@@ -84,7 +84,7 @@ class WebNotificationTray : public message_center::MessageCenterTrayDelegate,
PositionInfo GetPositionInfo();
- StatusIcon* GetStatusIcon();
+ void CreateStatusIcon(const gfx::ImageSkia& image, const string16& tool_tip);
void DestroyStatusIcon();
void AddQuietModeMenu(StatusIcon* status_icon);
MessageCenterWidgetDelegate* GetMessageCenterWidgetDelegateForTest();
diff --git a/chrome/browser/ui/views/message_center/web_notification_tray_win.cc b/chrome/browser/ui/views/message_center/web_notification_tray_win.cc
index dcc6e25..54a99f4 100644
--- a/chrome/browser/ui/views/message_center/web_notification_tray_win.cc
+++ b/chrome/browser/ui/views/message_center/web_notification_tray_win.cc
@@ -30,9 +30,9 @@ void WebNotificationTray::OnBalloonClicked() {
}
void WebNotificationTray::DisplayFirstRunBalloon() {
- StatusIcon* status_icon = GetStatusIcon();
- if (!status_icon)
- return;
+ // We should never be calling DisplayFirstRunBalloon without a status icon.
+ // The status icon must have been created before this call.
+ DCHECK(status_icon_);
base::win::Version win_version = base::win::GetVersion();
if (win_version == base::win::VERSION_PRE_XP)
@@ -52,8 +52,7 @@ void WebNotificationTray::DisplayFirstRunBalloon() {
scoped_ptr<SkBitmap> sized_app_icon_bitmap = GetAppIconForSize(icon_size);
gfx::ImageSkia sized_app_icon_skia =
gfx::ImageSkia::CreateFrom1xBitmap(*sized_app_icon_bitmap);
- string16 product_name(l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME));
- GetStatusIcon()->DisplayBalloon(
+ status_icon_->DisplayBalloon(
sized_app_icon_skia,
l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_BALLOON_TITLE),
l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_BALLOON_TEXT));
diff --git a/chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.cc b/chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.cc
index f257a3f..931abef 100644
--- a/chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.cc
+++ b/chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.cc
@@ -23,10 +23,6 @@ void StatusIconLinuxWrapper::SetToolTip(const string16& tool_tip) {
status_icon_->SetToolTip(tool_tip);
}
-void StatusIconLinuxWrapper::SetClickActionLabel(const string16& label) {
- status_icon_->SetClickActionLabel(label);
-}
-
void StatusIconLinuxWrapper::DisplayBalloon(const gfx::ImageSkia& icon,
const string16& title,
const string16& contents) {
@@ -37,10 +33,17 @@ void StatusIconLinuxWrapper::OnClick() {
DispatchClickEvent();
}
-StatusIconLinuxWrapper* StatusIconLinuxWrapper::CreateWrappedStatusIcon() {
+bool StatusIconLinuxWrapper::HasClickAction() {
+ return HasObservers();
+}
+
+StatusIconLinuxWrapper* StatusIconLinuxWrapper::CreateWrappedStatusIcon(
+ const gfx::ImageSkia& image,
+ const string16& tool_tip) {
const ui::LinuxUI* linux_ui = ui::LinuxUI::instance();
if (linux_ui) {
- scoped_ptr<StatusIconLinux> status_icon = linux_ui->CreateLinuxStatusIcon();
+ scoped_ptr<StatusIconLinux> status_icon =
+ linux_ui->CreateLinuxStatusIcon(image, tool_tip);
if (status_icon.get())
return new StatusIconLinuxWrapper(status_icon.release());
}
diff --git a/chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.h b/chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.h
index 5bb7dbf..153ce37 100644
--- a/chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.h
+++ b/chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.h
@@ -21,15 +21,17 @@ class StatusIconLinuxWrapper : public StatusIcon,
virtual void SetImage(const gfx::ImageSkia& image) OVERRIDE;
virtual void SetPressedImage(const gfx::ImageSkia& image) OVERRIDE;
virtual void SetToolTip(const string16& tool_tip) OVERRIDE;
- virtual void SetClickActionLabel(const string16& label) OVERRIDE;
virtual void DisplayBalloon(const gfx::ImageSkia& icon,
const string16& title,
const string16& contents) OVERRIDE;
// StatusIconLinux::Delegate overrides:
virtual void OnClick() OVERRIDE;
+ virtual bool HasClickAction() OVERRIDE;
- static StatusIconLinuxWrapper* CreateWrappedStatusIcon();
+ static StatusIconLinuxWrapper* CreateWrappedStatusIcon(
+ const gfx::ImageSkia& image,
+ const string16& tool_tip);
protected:
// StatusIcon overrides:
diff --git a/chrome/browser/ui/views/status_icons/status_tray_linux.cc b/chrome/browser/ui/views/status_icons/status_tray_linux.cc
index 2aa06c4..58db07a 100644
--- a/chrome/browser/ui/views/status_icons/status_tray_linux.cc
+++ b/chrome/browser/ui/views/status_icons/status_tray_linux.cc
@@ -14,8 +14,11 @@ StatusTrayLinux::StatusTrayLinux() {
StatusTrayLinux::~StatusTrayLinux() {
}
-StatusIcon* StatusTrayLinux::CreatePlatformStatusIcon(StatusIconType type) {
- return StatusIconLinuxWrapper::CreateWrappedStatusIcon();
+StatusIcon* StatusTrayLinux::CreatePlatformStatusIcon(
+ StatusIconType type,
+ const gfx::ImageSkia& image,
+ const string16& tool_tip) {
+ return StatusIconLinuxWrapper::CreateWrappedStatusIcon(image, tool_tip);
}
StatusTray* StatusTray::Create() {
diff --git a/chrome/browser/ui/views/status_icons/status_tray_linux.h b/chrome/browser/ui/views/status_icons/status_tray_linux.h
index ea38ae5..d1540a5 100644
--- a/chrome/browser/ui/views/status_icons/status_tray_linux.h
+++ b/chrome/browser/ui/views/status_icons/status_tray_linux.h
@@ -15,7 +15,10 @@ class StatusTrayLinux : public StatusTray {
protected:
// Overriden from StatusTray:
- virtual StatusIcon* CreatePlatformStatusIcon(StatusIconType type) OVERRIDE;
+ virtual StatusIcon* CreatePlatformStatusIcon(
+ StatusIconType type,
+ const gfx::ImageSkia& image,
+ const string16& tool_tip) OVERRIDE;
private:
DISALLOW_COPY_AND_ASSIGN(StatusTrayLinux);
diff --git a/chrome/browser/ui/views/status_icons/status_tray_win.cc b/chrome/browser/ui/views/status_icons/status_tray_win.cc
index 8df1cf5..21a00d4 100644
--- a/chrome/browser/ui/views/status_icons/status_tray_win.cc
+++ b/chrome/browser/ui/views/status_icons/status_tray_win.cc
@@ -120,16 +120,24 @@ StatusTrayWin::~StatusTrayWin() {
}
StatusIcon* StatusTrayWin::CreatePlatformStatusIcon(
- StatusTray::StatusIconType type) {
+ StatusTray::StatusIconType type,
+ const gfx::ImageSkia& image,
+ const string16& tool_tip) {
UINT next_icon_id;
if (type == StatusTray::OTHER_ICON)
next_icon_id = NextIconId();
else
next_icon_id = ReservedIconId(type);
+ StatusIcon* icon = NULL;
if (win8::IsSingleWindowMetroMode())
- return new StatusIconMetro(next_icon_id);
- return new StatusIconWin(next_icon_id, window_, kStatusIconMessage);
+ icon = new StatusIconMetro(next_icon_id);
+ else
+ icon = new StatusIconWin(next_icon_id, window_, kStatusIconMessage);
+
+ icon->SetImage(image);
+ icon->SetToolTip(tool_tip);
+ return icon;
}
UINT StatusTrayWin::NextIconId() {
diff --git a/chrome/browser/ui/views/status_icons/status_tray_win.h b/chrome/browser/ui/views/status_icons/status_tray_win.h
index 87974f0..3e2be2f 100644
--- a/chrome/browser/ui/views/status_icons/status_tray_win.h
+++ b/chrome/browser/ui/views/status_icons/status_tray_win.h
@@ -23,7 +23,10 @@ class StatusTrayWin : public StatusTray {
protected:
// Overriden from StatusTray:
- virtual StatusIcon* CreatePlatformStatusIcon(StatusIconType type) OVERRIDE;
+ virtual StatusIcon* CreatePlatformStatusIcon(
+ StatusIconType type,
+ const gfx::ImageSkia& image,
+ const string16& tool_tip) OVERRIDE;
private:
// Static callback invoked when a message comes in to our messaging window.
diff --git a/chrome/browser/ui/views/status_icons/status_tray_win_unittest.cc b/chrome/browser/ui/views/status_icons/status_tray_win_unittest.cc
index b42fd96..b021f8c 100644
--- a/chrome/browser/ui/views/status_icons/status_tray_win_unittest.cc
+++ b/chrome/browser/ui/views/status_icons/status_tray_win_unittest.cc
@@ -14,6 +14,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/models/simple_menu_model.h"
#include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/image/image_skia.h"
class FakeStatusIconObserver : public StatusIconObserver {
public:
@@ -43,12 +44,11 @@ TEST(StatusTrayWinTest, CreateIconAndMenu) {
// Create an icon, set the images, tooltip, and context menu, then shut it
// down.
StatusTrayWin tray;
- StatusIcon* icon = tray.CreateStatusIcon(StatusTray::OTHER_ICON);
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
gfx::ImageSkia* image = rb.GetImageSkiaNamed(IDR_STATUS_TRAY_ICON);
- icon->SetImage(*image);
+ StatusIcon* icon = tray.CreateStatusIcon(
+ StatusTray::OTHER_ICON, *image, ASCIIToUTF16("tool tip"));
icon->SetPressedImage(*image);
- icon->SetToolTip(ASCIIToUTF16("tool tip"));
ui::SimpleMenuModel* menu = new ui::SimpleMenuModel(NULL);
menu->AddItem(0, L"foo");
icon->SetContextMenu(menu);
@@ -58,8 +58,11 @@ TEST(StatusTrayWinTest, CreateIconAndMenu) {
TEST(StatusTrayWinTest, ClickOnIcon) {
// Create an icon, send a fake click event, make sure observer is called.
StatusTrayWin tray;
- StatusIconWin* icon = static_cast<StatusIconWin*>(
- tray.CreateStatusIcon(StatusTray::OTHER_ICON));
+ ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+ gfx::ImageSkia* image = rb.GetImageSkiaNamed(IDR_STATUS_TRAY_ICON);
+
+ StatusIconWin* icon = static_cast<StatusIconWin*>(tray.CreateStatusIcon(
+ StatusTray::OTHER_ICON, *image, ASCIIToUTF16("tool tip")));
FakeStatusIconObserver observer;
icon->AddObserver(&observer);
// Mimic a click.
@@ -73,8 +76,11 @@ TEST(StatusTrayWinTest, ClickOnIcon) {
TEST(StatusTrayWinTest, ClickOnBalloon) {
// Create an icon, send a fake click event, make sure observer is called.
StatusTrayWin tray;
- StatusIconWin* icon = static_cast<StatusIconWin*>(
- tray.CreateStatusIcon(StatusTray::OTHER_ICON));
+ ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+ gfx::ImageSkia* image = rb.GetImageSkiaNamed(IDR_STATUS_TRAY_ICON);
+
+ StatusIconWin* icon = static_cast<StatusIconWin*>(tray.CreateStatusIcon(
+ StatusTray::OTHER_ICON, *image, ASCIIToUTF16("tool tip")));
FakeStatusIconObserver observer;
icon->AddObserver(&observer);
// Mimic a click.
diff --git a/ui/base/strings/ui_strings.grd b/ui/base/strings/ui_strings.grd
index 0e06ca5..21d7001 100644
--- a/ui/base/strings/ui_strings.grd
+++ b/ui/base/strings/ui_strings.grd
@@ -501,12 +501,6 @@ need to be translated for each locale.-->
<message name="IDS_MESSAGE_CENTER_EXPAND_NOTIFICATION_BUTTON_ACCESSIBLE_NAME" desc="The spoken feedback text for the expand button in a notification. Usually 'button' is suffixed to this text automatically.">
Notification expand
</message>
- <message name="IDS_MESSAGE_CENTER_TOOLTIP" desc="Tooltip for notification tray icon without unread notifications">
- <ph name="product">$1<ex>Chrome</ex></ph> - Notifications
- </message>
- <message name="IDS_MESSAGE_CENTER_TOOLTIP_UNREAD" desc="Tooltip for notification tray icon with unread notifications">
- <ph name="product">$1<ex>Chrome</ex></ph> - Notifications (<ph name="QUANTITY">$2<ex>3</ex></ph> unread)
- </message>
<message name="IDS_MESSAGE_CENTER_NOTIFIER_SCREENSHOT_NAME" desc="The name of screenshot notifier that is a system componet">
Screenshot
</message>
diff --git a/ui/linux_ui/OWNERS b/ui/linux_ui/OWNERS
new file mode 100644
index 0000000..4733a4f
--- /dev/null
+++ b/ui/linux_ui/OWNERS
@@ -0,0 +1 @@
+erg@chromium.org
diff --git a/ui/linux_ui/linux_ui.h b/ui/linux_ui/linux_ui.h
index 119f97d..f609e9a 100644
--- a/ui/linux_ui/linux_ui.h
+++ b/ui/linux_ui/linux_ui.h
@@ -67,7 +67,9 @@ class LINUX_UI_EXPORT LinuxUI : public LinuxShellDialog {
virtual bool IsStatusIconSupported() const = 0;
// Create a native status icon.
- virtual scoped_ptr<StatusIconLinux> CreateLinuxStatusIcon() const = 0;
+ virtual scoped_ptr<StatusIconLinux> CreateLinuxStatusIcon(
+ const gfx::ImageSkia& image,
+ const string16& tool_tip) const = 0;
};
} // namespace ui
diff --git a/ui/linux_ui/status_icon_linux.h b/ui/linux_ui/status_icon_linux.h
index 1accefe..fbbf28f 100644
--- a/ui/linux_ui/status_icon_linux.h
+++ b/ui/linux_ui/status_icon_linux.h
@@ -25,6 +25,7 @@ class LINUX_UI_EXPORT StatusIconLinux {
class Delegate {
public:
virtual void OnClick() = 0;
+ virtual bool HasClickAction() = 0;
protected:
virtual ~Delegate();
@@ -36,7 +37,6 @@ class LINUX_UI_EXPORT StatusIconLinux {
virtual void SetImage(const gfx::ImageSkia& image) = 0;
virtual void SetPressedImage(const gfx::ImageSkia& image) = 0;
virtual void SetToolTip(const string16& tool_tip) = 0;
- virtual void SetClickActionLabel(const string16& label) = 0;
// Invoked after a call to SetContextMenu() to let the platform-specific
// subclass update the native context menu based on the new model. The