Index: ui/views/widget/widget_interactive_uitest.cc |
diff --git a/ui/views/widget/widget_interactive_uitest.cc b/ui/views/widget/widget_interactive_uitest.cc |
index 5daea56bee39d591452ba4d6dc85249cc194e2f3..c1350589d0c9811d1e236b9bf07e827b7dd0c0eb 100644 |
--- a/ui/views/widget/widget_interactive_uitest.cc |
+++ b/ui/views/widget/widget_interactive_uitest.cc |
@@ -1264,11 +1264,11 @@ TEST_F(WidgetTestInteractive, InitialFocus) { |
namespace { |
-// Used to verify OnMouseCaptureLost() has been invoked. |
-class CaptureLostTrackingWidget : public Widget { |
+// Helper class for CaptureLostTrackingWidget to store whether |
+// OnMouseCaptureLost has been invoked for a widget. |
+class CaptureLostState { |
public: |
- CaptureLostTrackingWidget() : got_capture_lost_(false) {} |
- ~CaptureLostTrackingWidget() override {} |
+ CaptureLostState() : got_capture_lost_(false) {} |
bool GetAndClearGotCaptureLost() { |
bool value = got_capture_lost_; |
@@ -1276,14 +1276,29 @@ class CaptureLostTrackingWidget : public Widget { |
return value; |
} |
+ void OnMouseCaptureLost() { got_capture_lost_ = true; } |
+ |
+ private: |
+ bool got_capture_lost_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(CaptureLostState); |
+}; |
+ |
+// Used to verify OnMouseCaptureLost() has been invoked. |
+class CaptureLostTrackingWidget : public Widget { |
+ public: |
+ CaptureLostTrackingWidget(CaptureLostState* capture_lost_state) |
+ : capture_lost_state_(capture_lost_state) {} |
+ |
// Widget: |
void OnMouseCaptureLost() override { |
- got_capture_lost_ = true; |
+ capture_lost_state_->OnMouseCaptureLost(); |
Widget::OnMouseCaptureLost(); |
} |
private: |
- bool got_capture_lost_; |
+ // Weak. Stores whether OnMouseCaptureLost has been invoked for this widget. |
+ CaptureLostState* capture_lost_state_; |
DISALLOW_COPY_AND_ASSIGN(CaptureLostTrackingWidget); |
}; |
@@ -1313,7 +1328,8 @@ class WidgetCaptureTest : public ViewsTestBase { |
// Verifies Widget::SetCapture() results in updating native capture along with |
// invoking the right Widget function. |
void TestCapture(bool use_desktop_native_widget) { |
- CaptureLostTrackingWidget widget1; |
+ CaptureLostState capture_state1; |
+ CaptureLostTrackingWidget widget1(&capture_state1); |
Widget::InitParams params1 = |
CreateParams(views::Widget::InitParams::TYPE_WINDOW); |
params1.native_widget = |
@@ -1322,7 +1338,8 @@ class WidgetCaptureTest : public ViewsTestBase { |
widget1.Init(params1); |
widget1.Show(); |
- CaptureLostTrackingWidget widget2; |
+ CaptureLostState capture_state2; |
+ CaptureLostTrackingWidget widget2(&capture_state2); |
Widget::InitParams params2 = |
CreateParams(views::Widget::InitParams::TYPE_WINDOW); |
params2.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
@@ -1335,22 +1352,22 @@ class WidgetCaptureTest : public ViewsTestBase { |
widget2.SetCapture(widget2.GetRootView()); |
EXPECT_FALSE(widget1.HasCapture()); |
EXPECT_TRUE(widget2.HasCapture()); |
- EXPECT_FALSE(widget1.GetAndClearGotCaptureLost()); |
- EXPECT_FALSE(widget2.GetAndClearGotCaptureLost()); |
+ EXPECT_FALSE(capture_state1.GetAndClearGotCaptureLost()); |
+ EXPECT_FALSE(capture_state2.GetAndClearGotCaptureLost()); |
// Set capture to widget1 and verify it gets it. |
widget1.SetCapture(widget1.GetRootView()); |
EXPECT_TRUE(widget1.HasCapture()); |
EXPECT_FALSE(widget2.HasCapture()); |
- EXPECT_FALSE(widget1.GetAndClearGotCaptureLost()); |
- EXPECT_TRUE(widget2.GetAndClearGotCaptureLost()); |
+ EXPECT_FALSE(capture_state1.GetAndClearGotCaptureLost()); |
+ EXPECT_TRUE(capture_state2.GetAndClearGotCaptureLost()); |
// Release and verify no one has it. |
widget1.ReleaseCapture(); |
EXPECT_FALSE(widget1.HasCapture()); |
EXPECT_FALSE(widget2.HasCapture()); |
- EXPECT_TRUE(widget1.GetAndClearGotCaptureLost()); |
- EXPECT_FALSE(widget2.GetAndClearGotCaptureLost()); |
+ EXPECT_TRUE(capture_state1.GetAndClearGotCaptureLost()); |
+ EXPECT_FALSE(capture_state2.GetAndClearGotCaptureLost()); |
} |
NativeWidget* CreateNativeWidget(const Widget::InitParams& params, |
@@ -1370,6 +1387,56 @@ TEST_F(WidgetCaptureTest, Capture) { |
TestCapture(false); |
} |
+// Tests to ensure capture is correctly released from a Widget with capture when |
+// it is destroyed. Test for crbug.com/622201. |
+TEST_F(WidgetCaptureTest, DestroyWithCapture_CloseNow) { |
+ CaptureLostState capture_state; |
+ CaptureLostTrackingWidget* widget = |
+ new CaptureLostTrackingWidget(&capture_state); |
+ Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW); |
+ params.native_widget = CreateNativeWidget(params, true, widget); |
+ widget->Init(params); |
+ widget->Show(); |
+ |
+ widget->SetCapture(widget->GetRootView()); |
+ EXPECT_TRUE(widget->HasCapture()); |
+ EXPECT_FALSE(capture_state.GetAndClearGotCaptureLost()); |
+ widget->CloseNow(); |
+ EXPECT_TRUE(capture_state.GetAndClearGotCaptureLost()); |
+} |
+ |
+TEST_F(WidgetCaptureTest, DestroyWithCapture_Close) { |
+ CaptureLostState capture_state; |
+ CaptureLostTrackingWidget* widget = |
+ new CaptureLostTrackingWidget(&capture_state); |
+ Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW); |
+ params.native_widget = CreateNativeWidget(params, true, widget); |
+ widget->Init(params); |
+ widget->Show(); |
+ |
+ widget->SetCapture(widget->GetRootView()); |
+ EXPECT_TRUE(widget->HasCapture()); |
+ EXPECT_FALSE(capture_state.GetAndClearGotCaptureLost()); |
+ widget->Close(); |
+ EXPECT_TRUE(capture_state.GetAndClearGotCaptureLost()); |
+} |
+ |
+TEST_F(WidgetCaptureTest, DestroyWithCapture_WidgetOwnsNativeWidget) { |
+ CaptureLostState capture_state; |
+ CaptureLostTrackingWidget widget(&capture_state); |
+ Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW); |
+ params.native_widget = CreateNativeWidget(params, true, &widget); |
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
+ widget.Init(params); |
+ widget.Show(); |
+ |
+ widget.SetCapture(widget.GetRootView()); |
+ EXPECT_TRUE(widget.HasCapture()); |
+ EXPECT_FALSE(capture_state.GetAndClearGotCaptureLost()); |
+ widget.CloseNow(); |
+ EXPECT_TRUE(capture_state.GetAndClearGotCaptureLost()); |
+} |
+ |
#if !defined(OS_CHROMEOS) |
// See description in TestCapture(). Creates DesktopNativeWidget. |
TEST_F(WidgetCaptureTest, CaptureDesktopNativeWidget) { |