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

Side by Side Diff: chrome/browser/gtk/browser_actions_toolbar_gtk.cc

Issue 1783010: GTK: more signal handler foolproofing. (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: Created 10 years, 7 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/gtk/browser_actions_toolbar_gtk.h" 5 #include "chrome/browser/gtk/browser_actions_toolbar_gtk.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "chrome/browser/browser.h" 9 #include "chrome/browser/browser.h"
10 #include "chrome/browser/extensions/extension_browser_event_router.h" 10 #include "chrome/browser/extensions/extension_browser_event_router.h"
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 // The Browser Action API does not allow the default icon path to be 93 // The Browser Action API does not allow the default icon path to be
94 // changed at runtime, so we can load this now and cache it. 94 // changed at runtime, so we can load this now and cache it.
95 std::string path = extension_->browser_action()->default_icon_path(); 95 std::string path = extension_->browser_action()->default_icon_path();
96 if (!path.empty()) { 96 if (!path.empty()) {
97 tracker_.LoadImage(extension_, extension_->GetResource(path), 97 tracker_.LoadImage(extension_, extension_->GetResource(path),
98 gfx::Size(Extension::kBrowserActionIconMaxSize, 98 gfx::Size(Extension::kBrowserActionIconMaxSize,
99 Extension::kBrowserActionIconMaxSize), 99 Extension::kBrowserActionIconMaxSize),
100 ImageLoadingTracker::DONT_CACHE); 100 ImageLoadingTracker::DONT_CACHE);
101 } 101 }
102 102
103 g_signal_connect(button_.get(), "button-press-event", 103 signals_.Connect(button_.get(), "button-press-event",
104 G_CALLBACK(OnButtonPress), this); 104 G_CALLBACK(OnButtonPress), this);
105 g_signal_connect(button_.get(), "clicked", 105 signals_.Connect(button_.get(), "clicked",
106 G_CALLBACK(OnClicked), this); 106 G_CALLBACK(OnClicked), this);
107 g_signal_connect_after(button_.get(), "expose-event", 107 signals_.ConnectAfter(button_.get(), "expose-event",
108 G_CALLBACK(OnExposeEvent), this); 108 G_CALLBACK(OnExposeEvent), this);
109 g_signal_connect(button_.get(), "drag-begin", 109 signals_.Connect(button_.get(), "drag-begin",
110 G_CALLBACK(&OnDragBegin), this); 110 G_CALLBACK(&OnDragBegin), this);
111 111
112 registrar_.Add(this, NotificationType::EXTENSION_BROWSER_ACTION_UPDATED, 112 registrar_.Add(this, NotificationType::EXTENSION_BROWSER_ACTION_UPDATED,
113 Source<ExtensionAction>(extension->browser_action())); 113 Source<ExtensionAction>(extension->browser_action()));
114 } 114 }
115 115
116 ~BrowserActionButton() { 116 ~BrowserActionButton() {
117 if (tab_specific_icon_) 117 if (tab_specific_icon_)
118 g_object_unref(tab_specific_icon_); 118 g_object_unref(tab_specific_icon_);
119 119
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 311
312 // If we are displaying a tab-specific icon, it will be here. 312 // If we are displaying a tab-specific icon, it will be here.
313 GdkPixbuf* tab_specific_icon_; 313 GdkPixbuf* tab_specific_icon_;
314 314
315 // If the browser action has a default icon, it will be here. 315 // If the browser action has a default icon, it will be here.
316 GdkPixbuf* default_icon_; 316 GdkPixbuf* default_icon_;
317 317
318 // Same as |default_icon_|, but stored as SkBitmap. 318 // Same as |default_icon_|, but stored as SkBitmap.
319 SkBitmap default_skbitmap_; 319 SkBitmap default_skbitmap_;
320 320
321 GtkSignalRegistrar signals_;
321 NotificationRegistrar registrar_; 322 NotificationRegistrar registrar_;
322 323
323 // The context menu view and model for this extension action. 324 // The context menu view and model for this extension action.
324 scoped_ptr<MenuGtk> context_menu_; 325 scoped_ptr<MenuGtk> context_menu_;
325 scoped_refptr<ExtensionContextMenuModel> context_menu_model_; 326 scoped_refptr<ExtensionContextMenuModel> context_menu_model_;
326 327
327 friend class BrowserActionsToolbarGtk; 328 friend class BrowserActionsToolbarGtk;
328 }; 329 };
329 330
330 // BrowserActionsToolbarGtk ---------------------------------------------------- 331 // BrowserActionsToolbarGtk ----------------------------------------------------
(...skipping 14 matching lines...) Expand all
345 start_width_(0), 346 start_width_(0),
346 method_factory_(this) { 347 method_factory_(this) {
347 ExtensionsService* extension_service = profile_->GetExtensionsService(); 348 ExtensionsService* extension_service = profile_->GetExtensionsService();
348 // The |extension_service| can be NULL in Incognito. 349 // The |extension_service| can be NULL in Incognito.
349 if (!extension_service) 350 if (!extension_service)
350 return; 351 return;
351 352
352 GtkWidget* gripper = gtk_button_new(); 353 GtkWidget* gripper = gtk_button_new();
353 GTK_WIDGET_UNSET_FLAGS(gripper, GTK_CAN_FOCUS); 354 GTK_WIDGET_UNSET_FLAGS(gripper, GTK_CAN_FOCUS);
354 gtk_widget_add_events(gripper, GDK_POINTER_MOTION_MASK); 355 gtk_widget_add_events(gripper, GDK_POINTER_MOTION_MASK);
355 g_signal_connect(gripper, "motion-notify-event", 356 signals_.Connect(gripper, "motion-notify-event",
356 G_CALLBACK(OnGripperMotionNotifyThunk), this); 357 G_CALLBACK(OnGripperMotionNotifyThunk), this);
357 g_signal_connect(gripper, "expose-event", 358 signals_.Connect(gripper, "expose-event",
358 G_CALLBACK(OnGripperExposeThunk), this); 359 G_CALLBACK(OnGripperExposeThunk), this);
359 g_signal_connect(gripper, "enter-notify-event", 360 signals_.Connect(gripper, "enter-notify-event",
360 G_CALLBACK(OnGripperEnterNotifyThunk), this); 361 G_CALLBACK(OnGripperEnterNotifyThunk), this);
361 g_signal_connect(gripper, "leave-notify-event", 362 signals_.Connect(gripper, "leave-notify-event",
362 G_CALLBACK(OnGripperLeaveNotifyThunk), this); 363 G_CALLBACK(OnGripperLeaveNotifyThunk), this);
363 g_signal_connect(gripper, "button-release-event", 364 signals_.Connect(gripper, "button-release-event",
364 G_CALLBACK(OnGripperButtonReleaseThunk), this); 365 G_CALLBACK(OnGripperButtonReleaseThunk), this);
365 g_signal_connect(gripper, "button-press-event", 366 signals_.Connect(gripper, "button-press-event",
366 G_CALLBACK(OnGripperButtonPressThunk), this); 367 G_CALLBACK(OnGripperButtonPressThunk), this);
367 g_signal_connect(overflow_button_.widget(), "button-press-event", 368 signals_.Connect(overflow_button_.widget(), "button-press-event",
368 G_CALLBACK(OnOverflowButtonPressThunk), this); 369 G_CALLBACK(OnOverflowButtonPressThunk), this);
369 370
370 gtk_box_pack_start(GTK_BOX(hbox_.get()), gripper, FALSE, FALSE, 0); 371 gtk_box_pack_start(GTK_BOX(hbox_.get()), gripper, FALSE, FALSE, 0);
371 gtk_box_pack_start(GTK_BOX(hbox_.get()), button_hbox_.get(), TRUE, TRUE, 0); 372 gtk_box_pack_start(GTK_BOX(hbox_.get()), button_hbox_.get(), TRUE, TRUE, 0);
372 gtk_box_pack_start(GTK_BOX(hbox_.get()), overflow_button_.widget(), 373 gtk_box_pack_start(GTK_BOX(hbox_.get()), overflow_button_.widget(),
373 FALSE, FALSE, 0); 374 FALSE, FALSE, 0);
374 gtk_box_pack_start(GTK_BOX(hbox_.get()), separator_, FALSE, FALSE, 0); 375 gtk_box_pack_start(GTK_BOX(hbox_.get()), separator_, FALSE, FALSE, 0);
375 376
376 model_ = extension_service->toolbar_model(); 377 model_ = extension_service->toolbar_model();
377 model_->AddObserver(this); 378 model_->AddObserver(this);
378 SetupDrags(); 379 SetupDrags();
379 380
380 if (model_->extensions_initialized()) { 381 if (model_->extensions_initialized()) {
381 CreateAllButtons(); 382 CreateAllButtons();
382 SetContainerWidth(); 383 SetContainerWidth();
383 } 384 }
384 385
385 // We want to connect to "set-focus" on the toplevel window; we have to wait 386 // We want to connect to "set-focus" on the toplevel window; we have to wait
386 // until we are added to a toplevel window to do so. 387 // until we are added to a toplevel window to do so.
387 g_signal_connect(widget(), "hierarchy-changed", 388 signals_.Connect(widget(), "hierarchy-changed",
388 G_CALLBACK(OnHierarchyChangedThunk), this); 389 G_CALLBACK(OnHierarchyChangedThunk), this);
389 390
390 ViewIDUtil::SetID(button_hbox_.get(), VIEW_ID_BROWSER_ACTION_TOOLBAR); 391 ViewIDUtil::SetID(button_hbox_.get(), VIEW_ID_BROWSER_ACTION_TOOLBAR);
391 } 392 }
392 393
393 BrowserActionsToolbarGtk::~BrowserActionsToolbarGtk() { 394 BrowserActionsToolbarGtk::~BrowserActionsToolbarGtk() {
394 GtkWidget* toplevel = gtk_widget_get_toplevel(widget());
395 if (toplevel) {
396 g_signal_handlers_disconnect_by_func(
397 toplevel, reinterpret_cast<gpointer>(OnSetFocusThunk), this);
398 }
399
400 if (model_) 395 if (model_)
401 model_->RemoveObserver(this); 396 model_->RemoveObserver(this);
402 button_hbox_.Destroy(); 397 button_hbox_.Destroy();
403 hbox_.Destroy(); 398 hbox_.Destroy();
404 } 399 }
405 400
406 int BrowserActionsToolbarGtk::GetCurrentTabId() { 401 int BrowserActionsToolbarGtk::GetCurrentTabId() {
407 TabContents* selected_tab = browser_->GetSelectedTabContents(); 402 TabContents* selected_tab = browser_->GetSelectedTabContents();
408 if (!selected_tab) 403 if (!selected_tab)
409 return -1; 404 return -1;
410 405
411 return selected_tab->controller().session_id().id(); 406 return selected_tab->controller().session_id().id();
412 } 407 }
413 408
414 void BrowserActionsToolbarGtk::Update() { 409 void BrowserActionsToolbarGtk::Update() {
415 for (ExtensionButtonMap::iterator iter = extension_button_map_.begin(); 410 for (ExtensionButtonMap::iterator iter = extension_button_map_.begin();
416 iter != extension_button_map_.end(); ++iter) { 411 iter != extension_button_map_.end(); ++iter) {
417 iter->second->UpdateState(); 412 iter->second->UpdateState();
418 } 413 }
419 } 414 }
420 415
421 void BrowserActionsToolbarGtk::SetupDrags() { 416 void BrowserActionsToolbarGtk::SetupDrags() {
422 GtkTargetEntry drag_target = GetDragTargetEntry(); 417 GtkTargetEntry drag_target = GetDragTargetEntry();
423 gtk_drag_dest_set(button_hbox_.get(), GTK_DEST_DEFAULT_DROP, &drag_target, 1, 418 gtk_drag_dest_set(button_hbox_.get(), GTK_DEST_DEFAULT_DROP, &drag_target, 1,
424 GDK_ACTION_MOVE); 419 GDK_ACTION_MOVE);
425 420
426 g_signal_connect(button_hbox_.get(), "drag-motion", 421 signals_.Connect(button_hbox_.get(), "drag-motion",
427 G_CALLBACK(OnDragMotionThunk), this); 422 G_CALLBACK(OnDragMotionThunk), this);
428 } 423 }
429 424
430 void BrowserActionsToolbarGtk::CreateAllButtons() { 425 void BrowserActionsToolbarGtk::CreateAllButtons() {
431 extension_button_map_.clear(); 426 extension_button_map_.clear();
432 427
433 int i = 0; 428 int i = 0;
434 for (ExtensionList::iterator iter = model_->begin(); 429 for (ExtensionList::iterator iter = model_->begin();
435 iter != model_->end(); ++iter) { 430 iter != model_->end(); ++iter) {
436 CreateButtonForExtension(*iter, i++); 431 CreateButtonForExtension(*iter, i++);
(...skipping 19 matching lines...) Expand all
456 new BrowserActionButton(this, extension)); 451 new BrowserActionButton(this, extension));
457 gtk_chrome_shrinkable_hbox_pack_start( 452 gtk_chrome_shrinkable_hbox_pack_start(
458 GTK_CHROME_SHRINKABLE_HBOX(button_hbox_.get()), button->widget(), 0); 453 GTK_CHROME_SHRINKABLE_HBOX(button_hbox_.get()), button->widget(), 0);
459 gtk_box_reorder_child(GTK_BOX(button_hbox_.get()), button->widget(), index); 454 gtk_box_reorder_child(GTK_BOX(button_hbox_.get()), button->widget(), index);
460 extension_button_map_[extension->id()] = button; 455 extension_button_map_[extension->id()] = button;
461 456
462 GtkTargetEntry drag_target = GetDragTargetEntry(); 457 GtkTargetEntry drag_target = GetDragTargetEntry();
463 gtk_drag_source_set(button->widget(), GDK_BUTTON1_MASK, &drag_target, 1, 458 gtk_drag_source_set(button->widget(), GDK_BUTTON1_MASK, &drag_target, 1,
464 GDK_ACTION_MOVE); 459 GDK_ACTION_MOVE);
465 // We ignore whether the drag was a "success" or "failure" in Gtk's opinion. 460 // We ignore whether the drag was a "success" or "failure" in Gtk's opinion.
466 g_signal_connect(button->widget(), "drag-end", 461 signals_.Connect(button->widget(), "drag-end",
467 G_CALLBACK(&OnDragEndThunk), this); 462 G_CALLBACK(&OnDragEndThunk), this);
468 g_signal_connect(button->widget(), "drag-failed", 463 signals_.Connect(button->widget(), "drag-failed",
469 G_CALLBACK(&OnDragFailedThunk), this); 464 G_CALLBACK(&OnDragFailedThunk), this);
470 465
471 // Any time a browser action button is shown or hidden we have to update 466 // Any time a browser action button is shown or hidden we have to update
472 // the chevron state. 467 // the chevron state.
473 g_signal_connect(button->widget(), "show", 468 signals_.Connect(button->widget(), "show",
474 G_CALLBACK(&OnButtonShowOrHideThunk), this); 469 G_CALLBACK(&OnButtonShowOrHideThunk), this);
475 g_signal_connect(button->widget(), "hide", 470 signals_.Connect(button->widget(), "hide",
476 G_CALLBACK(&OnButtonShowOrHideThunk), this); 471 G_CALLBACK(&OnButtonShowOrHideThunk), this);
477 472
478 gtk_widget_show(button->widget()); 473 gtk_widget_show(button->widget());
479 474
480 UpdateVisibility(); 475 UpdateVisibility();
481 } 476 }
482 477
483 GtkWidget* BrowserActionsToolbarGtk::GetBrowserActionWidget( 478 GtkWidget* BrowserActionsToolbarGtk::GetBrowserActionWidget(
484 Extension* extension) { 479 Extension* extension) {
485 ExtensionButtonMap::iterator it = extension_button_map_.find( 480 ExtensionButtonMap::iterator it = extension_button_map_.find(
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
705 // several seconds later. 700 // several seconds later.
706 return TRUE; 701 return TRUE;
707 } 702 }
708 703
709 void BrowserActionsToolbarGtk::OnHierarchyChanged( 704 void BrowserActionsToolbarGtk::OnHierarchyChanged(
710 GtkWidget* widget, GtkWidget* previous_toplevel) { 705 GtkWidget* widget, GtkWidget* previous_toplevel) {
711 GtkWidget* toplevel = gtk_widget_get_toplevel(widget); 706 GtkWidget* toplevel = gtk_widget_get_toplevel(widget);
712 if (!GTK_WIDGET_TOPLEVEL(toplevel)) 707 if (!GTK_WIDGET_TOPLEVEL(toplevel))
713 return; 708 return;
714 709
715 g_signal_connect(toplevel, "set-focus", G_CALLBACK(OnSetFocusThunk), this); 710 signals_.Connect(toplevel, "set-focus", G_CALLBACK(OnSetFocusThunk), this);
716 } 711 }
717 712
718 void BrowserActionsToolbarGtk::OnSetFocus(GtkWidget* widget, 713 void BrowserActionsToolbarGtk::OnSetFocus(GtkWidget* widget,
719 GtkWidget* focus_widget) { 714 GtkWidget* focus_widget) {
720 ExtensionPopupGtk* popup = ExtensionPopupGtk::get_current_extension_popup(); 715 ExtensionPopupGtk* popup = ExtensionPopupGtk::get_current_extension_popup();
721 // The focus of the parent window has changed. Close the popup. Delay the hide 716 // The focus of the parent window has changed. Close the popup. Delay the hide
722 // because it will destroy the RenderViewHost, which may still be on the 717 // because it will destroy the RenderViewHost, which may still be on the
723 // call stack. 718 // call stack.
724 if (!popup || popup->being_inspected()) 719 if (!popup || popup->being_inspected())
725 return; 720 return;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
819 GtkWidget* menu_item = overflow_menu_->AppendMenuItemWithIcon( 814 GtkWidget* menu_item = overflow_menu_->AppendMenuItemWithIcon(
820 model_index, 815 model_index,
821 extension->name(), 816 extension->name(),
822 button->GetIcon()); 817 button->GetIcon());
823 818
824 g_object_set_data(G_OBJECT(menu_item), kMenuItemKey, button); 819 g_object_set_data(G_OBJECT(menu_item), kMenuItemKey, button);
825 820
826 // TODO(estade): set the menu item's tooltip. 821 // TODO(estade): set the menu item's tooltip.
827 } 822 }
828 823
829 g_signal_connect(overflow_menu_->widget(), "button-press-event", 824 signals_.Connect(overflow_menu_->widget(), "button-press-event",
830 G_CALLBACK(OnOverflowMenuButtonPressThunk), this); 825 G_CALLBACK(OnOverflowMenuButtonPressThunk), this);
831 826
832 gtk_chrome_button_set_paint_state(GTK_CHROME_BUTTON(overflow), 827 gtk_chrome_button_set_paint_state(GTK_CHROME_BUTTON(overflow),
833 GTK_STATE_ACTIVE); 828 GTK_STATE_ACTIVE);
834 overflow_menu_->PopupAsFromKeyEvent(overflow); 829 overflow_menu_->PopupAsFromKeyEvent(overflow);
835 830
836 return FALSE; 831 return FALSE;
837 } 832 }
838 833
839 gboolean BrowserActionsToolbarGtk::OnOverflowMenuButtonPress( 834 gboolean BrowserActionsToolbarGtk::OnOverflowMenuButtonPress(
840 GtkWidget* overflow, GdkEventButton* event) { 835 GtkWidget* overflow, GdkEventButton* event) {
841 if (event->button != 3) 836 if (event->button != 3)
842 return FALSE; 837 return FALSE;
843 838
844 GtkWidget* menu_item = GTK_MENU_SHELL(overflow)->active_menu_item; 839 GtkWidget* menu_item = GTK_MENU_SHELL(overflow)->active_menu_item;
845 if (!menu_item) 840 if (!menu_item)
846 return FALSE; 841 return FALSE;
847 842
848 void* data = g_object_get_data(G_OBJECT(menu_item), kMenuItemKey); 843 void* data = g_object_get_data(G_OBJECT(menu_item), kMenuItemKey);
849 DCHECK(data); 844 DCHECK(data);
850 BrowserActionButton* button = static_cast<BrowserActionButton*>(data); 845 BrowserActionButton* button = static_cast<BrowserActionButton*>(data);
851 button->GetContextMenu()->PopupAsContext(event->time); 846 button->GetContextMenu()->PopupAsContext(event->time);
852 return TRUE; 847 return TRUE;
853 } 848 }
854 849
855 void BrowserActionsToolbarGtk::OnButtonShowOrHide(GtkWidget* sender) { 850 void BrowserActionsToolbarGtk::OnButtonShowOrHide(GtkWidget* sender) {
856 if (!resize_animation_.IsAnimating()) 851 if (!resize_animation_.IsAnimating())
857 UpdateChevronVisibility(); 852 UpdateChevronVisibility();
858 } 853 }
OLDNEW
« no previous file with comments | « chrome/browser/gtk/browser_actions_toolbar_gtk.h ('k') | chrome/browser/gtk/fullscreen_exit_bubble_gtk.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698