Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(75)

Side by Side Diff: ui/views/controls/menu/menu_runner_unittest.cc

Issue 2450903002: MacViews: Clear mouse handler when showing context menus. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix test on both Mac and Windows. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/views/controls/menu/menu_runner.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/views/controls/menu/menu_runner.h" 5 #include "ui/views/controls/menu/menu_runner.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <memory> 9 #include <memory>
10 10
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 } 208 }
209 209
210 MenuRunner* runner_; 210 MenuRunner* runner_;
211 Widget* owner_; 211 Widget* owner_;
212 212
213 DISALLOW_COPY_AND_ASSIGN(MenuLauncherEventHandler); 213 DISALLOW_COPY_AND_ASSIGN(MenuLauncherEventHandler);
214 }; 214 };
215 215
216 } // namespace 216 } // namespace
217 217
218 // Test harness that includes a parent Widget and View invoking the menu.
219 class MenuRunnerWidgetTest : public MenuRunnerTest {
220 public:
221 MenuRunnerWidgetTest() {}
222
223 Widget* widget() { return widget_; }
224 EventCountView* event_count_view() { return event_count_view_; }
225
226 std::unique_ptr<ui::test::EventGenerator> EventGeneratorForWidget(
227 Widget* widget) {
228 return base::MakeUnique<ui::test::EventGenerator>(
229 IsMus() ? widget->GetNativeWindow() : GetContext(),
230 widget->GetNativeWindow());
231 }
232
233 void AddMenuLauncherEventHandler(Widget* widget) {
234 consumer_ =
235 base::MakeUnique<MenuLauncherEventHandler>(menu_runner(), widget);
236 event_count_view_->AddPostTargetHandler(consumer_.get());
237 }
238
239 // ViewsTestBase:
240 void SetUp() override {
241 MenuRunnerTest::SetUp();
242 widget_ = new Widget;
243 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
244 widget_->Init(params);
245 widget_->Show();
246 widget_->SetSize(gfx::Size(300, 300));
247
248 event_count_view_ = new EventCountView();
249 event_count_view_->SetBounds(0, 0, 300, 300);
250 widget_->GetRootView()->AddChildView(event_count_view_);
251
252 InitMenuRunner(MenuRunner::ASYNC);
253 }
254
255 void TearDown() override {
256 widget_->CloseNow();
257 MenuRunnerTest::TearDown();
258 }
259
260 private:
261 Widget* widget_ = nullptr;
262 EventCountView* event_count_view_ = nullptr;
263 std::unique_ptr<MenuLauncherEventHandler> consumer_;
264
265 DISALLOW_COPY_AND_ASSIGN(MenuRunnerWidgetTest);
266 };
267
218 // Tests that when a mouse press launches a menu, that the target widget does 268 // Tests that when a mouse press launches a menu, that the target widget does
219 // not take explicit capture, nor closes the menu. 269 // not take explicit capture, nor closes the menu.
220 TEST_F(MenuRunnerTest, WidgetDoesntTakeCapture) { 270 TEST_F(MenuRunnerWidgetTest, WidgetDoesntTakeCapture) {
221 Widget* widget = new Widget; 271 AddMenuLauncherEventHandler(owner());
222 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
223 widget->Init(params);
224 widget->Show();
225 widget->SetSize(gfx::Size(300, 300));
226 272
227 EventCountView* event_count_view = new EventCountView();
228 event_count_view->SetBounds(0, 0, 300, 300);
229 widget->GetRootView()->AddChildView(event_count_view);
230
231 InitMenuRunner(MenuRunner::ASYNC);
232 MenuRunner* runner = menu_runner();
233
234 MenuLauncherEventHandler consumer(runner, owner());
235 event_count_view->AddPostTargetHandler(&consumer);
236 EXPECT_EQ(nullptr, internal::NativeWidgetPrivate::GetGlobalCapture( 273 EXPECT_EQ(nullptr, internal::NativeWidgetPrivate::GetGlobalCapture(
237 widget->GetNativeView())); 274 widget()->GetNativeView()));
238 std::unique_ptr<ui::test::EventGenerator> generator( 275 auto generator(EventGeneratorForWidget(widget()));
239 new ui::test::EventGenerator(
240 IsMus() ? widget->GetNativeWindow() : GetContext(),
241 widget->GetNativeWindow()));
242 // Implicit capture should not be held by |widget|. 276 // Implicit capture should not be held by |widget|.
243 generator->PressLeftButton(); 277 generator->PressLeftButton();
244 EXPECT_EQ(1, event_count_view->GetEventCount(ui::ET_MOUSE_PRESSED)); 278 EXPECT_EQ(1, event_count_view()->GetEventCount(ui::ET_MOUSE_PRESSED));
245 EXPECT_NE( 279 EXPECT_NE(widget()->GetNativeView(),
246 widget->GetNativeView(), 280 internal::NativeWidgetPrivate::GetGlobalCapture(
247 internal::NativeWidgetPrivate::GetGlobalCapture(widget->GetNativeView())); 281 widget()->GetNativeView()));
248 282
249 // The menu should still be open. 283 // The menu should still be open.
250 TestMenuDelegate* delegate = menu_delegate(); 284 TestMenuDelegate* delegate = menu_delegate();
251 EXPECT_TRUE(runner->IsRunning()); 285 EXPECT_TRUE(menu_runner()->IsRunning());
252 EXPECT_EQ(0, delegate->on_menu_closed_called()); 286 EXPECT_EQ(0, delegate->on_menu_closed_called());
287 }
253 288
254 widget->CloseNow(); 289 // Tests that after showing a menu on mouse press, that the subsequent mouse
290 // will be delivered to the correct view, and not to the one that showed the
291 // menu.
292 //
293 // The original bug is reproducible only when showing the menu on mouse press,
294 // as RootView::OnMouseReleased() doesn't have the same behavior.
295 TEST_F(MenuRunnerWidgetTest, ClearsMouseHandlerOnRun) {
296 AddMenuLauncherEventHandler(widget());
297
298 // Create a second view that's supposed to get the second mouse press.
299 EventCountView* second_event_count_view = new EventCountView();
300 widget()->GetRootView()->AddChildView(second_event_count_view);
301
302 widget()->SetBounds(gfx::Rect(0, 0, 200, 100));
303 event_count_view()->SetBounds(0, 0, 100, 100);
304 second_event_count_view->SetBounds(100, 0, 100, 100);
305
306 // Click on the first view to show the menu.
307 auto generator(EventGeneratorForWidget(widget()));
308 generator->MoveMouseTo(event_count_view()->bounds().CenterPoint());
309 generator->PressLeftButton();
310
311 // Pretend we dismissed the menu using normal means, as it doesn't matter.
312 EXPECT_TRUE(menu_runner()->IsRunning());
313 menu_runner()->Cancel();
314
315 // EventGenerator won't allow us to re-send the left button press without
316 // releasing it first. We can't send the release event using the same
317 // generator as it would be handled by the RootView in the main Widget.
318 // In actual application the RootView doesn't see the release event.
319 generator.reset();
320 generator = EventGeneratorForWidget(widget());
321
322 generator->MoveMouseTo(second_event_count_view->bounds().CenterPoint());
323 generator->PressLeftButton();
324 EXPECT_EQ(1, second_event_count_view->GetEventCount(ui::ET_MOUSE_PRESSED));
255 } 325 }
256 326
257 typedef MenuRunnerTest MenuRunnerImplTest; 327 typedef MenuRunnerTest MenuRunnerImplTest;
258 328
259 // Tests that when nested menu runners are destroyed out of order, that 329 // Tests that when nested menu runners are destroyed out of order, that
260 // MenuController is not accessed after it has been destroyed. This should not 330 // MenuController is not accessed after it has been destroyed. This should not
261 // crash on ASAN bots. 331 // crash on ASAN bots.
262 TEST_F(MenuRunnerImplTest, NestedMenuRunnersDestroyedOutOfOrder) { 332 TEST_F(MenuRunnerImplTest, NestedMenuRunnersDestroyedOutOfOrder) {
263 internal::MenuRunnerImpl* menu_runner = 333 internal::MenuRunnerImpl* menu_runner =
264 new internal::MenuRunnerImpl(menu_item_view()); 334 new internal::MenuRunnerImpl(menu_item_view());
(...skipping 20 matching lines...) Expand all
285 menu_runner->OnMenuClosed(internal::MenuControllerDelegate::NOTIFY_DELEGATE, 355 menu_runner->OnMenuClosed(internal::MenuControllerDelegate::NOTIFY_DELEGATE,
286 nullptr, 0); 356 nullptr, 0);
287 357
288 // This should not access the destroyed MenuController 358 // This should not access the destroyed MenuController
289 menu_runner2->Release(); 359 menu_runner2->Release();
290 menu_runner->Release(); 360 menu_runner->Release();
291 } 361 }
292 362
293 } // namespace test 363 } // namespace test
294 } // namespace views 364 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/controls/menu/menu_runner.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698