summaryrefslogtreecommitdiffstats
path: root/views/controls
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-21 20:56:11 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-21 20:56:11 +0000
commit281e32a4405d515657c156d240b777d5a1cbb031 (patch)
tree5983bd272280eb22c04e3bb1f42a7df7c40b3690 /views/controls
parent3ea8c32bc730e48119b2c86d1c39e7f6d65e1bb6 (diff)
downloadchromium_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/controls')
-rw-r--r--views/controls/menu/menu_2.h4
-rw-r--r--views/controls/menu/native_menu_gtk.cc38
-rw-r--r--views/controls/menu/native_menu_gtk.h22
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);