diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-07 22:31:35 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-07 22:31:35 +0000 |
commit | 23512f4ba83ab011aac513972290aa30b26785cd (patch) | |
tree | a60e0238bd60a79258de538c4564e984a5cf3506 /chrome | |
parent | b45243c422ce9eddf818d25777fea0f7e7f94e85 (diff) | |
download | chromium_src-23512f4ba83ab011aac513972290aa30b26785cd.zip chromium_src-23512f4ba83ab011aac513972290aa30b26785cd.tar.gz chromium_src-23512f4ba83ab011aac513972290aa30b26785cd.tar.bz2 |
Give page/app menu native menu bar feel.
Allow keyboard and mouse navigation between the two while one is open.
BUG=none
TEST=the page and wrench menus feel like a native menubar
Review URL: http://codereview.chromium.org/155164
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@20095 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/gtk/browser_toolbar_gtk.cc | 63 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_toolbar_gtk.h | 13 |
2 files changed, 76 insertions, 0 deletions
diff --git a/chrome/browser/gtk/browser_toolbar_gtk.cc b/chrome/browser/gtk/browser_toolbar_gtk.cc index 8340cef..d65bd81 100644 --- a/chrome/browser/gtk/browser_toolbar_gtk.cc +++ b/chrome/browser/gtk/browser_toolbar_gtk.cc @@ -154,6 +154,10 @@ void BrowserToolbarGtk::Init(Profile* profile, l10n_util::GetStringUTF8(IDS_PAGEMENU_TOOLTIP), &page_menu_button_); page_menu_.reset(new MenuGtk(this, GetStandardPageMenu(), accel_group_)); + g_signal_connect(page_menu_->widget(), "motion-notify-event", + G_CALLBACK(OnPageAppMenuMouseMotion), this); + g_signal_connect(page_menu_->widget(), "move-current", + G_CALLBACK(OnPageAppMenuMoveCurrent), this); gtk_box_pack_start(GTK_BOX(menus_hbox_), page_menu, FALSE, FALSE, 0); GtkWidget* chrome_menu = BuildToolbarMenuButton(IDR_MENU_CHROME, @@ -161,6 +165,10 @@ void BrowserToolbarGtk::Init(Profile* profile, WideToUTF16(l10n_util::GetString(IDS_PRODUCT_NAME))), &app_menu_button_); app_menu_.reset(new MenuGtk(this, GetStandardAppMenu(), accel_group_)); + g_signal_connect(app_menu_->widget(), "motion-notify-event", + G_CALLBACK(OnPageAppMenuMouseMotion), this); + g_signal_connect(app_menu_->widget(), "move-current", + G_CALLBACK(OnPageAppMenuMoveCurrent), this); gtk_box_pack_start(GTK_BOX(menus_hbox_), chrome_menu, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(toolbar_), menus_hbox_, FALSE, FALSE, 0); @@ -377,6 +385,27 @@ void BrowserToolbarGtk::SetUpDragForHomeButton() { G_CALLBACK(OnDragDataReceived), this); } +void BrowserToolbarGtk::ChangeActiveMenu(GtkWidget* active_menu, + guint timestamp) { + MenuGtk* old_menu; + MenuGtk* new_menu; + GtkWidget* relevant_button; + if (active_menu == app_menu_->widget()) { + old_menu = app_menu_.get(); + new_menu = page_menu_.get(); + relevant_button = page_menu_button_.get(); + } else { + old_menu = page_menu_.get(); + new_menu = app_menu_.get(); + relevant_button = app_menu_button_.get(); + } + + old_menu->Cancel(); + gtk_chrome_button_set_paint_state(GTK_CHROME_BUTTON(relevant_button), + GTK_STATE_ACTIVE); + new_menu->Popup(relevant_button, 0, timestamp); +} + // static gboolean BrowserToolbarGtk::OnToolbarExpose(GtkWidget* widget, GdkEventExpose* e, @@ -461,6 +490,40 @@ void BrowserToolbarGtk::OnDragDataReceived(GtkWidget* widget, } } +// static +gboolean BrowserToolbarGtk::OnPageAppMenuMouseMotion(GtkWidget* menu, + GdkEventMotion* event, BrowserToolbarGtk* toolbar) { + if (gtk_util::WidgetContainsCursor(menu == toolbar->app_menu_->widget() ? + toolbar->page_menu_button_.get() : + toolbar->app_menu_button_.get())) { + toolbar->ChangeActiveMenu(menu, event->time); + return TRUE; + } + + return FALSE; +} + +// static +void BrowserToolbarGtk::OnPageAppMenuMoveCurrent(GtkWidget* menu, + GtkMenuDirectionType dir, BrowserToolbarGtk* toolbar) { + GtkWidget* active_item = GTK_MENU_SHELL(menu)->active_menu_item; + + switch (dir) { + case GTK_MENU_DIR_CHILD: + // The move is going to open a submenu; don't override default behavior. + if (active_item && gtk_menu_item_get_submenu(GTK_MENU_ITEM(active_item))) + break; + // Fall through. + case GTK_MENU_DIR_PARENT: + toolbar->ChangeActiveMenu(menu, gtk_get_current_event_time()); + // This signal doesn't have a return value; we have to manually stop its + // propagation. + g_signal_stop_emission_by_name(menu, "move-current"); + default: + break; + } +} + void BrowserToolbarGtk::InitNineBox() { // TODO(estade): use |profile_|? background_ninebox_.reset(new NineBox( diff --git a/chrome/browser/gtk/browser_toolbar_gtk.h b/chrome/browser/gtk/browser_toolbar_gtk.h index 9ed0929..e6d76dc 100644 --- a/chrome/browser/gtk/browser_toolbar_gtk.h +++ b/chrome/browser/gtk/browser_toolbar_gtk.h @@ -109,6 +109,10 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver, // Connect signals for dragging a url onto the home button. void SetUpDragForHomeButton(); + // Helper for the PageAppMenu event handlers. Pops down the currently active + // meun and pops up the other menu. + void ChangeActiveMenu(GtkWidget* active_menu, guint timestamp); + // Gtk callback for the "expose-event" signal. static gboolean OnToolbarExpose(GtkWidget* widget, GdkEventExpose* e, BrowserToolbarGtk* toolbar); @@ -133,6 +137,15 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver, guint info, guint time, BrowserToolbarGtk* toolbar); + // These event handlers are used to fake menu-bar behavior in the page and + // app menus. + static gboolean OnPageAppMenuMouseMotion(GtkWidget* widget, + GdkEventMotion* event, + BrowserToolbarGtk* toolbar); + static void OnPageAppMenuMoveCurrent(GtkWidget* widget, + GtkMenuDirectionType dir, + BrowserToolbarGtk* toolbar); + // Initialize the background NineBox. void InitNineBox(); |