OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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_toolbar_gtk.h" | 5 #include "chrome/browser/gtk/browser_toolbar_gtk.h" |
6 | 6 |
7 #include <gdk/gdkkeysyms.h> | 7 #include <gdk/gdkkeysyms.h> |
8 #include <X11/XF86keysym.h> | 8 #include <X11/XF86keysym.h> |
9 | 9 |
10 #include "app/gtk_dnd_util.h" | 10 #include "app/gtk_dnd_util.h" |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 // BrowserToolbarGtk, public --------------------------------------------------- | 75 // BrowserToolbarGtk, public --------------------------------------------------- |
76 | 76 |
77 BrowserToolbarGtk::BrowserToolbarGtk(Browser* browser, BrowserWindowGtk* window) | 77 BrowserToolbarGtk::BrowserToolbarGtk(Browser* browser, BrowserWindowGtk* window) |
78 : toolbar_(NULL), | 78 : toolbar_(NULL), |
79 location_bar_(new LocationBarViewGtk(browser->command_updater(), | 79 location_bar_(new LocationBarViewGtk(browser->command_updater(), |
80 browser->toolbar_model(), | 80 browser->toolbar_model(), |
81 this)), | 81 this)), |
82 model_(browser->toolbar_model()), | 82 model_(browser->toolbar_model()), |
83 browser_(browser), | 83 browser_(browser), |
84 window_(window), | 84 window_(window), |
85 profile_(NULL) { | 85 profile_(NULL), |
| 86 menu_bar_helper_(this) { |
86 browser_->command_updater()->AddCommandObserver(IDC_BACK, this); | 87 browser_->command_updater()->AddCommandObserver(IDC_BACK, this); |
87 browser_->command_updater()->AddCommandObserver(IDC_FORWARD, this); | 88 browser_->command_updater()->AddCommandObserver(IDC_FORWARD, this); |
88 browser_->command_updater()->AddCommandObserver(IDC_RELOAD, this); | 89 browser_->command_updater()->AddCommandObserver(IDC_RELOAD, this); |
89 browser_->command_updater()->AddCommandObserver(IDC_HOME, this); | 90 browser_->command_updater()->AddCommandObserver(IDC_HOME, this); |
90 browser_->command_updater()->AddCommandObserver(IDC_STAR, this); | 91 browser_->command_updater()->AddCommandObserver(IDC_STAR, this); |
91 | 92 |
92 registrar_.Add(this, | 93 registrar_.Add(this, |
93 NotificationType::BROWSER_THEME_CHANGED, | 94 NotificationType::BROWSER_THEME_CHANGED, |
94 NotificationService::AllSources()); | 95 NotificationService::AllSources()); |
95 } | 96 } |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 g_signal_connect(location_hbox, "expose-event", | 213 g_signal_connect(location_hbox, "expose-event", |
213 G_CALLBACK(OnLocationHboxExpose), this); | 214 G_CALLBACK(OnLocationHboxExpose), this); |
214 gtk_box_pack_start(GTK_BOX(toolbar_), location_hbox, TRUE, TRUE, | 215 gtk_box_pack_start(GTK_BOX(toolbar_), location_hbox, TRUE, TRUE, |
215 ShouldOnlyShowLocation() ? 1 : 0); | 216 ShouldOnlyShowLocation() ? 1 : 0); |
216 | 217 |
217 // Group the menu buttons together in an hbox. | 218 // Group the menu buttons together in an hbox. |
218 GtkWidget* menus_hbox_ = gtk_hbox_new(FALSE, 0); | 219 GtkWidget* menus_hbox_ = gtk_hbox_new(FALSE, 0); |
219 GtkWidget* page_menu = BuildToolbarMenuButton( | 220 GtkWidget* page_menu = BuildToolbarMenuButton( |
220 l10n_util::GetStringUTF8(IDS_PAGEMENU_TOOLTIP), | 221 l10n_util::GetStringUTF8(IDS_PAGEMENU_TOOLTIP), |
221 &page_menu_button_); | 222 &page_menu_button_); |
| 223 menu_bar_helper_.Add(page_menu_button_.get()); |
222 page_menu_image_ = gtk_image_new_from_pixbuf( | 224 page_menu_image_ = gtk_image_new_from_pixbuf( |
223 theme_provider_->GetRTLEnabledPixbufNamed(IDR_MENU_PAGE)); | 225 theme_provider_->GetRTLEnabledPixbufNamed(IDR_MENU_PAGE)); |
224 gtk_container_add(GTK_CONTAINER(page_menu), page_menu_image_); | 226 gtk_container_add(GTK_CONTAINER(page_menu), page_menu_image_); |
225 | 227 |
226 encodings_menu_.reset(BuildEncodingsMenu(profile, this)); | 228 encodings_menu_.reset(BuildEncodingsMenu(profile, this)); |
227 page_menu_.reset(new MenuGtk(this, GetStandardPageMenu(encodings_menu_.get()), | 229 page_menu_.reset(new MenuGtk(this, GetStandardPageMenu(encodings_menu_.get()), |
228 accel_group_)); | 230 accel_group_)); |
229 g_signal_connect(page_menu_->widget(), "motion-notify-event", | |
230 G_CALLBACK(OnPageAppMenuMouseMotion), this); | |
231 g_signal_connect(page_menu_->widget(), "move-current", | |
232 G_CALLBACK(OnPageAppMenuMoveCurrent), this); | |
233 gtk_box_pack_start(GTK_BOX(menus_hbox_), page_menu, FALSE, FALSE, 0); | 231 gtk_box_pack_start(GTK_BOX(menus_hbox_), page_menu, FALSE, FALSE, 0); |
234 | 232 |
235 GtkWidget* chrome_menu = BuildToolbarMenuButton( | 233 GtkWidget* chrome_menu = BuildToolbarMenuButton( |
236 l10n_util::GetStringFUTF8(IDS_APPMENU_TOOLTIP, | 234 l10n_util::GetStringFUTF8(IDS_APPMENU_TOOLTIP, |
237 WideToUTF16(l10n_util::GetString(IDS_PRODUCT_NAME))), | 235 WideToUTF16(l10n_util::GetString(IDS_PRODUCT_NAME))), |
238 &app_menu_button_); | 236 &app_menu_button_); |
| 237 menu_bar_helper_.Add(app_menu_button_.get()); |
239 app_menu_image_ = gtk_image_new_from_pixbuf( | 238 app_menu_image_ = gtk_image_new_from_pixbuf( |
240 theme_provider_->GetRTLEnabledPixbufNamed(IDR_MENU_CHROME)); | 239 theme_provider_->GetRTLEnabledPixbufNamed(IDR_MENU_CHROME)); |
241 gtk_container_add(GTK_CONTAINER(chrome_menu), app_menu_image_); | 240 gtk_container_add(GTK_CONTAINER(chrome_menu), app_menu_image_); |
242 app_menu_.reset(new MenuGtk(this, GetStandardAppMenu(), accel_group_)); | 241 app_menu_.reset(new MenuGtk(this, GetStandardAppMenu(), accel_group_)); |
243 g_signal_connect(app_menu_->widget(), "motion-notify-event", | |
244 G_CALLBACK(OnPageAppMenuMouseMotion), this); | |
245 g_signal_connect(app_menu_->widget(), "move-current", | |
246 G_CALLBACK(OnPageAppMenuMoveCurrent), this); | |
247 gtk_box_pack_start(GTK_BOX(menus_hbox_), chrome_menu, FALSE, FALSE, 0); | 242 gtk_box_pack_start(GTK_BOX(menus_hbox_), chrome_menu, FALSE, FALSE, 0); |
248 | 243 |
249 gtk_box_pack_start(GTK_BOX(toolbar_), menus_hbox_, FALSE, FALSE, 0); | 244 gtk_box_pack_start(GTK_BOX(toolbar_), menus_hbox_, FALSE, FALSE, 0); |
250 | 245 |
251 // Page and app menu accelerators. | 246 // Page and app menu accelerators. |
252 GtkAccelGroup* accel_group = gtk_accel_group_new(); | 247 GtkAccelGroup* accel_group = gtk_accel_group_new(); |
253 gtk_window_add_accel_group(top_level_window, accel_group); | 248 gtk_window_add_accel_group(top_level_window, accel_group); |
254 // Drop the initial ref on |accel_group| so |window_| will own it. | 249 // Drop the initial ref on |accel_group| so |window_| will own it. |
255 g_object_unref(accel_group); | 250 g_object_unref(accel_group); |
256 // I would use "popup-menu" here, but GTK complains. I would use "activate", | 251 // I would use "popup-menu" here, but GTK complains. I would use "activate", |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
639 GdkEventButton* event, | 634 GdkEventButton* event, |
640 BrowserToolbarGtk* toolbar) { | 635 BrowserToolbarGtk* toolbar) { |
641 if (event->button != 1) | 636 if (event->button != 1) |
642 return FALSE; | 637 return FALSE; |
643 | 638 |
644 gtk_chrome_button_set_paint_state(GTK_CHROME_BUTTON(button), | 639 gtk_chrome_button_set_paint_state(GTK_CHROME_BUTTON(button), |
645 GTK_STATE_ACTIVE); | 640 GTK_STATE_ACTIVE); |
646 MenuGtk* menu = button == toolbar->page_menu_button_.get() ? | 641 MenuGtk* menu = button == toolbar->page_menu_button_.get() ? |
647 toolbar->page_menu_.get() : toolbar->app_menu_.get(); | 642 toolbar->page_menu_.get() : toolbar->app_menu_.get(); |
648 menu->Popup(button, reinterpret_cast<GdkEvent*>(event)); | 643 menu->Popup(button, reinterpret_cast<GdkEvent*>(event)); |
| 644 toolbar->menu_bar_helper_.MenuStartedShowing(button, menu->widget()); |
649 | 645 |
650 return TRUE; | 646 return TRUE; |
651 } | 647 } |
652 | 648 |
653 // static | 649 // static |
654 gboolean BrowserToolbarGtk::OnMenuClicked(GtkWidget* button, | 650 gboolean BrowserToolbarGtk::OnMenuClicked(GtkWidget* button, |
655 BrowserToolbarGtk* toolbar) { | 651 BrowserToolbarGtk* toolbar) { |
656 gtk_chrome_button_set_paint_state(GTK_CHROME_BUTTON(button), | 652 toolbar->PopupForButton(button); |
657 GTK_STATE_ACTIVE); | |
658 MenuGtk* menu = button == toolbar->page_menu_button_.get() ? | |
659 toolbar->page_menu_.get() : toolbar->app_menu_.get(); | |
660 menu->PopupAsFromKeyEvent(button); | |
661 | 653 |
662 return TRUE; | 654 return TRUE; |
663 } | 655 } |
664 | 656 |
665 // static | 657 // static |
666 void BrowserToolbarGtk::OnDragDataReceived(GtkWidget* widget, | 658 void BrowserToolbarGtk::OnDragDataReceived(GtkWidget* widget, |
667 GdkDragContext* drag_context, gint x, gint y, | 659 GdkDragContext* drag_context, gint x, gint y, |
668 GtkSelectionData* data, guint info, guint time, | 660 GtkSelectionData* data, guint info, guint time, |
669 BrowserToolbarGtk* toolbar) { | 661 BrowserToolbarGtk* toolbar) { |
670 if (info != GtkDndUtil::TEXT_PLAIN) { | 662 if (info != GtkDndUtil::TEXT_PLAIN) { |
671 NOTIMPLEMENTED() << "Only support plain text drops for now, sorry!"; | 663 NOTIMPLEMENTED() << "Only support plain text drops for now, sorry!"; |
672 return; | 664 return; |
673 } | 665 } |
674 | 666 |
675 GURL url(reinterpret_cast<char*>(data->data)); | 667 GURL url(reinterpret_cast<char*>(data->data)); |
676 if (!url.is_valid()) | 668 if (!url.is_valid()) |
677 return; | 669 return; |
678 | 670 |
679 bool url_is_newtab = url.spec() == chrome::kChromeUINewTabURL; | 671 bool url_is_newtab = url.spec() == chrome::kChromeUINewTabURL; |
680 toolbar->profile_->GetPrefs()->SetBoolean(prefs::kHomePageIsNewTabPage, | 672 toolbar->profile_->GetPrefs()->SetBoolean(prefs::kHomePageIsNewTabPage, |
681 url_is_newtab); | 673 url_is_newtab); |
682 if (!url_is_newtab) { | 674 if (!url_is_newtab) { |
683 toolbar->profile_->GetPrefs()->SetString(prefs::kHomePage, | 675 toolbar->profile_->GetPrefs()->SetString(prefs::kHomePage, |
684 UTF8ToWide(url.spec())); | 676 UTF8ToWide(url.spec())); |
685 } | 677 } |
686 } | 678 } |
687 | 679 |
688 // static | |
689 gboolean BrowserToolbarGtk::OnPageAppMenuMouseMotion(GtkWidget* menu, | |
690 GdkEventMotion* event, BrowserToolbarGtk* toolbar) { | |
691 if (gtk_util::WidgetContainsCursor(menu == toolbar->app_menu_->widget() ? | |
692 toolbar->page_menu_button_.get() : | |
693 toolbar->app_menu_button_.get())) { | |
694 toolbar->ChangeActiveMenu(menu, event->time); | |
695 return TRUE; | |
696 } | |
697 | |
698 return FALSE; | |
699 } | |
700 | |
701 // static | |
702 void BrowserToolbarGtk::OnPageAppMenuMoveCurrent(GtkWidget* menu, | |
703 GtkMenuDirectionType dir, BrowserToolbarGtk* toolbar) { | |
704 GtkWidget* active_item = GTK_MENU_SHELL(menu)->active_menu_item; | |
705 | |
706 switch (dir) { | |
707 case GTK_MENU_DIR_CHILD: | |
708 // The move is going to open a submenu; don't override default behavior. | |
709 if (active_item && gtk_menu_item_get_submenu(GTK_MENU_ITEM(active_item))) | |
710 break; | |
711 // Fall through. | |
712 case GTK_MENU_DIR_PARENT: | |
713 toolbar->ChangeActiveMenu(menu, gtk_get_current_event_time()); | |
714 // This signal doesn't have a return value; we have to manually stop its | |
715 // propagation. | |
716 g_signal_stop_emission_by_name(menu, "move-current"); | |
717 default: | |
718 break; | |
719 } | |
720 } | |
721 | |
722 bool BrowserToolbarGtk::ShouldOnlyShowLocation() const { | 680 bool BrowserToolbarGtk::ShouldOnlyShowLocation() const { |
723 // If we're a popup window, only show the location bar (omnibox). | 681 // If we're a popup window, only show the location bar (omnibox). |
724 return browser_->type() != Browser::TYPE_NORMAL; | 682 return browser_->type() != Browser::TYPE_NORMAL; |
725 } | 683 } |
| 684 |
| 685 void BrowserToolbarGtk::PopupForButton(GtkWidget* button) { |
| 686 page_menu_->Cancel(); |
| 687 app_menu_->Cancel(); |
| 688 |
| 689 gtk_chrome_button_set_paint_state(GTK_CHROME_BUTTON(button), |
| 690 GTK_STATE_ACTIVE); |
| 691 MenuGtk* menu = button == page_menu_button_.get() ? |
| 692 page_menu_.get() : app_menu_.get(); |
| 693 menu->PopupAsFromKeyEvent(button); |
| 694 menu_bar_helper_.MenuStartedShowing(button, menu->widget()); |
| 695 } |
| 696 |
| 697 void BrowserToolbarGtk::PopupForButtonNextTo(GtkWidget* button, |
| 698 GtkMenuDirectionType dir) { |
| 699 GtkWidget* other_button = button == page_menu_button_.get() ? |
| 700 app_menu_button_.get() : page_menu_button_.get(); |
| 701 PopupForButton(other_button); |
| 702 } |
OLD | NEW |