diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-21 20:56:11 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-21 20:56:11 +0000 |
commit | 281e32a4405d515657c156d240b777d5a1cbb031 (patch) | |
tree | 5983bd272280eb22c04e3bb1f42a7df7c40b3690 /views | |
parent | 3ea8c32bc730e48119b2c86d1c39e7f6d65e1bb6 (diff) | |
download | chromium_src-281e32a4405d515657c156d240b777d5a1cbb031.zip chromium_src-281e32a4405d515657c156d240b777d5a1cbb031.tar.gz chromium_src-281e32a4405d515657c156d240b777d5a1cbb031.tar.bz2 |
Fixes bug where submenus weren't working on views/gtk. Submenus end up
creating nested menus. This means that the menu Run is invoked on
isn't necessarily the selected menu. I need to push up state to the
menu run is invoked on, otherwise nothing happens when a menu is selected.
BUG=32662
TEST=see bug
Review URL: http://codereview.chromium.org/545142
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@36782 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views')
-rw-r--r-- | views/controls/menu/menu_2.h | 4 | ||||
-rw-r--r-- | views/controls/menu/native_menu_gtk.cc | 38 | ||||
-rw-r--r-- | views/controls/menu/native_menu_gtk.h | 22 |
3 files changed, 52 insertions, 12 deletions
diff --git a/views/controls/menu/menu_2.h b/views/controls/menu/menu_2.h index 2b9ea06..4bfe9b9 100644 --- a/views/controls/menu/menu_2.h +++ b/views/controls/menu/menu_2.h @@ -15,6 +15,8 @@ class Point; namespace views { +class NativeMenuGtk; + // A menu. Populated from a model, and relies on a delegate to execute commands. class Menu2 { public: @@ -51,6 +53,8 @@ class Menu2 { menus::MenuModel* model() const { return model_; } private: + friend class NativeMenuGtk; + menus::MenuModel* model_; // The object that actually implements the menu. diff --git a/views/controls/menu/native_menu_gtk.cc b/views/controls/menu/native_menu_gtk.cc index 8b3ce33..99aeec4 100644 --- a/views/controls/menu/native_menu_gtk.cc +++ b/views/controls/menu/native_menu_gtk.cc @@ -63,11 +63,12 @@ namespace views { // NativeMenuGtk, public: NativeMenuGtk::NativeMenuGtk(menus::MenuModel* model) - : model_(model), + : parent_(NULL), + model_(model), menu_(NULL), menu_shown_(false), suppress_activate_signal_(false), - menu_activated_(false), + activated_menu_(NULL), activated_index_(-1) { } @@ -79,7 +80,8 @@ NativeMenuGtk::~NativeMenuGtk() { // NativeMenuGtk, MenuWrapper implementation: void NativeMenuGtk::RunMenuAt(const gfx::Point& point, int alignment) { - menu_activated_ = false; + activated_menu_ = NULL; + activated_index_ = -1; UpdateStates(); Position position = { point, static_cast<Menu2::Alignment>(alignment) }; @@ -103,10 +105,8 @@ void NativeMenuGtk::RunMenuAt(const gfx::Point& point, int alignment) { // Call into the model after the nested message loop quits. This way if the // model ends up deleting us, or MessageLoop::Quit takes a while, there aren't // any problems. - if (menu_activated_ && model_->IsEnabledAt(activated_index_) && - MenuTypeCanExecute(model_->GetTypeAt(activated_index_))) { - model_->ActivatedAt(activated_index_); - } + if (activated_menu_) + activated_menu_->Activate(); } void NativeMenuGtk::CancelMenu() { @@ -210,6 +210,7 @@ GtkWidget* NativeMenuGtk::AddMenuItemAt(int index, // TODO(beng): we're leaking these objects right now... consider some other // arrangement. Menu2* submenu = new Menu2(model_->GetSubmenuModelAt(index)); + static_cast<NativeMenuGtk*>(submenu->wrapper_.get())->set_parent(this); g_object_set_data(G_OBJECT(menu_item), "submenu", submenu); gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), submenu->GetNativeMenu()); @@ -305,8 +306,13 @@ void NativeMenuGtk::OnActivate(GtkMenuItem* menu_item) { return; } - menu_activated_ = true; - activated_index_ = position; + // NOTE: we get activate messages for submenus when first shown. + if (model_->IsEnabledAt(position) && + MenuTypeCanExecute(model_->GetTypeAt(position))) { + NativeMenuGtk* ancestor = GetAncestor(); + ancestor->activated_menu_ = this; + activated_index_ = position; + } } // static @@ -315,6 +321,20 @@ void NativeMenuGtk::CallActivate(GtkMenuItem* menu_item, native_menu->OnActivate(menu_item); } +NativeMenuGtk* NativeMenuGtk::GetAncestor() { + NativeMenuGtk* ancestor = this; + while (ancestor->parent_) + ancestor = ancestor->parent_; + return ancestor; +} + +void NativeMenuGtk::Activate() { + if (model_->IsEnabledAt(activated_index_) && + MenuTypeCanExecute(model_->GetTypeAt(activated_index_))) { + model_->ActivatedAt(activated_index_); + } +} + //////////////////////////////////////////////////////////////////////////////// // MenuWrapper, public: diff --git a/views/controls/menu/native_menu_gtk.h b/views/controls/menu/native_menu_gtk.h index 8167954..b2aceff 100644 --- a/views/controls/menu/native_menu_gtk.h +++ b/views/controls/menu/native_menu_gtk.h @@ -52,6 +52,18 @@ class NativeMenuGtk : public MenuWrapper { // Gtk signal handlers. static void CallActivate(GtkMenuItem* menu_item, NativeMenuGtk* native_menu); + // Sets the parent of this menu. + void set_parent(NativeMenuGtk* parent) { parent_ = parent; } + + // Returns the root of the menu tree. + NativeMenuGtk* GetAncestor(); + + // Notifies the model the user selected an item. + void Activate(); + + // If we're a submenu, this is the parent. + NativeMenuGtk* parent_; + menus::MenuModel* model_; GtkWidget* menu_; @@ -63,10 +75,14 @@ class NativeMenuGtk : public MenuWrapper { // state is changed by |UpdateStates()| API. bool suppress_activate_signal_; - // Did the user select something from the menu? - bool menu_activated_; + // If the user selects something from the menu this is the menu they selected + // it from. When an item is selected menu_activated_ on the root ancestor is + // set to the menu the user selected and after the nested message loop exits + // Activate is invoked on this menu. + NativeMenuGtk* activated_menu_; - // If menu_activated_ is true, this is the index of the item. + // The index of the item the user selected. This is set on the actual menu the + // user selects and not the root. int activated_index_; DISALLOW_COPY_AND_ASSIGN(NativeMenuGtk); |