summaryrefslogtreecommitdiffstats
path: root/views
diff options
context:
space:
mode:
Diffstat (limited to 'views')
-rw-r--r--views/controls/menu/menu_host_gtk.cc38
-rw-r--r--views/controls/menu/menu_host_gtk.h16
-rw-r--r--views/widget/widget_gtk.cc10
-rw-r--r--views/widget/widget_gtk.h8
4 files changed, 48 insertions, 24 deletions
diff --git a/views/controls/menu/menu_host_gtk.cc b/views/controls/menu/menu_host_gtk.cc
index cc2faeb..8679490 100644
--- a/views/controls/menu/menu_host_gtk.cc
+++ b/views/controls/menu/menu_host_gtk.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -130,20 +130,27 @@ void MenuHostGtk::OnDestroy(GtkWidget* object) {
WidgetGtk::OnDestroy(object);
}
-void MenuHostGtk::HandleGrabBroke() {
- did_input_grab_ = false;
- // Grab can be broken by drag & drop, other menu or screen locker.
- if (!destroying_) {
- MenuController* menu_controller =
- submenu_->GetMenuItem()->GetMenuController();
- if (menu_controller && !menu_controller->drag_in_progress())
- menu_controller->CancelAll();
+void MenuHostGtk::HandleXGrabBroke() {
+ // Grab may already be release in ReleaseGrab.
+ if (did_input_grab_ && !destroying_) {
+ did_input_grab_ = false;
+ CancelAllIfNoDrag();
}
+ WidgetGtk::HandleXGrabBroke();
+}
- WidgetGtk::HandleGrabBroke();
+void MenuHostGtk::HandleGtkGrabBroke() {
+ // Grab can be broken by drag & drop, other menu or screen locker.
+ if (did_input_grab_ && !destroying_) {
+ ReleaseNativeCapture();
+ CancelAllIfNoDrag();
+ }
+ WidgetGtk::HandleGtkGrabBroke();
}
void MenuHostGtk::DoCapture() {
+ DCHECK(!did_input_grab_);
+
// Release the current grab.
GtkWidget* current_grab_window = gtk_grab_get_current();
if (current_grab_window)
@@ -168,6 +175,9 @@ void MenuHostGtk::DoCapture() {
did_input_grab_ = pointer_grab_status == GDK_GRAB_SUCCESS &&
keyboard_grab_status == GDK_GRAB_SUCCESS;
+ DCHECK_EQ(GDK_GRAB_SUCCESS, pointer_grab_status);
+ DCHECK_EQ(GDK_GRAB_SUCCESS, keyboard_grab_status);
+
#if defined(HAVE_XINPUT2) && defined(TOUCH_UI)
::Window window = GDK_WINDOW_XID(window_contents()->window);
Display* display = GDK_WINDOW_XDISPLAY(window_contents()->window);
@@ -179,4 +189,12 @@ void MenuHostGtk::DoCapture() {
// need keyboard grab.
}
+void MenuHostGtk::CancelAllIfNoDrag() {
+ MenuController* menu_controller =
+ submenu_->GetMenuItem()->GetMenuController();
+ if (menu_controller &&
+ !menu_controller->drag_in_progress())
+ menu_controller->CancelAll();
+}
+
} // namespace views
diff --git a/views/controls/menu/menu_host_gtk.h b/views/controls/menu/menu_host_gtk.h
index 626433c..468a351 100644
--- a/views/controls/menu/menu_host_gtk.h
+++ b/views/controls/menu/menu_host_gtk.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -34,21 +34,21 @@ class MenuHostGtk : public WidgetGtk, public MenuHost {
virtual gfx::NativeWindow GetMenuHostWindow() OVERRIDE;
protected:
- virtual RootView* CreateRootView();
+ virtual RootView* CreateRootView() OVERRIDE;
- // Overridden to return false, we do NOT want to release capture on mouse
- // release.
+ // WidgetGtk overrides:
virtual bool ReleaseCaptureOnMouseReleased() OVERRIDE;
-
- // Overridden to also release input grab.
virtual void ReleaseNativeCapture() OVERRIDE;
-
virtual void OnDestroy(GtkWidget* object) OVERRIDE;
- virtual void HandleGrabBroke() OVERRIDE;
+ virtual void HandleGtkGrabBroke() OVERRIDE;
+ virtual void HandleXGrabBroke() OVERRIDE;
private:
void DoCapture();
+ // Cancell all menus unless drag is in progress.
+ void CancelAllIfNoDrag();
+
// If true, DestroyMenuHost has been invoked.
bool destroying_;
diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc
index bd37038..f1594af 100644
--- a/views/widget/widget_gtk.cc
+++ b/views/widget/widget_gtk.cc
@@ -1223,16 +1223,15 @@ gboolean WidgetGtk::OnVisibilityNotify(GtkWidget* widget,
}
gboolean WidgetGtk::OnGrabBrokeEvent(GtkWidget* widget, GdkEvent* event) {
- HandleGrabBroke();
+ HandleXGrabBroke();
return false; // To let other widgets get the event.
}
void WidgetGtk::OnGrabNotify(GtkWidget* widget, gboolean was_grabbed) {
if (!window_contents_)
return; // Grab broke after window destroyed, don't try processing it.
-
gtk_grab_remove(window_contents_);
- HandleGrabBroke();
+ HandleGtkGrabBroke();
}
void WidgetGtk::OnDestroy(GtkWidget* object) {
@@ -1257,7 +1256,10 @@ bool WidgetGtk::ReleaseCaptureOnMouseReleased() {
return true;
}
-void WidgetGtk::HandleGrabBroke() {
+void WidgetGtk::HandleXGrabBroke() {
+}
+
+void WidgetGtk::HandleGtkGrabBroke() {
if (is_mouse_down_)
GetRootView()->ProcessMouseDragCanceled();
is_mouse_down_ = false;
diff --git a/views/widget/widget_gtk.h b/views/widget/widget_gtk.h
index 584be82..4df911c 100644
--- a/views/widget/widget_gtk.h
+++ b/views/widget/widget_gtk.h
@@ -270,9 +270,13 @@ class WidgetGtk : public Widget,
// is true.
virtual bool ReleaseCaptureOnMouseReleased();
- // Invoked when input grab is stolen by other GtkWidget in the same
+ // Invoked when gtk grab is stolen by other GtkWidget in the same
// application.
- virtual void HandleGrabBroke();
+ virtual void HandleGtkGrabBroke();
+
+ // Invoked when X input grab is broken. This typically happen
+ // when a window holding grab is closed without releasing grab.
+ virtual void HandleXGrabBroke();
// Are we a subclass of WindowGtk?
bool is_window_;