| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/corewm/tooltip_controller.h" | 5 #include "ui/views/corewm/tooltip_controller.h" |
| 6 | 6 |
| 7 #include "base/strings/utf_string_conversions.h" | 7 #include "base/strings/utf_string_conversions.h" |
| 8 #include "ui/aura/client/cursor_client.h" | 8 #include "ui/aura/client/cursor_client.h" |
| 9 #include "ui/aura/client/screen_position_client.h" | 9 #include "ui/aura/client/screen_position_client.h" |
| 10 #include "ui/aura/env.h" | 10 #include "ui/aura/env.h" |
| 11 #include "ui/aura/test/aura_test_base.h" | 11 #include "ui/aura/test/aura_test_base.h" |
| 12 #include "ui/aura/test/event_generator.h" | 12 #include "ui/aura/test/event_generator.h" |
| 13 #include "ui/aura/test/test_screen.h" | 13 #include "ui/aura/test/test_screen.h" |
| 14 #include "ui/aura/test/test_window_delegate.h" | 14 #include "ui/aura/test/test_window_delegate.h" |
| 15 #include "ui/aura/window.h" | 15 #include "ui/aura/window.h" |
| 16 #include "ui/aura/window_event_dispatcher.h" | 16 #include "ui/aura/window_event_dispatcher.h" |
| 17 #include "ui/base/resource/resource_bundle.h" | 17 #include "ui/base/resource/resource_bundle.h" |
| 18 #include "ui/gfx/font.h" | 18 #include "ui/gfx/font.h" |
| 19 #include "ui/gfx/point.h" | 19 #include "ui/gfx/point.h" |
| 20 #include "ui/gfx/screen.h" | 20 #include "ui/gfx/screen.h" |
| 21 #include "ui/gfx/screen_type_delegate.h" | 21 #include "ui/gfx/screen_type_delegate.h" |
| 22 #include "ui/gfx/text_elider.h" | 22 #include "ui/gfx/text_elider.h" |
| 23 #include "ui/views/corewm/tooltip_aura.h" | 23 #include "ui/views/corewm/tooltip_aura.h" |
| 24 #include "ui/views/corewm/tooltip_controller_test_helper.h" | 24 #include "ui/views/corewm/tooltip_controller_test_helper.h" |
| 25 #include "ui/views/test/desktop_test_views_delegate.h" |
| 26 #include "ui/views/test/test_views_delegate.h" |
| 25 #include "ui/views/view.h" | 27 #include "ui/views/view.h" |
| 26 #include "ui/views/widget/tooltip_manager.h" | 28 #include "ui/views/widget/tooltip_manager.h" |
| 27 #include "ui/views/widget/widget.h" | 29 #include "ui/views/widget/widget.h" |
| 28 #include "ui/wm/core/default_activation_client.h" | 30 #include "ui/wm/core/default_activation_client.h" |
| 29 #include "ui/wm/core/wm_state.h" | 31 #include "ui/wm/core/wm_state.h" |
| 30 #include "ui/wm/public/tooltip_client.h" | 32 #include "ui/wm/public/tooltip_client.h" |
| 31 #include "ui/wm/public/window_types.h" | 33 #include "ui/wm/public/window_types.h" |
| 32 | 34 |
| 33 #if defined(OS_WIN) | 35 #if defined(OS_WIN) |
| 34 #include "ui/base/win/scoped_ole_initializer.h" | 36 #include "ui/base/win/scoped_ole_initializer.h" |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 } | 72 } |
| 71 | 73 |
| 72 } // namespace | 74 } // namespace |
| 73 | 75 |
| 74 class TooltipControllerTest : public aura::test::AuraTestBase { | 76 class TooltipControllerTest : public aura::test::AuraTestBase { |
| 75 public: | 77 public: |
| 76 TooltipControllerTest() : view_(NULL) {} | 78 TooltipControllerTest() : view_(NULL) {} |
| 77 virtual ~TooltipControllerTest() {} | 79 virtual ~TooltipControllerTest() {} |
| 78 | 80 |
| 79 virtual void SetUp() OVERRIDE { | 81 virtual void SetUp() OVERRIDE { |
| 80 wm_state_.reset(new wm::WMState); | 82 #if defined(OS_CHROMEOS) |
| 83 views_delegate_.reset(new TestViewsDelegate); |
| 84 #else |
| 85 views_delegate_.reset(new DesktopTestViewsDelegate); |
| 86 #endif |
| 87 |
| 81 aura::test::AuraTestBase::SetUp(); | 88 aura::test::AuraTestBase::SetUp(); |
| 82 new wm::DefaultActivationClient(root_window()); | 89 new wm::DefaultActivationClient(root_window()); |
| 83 #if defined(OS_CHROMEOS) | 90 #if defined(OS_CHROMEOS) |
| 84 controller_.reset(new TooltipController( | 91 controller_.reset(new TooltipController( |
| 85 scoped_ptr<views::corewm::Tooltip>( | 92 scoped_ptr<views::corewm::Tooltip>( |
| 86 new views::corewm::TooltipAura(gfx::SCREEN_TYPE_ALTERNATE)))); | 93 new views::corewm::TooltipAura(gfx::SCREEN_TYPE_ALTERNATE)))); |
| 87 root_window()->AddPreTargetHandler(controller_.get()); | 94 root_window()->AddPreTargetHandler(controller_.get()); |
| 88 SetTooltipClient(root_window(), controller_.get()); | 95 SetTooltipClient(root_window(), controller_.get()); |
| 89 #endif | 96 #endif |
| 90 widget_.reset(CreateWidget(root_window())); | 97 widget_.reset(CreateWidget(root_window())); |
| 91 widget_->SetContentsView(new View); | 98 widget_->SetContentsView(new View); |
| 92 view_ = new TooltipTestView; | 99 view_ = new TooltipTestView; |
| 93 widget_->GetContentsView()->AddChildView(view_); | 100 widget_->GetContentsView()->AddChildView(view_); |
| 94 view_->SetBoundsRect(widget_->GetContentsView()->GetLocalBounds()); | 101 view_->SetBoundsRect(widget_->GetContentsView()->GetLocalBounds()); |
| 95 helper_.reset(new TooltipControllerTestHelper( | 102 helper_.reset(new TooltipControllerTestHelper( |
| 96 GetController(widget_.get()))); | 103 GetController(widget_.get()))); |
| 97 generator_.reset(new aura::test::EventGenerator(GetRootWindow())); | 104 generator_.reset(new aura::test::EventGenerator(GetRootWindow())); |
| 98 } | 105 } |
| 99 | 106 |
| 100 virtual void TearDown() OVERRIDE { | 107 virtual void TearDown() OVERRIDE { |
| 101 #if defined(OS_CHROMEOS) | 108 #if defined(OS_CHROMEOS) |
| 102 root_window()->RemovePreTargetHandler(controller_.get()); | 109 root_window()->RemovePreTargetHandler(controller_.get()); |
| 103 aura::client::SetTooltipClient(root_window(), NULL); | 110 aura::client::SetTooltipClient(root_window(), NULL); |
| 104 controller_.reset(); | 111 controller_.reset(); |
| 105 #endif | 112 #endif |
| 106 generator_.reset(); | 113 generator_.reset(); |
| 107 helper_.reset(); | 114 helper_.reset(); |
| 108 widget_.reset(); | 115 widget_.reset(); |
| 109 aura::test::AuraTestBase::TearDown(); | 116 aura::test::AuraTestBase::TearDown(); |
| 110 wm_state_.reset(); | 117 views_delegate_.reset(); |
| 111 } | 118 } |
| 112 | 119 |
| 113 protected: | 120 protected: |
| 114 aura::Window* GetWindow() { | 121 aura::Window* GetWindow() { |
| 115 return widget_->GetNativeWindow(); | 122 return widget_->GetNativeWindow(); |
| 116 } | 123 } |
| 117 | 124 |
| 118 aura::Window* GetRootWindow() { | 125 aura::Window* GetRootWindow() { |
| 119 return GetWindow()->GetRootWindow(); | 126 return GetWindow()->GetRootWindow(); |
| 120 } | 127 } |
| 121 | 128 |
| 122 TooltipTestView* PrepareSecondView() { | 129 TooltipTestView* PrepareSecondView() { |
| 123 TooltipTestView* view2 = new TooltipTestView; | 130 TooltipTestView* view2 = new TooltipTestView; |
| 124 widget_->GetContentsView()->AddChildView(view2); | 131 widget_->GetContentsView()->AddChildView(view2); |
| 125 view_->SetBounds(0, 0, 100, 100); | 132 view_->SetBounds(0, 0, 100, 100); |
| 126 view2->SetBounds(100, 0, 100, 100); | 133 view2->SetBounds(100, 0, 100, 100); |
| 127 return view2; | 134 return view2; |
| 128 } | 135 } |
| 129 | 136 |
| 130 scoped_ptr<views::Widget> widget_; | 137 scoped_ptr<views::Widget> widget_; |
| 131 TooltipTestView* view_; | 138 TooltipTestView* view_; |
| 132 scoped_ptr<TooltipControllerTestHelper> helper_; | 139 scoped_ptr<TooltipControllerTestHelper> helper_; |
| 133 scoped_ptr<aura::test::EventGenerator> generator_; | 140 scoped_ptr<aura::test::EventGenerator> generator_; |
| 134 | 141 |
| 135 private: | 142 private: |
| 136 scoped_ptr<TooltipController> controller_; | 143 scoped_ptr<TooltipController> controller_; |
| 137 | 144 |
| 145 scoped_ptr<views::TestViewsDelegate> views_delegate_; |
| 146 |
| 138 #if defined(OS_WIN) | 147 #if defined(OS_WIN) |
| 139 ui::ScopedOleInitializer ole_initializer_; | 148 ui::ScopedOleInitializer ole_initializer_; |
| 140 #endif | 149 #endif |
| 141 | 150 |
| 142 scoped_ptr<wm::WMState> wm_state_; | |
| 143 | |
| 144 DISALLOW_COPY_AND_ASSIGN(TooltipControllerTest); | 151 DISALLOW_COPY_AND_ASSIGN(TooltipControllerTest); |
| 145 }; | 152 }; |
| 146 | 153 |
| 147 TEST_F(TooltipControllerTest, ViewTooltip) { | 154 TEST_F(TooltipControllerTest, ViewTooltip) { |
| 148 view_->set_tooltip_text(ASCIIToUTF16("Tooltip Text")); | 155 view_->set_tooltip_text(ASCIIToUTF16("Tooltip Text")); |
| 149 EXPECT_EQ(base::string16(), helper_->GetTooltipText()); | 156 EXPECT_EQ(base::string16(), helper_->GetTooltipText()); |
| 150 EXPECT_EQ(NULL, helper_->GetTooltipWindow()); | 157 EXPECT_EQ(NULL, helper_->GetTooltipWindow()); |
| 151 generator_->MoveMouseToCenterOf(GetWindow()); | 158 generator_->MoveMouseToCenterOf(GetWindow()); |
| 152 | 159 |
| 153 EXPECT_EQ(GetWindow(), GetRootWindow()->GetEventHandlerForPoint( | 160 EXPECT_EQ(GetWindow(), GetRootWindow()->GetEventHandlerForPoint( |
| (...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 533 widget2->SetNativeWindowProperty(TooltipManager::kGroupingPropertyKey, | 540 widget2->SetNativeWindowProperty(TooltipManager::kGroupingPropertyKey, |
| 534 reinterpret_cast<void*>(grouping_key)); | 541 reinterpret_cast<void*>(grouping_key)); |
| 535 generator_->MoveMouseBy(1, 10); | 542 generator_->MoveMouseBy(1, 10); |
| 536 EXPECT_TRUE(helper_->IsTooltipTimerRunning()); | 543 EXPECT_TRUE(helper_->IsTooltipTimerRunning()); |
| 537 helper_->FireTooltipTimer(); | 544 helper_->FireTooltipTimer(); |
| 538 EXPECT_EQ(tooltip_text2, helper_->GetTooltipText()); | 545 EXPECT_EQ(tooltip_text2, helper_->GetTooltipText()); |
| 539 | 546 |
| 540 widget2.reset(); | 547 widget2.reset(); |
| 541 } | 548 } |
| 542 | 549 |
| 543 // These tests search for a specific aura::Window to identify the | |
| 544 // tooltip. Windows shows the tooltip using a native tooltip, so these tests | |
| 545 // don't apply. | |
| 546 #if !defined(OS_WIN) && !defined(OS_CHROMEOS) | |
| 547 // This test creates two top level windows and verifies that the tooltip | |
| 548 // displays correctly when mouse moves are dispatched to these windows. | |
| 549 // Additionally it also verifies that the tooltip is reparented to the new | |
| 550 // window when mouse moves are dispatched to it. | |
| 551 TEST_F(TooltipControllerTest, TooltipsInMultipleRootWindows) { | |
| 552 view_->set_tooltip_text(ASCIIToUTF16("Tooltip Text For RootWindow1")); | |
| 553 EXPECT_EQ(base::string16(), helper_->GetTooltipText()); | |
| 554 EXPECT_EQ(NULL, helper_->GetTooltipWindow()); | |
| 555 | |
| 556 aura::Window* window = GetWindow(); | |
| 557 aura::Window* root_window = GetRootWindow(); | |
| 558 | |
| 559 // Fire tooltip timer so tooltip becomes visible. | |
| 560 generator_->MoveMouseRelativeTo(window, view_->bounds().CenterPoint()); | |
| 561 helper_->FireTooltipTimer(); | |
| 562 EXPECT_TRUE(helper_->IsTooltipVisible()); | |
| 563 for (int i = 0; i < 49; ++i) { | |
| 564 generator_->MoveMouseBy(1, 0); | |
| 565 EXPECT_TRUE(helper_->IsTooltipVisible()); | |
| 566 EXPECT_EQ(window, root_window->GetEventHandlerForPoint( | |
| 567 generator_->current_location())); | |
| 568 base::string16 expected_tooltip = | |
| 569 ASCIIToUTF16("Tooltip Text For RootWindow1"); | |
| 570 EXPECT_EQ(expected_tooltip, aura::client::GetTooltipText(window)); | |
| 571 EXPECT_EQ(expected_tooltip, helper_->GetTooltipText()); | |
| 572 EXPECT_EQ(window, helper_->GetTooltipWindow()); | |
| 573 } | |
| 574 | |
| 575 views::Widget* widget2 = CreateWidget(NULL); | |
| 576 widget2->SetContentsView(new View); | |
| 577 TooltipTestView* view2 = new TooltipTestView; | |
| 578 widget2->GetContentsView()->AddChildView(view2); | |
| 579 view2->SetBoundsRect(widget2->GetContentsView()->GetLocalBounds()); | |
| 580 helper_.reset(new TooltipControllerTestHelper( | |
| 581 GetController(widget2))); | |
| 582 generator_.reset(new aura::test::EventGenerator( | |
| 583 widget2->GetNativeWindow()->GetRootWindow())); | |
| 584 view2->set_tooltip_text(ASCIIToUTF16("Tooltip Text For RootWindow2")); | |
| 585 | |
| 586 aura::Window* window2 = widget2->GetNativeWindow(); | |
| 587 aura::Window* root_window2 = | |
| 588 widget2->GetNativeWindow()->GetRootWindow(); | |
| 589 // Fire tooltip timer so tooltip becomes visible. | |
| 590 generator_->MoveMouseRelativeTo(window2, view2->bounds().CenterPoint()); | |
| 591 helper_->FireTooltipTimer(); | |
| 592 | |
| 593 EXPECT_NE(root_window, root_window2); | |
| 594 EXPECT_NE(window, window2); | |
| 595 | |
| 596 for (int i = 0; i < 49; ++i) { | |
| 597 generator_->MoveMouseBy(1, 0); | |
| 598 EXPECT_TRUE(helper_->IsTooltipVisible()); | |
| 599 EXPECT_EQ(window2, root_window2->GetEventHandlerForPoint( | |
| 600 generator_->current_location())); | |
| 601 base::string16 expected_tooltip = | |
| 602 ASCIIToUTF16("Tooltip Text For RootWindow2"); | |
| 603 EXPECT_EQ(expected_tooltip, aura::client::GetTooltipText(window2)); | |
| 604 EXPECT_EQ(expected_tooltip, helper_->GetTooltipText()); | |
| 605 EXPECT_EQ(window2, helper_->GetTooltipWindow()); | |
| 606 } | |
| 607 | |
| 608 bool tooltip_reparented = false; | |
| 609 for (size_t i = 0; i < root_window2->children().size(); ++i) { | |
| 610 if (root_window2->children()[i]->type() == ui::wm::WINDOW_TYPE_TOOLTIP) { | |
| 611 tooltip_reparented = true; | |
| 612 break; | |
| 613 } | |
| 614 } | |
| 615 EXPECT_TRUE(tooltip_reparented); | |
| 616 widget2->Close(); | |
| 617 } | |
| 618 | |
| 619 // This test validates whether the tooltip after becoming visible stays at the | |
| 620 // top of the ZOrder in its root window after activation changes. | |
| 621 TEST_F(TooltipControllerTest, TooltipAtTopOfZOrderAfterActivation) { | |
| 622 view_->set_tooltip_text(ASCIIToUTF16("Tooltip Text")); | |
| 623 EXPECT_EQ(base::string16(), helper_->GetTooltipText()); | |
| 624 EXPECT_EQ(NULL, helper_->GetTooltipWindow()); | |
| 625 generator_->MoveMouseToCenterOf(GetWindow()); | |
| 626 | |
| 627 EXPECT_EQ(GetWindow(), GetRootWindow()->GetEventHandlerForPoint( | |
| 628 generator_->current_location())); | |
| 629 base::string16 expected_tooltip = ASCIIToUTF16("Tooltip Text"); | |
| 630 EXPECT_EQ(expected_tooltip, aura::client::GetTooltipText(GetWindow())); | |
| 631 EXPECT_EQ(base::string16(), helper_->GetTooltipText()); | |
| 632 EXPECT_EQ(GetWindow(), helper_->GetTooltipWindow()); | |
| 633 | |
| 634 // Fire tooltip timer so tooltip becomes visible. | |
| 635 helper_->FireTooltipTimer(); | |
| 636 | |
| 637 EXPECT_TRUE(helper_->IsTooltipVisible()); | |
| 638 generator_->MoveMouseBy(1, 0); | |
| 639 | |
| 640 EXPECT_TRUE(helper_->IsTooltipVisible()); | |
| 641 EXPECT_EQ(expected_tooltip, aura::client::GetTooltipText(GetWindow())); | |
| 642 EXPECT_EQ(expected_tooltip, helper_->GetTooltipText()); | |
| 643 EXPECT_EQ(GetWindow(), helper_->GetTooltipWindow()); | |
| 644 | |
| 645 // Fake activation loss and gain in the native widget. This should cause a | |
| 646 // ZOrder change which should not affect the position of the tooltip. | |
| 647 DesktopNativeWidgetAura* native_widget = | |
| 648 static_cast<DesktopNativeWidgetAura*>(widget_->native_widget()); | |
| 649 EXPECT_TRUE(native_widget != NULL); | |
| 650 | |
| 651 native_widget->HandleActivationChanged(false); | |
| 652 native_widget->HandleActivationChanged(true); | |
| 653 | |
| 654 EXPECT_EQ( | |
| 655 widget_->GetNativeWindow()->GetRootWindow()->children().back()->type(), | |
| 656 ui::wm::WINDOW_TYPE_TOOLTIP); | |
| 657 } | |
| 658 #endif | |
| 659 | |
| 660 namespace { | 550 namespace { |
| 661 | 551 |
| 662 class TestTooltip : public Tooltip { | 552 class TestTooltip : public Tooltip { |
| 663 public: | 553 public: |
| 664 TestTooltip() : is_visible_(false) {} | 554 TestTooltip() : is_visible_(false) {} |
| 665 virtual ~TestTooltip() {} | 555 virtual ~TestTooltip() {} |
| 666 | 556 |
| 667 const base::string16& tooltip_text() const { return tooltip_text_; } | 557 const base::string16& tooltip_text() const { return tooltip_text_; } |
| 668 | 558 |
| 669 // Tooltip: | 559 // Tooltip: |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 933 helper_->FireTooltipTimer(); | 823 helper_->FireTooltipTimer(); |
| 934 tooltip_bounds1 = test_tooltip_->location(); | 824 tooltip_bounds1 = test_tooltip_->location(); |
| 935 | 825 |
| 936 EXPECT_NE(tooltip_bounds1_1, tooltip_bounds1); | 826 EXPECT_NE(tooltip_bounds1_1, tooltip_bounds1); |
| 937 EXPECT_EQ(reference_string, helper_->GetTooltipText()); | 827 EXPECT_EQ(reference_string, helper_->GetTooltipText()); |
| 938 } | 828 } |
| 939 | 829 |
| 940 } // namespace test | 830 } // namespace test |
| 941 } // namespace corewm | 831 } // namespace corewm |
| 942 } // namespace views | 832 } // namespace views |
| OLD | NEW |