summaryrefslogtreecommitdiffstats
path: root/views
diff options
context:
space:
mode:
authorchocobo@google.com <chocobo@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-21 21:31:23 +0000
committerchocobo@google.com <chocobo@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-21 21:31:23 +0000
commitd01a87df31bfe4266d0ce00df7fa4dc063c0611a (patch)
tree6e595acebdb74232149c06d70254172c7824ea0a /views
parentcbd7dcc7c93c7e73443abd6ddc6c140e2e7e98fd (diff)
downloadchromium_src-d01a87df31bfe4266d0ce00df7fa4dc063c0611a.zip
chromium_src-d01a87df31bfe4266d0ce00df7fa4dc063c0611a.tar.gz
chromium_src-d01a87df31bfe4266d0ce00df7fa4dc063c0611a.tar.bz2
Make gtk menu block on call to RunMenuAt.
TEST=none BUG=25429 Review URL: http://codereview.chromium.org/293057 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@29711 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views')
-rw-r--r--views/controls/menu/menu_2.h6
-rw-r--r--views/controls/menu/menu_wrapper.h3
-rw-r--r--views/controls/menu/native_menu_gtk.cc28
-rw-r--r--views/controls/menu/native_menu_gtk.h4
4 files changed, 35 insertions, 6 deletions
diff --git a/views/controls/menu/menu_2.h b/views/controls/menu/menu_2.h
index 3eba306..e91d5d3 100644
--- a/views/controls/menu/menu_2.h
+++ b/views/controls/menu/menu_2.h
@@ -116,9 +116,9 @@ class Menu2 {
ALIGN_TOPRIGHT
};
- // Runs the menu at the specified point. This may or may not block, depending
- // on the platform and type of menu in use. RunContextMenuAt is the same, but
- // the alignment is the default for a context menu.
+ // Runs the menu at the specified point. This method blocks until done.
+ // RunContextMenuAt is the same, but the alignment is the default for a
+ // context menu.
void RunMenuAt(const gfx::Point& point, Alignment alignment);
void RunContextMenuAt(const gfx::Point& point);
diff --git a/views/controls/menu/menu_wrapper.h b/views/controls/menu/menu_wrapper.h
index 740ece2..65d75ce 100644
--- a/views/controls/menu/menu_wrapper.h
+++ b/views/controls/menu/menu_wrapper.h
@@ -20,8 +20,7 @@ class MenuWrapper {
public:
virtual ~MenuWrapper() {}
- // Runs the menu at the specified point. This may or may not block depending
- // on the platform.
+ // Runs the menu at the specified point. This blocks until done.
virtual void RunMenuAt(const gfx::Point& point, int alignment) = 0;
// Cancels the active menu.
diff --git a/views/controls/menu/native_menu_gtk.cc b/views/controls/menu/native_menu_gtk.cc
index aea28b0..b5e59c0 100644
--- a/views/controls/menu/native_menu_gtk.cc
+++ b/views/controls/menu/native_menu_gtk.cc
@@ -8,6 +8,7 @@
#include "app/gfx/gtk_util.h"
#include "base/keyboard_codes.h"
+#include "base/message_loop.h"
#include "base/string_util.h"
#include "base/time.h"
#include "third_party/skia/include/core/SkBitmap.h"
@@ -64,7 +65,10 @@ namespace views {
////////////////////////////////////////////////////////////////////////////////
// NativeMenuGtk, public:
-NativeMenuGtk::NativeMenuGtk(Menu2Model* model) : model_(model), menu_(NULL) {
+NativeMenuGtk::NativeMenuGtk(Menu2Model* model)
+ : model_(model),
+ menu_(NULL),
+ menu_shown_(false) {
}
NativeMenuGtk::~NativeMenuGtk() {
@@ -79,6 +83,14 @@ void NativeMenuGtk::RunMenuAt(const gfx::Point& point, int alignment) {
// TODO(beng): value of '1' will not work for context menus!
gtk_menu_popup(GTK_MENU(menu_), NULL, NULL, MenuPositionFunc, &position, 1,
gtk_get_current_event_time());
+
+ DCHECK(!menu_shown_);
+ menu_shown_ = true;
+
+ // Block until menu is no longer shown by running a nested message loop.
+ MessageLoopForUI::current()->Run(NULL);
+
+ menu_shown_ = false;
}
void NativeMenuGtk::CancelMenu() {
@@ -110,6 +122,17 @@ gfx::NativeMenu NativeMenuGtk::GetNativeMenu() const {
////////////////////////////////////////////////////////////////////////////////
// NativeMenuGtk, private:
+// static
+void NativeMenuGtk::OnMenuHidden(GtkWidget* widget, NativeMenuGtk* menu) {
+ if (!menu->menu_shown_) {
+ // This indicates we don't have a menu open, and should never happen.
+ NOTREACHED();
+ return;
+ }
+ // Quit the nested message loop we spawned in RunMenuAt.
+ MessageLoop::current()->Quit();
+}
+
void NativeMenuGtk::AddSeparatorAt(int index) {
GtkWidget* separator = gtk_separator_menu_item_new();
gtk_widget_show(separator);
@@ -200,6 +223,9 @@ void NativeMenuGtk::ResetMenu() {
if (menu_)
gtk_widget_destroy(menu_);
menu_ = gtk_menu_new();
+ // Listen for "hide" signal so that we know when to return from the blocking
+ // RunMenuAt call.
+ g_signal_connect(G_OBJECT(menu_), "hide", G_CALLBACK(OnMenuHidden), this);
}
// static
diff --git a/views/controls/menu/native_menu_gtk.h b/views/controls/menu/native_menu_gtk.h
index b9fcb45d..768fada 100644
--- a/views/controls/menu/native_menu_gtk.h
+++ b/views/controls/menu/native_menu_gtk.h
@@ -28,6 +28,8 @@ class NativeMenuGtk : public MenuWrapper {
virtual gfx::NativeMenu GetNativeMenu() const;
private:
+ static void OnMenuHidden(GtkWidget* widget, NativeMenuGtk* menu);
+
void AddSeparatorAt(int index);
void AddMenuItemAt(int index, GtkRadioMenuItem** last_radio_item);
@@ -49,6 +51,8 @@ class NativeMenuGtk : public MenuWrapper {
GtkWidget* menu_;
+ bool menu_shown_;
+
DISALLOW_COPY_AND_ASSIGN(NativeMenuGtk);
};