diff options
author | glider@chromium.org <glider@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-24 13:08:39 +0000 |
---|---|---|
committer | glider@chromium.org <glider@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-24 13:08:39 +0000 |
commit | f133ae5ffe7b7c6e67b41c001aeb15205bea1e43 (patch) | |
tree | be68f9437dd7a77e93ef236e47d30037fdcc47c3 /ash | |
parent | 250c3ff6bcda585d954f7a34ca687ce43ab16e3b (diff) | |
download | chromium_src-f133ae5ffe7b7c6e67b41c001aeb15205bea1e43.zip chromium_src-f133ae5ffe7b7c6e67b41c001aeb15205bea1e43.tar.gz chromium_src-f133ae5ffe7b7c6e67b41c001aeb15205bea1e43.tar.bz2 |
Revert 148079 - Add EventFilter for LauncherTooltip.
This change made ASan report a use-after-free in LauncherTooltipManagerTest.ShowingBasics
Now it monitors mouse/touch/gesture events and hides the tooltip if necessary.
BUG=137678
TEST=manually verified && aura_shell_unittests passed
Review URL: https://chromiumcodereview.appspot.com/10810011
TBR=mukai@chromium.org
Review URL: https://chromiumcodereview.appspot.com/10809070
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@148096 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r-- | ash/launcher/launcher_tooltip_manager.cc | 110 | ||||
-rw-r--r-- | ash/launcher/launcher_tooltip_manager.h | 21 | ||||
-rw-r--r-- | ash/launcher/launcher_tooltip_manager_unittest.cc | 87 | ||||
-rw-r--r-- | ash/launcher/launcher_view.cc | 17 | ||||
-rw-r--r-- | ash/launcher/launcher_view.h | 2 |
5 files changed, 39 insertions, 198 deletions
diff --git a/ash/launcher/launcher_tooltip_manager.cc b/ash/launcher/launcher_tooltip_manager.cc index 6cbc190..f0741fe 100644 --- a/ash/launcher/launcher_tooltip_manager.cc +++ b/ash/launcher/launcher_tooltip_manager.cc @@ -4,7 +4,6 @@ #include "ash/launcher/launcher_tooltip_manager.h" -#include "ash/launcher/launcher_view.h" #include "ash/shell.h" #include "ash/shell_window_ids.h" #include "ash/wm/window_animations.h" @@ -12,10 +11,7 @@ #include "base/message_loop.h" #include "base/time.h" #include "base/timer.h" -#include "ui/aura/event.h" -#include "ui/aura/root_window.h" #include "ui/aura/window.h" -#include "ui/base/events.h" #include "ui/gfx/insets.h" #include "ui/views/bubble/bubble_delegate.h" #include "ui/views/controls/label.h" @@ -57,6 +53,9 @@ class LauncherTooltipManager::LauncherTooltipBubble void SetText(const string16& text); private: + // views::View overrides: + virtual void OnMouseExited(const views::MouseEvent& event) OVERRIDE; + // views::WidgetDelegate overrides; virtual void WindowClosing() OVERRIDE; @@ -96,33 +95,31 @@ void LauncherTooltipManager::LauncherTooltipBubble::SetText( SizeToContents(); } +void LauncherTooltipManager::LauncherTooltipBubble::OnMouseExited( + const views::MouseEvent& event) { + GetWidget()->Close(); + host_->OnBubbleClosed(this); +} + void LauncherTooltipManager::LauncherTooltipBubble::WindowClosing() { views::BubbleDelegateView::WindowClosing(); host_->OnBubbleClosed(this); } LauncherTooltipManager::LauncherTooltipManager( - ShelfAlignment alignment, - ShelfLayoutManager* shelf_layout_manager, - LauncherView* launcher_view) + ShelfAlignment alignment, ShelfLayoutManager* shelf_layout_manager) : view_(NULL), - widget_(NULL), anchor_(NULL), alignment_(alignment), - shelf_layout_manager_(shelf_layout_manager), - launcher_view_(launcher_view) { + shelf_layout_manager_(shelf_layout_manager) { if (shelf_layout_manager) shelf_layout_manager->AddObserver(this); - if (Shell::HasInstance()) - Shell::GetInstance()->AddEnvEventFilter(this); } LauncherTooltipManager::~LauncherTooltipManager() { Close(); if (shelf_layout_manager_) shelf_layout_manager_->RemoveObserver(this); - if (Shell::HasInstance()) - Shell::GetInstance()->RemoveEnvEventFilter(this); } void LauncherTooltipManager::ShowDelayed(views::View* anchor, @@ -138,7 +135,7 @@ void LauncherTooltipManager::ShowDelayed(views::View* anchor, return; CreateBubble(anchor, text); - gfx::NativeView native_view = widget_->GetNativeView(); + gfx::NativeView native_view = view_->GetWidget()->GetNativeView(); SetWindowVisibilityAnimationType( native_view, WINDOW_VISIBILITY_ANIMATION_TYPE_VERTICAL); SetWindowVisibilityAnimationTransition(native_view, ANIMATE_SHOW); @@ -157,26 +154,22 @@ void LauncherTooltipManager::ShowImmediately(views::View* anchor, return; CreateBubble(anchor, text); - gfx::NativeView native_view = widget_->GetNativeView(); + gfx::NativeView native_view = view_->GetWidget()->GetNativeView(); SetWindowVisibilityAnimationTransition(native_view, ANIMATE_NONE); ShowInternal(); } void LauncherTooltipManager::Close() { - if (widget_) { - if (widget_->IsVisible()) - widget_->Close(); + if (view_) { + view_->GetWidget()->Close(); view_ = NULL; - widget_ = NULL; } } void LauncherTooltipManager::OnBubbleClosed( views::BubbleDelegateView* view) { - if (view == view_) { + if (view == view_) view_ = NULL; - widget_ = NULL; - } } void LauncherTooltipManager::SetArrowLocation(ShelfAlignment alignment) { @@ -218,72 +211,7 @@ bool LauncherTooltipManager::IsVisible() { if (timer_.get() && timer_->IsRunning()) return false; - return widget_ && widget_->IsVisible(); -} - -bool LauncherTooltipManager::PreHandleKeyEvent(aura::Window* target, - aura::KeyEvent* event) { - // Not handled. - return false; -} - -bool LauncherTooltipManager::PreHandleMouseEvent(aura::Window* target, - aura::MouseEvent* event) { - DCHECK(target); - DCHECK(event); - if (!widget_ || !widget_->IsVisible()) - return false; - - DCHECK(view_); - DCHECK(launcher_view_); - - if (widget_->GetNativeWindow()->GetRootWindow() != target->GetRootWindow()) { - MessageLoopForUI::current()->PostTask( - FROM_HERE, - base::Bind(&LauncherTooltipManager::Close, base::Unretained(this))); - return false; - } - - gfx::Point location_in_launcher_view = event->location(); - aura::Window::ConvertPointToWindow( - target, launcher_view_->GetWidget()->GetNativeWindow(), - &location_in_launcher_view); - - gfx::Point location_on_screen = event->location(); - aura::Window::ConvertPointToWindow( - target, target->GetRootWindow(), &location_on_screen); - gfx::Rect bubble_rect = widget_->GetWindowBoundsInScreen(); - - if (launcher_view_->ShouldHideTooltip(location_in_launcher_view) && - !bubble_rect.Contains(location_on_screen)) { - // Because this mouse event may arrive to |view_|, here we just schedule - // the closing event rather than directly calling Close(). - MessageLoopForUI::current()->PostTask( - FROM_HERE, - base::Bind(&LauncherTooltipManager::Close, base::Unretained(this))); - } - - return false; -} - -ui::TouchStatus LauncherTooltipManager::PreHandleTouchEvent( - aura::Window* target, aura::TouchEvent* event) { - if (widget_ && widget_->IsVisible() && widget_->GetNativeWindow() != target) - Close(); - return ui::TOUCH_STATUS_UNKNOWN; -} - -ui::GestureStatus LauncherTooltipManager::PreHandleGestureEvent( - aura::Window* target, aura::GestureEvent* event) { - if (widget_ && widget_->IsVisible()) { - // Because this mouse event may arrive to |view_|, here we just schedule - // the closing event rather than directly calling Close(). - MessageLoopForUI::current()->PostTask( - FROM_HERE, - base::Bind(&LauncherTooltipManager::Close, base::Unretained(this))); - } - - return ui::GESTURE_STATUS_UNKNOWN; + return view_ && view_->GetWidget() && view_->GetWidget()->IsVisible(); } void LauncherTooltipManager::WillDeleteShelf() { @@ -312,9 +240,8 @@ void LauncherTooltipManager::OnAutoHideStateChanged( } void LauncherTooltipManager::ShowInternal() { - if (view_) { + if (view_) view_->Show(); - } timer_.reset(); } @@ -328,7 +255,6 @@ void LauncherTooltipManager::CreateBubble(views::View* anchor, view_ = new LauncherTooltipBubble( anchor, GetArrowLocation(alignment_), this); views::BubbleDelegateView::CreateBubble(view_); - widget_ = view_->GetWidget(); view_->SetText(text_); } diff --git a/ash/launcher/launcher_tooltip_manager.h b/ash/launcher/launcher_tooltip_manager.h index b2cb8c4..b32ec98 100644 --- a/ash/launcher/launcher_tooltip_manager.h +++ b/ash/launcher/launcher_tooltip_manager.h @@ -11,7 +11,6 @@ #include "base/basictypes.h" #include "base/string16.h" #include "ui/gfx/rect.h" -#include "ui/aura/event_filter.h" #include "ui/views/bubble/bubble_border.h" #include "ui/views/bubble/bubble_delegate.h" @@ -31,16 +30,13 @@ class LauncherViewTest; } namespace internal { -class LauncherView; // LauncherTooltipManager manages the tooltip balloon poping up on launcher // items. -class ASH_EXPORT LauncherTooltipManager : public aura::EventFilter, - public ShelfLayoutManager::Observer { +class ASH_EXPORT LauncherTooltipManager : public ShelfLayoutManager::Observer { public: LauncherTooltipManager(ShelfAlignment alignment, - ShelfLayoutManager* shelf_layout_manager, - LauncherView* launcher_view); + ShelfLayoutManager* shelf_layout_manager); virtual ~LauncherTooltipManager(); // Called when the bubble is closed. @@ -70,17 +66,6 @@ class ASH_EXPORT LauncherTooltipManager : public aura::EventFilter, bool IsVisible(); protected: - // aura::EventFilter overrides: - virtual bool PreHandleKeyEvent(aura::Window* target, - aura::KeyEvent* event) OVERRIDE; - virtual bool PreHandleMouseEvent(aura::Window* target, - aura::MouseEvent* event) OVERRIDE; - virtual ui::TouchStatus PreHandleTouchEvent(aura::Window* target, - aura::TouchEvent* event) OVERRIDE; - virtual ui::GestureStatus PreHandleGestureEvent( - aura::Window* target, - aura::GestureEvent* event) OVERRIDE; - // ShelfLayoutManager::Observer overrides: virtual void WillDeleteShelf() OVERRIDE; virtual void WillChangeVisibilityState( @@ -97,14 +82,12 @@ protected: void CreateBubble(views::View* anchor, const string16& text); LauncherTooltipBubble* view_; - views::Widget* widget_; views::View* anchor_; string16 text_; ShelfAlignment alignment_; scoped_ptr<base::Timer> timer_; ShelfLayoutManager* shelf_layout_manager_; - LauncherView* launcher_view_; DISALLOW_COPY_AND_ASSIGN(LauncherTooltipManager); }; diff --git a/ash/launcher/launcher_tooltip_manager_unittest.cc b/ash/launcher/launcher_tooltip_manager_unittest.cc index 6d14c89..0e42857 100644 --- a/ash/launcher/launcher_tooltip_manager_unittest.cc +++ b/ash/launcher/launcher_tooltip_manager_unittest.cc @@ -8,12 +8,6 @@ #include "ash/wm/shelf_layout_manager.h" #include "ash/wm/window_util.h" #include "base/string16.h" -#include "base/time.h" -#include "ui/aura/event.h" -#include "ui/aura/event_filter.h" -#include "ui/aura/root_window.h" -#include "ui/base/events.h" -#include "ui/base/keycodes/keyboard_codes.h" #include "ui/views/widget/widget.h" namespace ash { @@ -25,17 +19,10 @@ class LauncherTooltipManagerTest : public AshTestBase { virtual ~LauncherTooltipManagerTest() {} virtual void SetUp() OVERRIDE { - AshTestBase::SetUp(); + ash::test::AshTestBase::SetUp(); tooltip_manager_.reset(new internal::LauncherTooltipManager( - SHELF_ALIGNMENT_BOTTOM, - Shell::GetInstance()->shelf(), - Shell::GetInstance()->launcher()->GetLauncherViewForTest())); - } - - virtual void TearDown() OVERRIDE { - tooltip_manager_.reset(); - AshTestBase::TearDown(); + SHELF_ALIGNMENT_BOTTOM, Shell::GetInstance()->shelf())); } void ShowDelayed() { @@ -56,14 +43,6 @@ class LauncherTooltipManagerTest : public AshTestBase { return tooltip_manager_->timer_.get() != NULL; } - aura::EventFilter* GetEventFilter() { - return tooltip_manager_.get(); - } - - views::Widget* GetTooltipWidget() { - return tooltip_manager_->widget_; - } - protected: scoped_ptr<views::View> dummy_anchor_; scoped_ptr<internal::LauncherTooltipManager> tooltip_manager_; @@ -133,67 +112,5 @@ TEST_F(LauncherTooltipManagerTest, HideWhenShelfIsAutoHide) { EXPECT_FALSE(IsTimerRunning()); } -TEST_F(LauncherTooltipManagerTest, ShouldHideForEvents) { - ShowImmediately(); - ASSERT_TRUE(TooltipIsVisible()); - - aura::RootWindow* root_window = Shell::GetInstance()->GetPrimaryRootWindow(); - aura::EventFilter* event_filter = GetEventFilter(); - - // Should not hide for key events. - aura::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE); - EXPECT_FALSE(event_filter->PreHandleKeyEvent(root_window, &key_event)); - EXPECT_TRUE(TooltipIsVisible()); - - // Should hide for touch events. - aura::TouchEvent touch_event( - ui::ET_TOUCH_PRESSED, gfx::Point(), 0, base::TimeDelta()); - EXPECT_EQ(ui::TOUCH_STATUS_UNKNOWN, - event_filter->PreHandleTouchEvent(root_window, &touch_event)); - EXPECT_FALSE(TooltipIsVisible()); - - // Shouldn't hide if the touch happens on the tooltip. - ShowImmediately(); - views::Widget* tooltip_widget = GetTooltipWidget(); - EXPECT_EQ(ui::TOUCH_STATUS_UNKNOWN, - event_filter->PreHandleTouchEvent( - tooltip_widget->GetNativeWindow(), &touch_event)); - EXPECT_TRUE(TooltipIsVisible()); - - // Should hide for gesture events. - aura::GestureEvent gesture_event( - ui::ET_GESTURE_BEGIN, 0, 0, ui::EF_NONE, base::Time(), - ui::GestureEventDetails(ui::ET_GESTURE_BEGIN, 0.0f, 0.0f), 0); - EXPECT_EQ(ui::GESTURE_STATUS_UNKNOWN, - event_filter->PreHandleGestureEvent(root_window, &gesture_event)); - RunAllPendingInMessageLoop(); - EXPECT_FALSE(TooltipIsVisible()); -} - -TEST_F(LauncherTooltipManagerTest, HideForMouseEvent) { - ShowImmediately(); - ASSERT_TRUE(TooltipIsVisible()); - - aura::RootWindow* root_window = Shell::GetInstance()->GetPrimaryRootWindow(); - aura::EventFilter* event_filter = GetEventFilter(); - - gfx::Rect tooltip_rect = GetTooltipWidget()->GetNativeWindow()->bounds(); - ASSERT_FALSE(tooltip_rect.IsEmpty()); - - // Shouldn't hide if the mouse is in the tooltip. - aura::MouseEvent mouse_event(ui::ET_MOUSE_MOVED, tooltip_rect.CenterPoint(), - tooltip_rect.CenterPoint(), ui::EF_NONE); - aura::LocatedEvent::TestApi test_api(&mouse_event); - - EXPECT_FALSE(event_filter->PreHandleMouseEvent(root_window, &mouse_event)); - EXPECT_TRUE(TooltipIsVisible()); - - // Should hide if the mouse is out of the tooltip. - test_api.set_location(tooltip_rect.origin().Add(gfx::Point(-1, -1))); - EXPECT_FALSE(event_filter->PreHandleMouseEvent(root_window, &mouse_event)); - RunAllPendingInMessageLoop(); - EXPECT_FALSE(TooltipIsVisible()); -} - } // namespace test } // namespace ash diff --git a/ash/launcher/launcher_view.cc b/ash/launcher/launcher_view.cc index 21b173b..20a513b 100644 --- a/ash/launcher/launcher_view.cc +++ b/ash/launcher/launcher_view.cc @@ -283,8 +283,7 @@ LauncherView::LauncherView(LauncherModel* model, bounds_animator_->AddObserver(this); set_context_menu_controller(this); focus_search_.reset(new LauncherFocusSearch(view_model_.get())); - tooltip_.reset(new LauncherTooltipManager( - alignment_, shelf_layout_manager, this)); + tooltip_.reset(new LauncherTooltipManager(alignment_, shelf_layout_manager)); } LauncherView::~LauncherView() { @@ -815,6 +814,20 @@ views::FocusTraversable* LauncherView::GetPaneFocusTraversable() { return this; } +void LauncherView::OnMouseMoved(const views::MouseEvent& event) { + if (ShouldHideTooltip(event.location()) && tooltip_->IsVisible()) + tooltip_->Close(); +} + +void LauncherView::OnMouseExited(const views::MouseEvent& event) { + // Mouse exit events are fired for entering to a launcher button from + // the launcher view, so it checks the location by ShouldHideTooltip(). + gfx::Point point = event.location(); + views::View::ConvertPointToView(parent(), this, &point); + if (ShouldHideTooltip(point) && tooltip_->IsVisible()) + tooltip_->Close(); +} + void LauncherView::LauncherItemAdded(int model_index) { model_index = CancelDrag(model_index); views::View* view = CreateViewForItem(model_->items()[model_index]); diff --git a/ash/launcher/launcher_view.h b/ash/launcher/launcher_view.h index 6dbe133..ab78f8c 100644 --- a/ash/launcher/launcher_view.h +++ b/ash/launcher/launcher_view.h @@ -178,6 +178,8 @@ class ASH_EXPORT LauncherView : public views::View, virtual gfx::Size GetPreferredSize() OVERRIDE; virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE; virtual FocusTraversable* GetPaneFocusTraversable() OVERRIDE; + virtual void OnMouseMoved(const views::MouseEvent& event) OVERRIDE; + virtual void OnMouseExited(const views::MouseEvent& event) OVERRIDE; // Overridden from LauncherModelObserver: virtual void LauncherItemAdded(int model_index) OVERRIDE; |