summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-07 22:31:35 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-07 22:31:35 +0000
commit23512f4ba83ab011aac513972290aa30b26785cd (patch)
treea60e0238bd60a79258de538c4564e984a5cf3506 /chrome
parentb45243c422ce9eddf818d25777fea0f7e7f94e85 (diff)
downloadchromium_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.cc63
-rw-r--r--chrome/browser/gtk/browser_toolbar_gtk.h13
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();