| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/gtk/browser_actions_toolbar_gtk.h" | 5 #include "chrome/browser/ui/gtk/browser_actions_toolbar_gtk.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/command_line.h" |
| 10 #include "base/i18n/rtl.h" | 11 #include "base/i18n/rtl.h" |
| 11 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
| 12 #include "chrome/browser/extensions/extension_browser_event_router.h" | 13 #include "chrome/browser/extensions/extension_browser_event_router.h" |
| 13 #include "chrome/browser/extensions/extension_context_menu_model.h" | 14 #include "chrome/browser/extensions/extension_context_menu_model.h" |
| 14 #include "chrome/browser/extensions/extension_service.h" | 15 #include "chrome/browser/extensions/extension_service.h" |
| 15 #include "chrome/browser/extensions/image_loading_tracker.h" | 16 #include "chrome/browser/extensions/image_loading_tracker.h" |
| 16 #include "chrome/browser/profiles/profile.h" | 17 #include "chrome/browser/profiles/profile.h" |
| 17 #include "chrome/browser/sessions/restore_tab_helper.h" | 18 #include "chrome/browser/sessions/restore_tab_helper.h" |
| 18 #include "chrome/browser/ui/browser.h" | 19 #include "chrome/browser/ui/browser.h" |
| 19 #include "chrome/browser/ui/gtk/cairo_cached_surface.h" | 20 #include "chrome/browser/ui/gtk/cairo_cached_surface.h" |
| 20 #include "chrome/browser/ui/gtk/extensions/extension_popup_gtk.h" | 21 #include "chrome/browser/ui/gtk/extensions/extension_popup_gtk.h" |
| 21 #include "chrome/browser/ui/gtk/gtk_chrome_button.h" | 22 #include "chrome/browser/ui/gtk/gtk_chrome_button.h" |
| 22 #include "chrome/browser/ui/gtk/gtk_chrome_shrinkable_hbox.h" | 23 #include "chrome/browser/ui/gtk/gtk_chrome_shrinkable_hbox.h" |
| 23 #include "chrome/browser/ui/gtk/gtk_theme_service.h" | 24 #include "chrome/browser/ui/gtk/gtk_theme_service.h" |
| 24 #include "chrome/browser/ui/gtk/gtk_util.h" | 25 #include "chrome/browser/ui/gtk/gtk_util.h" |
| 25 #include "chrome/browser/ui/gtk/hover_controller_gtk.h" | 26 #include "chrome/browser/ui/gtk/hover_controller_gtk.h" |
| 26 #include "chrome/browser/ui/gtk/menu_gtk.h" | 27 #include "chrome/browser/ui/gtk/menu_gtk.h" |
| 27 #include "chrome/browser/ui/gtk/view_id_util.h" | 28 #include "chrome/browser/ui/gtk/view_id_util.h" |
| 28 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | 29 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" |
| 29 #include "chrome/common/chrome_notification_types.h" | 30 #include "chrome/common/chrome_notification_types.h" |
| 31 #include "chrome/common/chrome_switches.h" |
| 30 #include "chrome/common/extensions/extension.h" | 32 #include "chrome/common/extensions/extension.h" |
| 31 #include "chrome/common/extensions/extension_action.h" | 33 #include "chrome/common/extensions/extension_action.h" |
| 32 #include "chrome/common/extensions/extension_resource.h" | 34 #include "chrome/common/extensions/extension_resource.h" |
| 33 #include "content/browser/tab_contents/tab_contents.h" | 35 #include "content/browser/tab_contents/tab_contents.h" |
| 34 #include "content/common/notification_details.h" | 36 #include "content/common/notification_details.h" |
| 35 #include "content/common/notification_service.h" | 37 #include "content/common/notification_service.h" |
| 36 #include "content/common/notification_source.h" | 38 #include "content/common/notification_source.h" |
| 37 #include "grit/theme_resources.h" | 39 #include "grit/theme_resources.h" |
| 38 #include "grit/theme_resources_standard.h" | 40 #include "grit/theme_resources_standard.h" |
| 39 #include "grit/ui_resources.h" | 41 #include "grit/ui_resources.h" |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 public MenuGtk::Delegate { | 89 public MenuGtk::Delegate { |
| 88 public: | 90 public: |
| 89 BrowserActionButton(BrowserActionsToolbarGtk* toolbar, | 91 BrowserActionButton(BrowserActionsToolbarGtk* toolbar, |
| 90 const Extension* extension, | 92 const Extension* extension, |
| 91 GtkThemeService* theme_provider) | 93 GtkThemeService* theme_provider) |
| 92 : toolbar_(toolbar), | 94 : toolbar_(toolbar), |
| 93 extension_(extension), | 95 extension_(extension), |
| 94 image_(NULL), | 96 image_(NULL), |
| 95 tracker_(this), | 97 tracker_(this), |
| 96 tab_specific_icon_(NULL), | 98 tab_specific_icon_(NULL), |
| 97 default_icon_(NULL) { | 99 default_icon_(NULL), |
| 100 waiting_for_background_page_(false) { |
| 98 button_.reset(new CustomDrawButton( | 101 button_.reset(new CustomDrawButton( |
| 99 theme_provider, | 102 theme_provider, |
| 100 IDR_BROWSER_ACTION, | 103 IDR_BROWSER_ACTION, |
| 101 IDR_BROWSER_ACTION_P, | 104 IDR_BROWSER_ACTION_P, |
| 102 IDR_BROWSER_ACTION_H, | 105 IDR_BROWSER_ACTION_H, |
| 103 0, | 106 0, |
| 104 NULL)); | 107 NULL)); |
| 105 alignment_.Own(gtk_alignment_new(0, 0, 1, 1)); | 108 alignment_.Own(gtk_alignment_new(0, 0, 1, 1)); |
| 106 gtk_container_add(GTK_CONTAINER(alignment_.get()), button()); | 109 gtk_container_add(GTK_CONTAINER(alignment_.get()), button()); |
| 107 gtk_widget_show(button()); | 110 gtk_widget_show(button()); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 GtkWidget* button() { return button_->widget(); } | 149 GtkWidget* button() { return button_->widget(); } |
| 147 | 150 |
| 148 GtkWidget* widget() { return alignment_.get(); } | 151 GtkWidget* widget() { return alignment_.get(); } |
| 149 | 152 |
| 150 const Extension* extension() { return extension_; } | 153 const Extension* extension() { return extension_; } |
| 151 | 154 |
| 152 // NotificationObserver implementation. | 155 // NotificationObserver implementation. |
| 153 void Observe(int type, | 156 void Observe(int type, |
| 154 const NotificationSource& source, | 157 const NotificationSource& source, |
| 155 const NotificationDetails& details) { | 158 const NotificationDetails& details) { |
| 156 if (type == chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED) | 159 if (type == chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED) { |
| 157 UpdateState(); | 160 UpdateState(); |
| 158 else | 161 } else if (type == chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING) { |
| 162 BrowserActionExecuted(); |
| 163 registrar_.Remove(this, |
| 164 chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING, |
| 165 Source<Profile>(toolbar_->browser()->profile())); |
| 166 waiting_for_background_page_ = false; |
| 167 } else { |
| 159 NOTREACHED(); | 168 NOTREACHED(); |
| 169 } |
| 160 } | 170 } |
| 161 | 171 |
| 162 // ImageLoadingTracker::Observer implementation. | 172 // ImageLoadingTracker::Observer implementation. |
| 163 void OnImageLoaded(SkBitmap* image, const ExtensionResource& resource, | 173 void OnImageLoaded(SkBitmap* image, const ExtensionResource& resource, |
| 164 int index) { | 174 int index) { |
| 165 if (image) { | 175 if (image) { |
| 166 default_skbitmap_ = *image; | 176 default_skbitmap_ = *image; |
| 167 default_icon_ = gfx::GdkPixbufFromSkBitmap(image); | 177 default_icon_ = gfx::GdkPixbufFromSkBitmap(image); |
| 168 } | 178 } |
| 169 UpdateState(); | 179 UpdateState(); |
| 170 } | 180 } |
| 171 | 181 |
| 182 bool IsBackgroundPageMissing() { |
| 183 if (extension_->background_url().is_valid()) { |
| 184 ExtensionProcessManager* pm = |
| 185 toolbar_->browser()->profile()->GetExtensionProcessManager(); |
| 186 return pm->GetBackgroundHostForExtension(extension_) == NULL; |
| 187 } |
| 188 |
| 189 return false; // Extension doesn't have a background page. |
| 190 } |
| 191 |
| 192 |
| 193 void AddObserverForBackgroundPageLoaded() { |
| 194 if (waiting_for_background_page_) |
| 195 return; // NotificationRegistrar doesn't like dups. |
| 196 registrar_.Add(this, |
| 197 chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING, |
| 198 Source<Profile>(toolbar_->browser()->profile())); |
| 199 waiting_for_background_page_ = true; |
| 200 } |
| 201 |
| 202 void BrowserActionExecuted() { |
| 203 ExtensionService* service = |
| 204 toolbar_->browser()->profile()->GetExtensionService(); |
| 205 service->browser_event_router()->BrowserActionExecuted( |
| 206 toolbar_->browser()->profile(), extension_->id(), |
| 207 toolbar_->browser()); |
| 208 } |
| 209 |
| 172 // Updates the button based on the latest state from the associated | 210 // Updates the button based on the latest state from the associated |
| 173 // browser action. | 211 // browser action. |
| 174 void UpdateState() { | 212 void UpdateState() { |
| 175 int tab_id = toolbar_->GetCurrentTabId(); | 213 int tab_id = toolbar_->GetCurrentTabId(); |
| 176 if (tab_id < 0) | 214 if (tab_id < 0) |
| 177 return; | 215 return; |
| 178 | 216 |
| 179 std::string tooltip = extension_->browser_action()->GetTitle(tab_id); | 217 std::string tooltip = extension_->browser_action()->GetTitle(tab_id); |
| 180 if (tooltip.empty()) | 218 if (tooltip.empty()) |
| 181 gtk_widget_set_has_tooltip(button(), FALSE); | 219 gtk_widget_set_has_tooltip(button(), FALSE); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 action->button_->SetPaintOverride(GTK_STATE_ACTIVE); | 320 action->button_->SetPaintOverride(GTK_STATE_ACTIVE); |
| 283 menu->PopupForWidget(widget, event->button, event->time); | 321 menu->PopupForWidget(widget, event->button, event->time); |
| 284 | 322 |
| 285 return TRUE; | 323 return TRUE; |
| 286 } | 324 } |
| 287 | 325 |
| 288 static void OnClicked(GtkWidget* widget, BrowserActionButton* action) { | 326 static void OnClicked(GtkWidget* widget, BrowserActionButton* action) { |
| 289 if (action->ShowPopup(false)) | 327 if (action->ShowPopup(false)) |
| 290 return; | 328 return; |
| 291 | 329 |
| 292 ExtensionService* service = | 330 // Time to create the background page! |
| 293 action->toolbar_->browser()->profile()->GetExtensionService(); | 331 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 294 service->browser_event_router()->BrowserActionExecuted( | 332 switches::kEnableLazyBackgroundPages) && |
| 295 action->toolbar_->browser()->profile(), action->extension_->id(), | 333 action->IsBackgroundPageMissing()) { |
| 296 action->toolbar_->browser()); | 334 // Dispatch the OnClicked event when the background page is loaded. |
| 335 action->AddObserverForBackgroundPageLoaded(); |
| 336 |
| 337 ExtensionProcessManager* pm = |
| 338 action->toolbar_->browser()->profile()->GetExtensionProcessManager(); |
| 339 pm->CreateBackgroundHost(action->extension_, |
| 340 action->extension_->background_url()); |
| 341 } else { |
| 342 action->BrowserActionExecuted(); |
| 343 } |
| 297 } | 344 } |
| 298 | 345 |
| 299 static gboolean OnExposeEvent(GtkWidget* widget, | 346 static gboolean OnExposeEvent(GtkWidget* widget, |
| 300 GdkEventExpose* event, | 347 GdkEventExpose* event, |
| 301 BrowserActionButton* button) { | 348 BrowserActionButton* button) { |
| 302 int tab_id = button->toolbar_->GetCurrentTabId(); | 349 int tab_id = button->toolbar_->GetCurrentTabId(); |
| 303 if (tab_id < 0) | 350 if (tab_id < 0) |
| 304 return FALSE; | 351 return FALSE; |
| 305 | 352 |
| 306 ExtensionAction* action = button->extension_->browser_action(); | 353 ExtensionAction* action = button->extension_->browser_action(); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 // Same as |default_icon_|, but stored as SkBitmap. | 399 // Same as |default_icon_|, but stored as SkBitmap. |
| 353 SkBitmap default_skbitmap_; | 400 SkBitmap default_skbitmap_; |
| 354 | 401 |
| 355 ui::GtkSignalRegistrar signals_; | 402 ui::GtkSignalRegistrar signals_; |
| 356 NotificationRegistrar registrar_; | 403 NotificationRegistrar registrar_; |
| 357 | 404 |
| 358 // The context menu view and model for this extension action. | 405 // The context menu view and model for this extension action. |
| 359 scoped_ptr<MenuGtk> context_menu_; | 406 scoped_ptr<MenuGtk> context_menu_; |
| 360 scoped_refptr<ExtensionContextMenuModel> context_menu_model_; | 407 scoped_refptr<ExtensionContextMenuModel> context_menu_model_; |
| 361 | 408 |
| 409 bool waiting_for_background_page_; |
| 410 |
| 362 friend class BrowserActionsToolbarGtk; | 411 friend class BrowserActionsToolbarGtk; |
| 363 }; | 412 }; |
| 364 | 413 |
| 365 // BrowserActionsToolbarGtk ---------------------------------------------------- | 414 // BrowserActionsToolbarGtk ---------------------------------------------------- |
| 366 | 415 |
| 367 BrowserActionsToolbarGtk::BrowserActionsToolbarGtk(Browser* browser) | 416 BrowserActionsToolbarGtk::BrowserActionsToolbarGtk(Browser* browser) |
| 368 : browser_(browser), | 417 : browser_(browser), |
| 369 profile_(browser->profile()), | 418 profile_(browser->profile()), |
| 370 theme_service_(GtkThemeService::GetFrom(browser->profile())), | 419 theme_service_(GtkThemeService::GetFrom(browser->profile())), |
| 371 model_(NULL), | 420 model_(NULL), |
| (...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 951 | 1000 |
| 952 menu->PopupAsContext(gfx::Point(event->x_root, event->y_root), | 1001 menu->PopupAsContext(gfx::Point(event->x_root, event->y_root), |
| 953 event->time); | 1002 event->time); |
| 954 return TRUE; | 1003 return TRUE; |
| 955 } | 1004 } |
| 956 | 1005 |
| 957 void BrowserActionsToolbarGtk::OnButtonShowOrHide(GtkWidget* sender) { | 1006 void BrowserActionsToolbarGtk::OnButtonShowOrHide(GtkWidget* sender) { |
| 958 if (!resize_animation_.is_animating()) | 1007 if (!resize_animation_.is_animating()) |
| 959 UpdateChevronVisibility(); | 1008 UpdateChevronVisibility(); |
| 960 } | 1009 } |
| OLD | NEW |