summaryrefslogtreecommitdiffstats
path: root/views/controls/menu/menu_host_gtk.cc
diff options
context:
space:
mode:
Diffstat (limited to 'views/controls/menu/menu_host_gtk.cc')
-rw-r--r--views/controls/menu/menu_host_gtk.cc132
1 files changed, 73 insertions, 59 deletions
diff --git a/views/controls/menu/menu_host_gtk.cc b/views/controls/menu/menu_host_gtk.cc
index bdd8ffe..95fea7b 100644
--- a/views/controls/menu/menu_host_gtk.cc
+++ b/views/controls/menu/menu_host_gtk.cc
@@ -1,8 +1,7 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-
#include "views/controls/menu/menu_host_gtk.h"
#include <gdk/gdk.h>
@@ -14,9 +13,14 @@
namespace views {
-MenuHost::MenuHost(SubmenuView* submenu)
+// static
+MenuHost* MenuHost::Create(SubmenuView* submenu_view) {
+ return new MenuHostGtk(submenu_view);
+}
+
+MenuHostGtk::MenuHostGtk(SubmenuView* submenu)
: WidgetGtk(WidgetGtk::TYPE_POPUP),
- closed_(false),
+ destroying_(false),
submenu_(submenu),
did_pointer_grab_(false) {
GdkEvent* event = gtk_get_current_event();
@@ -29,50 +33,92 @@ MenuHost::MenuHost(SubmenuView* submenu)
}
}
-void MenuHost::Init(gfx::NativeWindow parent,
+MenuHostGtk::~MenuHostGtk() {
+}
+
+void MenuHostGtk::Init(gfx::NativeWindow parent,
const gfx::Rect& bounds,
View* contents_view,
bool do_capture) {
+ make_transient_to_parent();
WidgetGtk::Init(GTK_WIDGET(parent), bounds);
+ // Make sure we get destroyed when the parent is destroyed.
+ gtk_window_set_destroy_with_parent(GTK_WINDOW(GetNativeView()), TRUE);
gtk_window_set_type_hint(GTK_WINDOW(GetNativeView()),
GDK_WINDOW_TYPE_HINT_MENU);
SetContentsView(contents_view);
- Show();
+ ShowMenuHost(do_capture);
+}
+
+bool MenuHostGtk::IsMenuHostVisible() {
+ return IsVisible();
+}
+
+void MenuHostGtk::ShowMenuHost(bool do_capture) {
+ WidgetGtk::Show();
if (do_capture)
DoCapture();
}
-gfx::NativeWindow MenuHost::GetNativeWindow() {
+void MenuHostGtk::HideMenuHost() {
+ // Make sure we release capture before hiding.
+ ReleaseMenuHostCapture();
+
+ WidgetGtk::Hide();
+}
+
+void MenuHostGtk::DestroyMenuHost() {
+ HideMenuHost();
+ destroying_ = true;
+ CloseNow();
+}
+
+void MenuHostGtk::SetMenuHostBounds(const gfx::Rect& bounds) {
+ SetBounds(bounds);
+}
+
+void MenuHostGtk::ReleaseMenuHostCapture() {
+ ReleaseGrab();
+}
+
+gfx::NativeWindow MenuHostGtk::GetMenuHostWindow() {
return GTK_WINDOW(GetNativeView());
}
-void MenuHost::Show() {
- WidgetGtk::Show();
+RootView* MenuHostGtk::CreateRootView() {
+ return new MenuHostRootView(this, submenu_);
+}
+
+bool MenuHostGtk::ReleaseCaptureOnMouseReleased() {
+ return false;
}
-void MenuHost::Hide() {
- if (closed_) {
- // We're already closed, nothing to do.
- // This is invoked twice if the first time just hid us, and the second
- // time deleted Closed (deleted) us.
- return;
+void MenuHostGtk::ReleaseGrab() {
+ WidgetGtk::ReleaseGrab();
+ if (did_pointer_grab_) {
+ did_pointer_grab_ = false;
+ gdk_pointer_ungrab(GDK_CURRENT_TIME);
}
- // The menus are freed separately, and possibly before the window is closed,
- // remove them so that View doesn't try to access deleted objects.
- static_cast<MenuHostRootView*>(GetRootView())->suspend_events();
- GetRootView()->RemoveAllChildViews(false);
- ReleaseGrab();
- closed_ = true;
- WidgetGtk::Hide();
}
-void MenuHost::HideWindow() {
- // Make sure we release capture before hiding.
- ReleaseGrab();
- WidgetGtk::Hide();
+void MenuHostGtk::OnDestroy(GtkWidget* object) {
+ if (!destroying_) {
+ // We weren't explicitly told to destroy ourselves, which means the menu was
+ // deleted out from under us (the window we're parented to was closed). Tell
+ // the SubmenuView to drop references to us.
+ submenu_->MenuHostDestroyed();
+ }
+ WidgetGtk::OnDestroy(object);
+}
+
+gboolean MenuHostGtk::OnGrabBrokeEvent(GtkWidget* widget, GdkEvent* event) {
+ // Grab breaking only happens when drag and drop starts. So, we don't try
+ // and ungrab or cancel the menu.
+ did_pointer_grab_ = false;
+ return WidgetGtk::OnGrabBrokeEvent(widget, event);
}
-void MenuHost::DoCapture() {
+void MenuHostGtk::DoCapture() {
// Release the current grab.
GtkWidget* current_grab_window = gtk_grab_get_current();
if (current_grab_window)
@@ -93,38 +139,6 @@ void MenuHost::DoCapture() {
did_pointer_grab_ = (grab_status == GDK_GRAB_SUCCESS);
DCHECK(did_pointer_grab_);
// need keyboard grab.
-#ifdef DEBUG_MENU
- DLOG(INFO) << "Doing capture";
-#endif
-}
-
-void MenuHost::ReleaseCapture() {
- ReleaseGrab();
-}
-
-RootView* MenuHost::CreateRootView() {
- return new MenuHostRootView(this, submenu_);
-}
-
-gboolean MenuHost::OnGrabBrokeEvent(GtkWidget* widget, GdkEvent* event) {
- // Grab breaking only happens when drag and drop starts. So, we don't try
- // and ungrab or cancel the menu.
- did_pointer_grab_ = false;
- return WidgetGtk::OnGrabBrokeEvent(widget, event);
-}
-
-// Overriden to return false, we do NOT want to release capture on mouse
-// release.
-bool MenuHost::ReleaseCaptureOnMouseReleased() {
- return false;
-}
-
-void MenuHost::ReleaseGrab() {
- WidgetGtk::ReleaseGrab();
- if (did_pointer_grab_) {
- did_pointer_grab_ = false;
- gdk_pointer_ungrab(GDK_CURRENT_TIME);
- }
}
} // namespace views