Index: chrome/browser/ui/gtk/extensions/extension_installed_bubble_gtk.cc |
diff --git a/chrome/browser/ui/gtk/extensions/extension_installed_bubble_gtk.cc b/chrome/browser/ui/gtk/extensions/extension_installed_bubble_gtk.cc |
index b1531060bea3f2b8f66d3477aefa69cd1ca9e752..3a219b956d55607765fdca38ea8082747be83136 100644 |
--- a/chrome/browser/ui/gtk/extensions/extension_installed_bubble_gtk.cc |
+++ b/chrome/browser/ui/gtk/extensions/extension_installed_bubble_gtk.cc |
@@ -6,10 +6,7 @@ |
#include <string> |
-#include "base/bind.h" |
-#include "base/bind_helpers.h" |
#include "base/i18n/rtl.h" |
-#include "base/message_loop/message_loop.h" |
#include "base/strings/utf_string_conversions.h" |
#include "chrome/browser/chrome_notification_types.h" |
#include "chrome/browser/extensions/api/commands/command_service.h" |
@@ -24,7 +21,6 @@ |
#include "chrome/browser/ui/gtk/gtk_util.h" |
#include "chrome/browser/ui/gtk/location_bar_view_gtk.h" |
#include "chrome/browser/ui/singleton_tabs.h" |
-#include "chrome/common/extensions/api/extension_action/action_info.h" |
#include "chrome/common/extensions/api/omnibox/omnibox_handler.h" |
#include "chrome/common/extensions/extension.h" |
#include "chrome/common/url_constants.h" |
@@ -49,12 +45,6 @@ const int kIconSize = 43; |
const int kTextColumnVerticalSpacing = 7; |
const int kTextColumnWidth = 350; |
-// When showing the bubble for a new browser action, we may have to wait for |
-// the toolbar to finish animating to know where the item's final position |
-// will be. |
-const int kAnimationWaitRetries = 10; |
-const int kAnimationWaitMS = 50; |
- |
} // namespace |
namespace chrome { |
@@ -75,94 +65,30 @@ void ExtensionInstalledBubbleGtk::Show(const Extension* extension, |
ExtensionInstalledBubbleGtk::ExtensionInstalledBubbleGtk( |
const Extension* extension, Browser *browser, const SkBitmap& icon) |
- : extension_(extension), |
- browser_(browser), |
- icon_(icon), |
- animation_wait_retries_(kAnimationWaitRetries), |
- bubble_(NULL), |
- weak_factory_(this) { |
- if (!extensions::OmniboxInfo::GetKeyword(extension_).empty()) |
- type_ = OMNIBOX_KEYWORD; |
- else if (extensions::ActionInfo::GetBrowserActionInfo(extension_)) |
- type_ = BROWSER_ACTION; |
- else if (extensions::ActionInfo::GetPageActionInfo(extension) && |
- extensions::ActionInfo::IsVerboseInstallMessage(extension)) |
- type_ = PAGE_ACTION; |
- else |
- type_ = GENERIC; |
- |
- // |extension| has been initialized but not loaded at this point. We need |
- // to wait on showing the Bubble until not only the EXTENSION_LOADED gets |
- // fired, but all of the EXTENSION_LOADED Observers have run. Only then can we |
- // be sure that a browser action or page action has had views created which we |
- // can inspect for the purpose of pointing to them. |
- registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, |
- content::Source<Profile>(browser->profile())); |
- registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, |
- content::Source<Profile>(browser->profile())); |
- registrar_.Add(this, chrome::NOTIFICATION_BROWSER_CLOSING, |
- content::Source<Browser>(browser)); |
+ : bubble_(this, extension, browser, icon) { |
} |
ExtensionInstalledBubbleGtk::~ExtensionInstalledBubbleGtk() {} |
-void ExtensionInstalledBubbleGtk::Observe( |
- int type, |
- const content::NotificationSource& source, |
- const content::NotificationDetails& details) { |
- if (type == chrome::NOTIFICATION_EXTENSION_LOADED) { |
- const Extension* extension = |
- content::Details<const Extension>(details).ptr(); |
- if (extension == extension_) { |
- // PostTask to ourself to allow all EXTENSION_LOADED Observers to run. |
- base::MessageLoopForUI::current()->PostTask( |
- FROM_HERE, |
- base::Bind(&ExtensionInstalledBubbleGtk::ShowInternal, |
- weak_factory_.GetWeakPtr())); |
- } |
- } else if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED) { |
- const Extension* extension = |
- content::Details<extensions::UnloadedExtensionInfo>(details)->extension; |
- if (extension == extension_) { |
- // Extension is going away, make sure ShowInternal won't be called. |
- weak_factory_.InvalidateWeakPtrs(); |
- extension_ = NULL; |
- } |
- } else if (type == chrome::NOTIFICATION_BROWSER_CLOSING) { |
- // The browser closed before the bubble could be created. |
- if (!bubble_) |
- delete this; |
- } else { |
- NOTREACHED() << L"Received unexpected notification"; |
- } |
-} |
- |
void ExtensionInstalledBubbleGtk::OnDestroy(GtkWidget* widget) { |
- bubble_ = NULL; |
+ gtk_bubble_ = NULL; |
delete this; |
} |
-void ExtensionInstalledBubbleGtk::ShowInternal() { |
+bool ExtensionInstalledBubbleGtk::MaybeShowNow() { |
BrowserWindowGtk* browser_window = |
BrowserWindowGtk::GetBrowserWindowForNativeWindow( |
- browser_->window()->GetNativeWindow()); |
+ bubble_.browser()->window()->GetNativeWindow()); |
GtkWidget* reference_widget = NULL; |
- if (type_ == BROWSER_ACTION) { |
+ if (bubble_.type() == bubble_.BROWSER_ACTION) { |
BrowserActionsToolbarGtk* toolbar = |
browser_window->GetToolbar()->GetBrowserActionsToolbar(); |
+ if (toolbar->animating()) |
+ return false; |
- if (toolbar->animating() && animation_wait_retries_-- > 0) { |
- base::MessageLoopForUI::current()->PostDelayedTask( |
- FROM_HERE, |
- base::Bind(&ExtensionInstalledBubbleGtk::ShowInternal, |
- weak_factory_.GetWeakPtr()), |
- base::TimeDelta::FromMilliseconds(kAnimationWaitMS)); |
- return; |
- } |
- |
- reference_widget = toolbar->GetBrowserActionWidget(extension_); |
+ reference_widget = toolbar->GetBrowserActionWidget(bubble_.extension()); |
// glib delays recalculating layout, but we need reference_widget to know |
// its coordinates, so we force a check_resize here. |
gtk_container_check_resize(GTK_CONTAINER( |
@@ -174,12 +100,12 @@ void ExtensionInstalledBubbleGtk::ShowInternal() { |
reference_widget = gtk_widget_get_visible(toolbar->chevron()) ? |
toolbar->chevron() : NULL; |
} |
- } else if (type_ == PAGE_ACTION) { |
+ } else if (bubble_.type() == bubble_.PAGE_ACTION) { |
LocationBarViewGtk* location_bar_view = |
browser_window->GetToolbar()->GetLocationBarView(); |
ExtensionAction* page_action = |
- ExtensionActionManager::Get(browser_->profile())-> |
- GetPageAction(*extension_); |
+ ExtensionActionManager::Get(bubble_.browser()->profile())-> |
+ GetPageAction(*bubble_.extension()); |
location_bar_view->SetPreviewEnabledPageAction(page_action, |
true); // preview_enabled |
reference_widget = location_bar_view->GetPageActionWidget(page_action); |
@@ -188,7 +114,7 @@ void ExtensionInstalledBubbleGtk::ShowInternal() { |
gtk_container_check_resize(GTK_CONTAINER( |
browser_window->GetToolbar()->widget())); |
DCHECK(reference_widget); |
- } else if (type_ == OMNIBOX_KEYWORD) { |
+ } else if (bubble_.type() == bubble_.OMNIBOX_KEYWORD) { |
LocationBarViewGtk* location_bar_view = |
browser_window->GetToolbar()->GetLocationBarView(); |
reference_widget = location_bar_view->location_entry_widget(); |
@@ -200,17 +126,17 @@ void ExtensionInstalledBubbleGtk::ShowInternal() { |
reference_widget = browser_window->GetToolbar()->GetAppMenuButton(); |
GtkThemeService* theme_provider = GtkThemeService::GetFrom( |
- browser_->profile()); |
+ bubble_.browser()->profile()); |
// Setup the BubbleGtk content. |
GtkWidget* bubble_content = gtk_hbox_new(FALSE, kHorizontalColumnSpacing); |
gtk_container_set_border_width(GTK_CONTAINER(bubble_content), |
ui::kContentAreaBorder); |
- if (!icon_.isNull()) { |
+ if (!bubble_.icon().isNull()) { |
// Scale icon down to 43x43, but allow smaller icons (don't scale up). |
- GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(icon_); |
- gfx::Size size(icon_.width(), icon_.height()); |
+ GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(bubble_.icon()); |
+ gfx::Size size(bubble_.icon().width(), bubble_.icon().height()); |
if (size.width() > kIconSize || size.height() > kIconSize) { |
if (size.width() > size.height()) { |
size.set_height(size.height() * kIconSize / size.width()); |
@@ -243,7 +169,7 @@ void ExtensionInstalledBubbleGtk::ShowInternal() { |
// Heading label. |
GtkWidget* heading_label = gtk_label_new(NULL); |
- string16 extension_name = UTF8ToUTF16(extension_->name()); |
+ string16 extension_name = UTF8ToUTF16(bubble_.extension()->name()); |
base::i18n::AdjustStringForLocaleDirection(&extension_name); |
std::string heading_text = l10n_util::GetStringFUTF8( |
IDS_EXTENSION_INSTALLED_HEADING, extension_name); |
@@ -258,13 +184,13 @@ void ExtensionInstalledBubbleGtk::ShowInternal() { |
bool has_keybinding = false; |
// Browser action label. |
- if (type_ == BROWSER_ACTION) { |
+ if (bubble_.type() == bubble_.BROWSER_ACTION) { |
extensions::CommandService* command_service = |
- extensions::CommandService::Get(browser_->profile()); |
+ extensions::CommandService::Get(bubble_.browser()->profile()); |
extensions::Command browser_action_command; |
GtkWidget* info_label; |
if (!command_service->GetBrowserActionCommand( |
- extension_->id(), |
+ bubble_.extension()->id(), |
extensions::CommandService::ACTIVE_ONLY, |
&browser_action_command, |
NULL)) { |
@@ -281,13 +207,13 @@ void ExtensionInstalledBubbleGtk::ShowInternal() { |
} |
// Page action label. |
- if (type_ == PAGE_ACTION) { |
+ if (bubble_.type() == bubble_.PAGE_ACTION) { |
extensions::CommandService* command_service = |
- extensions::CommandService::Get(browser_->profile()); |
+ extensions::CommandService::Get(bubble_.browser()->profile()); |
extensions::Command page_action_command; |
GtkWidget* info_label; |
if (!command_service->GetPageActionCommand( |
- extension_->id(), |
+ bubble_.extension()->id(), |
extensions::CommandService::ACTIVE_ONLY, |
&page_action_command, |
NULL)) { |
@@ -304,10 +230,11 @@ void ExtensionInstalledBubbleGtk::ShowInternal() { |
} |
// Omnibox keyword label. |
- if (type_ == OMNIBOX_KEYWORD) { |
+ if (bubble_.type() == bubble_.OMNIBOX_KEYWORD) { |
GtkWidget* info_label = gtk_label_new(l10n_util::GetStringFUTF8( |
IDS_EXTENSION_INSTALLED_OMNIBOX_KEYWORD_INFO, |
- UTF8ToUTF16(extensions::OmniboxInfo::GetKeyword(extension_))).c_str()); |
+ UTF8ToUTF16(extensions::OmniboxInfo::GetKeyword( |
+ bubble_.extension()))).c_str()); |
gtk_util::SetLabelWidth(info_label, kTextColumnWidth); |
gtk_box_pack_start(GTK_BOX(text_column), info_label, FALSE, FALSE, 0); |
} |
@@ -341,7 +268,7 @@ void ExtensionInstalledBubbleGtk::ShowInternal() { |
BubbleGtk::FrameStyle frame_style = BubbleGtk::ANCHOR_TOP_RIGHT; |
gfx::Rect bounds = gtk_util::WidgetBounds(reference_widget); |
- if (type_ == OMNIBOX_KEYWORD) { |
+ if (bubble_.type() == bubble_.OMNIBOX_KEYWORD) { |
// Reverse the arrow for omnibox keywords, since the bubble will be on the |
// other side of the window. We also clear the width to avoid centering |
// the popup on the URL bar. |
@@ -351,52 +278,57 @@ void ExtensionInstalledBubbleGtk::ShowInternal() { |
bounds.set_width(0); |
} |
- bubble_ = BubbleGtk::Show(reference_widget, |
- &bounds, |
- bubble_content, |
- frame_style, |
- BubbleGtk::MATCH_SYSTEM_THEME | |
+ gtk_bubble_ = BubbleGtk::Show(reference_widget, |
+ &bounds, |
+ bubble_content, |
+ frame_style, |
+ BubbleGtk::MATCH_SYSTEM_THEME | |
BubbleGtk::POPUP_WINDOW | |
BubbleGtk::GRAB_INPUT, |
- theme_provider, |
- this); |
+ theme_provider, |
+ this); |
g_signal_connect(bubble_content, "destroy", |
G_CALLBACK(&OnDestroyThunk), this); |
+ |
+ // gtk_bubble_ is now the owner of |this| and deletes it when the bubble |
+ // goes away. |
+ bubble_.IgnoreBrowserClosing(); |
+ return true; |
} |
// static |
void ExtensionInstalledBubbleGtk::OnButtonClick(GtkWidget* button, |
ExtensionInstalledBubbleGtk* bubble) { |
if (button == bubble->close_button_->widget()) { |
- bubble->bubble_->Close(); |
+ bubble->gtk_bubble_->Close(); |
} else { |
NOTREACHED(); |
} |
} |
void ExtensionInstalledBubbleGtk::OnLinkClicked(GtkWidget* widget) { |
- bubble_->Close(); |
+ gtk_bubble_->Close(); |
std::string configure_url = chrome::kChromeUIExtensionsURL; |
configure_url += chrome::kExtensionConfigureCommandsSubPage; |
chrome::NavigateParams params( |
chrome::GetSingletonTabNavigateParams( |
- browser_, GURL(configure_url.c_str()))); |
+ bubble_.browser(), GURL(configure_url.c_str()))); |
chrome::Navigate(¶ms); |
} |
void ExtensionInstalledBubbleGtk::BubbleClosing(BubbleGtk* bubble, |
bool closed_by_escape) { |
- if (extension_ && type_ == PAGE_ACTION) { |
+ if (bubble_.extension() && bubble_.type() == bubble_.PAGE_ACTION) { |
// Turn the page action preview off. |
BrowserWindowGtk* browser_window = |
BrowserWindowGtk::GetBrowserWindowForNativeWindow( |
- browser_->window()->GetNativeWindow()); |
+ bubble_.browser()->window()->GetNativeWindow()); |
LocationBarViewGtk* location_bar_view = |
browser_window->GetToolbar()->GetLocationBarView(); |
location_bar_view->SetPreviewEnabledPageAction( |
- ExtensionActionManager::Get(browser_->profile())-> |
- GetPageAction(*extension_), |
+ ExtensionActionManager::Get(bubble_.browser()->profile())-> |
+ GetPageAction(*bubble_.extension()), |
false); // preview_enabled |
} |
} |