| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <algorithm> | 5 #include <algorithm> |
| 6 #include <set> | 6 #include <set> |
| 7 | 7 |
| 8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| 11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
| 12 #include "base/run_loop.h" | 12 #include "base/run_loop.h" |
| 13 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
| 14 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
| 15 #include "ui/base/events/event_utils.h" | 15 #include "ui/base/events/event_utils.h" |
| 16 #include "ui/gfx/native_widget_types.h" | 16 #include "ui/gfx/native_widget_types.h" |
| 17 #include "ui/gfx/point.h" | 17 #include "ui/gfx/point.h" |
| 18 #include "ui/views/bubble/bubble_delegate.h" | 18 #include "ui/views/bubble/bubble_delegate.h" |
| 19 #include "ui/views/controls/textfield/textfield.h" | 19 #include "ui/views/controls/textfield/textfield.h" |
| 20 #include "ui/views/test/test_views_delegate.h" | 20 #include "ui/views/test/test_views_delegate.h" |
| 21 #include "ui/views/test/views_test_base.h" | 21 #include "ui/views/test/widget_test.h" |
| 22 #include "ui/views/views_delegate.h" | 22 #include "ui/views/views_delegate.h" |
| 23 #include "ui/views/widget/native_widget_delegate.h" | 23 #include "ui/views/widget/native_widget_delegate.h" |
| 24 #include "ui/views/widget/root_view.h" | 24 #include "ui/views/widget/root_view.h" |
| 25 #include "ui/views/window/native_frame_view.h" | 25 #include "ui/views/window/native_frame_view.h" |
| 26 | 26 |
| 27 #if defined(USE_AURA) | 27 #if defined(USE_AURA) |
| 28 #include "ui/aura/client/aura_constants.h" | 28 #include "ui/aura/client/aura_constants.h" |
| 29 #include "ui/aura/env.h" | |
| 30 #include "ui/aura/root_window.h" | 29 #include "ui/aura/root_window.h" |
| 31 #include "ui/aura/test/test_cursor_client.h" | 30 #include "ui/aura/test/test_cursor_client.h" |
| 32 #include "ui/aura/test/test_window_delegate.h" | 31 #include "ui/aura/test/test_window_delegate.h" |
| 33 #include "ui/aura/window.h" | 32 #include "ui/aura/window.h" |
| 34 #include "ui/views/widget/native_widget_aura.h" | 33 #include "ui/views/widget/native_widget_aura.h" |
| 35 #if !defined(OS_CHROMEOS) | 34 #if !defined(OS_CHROMEOS) |
| 36 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" | 35 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" |
| 37 #endif | 36 #endif |
| 38 #elif defined(OS_WIN) | 37 #elif defined(OS_WIN) |
| 39 #include "ui/views/widget/native_widget_win.h" | 38 #include "ui/views/widget/native_widget_win.h" |
| 40 #endif | 39 #endif |
| 41 | 40 |
| 42 namespace views { | 41 namespace views { |
| 43 namespace test { | 42 namespace test { |
| 44 | 43 |
| 45 // A generic typedef to pick up relevant NativeWidget implementations. | |
| 46 #if defined(USE_AURA) | |
| 47 typedef NativeWidgetAura NativeWidgetPlatform; | |
| 48 #elif defined(OS_WIN) | |
| 49 typedef NativeWidgetWin NativeWidgetPlatform; | |
| 50 #endif | |
| 51 | |
| 52 // A widget that assumes mouse capture always works. It won't on Aura in | |
| 53 // testing, so we mock it. | |
| 54 #if defined(USE_AURA) | |
| 55 class NativeWidgetCapture : public NativeWidgetPlatform { | |
| 56 public: | |
| 57 explicit NativeWidgetCapture(internal::NativeWidgetDelegate* delegate) | |
| 58 : NativeWidgetPlatform(delegate), | |
| 59 mouse_capture_(false) {} | |
| 60 virtual ~NativeWidgetCapture() {} | |
| 61 | |
| 62 virtual void SetCapture() OVERRIDE { | |
| 63 mouse_capture_ = true; | |
| 64 } | |
| 65 virtual void ReleaseCapture() OVERRIDE { | |
| 66 if (mouse_capture_) | |
| 67 delegate()->OnMouseCaptureLost(); | |
| 68 mouse_capture_ = false; | |
| 69 } | |
| 70 virtual bool HasCapture() const OVERRIDE { | |
| 71 return mouse_capture_; | |
| 72 } | |
| 73 | |
| 74 private: | |
| 75 bool mouse_capture_; | |
| 76 | |
| 77 DISALLOW_COPY_AND_ASSIGN(NativeWidgetCapture); | |
| 78 }; | |
| 79 #endif | |
| 80 | |
| 81 // A typedef that inserts our mock-capture NativeWidget implementation for | |
| 82 // relevant platforms. | |
| 83 #if defined(USE_AURA) | |
| 84 typedef NativeWidgetCapture NativeWidgetPlatformForTest; | |
| 85 #elif defined(OS_WIN) | |
| 86 typedef NativeWidgetWin NativeWidgetPlatformForTest; | |
| 87 #endif | |
| 88 | |
| 89 // A view that always processes all mouse events. | |
| 90 class MouseView : public View { | |
| 91 public: | |
| 92 MouseView() | |
| 93 : View(), | |
| 94 entered_(0), | |
| 95 exited_(0), | |
| 96 pressed_(0) { | |
| 97 } | |
| 98 virtual ~MouseView() {} | |
| 99 | |
| 100 virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE { | |
| 101 pressed_++; | |
| 102 return true; | |
| 103 } | |
| 104 | |
| 105 virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE { | |
| 106 entered_++; | |
| 107 } | |
| 108 | |
| 109 virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE { | |
| 110 exited_++; | |
| 111 } | |
| 112 | |
| 113 // Return the number of OnMouseEntered calls and reset the counter. | |
| 114 int EnteredCalls() { | |
| 115 int i = entered_; | |
| 116 entered_ = 0; | |
| 117 return i; | |
| 118 } | |
| 119 | |
| 120 // Return the number of OnMouseExited calls and reset the counter. | |
| 121 int ExitedCalls() { | |
| 122 int i = exited_; | |
| 123 exited_ = 0; | |
| 124 return i; | |
| 125 } | |
| 126 | |
| 127 int pressed() const { return pressed_; } | |
| 128 | |
| 129 private: | |
| 130 int entered_; | |
| 131 int exited_; | |
| 132 | |
| 133 int pressed_; | |
| 134 | |
| 135 DISALLOW_COPY_AND_ASSIGN(MouseView); | |
| 136 }; | |
| 137 | |
| 138 // A view that keeps track of the events it receives, but consumes no events. | 44 // A view that keeps track of the events it receives, but consumes no events. |
| 139 class EventCountView : public View { | 45 class EventCountView : public View { |
| 140 public: | 46 public: |
| 141 EventCountView() {} | 47 EventCountView() {} |
| 142 virtual ~EventCountView() {} | 48 virtual ~EventCountView() {} |
| 143 | 49 |
| 144 int GetEventCount(ui::EventType type) { | 50 int GetEventCount(ui::EventType type) { |
| 145 return event_count_[type]; | 51 return event_count_[type]; |
| 146 } | 52 } |
| 147 | 53 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 event->SetHandled(); | 102 event->SetHandled(); |
| 197 break; | 103 break; |
| 198 default: | 104 default: |
| 199 break; | 105 break; |
| 200 } | 106 } |
| 201 } | 107 } |
| 202 | 108 |
| 203 DISALLOW_COPY_AND_ASSIGN(ScrollableEventCountView); | 109 DISALLOW_COPY_AND_ASSIGN(ScrollableEventCountView); |
| 204 }; | 110 }; |
| 205 | 111 |
| 206 // A view that does a capture on gesture-begin events. | |
| 207 class GestureCaptureView : public View { | |
| 208 public: | |
| 209 GestureCaptureView() {} | |
| 210 virtual ~GestureCaptureView() {} | |
| 211 | |
| 212 private: | |
| 213 // Overridden from View: | |
| 214 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE { | |
| 215 if (event->type() == ui::ET_GESTURE_BEGIN) { | |
| 216 GetWidget()->SetCapture(this); | |
| 217 event->StopPropagation(); | |
| 218 } | |
| 219 } | |
| 220 | |
| 221 DISALLOW_COPY_AND_ASSIGN(GestureCaptureView); | |
| 222 }; | |
| 223 | |
| 224 // A view that implements GetMinimumSize. | 112 // A view that implements GetMinimumSize. |
| 225 class MinimumSizeFrameView : public NativeFrameView { | 113 class MinimumSizeFrameView : public NativeFrameView { |
| 226 public: | 114 public: |
| 227 explicit MinimumSizeFrameView(Widget* frame): NativeFrameView(frame) {} | 115 explicit MinimumSizeFrameView(Widget* frame): NativeFrameView(frame) {} |
| 228 virtual ~MinimumSizeFrameView() {} | 116 virtual ~MinimumSizeFrameView() {} |
| 229 | 117 |
| 230 private: | 118 private: |
| 231 // Overridden from View: | 119 // Overridden from View: |
| 232 virtual gfx::Size GetMinimumSize() OVERRIDE { | 120 virtual gfx::Size GetMinimumSize() OVERRIDE { |
| 233 return gfx::Size(300, 400); | 121 return gfx::Size(300, 400); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 261 private: | 149 private: |
| 262 void RecordEvent(const ui::Event& event) { | 150 void RecordEvent(const ui::Event& event) { |
| 263 ++event_count_[event.type()]; | 151 ++event_count_[event.type()]; |
| 264 } | 152 } |
| 265 | 153 |
| 266 std::map<ui::EventType, int> event_count_; | 154 std::map<ui::EventType, int> event_count_; |
| 267 | 155 |
| 268 DISALLOW_COPY_AND_ASSIGN(EventCountHandler); | 156 DISALLOW_COPY_AND_ASSIGN(EventCountHandler); |
| 269 }; | 157 }; |
| 270 | 158 |
| 271 // A View that shows a different widget, sets capture on that widget, and | |
| 272 // initiates a nested message-loop when it receives a mouse-press event. | |
| 273 class NestedLoopCaptureView : public View { | |
| 274 public: | |
| 275 explicit NestedLoopCaptureView(Widget* widget) : widget_(widget) {} | |
| 276 virtual ~NestedLoopCaptureView() {} | |
| 277 | |
| 278 private: | |
| 279 // Overridden from View: | |
| 280 virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE { | |
| 281 // Start a nested loop. | |
| 282 widget_->Show(); | |
| 283 widget_->SetCapture(widget_->GetContentsView()); | |
| 284 EXPECT_TRUE(widget_->HasCapture()); | |
| 285 | |
| 286 base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); | |
| 287 base::MessageLoop::ScopedNestableTaskAllower allow(loop); | |
| 288 | |
| 289 base::RunLoop run_loop; | |
| 290 #if defined(USE_AURA) | |
| 291 run_loop.set_dispatcher(aura::Env::GetInstance()->GetDispatcher()); | |
| 292 #endif | |
| 293 run_loop.Run(); | |
| 294 return true; | |
| 295 } | |
| 296 | |
| 297 Widget* widget_; | |
| 298 | |
| 299 DISALLOW_COPY_AND_ASSIGN(NestedLoopCaptureView); | |
| 300 }; | |
| 301 | |
| 302 // A View that closes the Widget and exits the current message-loop when it | |
| 303 // receives a mouse-release event. | |
| 304 class ExitLoopOnRelease : public View { | |
| 305 public: | |
| 306 ExitLoopOnRelease() {} | |
| 307 virtual ~ExitLoopOnRelease() {} | |
| 308 | |
| 309 private: | |
| 310 // Overridden from View: | |
| 311 virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE { | |
| 312 GetWidget()->Close(); | |
| 313 base::MessageLoop::current()->QuitNow(); | |
| 314 } | |
| 315 | |
| 316 DISALLOW_COPY_AND_ASSIGN(ExitLoopOnRelease); | |
| 317 }; | |
| 318 | |
| 319 class WidgetTest : public ViewsTestBase { | |
| 320 public: | |
| 321 WidgetTest() {} | |
| 322 virtual ~WidgetTest() {} | |
| 323 | |
| 324 NativeWidget* CreatePlatformNativeWidget( | |
| 325 internal::NativeWidgetDelegate* delegate) { | |
| 326 return new NativeWidgetPlatformForTest(delegate); | |
| 327 } | |
| 328 | |
| 329 Widget* CreateTopLevelPlatformWidget() { | |
| 330 Widget* toplevel = new Widget; | |
| 331 Widget::InitParams toplevel_params = | |
| 332 CreateParams(Widget::InitParams::TYPE_WINDOW); | |
| 333 toplevel_params.native_widget = CreatePlatformNativeWidget(toplevel); | |
| 334 toplevel->Init(toplevel_params); | |
| 335 return toplevel; | |
| 336 } | |
| 337 | |
| 338 Widget* CreateTopLevelFramelessPlatformWidget() { | |
| 339 Widget* toplevel = new Widget; | |
| 340 Widget::InitParams toplevel_params = | |
| 341 CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS); | |
| 342 toplevel_params.native_widget = CreatePlatformNativeWidget(toplevel); | |
| 343 toplevel->Init(toplevel_params); | |
| 344 return toplevel; | |
| 345 } | |
| 346 | |
| 347 Widget* CreateChildPlatformWidget(gfx::NativeView parent_native_view) { | |
| 348 Widget* child = new Widget; | |
| 349 Widget::InitParams child_params = | |
| 350 CreateParams(Widget::InitParams::TYPE_CONTROL); | |
| 351 child_params.native_widget = CreatePlatformNativeWidget(child); | |
| 352 child_params.parent = parent_native_view; | |
| 353 child->Init(child_params); | |
| 354 child->SetContentsView(new View); | |
| 355 return child; | |
| 356 } | |
| 357 | |
| 358 #if defined(OS_WIN) && !defined(USE_AURA) | |
| 359 // On Windows, it is possible for us to have a child window that is | |
| 360 // TYPE_POPUP. | |
| 361 Widget* CreateChildPopupPlatformWidget(gfx::NativeView parent_native_view) { | |
| 362 Widget* child = new Widget; | |
| 363 Widget::InitParams child_params = | |
| 364 CreateParams(Widget::InitParams::TYPE_POPUP); | |
| 365 child_params.child = true; | |
| 366 child_params.native_widget = CreatePlatformNativeWidget(child); | |
| 367 child_params.parent = parent_native_view; | |
| 368 child->Init(child_params); | |
| 369 child->SetContentsView(new View); | |
| 370 return child; | |
| 371 } | |
| 372 #endif | |
| 373 | |
| 374 Widget* CreateTopLevelNativeWidget() { | |
| 375 Widget* toplevel = new Widget; | |
| 376 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW); | |
| 377 toplevel->Init(params); | |
| 378 return toplevel; | |
| 379 } | |
| 380 | |
| 381 Widget* CreateChildNativeWidgetWithParent(Widget* parent) { | |
| 382 Widget* child = new Widget; | |
| 383 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_CONTROL); | |
| 384 params.parent = parent->GetNativeView(); | |
| 385 child->Init(params); | |
| 386 child->SetContentsView(new View); | |
| 387 return child; | |
| 388 } | |
| 389 | |
| 390 Widget* CreateChildNativeWidget() { | |
| 391 return CreateChildNativeWidgetWithParent(NULL); | |
| 392 } | |
| 393 | |
| 394 View* GetMousePressedHandler(internal::RootView* root_view) { | |
| 395 return root_view->mouse_pressed_handler_; | |
| 396 } | |
| 397 | |
| 398 View* GetMouseMoveHandler(internal::RootView* root_view) { | |
| 399 return root_view->mouse_move_handler_; | |
| 400 } | |
| 401 | |
| 402 View* GetGestureHandler(internal::RootView* root_view) { | |
| 403 return root_view->gesture_handler_; | |
| 404 } | |
| 405 }; | |
| 406 | |
| 407 bool WidgetHasMouseCapture(const Widget* widget) { | |
| 408 return static_cast<const internal::NativeWidgetPrivate*>(widget-> | |
| 409 native_widget())->HasCapture(); | |
| 410 } | |
| 411 | |
| 412 ui::WindowShowState GetWidgetShowState(const Widget* widget) { | 159 ui::WindowShowState GetWidgetShowState(const Widget* widget) { |
| 413 // Use IsMaximized/IsMinimized/IsFullScreen instead of GetWindowPlacement | 160 // Use IsMaximized/IsMinimized/IsFullScreen instead of GetWindowPlacement |
| 414 // because the former is implemented on all platforms but the latter is not. | 161 // because the former is implemented on all platforms but the latter is not. |
| 415 return widget->IsFullscreen() ? ui::SHOW_STATE_FULLSCREEN : | 162 return widget->IsFullscreen() ? ui::SHOW_STATE_FULLSCREEN : |
| 416 widget->IsMaximized() ? ui::SHOW_STATE_MAXIMIZED : | 163 widget->IsMaximized() ? ui::SHOW_STATE_MAXIMIZED : |
| 417 widget->IsMinimized() ? ui::SHOW_STATE_MINIMIZED : | 164 widget->IsMinimized() ? ui::SHOW_STATE_MINIMIZED : |
| 418 ui::SHOW_STATE_NORMAL; | 165 ui::SHOW_STATE_NORMAL; |
| 419 } | 166 } |
| 420 | 167 |
| 421 TEST_F(WidgetTest, WidgetInitParams) { | 168 TEST_F(WidgetTest, WidgetInitParams) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 448 gfx::NativeView parent = toplevel->GetNativeView(); | 195 gfx::NativeView parent = toplevel->GetNativeView(); |
| 449 Widget* child = CreateChildPlatformWidget(parent); | 196 Widget* child = CreateChildPlatformWidget(parent); |
| 450 | 197 |
| 451 EXPECT_EQ(toplevel, toplevel->GetTopLevelWidget()); | 198 EXPECT_EQ(toplevel, toplevel->GetTopLevelWidget()); |
| 452 EXPECT_EQ(toplevel, child->GetTopLevelWidget()); | 199 EXPECT_EQ(toplevel, child->GetTopLevelWidget()); |
| 453 | 200 |
| 454 toplevel->CloseNow(); | 201 toplevel->CloseNow(); |
| 455 // |child| should be automatically destroyed with |toplevel|. | 202 // |child| should be automatically destroyed with |toplevel|. |
| 456 } | 203 } |
| 457 | 204 |
| 458 // Tests some grab/ungrab events. | |
| 459 TEST_F(WidgetTest, DISABLED_GrabUngrab) { | |
| 460 Widget* toplevel = CreateTopLevelPlatformWidget(); | |
| 461 Widget* child1 = CreateChildNativeWidgetWithParent(toplevel); | |
| 462 Widget* child2 = CreateChildNativeWidgetWithParent(toplevel); | |
| 463 | |
| 464 toplevel->SetBounds(gfx::Rect(0, 0, 500, 500)); | |
| 465 | |
| 466 child1->SetBounds(gfx::Rect(10, 10, 300, 300)); | |
| 467 View* view = new MouseView(); | |
| 468 view->SetBounds(0, 0, 300, 300); | |
| 469 child1->GetRootView()->AddChildView(view); | |
| 470 | |
| 471 child2->SetBounds(gfx::Rect(200, 10, 200, 200)); | |
| 472 view = new MouseView(); | |
| 473 view->SetBounds(0, 0, 200, 200); | |
| 474 child2->GetRootView()->AddChildView(view); | |
| 475 | |
| 476 toplevel->Show(); | |
| 477 RunPendingMessages(); | |
| 478 | |
| 479 // Click on child1 | |
| 480 gfx::Point p1(45, 45); | |
| 481 ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, p1, p1, | |
| 482 ui::EF_LEFT_MOUSE_BUTTON); | |
| 483 toplevel->OnMouseEvent(&pressed); | |
| 484 | |
| 485 EXPECT_TRUE(WidgetHasMouseCapture(toplevel)); | |
| 486 EXPECT_TRUE(WidgetHasMouseCapture(child1)); | |
| 487 EXPECT_FALSE(WidgetHasMouseCapture(child2)); | |
| 488 | |
| 489 ui::MouseEvent released(ui::ET_MOUSE_RELEASED, p1, p1, | |
| 490 ui::EF_LEFT_MOUSE_BUTTON); | |
| 491 toplevel->OnMouseEvent(&released); | |
| 492 | |
| 493 EXPECT_FALSE(WidgetHasMouseCapture(toplevel)); | |
| 494 EXPECT_FALSE(WidgetHasMouseCapture(child1)); | |
| 495 EXPECT_FALSE(WidgetHasMouseCapture(child2)); | |
| 496 | |
| 497 RunPendingMessages(); | |
| 498 | |
| 499 // Click on child2 | |
| 500 gfx::Point p2(315, 45); | |
| 501 ui::MouseEvent pressed2(ui::ET_MOUSE_PRESSED, p2, p2, | |
| 502 ui::EF_LEFT_MOUSE_BUTTON); | |
| 503 toplevel->OnMouseEvent(&pressed2); | |
| 504 EXPECT_TRUE(pressed2.handled()); | |
| 505 EXPECT_TRUE(WidgetHasMouseCapture(toplevel)); | |
| 506 EXPECT_TRUE(WidgetHasMouseCapture(child2)); | |
| 507 EXPECT_FALSE(WidgetHasMouseCapture(child1)); | |
| 508 | |
| 509 ui::MouseEvent released2(ui::ET_MOUSE_RELEASED, p2, p2, | |
| 510 ui::EF_LEFT_MOUSE_BUTTON); | |
| 511 toplevel->OnMouseEvent(&released2); | |
| 512 EXPECT_FALSE(WidgetHasMouseCapture(toplevel)); | |
| 513 EXPECT_FALSE(WidgetHasMouseCapture(child1)); | |
| 514 EXPECT_FALSE(WidgetHasMouseCapture(child2)); | |
| 515 | |
| 516 toplevel->CloseNow(); | |
| 517 } | |
| 518 | |
| 519 // Tests mouse move outside of the window into the "resize controller" and back | |
| 520 // will still generate an OnMouseEntered and OnMouseExited event.. | |
| 521 TEST_F(WidgetTest, CheckResizeControllerEvents) { | |
| 522 Widget* toplevel = CreateTopLevelPlatformWidget(); | |
| 523 | |
| 524 toplevel->SetBounds(gfx::Rect(0, 0, 100, 100)); | |
| 525 | |
| 526 MouseView* view = new MouseView(); | |
| 527 view->SetBounds(90, 90, 10, 10); | |
| 528 toplevel->GetRootView()->AddChildView(view); | |
| 529 | |
| 530 toplevel->Show(); | |
| 531 RunPendingMessages(); | |
| 532 | |
| 533 // Move to an outside position. | |
| 534 gfx::Point p1(200, 200); | |
| 535 ui::MouseEvent moved_out(ui::ET_MOUSE_MOVED, p1, p1, ui::EF_NONE); | |
| 536 toplevel->OnMouseEvent(&moved_out); | |
| 537 EXPECT_EQ(0, view->EnteredCalls()); | |
| 538 EXPECT_EQ(0, view->ExitedCalls()); | |
| 539 | |
| 540 // Move onto the active view. | |
| 541 gfx::Point p2(95, 95); | |
| 542 ui::MouseEvent moved_over(ui::ET_MOUSE_MOVED, p2, p2, ui::EF_NONE); | |
| 543 toplevel->OnMouseEvent(&moved_over); | |
| 544 EXPECT_EQ(1, view->EnteredCalls()); | |
| 545 EXPECT_EQ(0, view->ExitedCalls()); | |
| 546 | |
| 547 // Move onto the outer resizing border. | |
| 548 gfx::Point p3(102, 95); | |
| 549 ui::MouseEvent moved_resizer(ui::ET_MOUSE_MOVED, p3, p3, ui::EF_NONE); | |
| 550 toplevel->OnMouseEvent(&moved_resizer); | |
| 551 EXPECT_EQ(0, view->EnteredCalls()); | |
| 552 EXPECT_EQ(1, view->ExitedCalls()); | |
| 553 | |
| 554 // Move onto the view again. | |
| 555 toplevel->OnMouseEvent(&moved_over); | |
| 556 EXPECT_EQ(1, view->EnteredCalls()); | |
| 557 EXPECT_EQ(0, view->ExitedCalls()); | |
| 558 | |
| 559 RunPendingMessages(); | |
| 560 | |
| 561 toplevel->CloseNow(); | |
| 562 } | |
| 563 | |
| 564 // Test if a focus manager and an inputmethod work without CHECK failure | 205 // Test if a focus manager and an inputmethod work without CHECK failure |
| 565 // when window activation changes. | 206 // when window activation changes. |
| 566 TEST_F(WidgetTest, ChangeActivation) { | 207 TEST_F(WidgetTest, ChangeActivation) { |
| 567 Widget* top1 = CreateTopLevelPlatformWidget(); | 208 Widget* top1 = CreateTopLevelPlatformWidget(); |
| 568 // CreateInputMethod before activated | 209 // CreateInputMethod before activated |
| 569 top1->GetInputMethod(); | 210 top1->GetInputMethod(); |
| 570 top1->Show(); | 211 top1->Show(); |
| 571 RunPendingMessages(); | 212 RunPendingMessages(); |
| 572 | 213 |
| 573 Widget* top2 = CreateTopLevelPlatformWidget(); | 214 Widget* top2 = CreateTopLevelPlatformWidget(); |
| (...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1267 RunPendingMessages(); | 908 RunPendingMessages(); |
| 1268 | 909 |
| 1269 // And it stays maximized after getting out of full screen. | 910 // And it stays maximized after getting out of full screen. |
| 1270 EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, GetWidgetShowState(toplevel)); | 911 EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, GetWidgetShowState(toplevel)); |
| 1271 | 912 |
| 1272 // Clean up. | 913 // Clean up. |
| 1273 toplevel->Close(); | 914 toplevel->Close(); |
| 1274 RunPendingMessages(); | 915 RunPendingMessages(); |
| 1275 } | 916 } |
| 1276 | 917 |
| 1277 // Checks that if a mouse-press triggers a capture on a different widget (which | |
| 1278 // consumes the mouse-release event), then the target of the press does not have | |
| 1279 // capture. | |
| 1280 // Fails on chromium.webkit Windows bot, see crbug.com/264872. | |
| 1281 #if defined(OS_WIN) | |
| 1282 #define MAYBE_DisableCaptureWidgetFromMousePress\ | |
| 1283 DISABLED_CaptureWidgetFromMousePress | |
| 1284 #else | |
| 1285 #define MAYBE_DisableCaptureWidgetFromMousePress\ | |
| 1286 CaptureWidgetFromMousePress | |
| 1287 #endif | |
| 1288 TEST_F(WidgetTest, MAYBE_DisableCaptureWidgetFromMousePress) { | |
| 1289 // The test creates two widgets: |first| and |second|. | |
| 1290 // The View in |first| makes |second| visible, sets capture on it, and starts | |
| 1291 // a nested loop (like a menu does). The View in |second| terminates the | |
| 1292 // nested loop and closes the widget. | |
| 1293 // The test sends a mouse-press event to |first|, and posts a task to send a | |
| 1294 // release event to |second|, to make sure that the release event is | |
| 1295 // dispatched after the nested loop starts. | |
| 1296 | |
| 1297 Widget* first = CreateTopLevelFramelessPlatformWidget(); | |
| 1298 Widget* second = CreateTopLevelFramelessPlatformWidget(); | |
| 1299 | |
| 1300 View* container = new NestedLoopCaptureView(second); | |
| 1301 first->SetContentsView(container); | |
| 1302 | |
| 1303 second->SetContentsView(new ExitLoopOnRelease()); | |
| 1304 | |
| 1305 first->SetSize(gfx::Size(100, 100)); | |
| 1306 first->Show(); | |
| 1307 | |
| 1308 gfx::Point location(20, 20); | |
| 1309 base::MessageLoop::current()->PostTask(FROM_HERE, | |
| 1310 base::Bind(&Widget::OnMouseEvent, | |
| 1311 base::Unretained(second), | |
| 1312 base::Owned(new ui::MouseEvent(ui::ET_MOUSE_RELEASED, | |
| 1313 location, | |
| 1314 location, | |
| 1315 ui::EF_LEFT_MOUSE_BUTTON)))); | |
| 1316 ui::MouseEvent press(ui::ET_MOUSE_PRESSED, location, location, | |
| 1317 ui::EF_LEFT_MOUSE_BUTTON); | |
| 1318 first->OnMouseEvent(&press); | |
| 1319 EXPECT_FALSE(first->HasCapture()); | |
| 1320 first->Close(); | |
| 1321 RunPendingMessages(); | |
| 1322 } | |
| 1323 | |
| 1324 TEST_F(WidgetTest, ResetCaptureOnGestureEnd) { | |
| 1325 Widget* toplevel = CreateTopLevelFramelessPlatformWidget(); | |
| 1326 View* container = new View; | |
| 1327 toplevel->SetContentsView(container); | |
| 1328 | |
| 1329 View* gesture = new GestureCaptureView; | |
| 1330 gesture->SetBounds(0, 0, 30, 30); | |
| 1331 container->AddChildView(gesture); | |
| 1332 | |
| 1333 MouseView* mouse = new MouseView; | |
| 1334 mouse->SetBounds(30, 0, 30, 30); | |
| 1335 container->AddChildView(mouse); | |
| 1336 | |
| 1337 toplevel->SetSize(gfx::Size(100, 100)); | |
| 1338 toplevel->Show(); | |
| 1339 | |
| 1340 // Start a gesture on |gesture|. | |
| 1341 ui::GestureEvent begin(ui::ET_GESTURE_BEGIN, | |
| 1342 15, 15, 0, base::TimeDelta(), | |
| 1343 ui::GestureEventDetails(ui::ET_GESTURE_BEGIN, 0, 0), 1); | |
| 1344 ui::GestureEvent end(ui::ET_GESTURE_END, | |
| 1345 15, 15, 0, base::TimeDelta(), | |
| 1346 ui::GestureEventDetails(ui::ET_GESTURE_END, 0, 0), 1); | |
| 1347 toplevel->OnGestureEvent(&begin); | |
| 1348 | |
| 1349 // Now try to click on |mouse|. Since |gesture| will have capture, |mouse| | |
| 1350 // will not receive the event. | |
| 1351 gfx::Point click_location(45, 15); | |
| 1352 | |
| 1353 ui::MouseEvent press(ui::ET_MOUSE_PRESSED, click_location, click_location, | |
| 1354 ui::EF_LEFT_MOUSE_BUTTON); | |
| 1355 ui::MouseEvent release(ui::ET_MOUSE_RELEASED, click_location, click_location, | |
| 1356 ui::EF_LEFT_MOUSE_BUTTON); | |
| 1357 | |
| 1358 toplevel->OnMouseEvent(&press); | |
| 1359 toplevel->OnMouseEvent(&release); | |
| 1360 EXPECT_EQ(0, mouse->pressed()); | |
| 1361 | |
| 1362 // The end of the gesture should release the capture, and pressing on |mouse| | |
| 1363 // should now reach |mouse|. | |
| 1364 toplevel->OnGestureEvent(&end); | |
| 1365 toplevel->OnMouseEvent(&press); | |
| 1366 toplevel->OnMouseEvent(&release); | |
| 1367 EXPECT_EQ(1, mouse->pressed()); | |
| 1368 | |
| 1369 toplevel->Close(); | |
| 1370 RunPendingMessages(); | |
| 1371 } | |
| 1372 | |
| 1373 #if defined(USE_AURA) | 918 #if defined(USE_AURA) |
| 1374 // The key-event propagation from Widget happens differently on aura and | 919 // The key-event propagation from Widget happens differently on aura and |
| 1375 // non-aura systems because of the difference in IME. So this test works only on | 920 // non-aura systems because of the difference in IME. So this test works only on |
| 1376 // aura. | 921 // aura. |
| 1377 TEST_F(WidgetTest, KeyboardInputEvent) { | 922 TEST_F(WidgetTest, KeyboardInputEvent) { |
| 1378 Widget* toplevel = CreateTopLevelPlatformWidget(); | 923 Widget* toplevel = CreateTopLevelPlatformWidget(); |
| 1379 View* container = toplevel->client_view(); | 924 View* container = toplevel->client_view(); |
| 1380 | 925 |
| 1381 Textfield* textfield = new Textfield(); | 926 Textfield* textfield = new Textfield(); |
| 1382 textfield->SetText(ASCIIToUTF16("some text")); | 927 textfield->SetText(ASCIIToUTF16("some text")); |
| (...skipping 995 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2378 | 1923 |
| 2379 std::set<Widget*> widgets; | 1924 std::set<Widget*> widgets; |
| 2380 Widget::GetAllChildWidgets(toplevel->GetNativeView(), &widgets); | 1925 Widget::GetAllChildWidgets(toplevel->GetNativeView(), &widgets); |
| 2381 | 1926 |
| 2382 EXPECT_EQ(expected.size(), widgets.size()); | 1927 EXPECT_EQ(expected.size(), widgets.size()); |
| 2383 EXPECT_TRUE(std::equal(expected.begin(), expected.end(), widgets.begin())); | 1928 EXPECT_TRUE(std::equal(expected.begin(), expected.end(), widgets.begin())); |
| 2384 } | 1929 } |
| 2385 | 1930 |
| 2386 } // namespace test | 1931 } // namespace test |
| 2387 } // namespace views | 1932 } // namespace views |
| OLD | NEW |