1424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// found in the LICENSE file.
4424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
5e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "ui/views/widget/root_view.h"
6e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
7e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "ui/views/context_menu_controller.h"
8424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ui/views/test/views_test_base.h"
9c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/views/view_targeter.h"
10c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/views/widget/root_view.h"
11424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
12424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)namespace views {
13424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)namespace test {
14424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
15424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)typedef ViewsTestBase RootViewTest;
16424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
17424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)class DeleteOnKeyEventView : public View {
18424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) public:
19424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  explicit DeleteOnKeyEventView(bool* set_on_key) : set_on_key_(set_on_key) {}
20424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual ~DeleteOnKeyEventView() {}
21424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
22424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual bool OnKeyPressed(const ui::KeyEvent& event) OVERRIDE {
23424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    *set_on_key_ = true;
24424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    delete this;
25424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return true;
26424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
27424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
28424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) private:
29424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Set to true in OnKeyPressed().
30424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool* set_on_key_;
31424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
32424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DeleteOnKeyEventView);
33424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
34424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
35c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Verifies deleting a View in OnKeyPressed() doesn't crash and that the
36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// target is marked as destroyed in the returned EventDispatchDetails.
37424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(RootViewTest, DeleteViewDuringKeyEventDispatch) {
38424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  Widget widget;
39424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  Widget::InitParams init_params =
40424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      CreateParams(Widget::InitParams::TYPE_POPUP);
41424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
42424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  widget.Init(init_params);
43424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
44424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool got_key_event = false;
45424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
46424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  View* content = new View;
47424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  widget.SetContentsView(content);
48424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
49424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  View* child = new DeleteOnKeyEventView(&got_key_event);
50424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  content->AddChildView(child);
51424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
52c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Give focus to |child| so that it will be the target of the key event.
53c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  child->SetFocusable(true);
54c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  child->RequestFocus();
55c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
56c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  internal::RootView* root_view =
57c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      static_cast<internal::RootView*>(widget.GetRootView());
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ViewTargeter* view_targeter = new ViewTargeter(root_view);
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  root_view->SetEventTargeter(make_scoped_ptr(view_targeter));
60c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_ESCAPE, ui::EF_NONE);
62c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ui::EventDispatchDetails details = root_view->OnEventFromSource(&key_event);
63c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_TRUE(details.target_destroyed);
64c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_FALSE(details.dispatcher_destroyed);
65424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  EXPECT_TRUE(got_key_event);
66424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
67424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Tracks whether a context menu is shown.
69e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochclass TestContextMenuController : public ContextMenuController {
70e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch public:
71e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  TestContextMenuController()
72e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      : show_context_menu_calls_(0),
73e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        menu_source_view_(NULL),
74e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        menu_source_type_(ui::MENU_SOURCE_NONE) {
75e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
76e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  virtual ~TestContextMenuController() {}
77e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
78e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  int show_context_menu_calls() const { return show_context_menu_calls_; }
79e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  View* menu_source_view() const { return menu_source_view_; }
80e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  ui::MenuSourceType menu_source_type() const { return menu_source_type_; }
81e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
82e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  void Reset() {
83e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    show_context_menu_calls_ = 0;
84e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    menu_source_view_ = NULL;
85e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    menu_source_type_ = ui::MENU_SOURCE_NONE;
86e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
87e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
88e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // ContextMenuController:
89e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  virtual void ShowContextMenuForView(
90e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      View* source,
91e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      const gfx::Point& point,
92e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      ui::MenuSourceType source_type) OVERRIDE {
93e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    show_context_menu_calls_++;
94e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    menu_source_view_ = source;
95e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    menu_source_type_ = source_type;
96e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
97e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
98e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch private:
99e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  int show_context_menu_calls_;
100e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  View* menu_source_view_;
101e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  ui::MenuSourceType menu_source_type_;
102e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
103e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  DISALLOW_COPY_AND_ASSIGN(TestContextMenuController);
104e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch};
105e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
106e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// Tests that context menus are shown for certain key events (Shift+F10
107e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// and VKEY_APPS) by the pre-target handler installed on RootView.
108e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochTEST_F(RootViewTest, ContextMenuFromKeyEvent) {
109e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  Widget widget;
110e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  Widget::InitParams init_params =
111e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      CreateParams(Widget::InitParams::TYPE_POPUP);
112e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
113e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  widget.Init(init_params);
114e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  internal::RootView* root_view =
115e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      static_cast<internal::RootView*>(widget.GetRootView());
116e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
117e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  TestContextMenuController controller;
118e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  View* focused_view = new View;
119e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  focused_view->set_context_menu_controller(&controller);
120e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  widget.SetContentsView(focused_view);
121e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  focused_view->SetFocusable(true);
122e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  focused_view->RequestFocus();
123e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
124e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // No context menu should be shown for a keypress of 'A'.
1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::KeyEvent nomenu_key_event('a', ui::VKEY_A, ui::EF_NONE);
126e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  ui::EventDispatchDetails details =
127e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      root_view->OnEventFromSource(&nomenu_key_event);
128e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_FALSE(details.target_destroyed);
129e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_FALSE(details.dispatcher_destroyed);
130e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(0, controller.show_context_menu_calls());
131e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(NULL, controller.menu_source_view());
132e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(ui::MENU_SOURCE_NONE, controller.menu_source_type());
133e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  controller.Reset();
134e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
135e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // A context menu should be shown for a keypress of Shift+F10.
136e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  ui::KeyEvent menu_key_event(
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ui::ET_KEY_PRESSED, ui::VKEY_F10, ui::EF_SHIFT_DOWN);
138e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  details = root_view->OnEventFromSource(&menu_key_event);
139e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_FALSE(details.target_destroyed);
140e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_FALSE(details.dispatcher_destroyed);
141e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(1, controller.show_context_menu_calls());
142e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(focused_view, controller.menu_source_view());
143e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(ui::MENU_SOURCE_KEYBOARD, controller.menu_source_type());
144e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  controller.Reset();
145e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
146e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // A context menu should be shown for a keypress of VKEY_APPS.
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::KeyEvent menu_key_event2(ui::ET_KEY_PRESSED, ui::VKEY_APPS, ui::EF_NONE);
148e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  details = root_view->OnEventFromSource(&menu_key_event2);
149e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_FALSE(details.target_destroyed);
150e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_FALSE(details.dispatcher_destroyed);
151e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(1, controller.show_context_menu_calls());
152e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(focused_view, controller.menu_source_view());
153e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(ui::MENU_SOURCE_KEYBOARD, controller.menu_source_type());
154e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  controller.Reset();
155e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
156e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// View which handles all gesture events.
158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class GestureHandlingView : public View {
159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GestureHandlingView() {
161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual ~GestureHandlingView() {
164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    event->SetHandled();
168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(GestureHandlingView);
172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Tests that context menus are shown for long press by the post-target handler
175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// installed on the RootView only if the event is targetted at a view which can
176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// show a context menu.
177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(RootViewTest, ContextMenuFromLongPress) {
178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Widget widget;
179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Widget::InitParams init_params =
180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      CreateParams(Widget::InitParams::TYPE_POPUP);
181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
18203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  init_params.bounds = gfx::Rect(100, 100);
183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  widget.Init(init_params);
184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  internal::RootView* root_view =
185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      static_cast<internal::RootView*>(widget.GetRootView());
186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Create a view capable of showing the context menu with two children one of
188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // which handles all gesture events (e.g. a button).
189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestContextMenuController controller;
190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  View* parent_view = new View;
191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  parent_view->set_context_menu_controller(&controller);
192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  widget.SetContentsView(parent_view);
193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  View* gesture_handling_child_view = new GestureHandlingView;
19503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  gesture_handling_child_view->SetBoundsRect(gfx::Rect(10, 10));
196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  parent_view->AddChildView(gesture_handling_child_view);
197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  View* other_child_view = new View;
19903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  other_child_view->SetBoundsRect(gfx::Rect(20, 0, 10, 10));
200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  parent_view->AddChildView(other_child_view);
201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // |parent_view| should not show a context menu as a result of a long press on
203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // |gesture_handling_child_view|.
204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ui::GestureEvent long_press1(
205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      5,
206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      5,
207116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      0,
208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::TimeDelta(),
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS));
2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::EventDispatchDetails details = root_view->OnEventFromSource(&long_press1);
211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ui::GestureEvent end1(
2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      5, 5, 0, base::TimeDelta(), ui::GestureEventDetails(ui::ET_GESTURE_END));
214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  details = root_view->OnEventFromSource(&end1);
215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(details.target_destroyed);
217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(details.dispatcher_destroyed);
218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(0, controller.show_context_menu_calls());
21903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  controller.Reset();
220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // |parent_view| should show a context menu as a result of a long press on
222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // |other_child_view|.
223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ui::GestureEvent long_press2(
224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      25,
225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      5,
226116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      0,
227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::TimeDelta(),
2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS));
229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  details = root_view->OnEventFromSource(&long_press2);
230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ui::GestureEvent end2(
2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      25, 5, 0, base::TimeDelta(), ui::GestureEventDetails(ui::ET_GESTURE_END));
233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  details = root_view->OnEventFromSource(&end2);
234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(details.target_destroyed);
236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(details.dispatcher_destroyed);
237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(1, controller.show_context_menu_calls());
23803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  controller.Reset();
23903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
24003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // |parent_view| should show a context menu as a result of a long press on
24103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // itself.
24203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ui::GestureEvent long_press3(
24303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      50,
24403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      50,
24503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      0,
24603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::TimeDelta(),
2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS));
24803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  details = root_view->OnEventFromSource(&long_press3);
24903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ui::GestureEvent end3(
2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      25, 5, 0, base::TimeDelta(), ui::GestureEventDetails(ui::ET_GESTURE_END));
25203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  details = root_view->OnEventFromSource(&end3);
25303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
25403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_FALSE(details.target_destroyed);
25503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_FALSE(details.dispatcher_destroyed);
25603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(1, controller.show_context_menu_calls());
25703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
25803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
25903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Tests that context menus are not shown for disabled views on a long press.
26003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_F(RootViewTest, ContextMenuFromLongPressOnDisabledView) {
26103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  Widget widget;
26203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  Widget::InitParams init_params =
26303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      CreateParams(Widget::InitParams::TYPE_POPUP);
26403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
26503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  init_params.bounds = gfx::Rect(100, 100);
26603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  widget.Init(init_params);
26703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  internal::RootView* root_view =
26803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      static_cast<internal::RootView*>(widget.GetRootView());
26903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
27003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Create a view capable of showing the context menu with two children one of
27103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // which handles all gesture events (e.g. a button). Also mark this view
27203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // as disabled.
27303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  TestContextMenuController controller;
27403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  View* parent_view = new View;
27503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  parent_view->set_context_menu_controller(&controller);
27603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  parent_view->SetEnabled(false);
27703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  widget.SetContentsView(parent_view);
27803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
27903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  View* gesture_handling_child_view = new GestureHandlingView;
28003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  gesture_handling_child_view->SetBoundsRect(gfx::Rect(10, 10));
28103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  parent_view->AddChildView(gesture_handling_child_view);
28203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
28303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  View* other_child_view = new View;
28403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  other_child_view->SetBoundsRect(gfx::Rect(20, 0, 10, 10));
28503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  parent_view->AddChildView(other_child_view);
28603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
28703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // |parent_view| should not show a context menu as a result of a long press on
28803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // |gesture_handling_child_view|.
28903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ui::GestureEvent long_press1(
29003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      5,
29103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      5,
29203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      0,
29303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::TimeDelta(),
2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS));
29503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ui::EventDispatchDetails details = root_view->OnEventFromSource(&long_press1);
29603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ui::GestureEvent end1(
2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      5, 5, 0, base::TimeDelta(), ui::GestureEventDetails(ui::ET_GESTURE_END));
29903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  details = root_view->OnEventFromSource(&end1);
30003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
30103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_FALSE(details.target_destroyed);
30203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_FALSE(details.dispatcher_destroyed);
30303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(0, controller.show_context_menu_calls());
30403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  controller.Reset();
30503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
30603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // |parent_view| should not show a context menu as a result of a long press on
30703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // |other_child_view|.
30803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ui::GestureEvent long_press2(
30903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      25,
31003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      5,
31103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      0,
31203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::TimeDelta(),
3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS));
31403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  details = root_view->OnEventFromSource(&long_press2);
31503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ui::GestureEvent end2(
3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      25, 5, 0, base::TimeDelta(), ui::GestureEventDetails(ui::ET_GESTURE_END));
31803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  details = root_view->OnEventFromSource(&end2);
31903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
32003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_FALSE(details.target_destroyed);
32103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_FALSE(details.dispatcher_destroyed);
32203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(0, controller.show_context_menu_calls());
32303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  controller.Reset();
32403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
32503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // |parent_view| should not show a context menu as a result of a long press on
32603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // itself.
32703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ui::GestureEvent long_press3(
32803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      50,
32903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      50,
33003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      0,
33103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::TimeDelta(),
3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS));
33303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  details = root_view->OnEventFromSource(&long_press3);
33403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ui::GestureEvent end3(
3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      25, 5, 0, base::TimeDelta(), ui::GestureEventDetails(ui::ET_GESTURE_END));
33703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  details = root_view->OnEventFromSource(&end3);
33803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
33903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_FALSE(details.target_destroyed);
34003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_FALSE(details.dispatcher_destroyed);
34103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(0, controller.show_context_menu_calls());
342cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
344424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}  // namespace test
345424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}  // namespace views
346