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

Side by Side Diff: ash/shelf/shelf_tooltip_manager.cc

Issue 1828133004: Refine ash shelf tooltip closing on non-mash ChromeOS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Avoid WillDeleteShelf in PrepareForShutdown; use aura::WindowObserver instead. Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ash/shelf/shelf_tooltip_manager.h ('k') | ash/shelf/shelf_tooltip_manager_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 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 "ash/shelf/shelf_tooltip_manager.h" 5 #include "ash/shelf/shelf_tooltip_manager.h"
6 6
7 #include "ash/shelf/shelf.h" 7 #include "ash/shelf/shelf.h"
8 #include "ash/shelf/shelf_layout_manager.h" 8 #include "ash/shelf/shelf_layout_manager.h"
9 #include "ash/shelf/shelf_view.h" 9 #include "ash/shelf/shelf_view.h"
10 #include "ash/shell.h" 10 #include "ash/shell.h"
11 #include "ash/shell_window_ids.h" 11 #include "ash/shell_window_ids.h"
12 #include "ash/wm/window_animations.h" 12 #include "ash/wm/window_animations.h"
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/thread_task_runner_handle.h" 14 #include "base/thread_task_runner_handle.h"
15 #include "base/time/time.h" 15 #include "base/time/time.h"
16 #include "ui/aura/window.h" 16 #include "ui/aura/window.h"
17 #include "ui/events/event.h" 17 #include "ui/events/event.h"
18 #include "ui/events/event_constants.h" 18 #include "ui/events/event_constants.h"
19 #include "ui/gfx/geometry/insets.h" 19 #include "ui/gfx/geometry/insets.h"
20 #include "ui/views/bubble/bubble_delegate.h" 20 #include "ui/views/bubble/bubble_delegate.h"
21 #include "ui/views/controls/label.h" 21 #include "ui/views/controls/label.h"
22 #include "ui/views/layout/fill_layout.h" 22 #include "ui/views/layout/fill_layout.h"
23 #include "ui/views/widget/widget.h" 23 #include "ui/views/widget/widget.h"
24 24
25 namespace ash { 25 namespace ash {
26 namespace { 26 namespace {
27
27 const int kTooltipTopBottomMargin = 3; 28 const int kTooltipTopBottomMargin = 3;
28 const int kTooltipLeftRightMargin = 10; 29 const int kTooltipLeftRightMargin = 10;
29 const int kTooltipAppearanceDelay = 1000; // msec 30 const int kTooltipAppearanceDelay = 1000; // msec
30 const int kTooltipMinHeight = 29 - 2 * kTooltipTopBottomMargin; 31 const int kTooltipMinHeight = 29 - 2 * kTooltipTopBottomMargin;
31 const SkColor kTooltipTextColor = SkColorSetRGB(0x22, 0x22, 0x22); 32 const SkColor kTooltipTextColor = SkColorSetRGB(0x22, 0x22, 0x22);
32 33
33 // The maximum width of the tooltip bubble. Borrowed the value from 34 // The maximum width of the tooltip bubble. Borrowed the value from
34 // ash/tooltip/tooltip_controller.cc 35 // ash/tooltip/tooltip_controller.cc
35 const int kTooltipMaxWidth = 250; 36 const int kTooltipMaxWidth = 250;
36 37
37 // The offset for the tooltip bubble - making sure that the bubble is flush 38 // The offset for the tooltip bubble - making sure that the bubble is flush
38 // with the shelf. The offset includes the arrow size in pixels as well as 39 // with the shelf. The offset includes the arrow size in pixels as well as
39 // the activation bar and other spacing elements. 40 // the activation bar and other spacing elements.
40 const int kArrowOffsetLeftRight = 11; 41 const int kArrowOffsetLeftRight = 11;
41 const int kArrowOffsetTopBottom = 7; 42 const int kArrowOffsetTopBottom = 7;
42 43
43 } // namespace 44 } // namespace
44 45
45 // The implementation of tooltip of the launcher. 46 // The implementation of tooltip of the launcher.
46 class ShelfTooltipManager::ShelfTooltipBubble 47 class ShelfTooltipManager::ShelfTooltipBubble
47 : public views::BubbleDelegateView { 48 : public views::BubbleDelegateView {
48 public: 49 public:
49 ShelfTooltipBubble(views::View* anchor, 50 ShelfTooltipBubble(views::View* anchor,
50 views::BubbleBorder::Arrow arrow, 51 views::BubbleBorder::Arrow arrow,
51 const base::string16& text); 52 const base::string16& text)
53 : views::BubbleDelegateView(anchor, arrow) {
54 gfx::Insets insets =
55 gfx::Insets(kArrowOffsetTopBottom, kArrowOffsetLeftRight);
56 // Adjust the anchor location for asymmetrical borders of shelf item.
57 if (anchor->border())
58 insets += anchor->border()->GetInsets();
59
60 set_anchor_view_insets(insets);
61 set_close_on_esc(false);
62 set_close_on_deactivate(false);
63 set_can_activate(false);
64 set_accept_events(false);
65 set_margins(gfx::Insets(kTooltipTopBottomMargin, kTooltipLeftRightMargin));
66 set_shadow(views::BubbleBorder::SMALL_SHADOW);
67 SetLayoutManager(new views::FillLayout());
68 // The anchor may not have the widget in tests.
69 if (anchor->GetWidget() && anchor->GetWidget()->GetNativeWindow()) {
70 set_parent_window(ash::Shell::GetContainer(
71 anchor->GetWidget()->GetNativeWindow()->GetRootWindow(),
72 ash::kShellWindowId_SettingBubbleContainer));
73 }
74 views::Label* label = new views::Label(text);
75 label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
76 label->SetEnabledColor(kTooltipTextColor);
77 AddChildView(label);
78 views::BubbleDelegateView::CreateBubble(this);
79 SizeToContents();
80 }
52 81
53 private: 82 private:
54 // views::View overrides: 83 // views::View overrides:
55 gfx::Size GetPreferredSize() const override; 84 gfx::Size GetPreferredSize() const override {
85 const gfx::Size size = views::BubbleDelegateView::GetPreferredSize();
86 return gfx::Size(std::min(size.width(), kTooltipMaxWidth),
87 std::max(size.height(), kTooltipMinHeight));
88 }
56 89
57 DISALLOW_COPY_AND_ASSIGN(ShelfTooltipBubble); 90 DISALLOW_COPY_AND_ASSIGN(ShelfTooltipBubble);
58 }; 91 };
59 92
60 ShelfTooltipManager::ShelfTooltipBubble::ShelfTooltipBubble(
61 views::View* anchor,
62 views::BubbleBorder::Arrow arrow,
63 const base::string16& text)
64 : views::BubbleDelegateView(anchor, arrow) {
65 gfx::Insets insets = gfx::Insets(kArrowOffsetTopBottom,
66 kArrowOffsetLeftRight);
67 // Adjust the anchor location for asymmetrical borders of shelf item.
68 if (anchor->border())
69 insets += anchor->border()->GetInsets();
70
71 set_anchor_view_insets(insets);
72 set_close_on_esc(false);
73 set_close_on_deactivate(false);
74 set_can_activate(false);
75 set_accept_events(false);
76 set_margins(gfx::Insets(kTooltipTopBottomMargin, kTooltipLeftRightMargin));
77 set_shadow(views::BubbleBorder::SMALL_SHADOW);
78 SetLayoutManager(new views::FillLayout());
79 // The anchor may not have the widget in tests.
80 if (anchor->GetWidget() && anchor->GetWidget()->GetNativeWindow()) {
81 set_parent_window(ash::Shell::GetContainer(
82 anchor->GetWidget()->GetNativeWindow()->GetRootWindow(),
83 ash::kShellWindowId_SettingBubbleContainer));
84 }
85 views::Label* label = new views::Label(text);
86 label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
87 label->SetEnabledColor(kTooltipTextColor);
88 AddChildView(label);
89 views::BubbleDelegateView::CreateBubble(this);
90 SizeToContents();
91 }
92
93 gfx::Size ShelfTooltipManager::ShelfTooltipBubble::GetPreferredSize() const {
94 const gfx::Size size = views::BubbleDelegateView::GetPreferredSize();
95 return gfx::Size(std::min(size.width(), kTooltipMaxWidth),
96 std::max(size.height(), kTooltipMinHeight));
97 }
98
99 ShelfTooltipManager::ShelfTooltipManager(ShelfView* shelf_view) 93 ShelfTooltipManager::ShelfTooltipManager(ShelfView* shelf_view)
100 : timer_delay_(kTooltipAppearanceDelay), 94 : timer_delay_(kTooltipAppearanceDelay),
101 shelf_view_(shelf_view), 95 shelf_view_(shelf_view),
96 root_window_(nullptr),
102 shelf_layout_manager_(nullptr), 97 shelf_layout_manager_(nullptr),
103 bubble_(nullptr), 98 bubble_(nullptr),
104 weak_factory_(this) {} 99 weak_factory_(this) {}
105 100
106 ShelfTooltipManager::~ShelfTooltipManager() { 101 ShelfTooltipManager::~ShelfTooltipManager() {
107 WillDeleteShelf(); 102 WillDeleteShelf();
103 if (root_window_) {
104 root_window_->RemoveObserver(this);
105 root_window_->RemovePreTargetHandler(this);
106 root_window_ = nullptr;
107 }
108 } 108 }
109 109
110 void ShelfTooltipManager::Init() { 110 void ShelfTooltipManager::Init() {
111 shelf_layout_manager_ = shelf_view_->shelf()->shelf_layout_manager(); 111 shelf_layout_manager_ = shelf_view_->shelf()->shelf_layout_manager();
112 shelf_layout_manager_->AddObserver(this); 112 shelf_layout_manager_->AddObserver(this);
113 // TODO(msw): Capture events outside the shelf to close tooltips? 113
114 shelf_view_->GetWidget()->GetNativeWindow()->AddPreTargetHandler(this); 114 // TODO(msw): Observe events outside the shelf in mash, to close tooltips.
115 root_window_ = shelf_view_->GetWidget()->GetNativeWindow()->GetRootWindow();
116 root_window_->AddPreTargetHandler(this);
117 root_window_->AddObserver(this);
115 } 118 }
116 119
117 void ShelfTooltipManager::Close() { 120 void ShelfTooltipManager::Close() {
118 timer_.Stop(); 121 timer_.Stop();
119 if (bubble_) 122 if (bubble_)
120 bubble_->GetWidget()->Close(); 123 bubble_->GetWidget()->Close();
121 bubble_ = nullptr; 124 bubble_ = nullptr;
122 } 125 }
123 126
124 bool ShelfTooltipManager::IsVisible() const { 127 bool ShelfTooltipManager::IsVisible() const {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 160
158 void ShelfTooltipManager::ShowTooltipWithDelay(views::View* view) { 161 void ShelfTooltipManager::ShowTooltipWithDelay(views::View* view) {
159 if (!shelf_layout_manager_ || shelf_layout_manager_->IsVisible()) { 162 if (!shelf_layout_manager_ || shelf_layout_manager_->IsVisible()) {
160 timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(timer_delay_), 163 timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(timer_delay_),
161 base::Bind(&ShelfTooltipManager::ShowTooltip, 164 base::Bind(&ShelfTooltipManager::ShowTooltip,
162 weak_factory_.GetWeakPtr(), view)); 165 weak_factory_.GetWeakPtr(), view));
163 } 166 }
164 } 167 }
165 168
166 void ShelfTooltipManager::OnEvent(ui::Event* event) { 169 void ShelfTooltipManager::OnEvent(ui::Event* event) {
167 // Close the tooltip on mouse press or exit, and on most non-mouse events.
168 if (event->type() == ui::ET_MOUSE_PRESSED || 170 if (event->type() == ui::ET_MOUSE_PRESSED ||
169 event->type() == ui::ET_MOUSE_EXITED || !event->IsMouseEvent()) { 171 event->type() == ui::ET_MOUSE_EXITED || !event->IsMouseEvent() ||
172 event->target() != shelf_view_->GetWidget()->GetNativeWindow()) {
170 if (!event->IsKeyEvent()) 173 if (!event->IsKeyEvent())
171 Close(); 174 Close();
172 return; 175 return;
173 } 176 }
174 177
175 gfx::Point point = static_cast<ui::LocatedEvent*>(event)->location(); 178 gfx::Point point = static_cast<ui::LocatedEvent*>(event)->location();
179 aura::Window::ConvertPointToTarget(
180 static_cast<aura::Window*>(event->target()),
181 shelf_view_->GetWidget()->GetNativeWindow(), &point);
176 views::View::ConvertPointFromWidget(shelf_view_, &point); 182 views::View::ConvertPointFromWidget(shelf_view_, &point);
177 if (IsVisible() && shelf_view_->ShouldHideTooltip(point)) {
178 Close();
179 return;
180 }
181
182 views::View* view = shelf_view_->GetTooltipHandlerForPoint(point); 183 views::View* view = shelf_view_->GetTooltipHandlerForPoint(point);
183 const bool should_show = shelf_view_->ShouldShowTooltipForView(view); 184 const bool should_show = shelf_view_->ShouldShowTooltipForView(view);
184 if (IsVisible() && bubble_->GetAnchorView() != view && should_show) 185
186 timer_.Stop();
187 if (IsVisible() && should_show && bubble_->GetAnchorView() != view)
185 ShowTooltip(view); 188 ShowTooltip(view);
189 else if (!IsVisible() && should_show && event->type() == ui::ET_MOUSE_MOVED)
190 ShowTooltipWithDelay(view);
191 else if (IsVisible() && shelf_view_->ShouldHideTooltip(point))
192 Close();
193 }
186 194
187 if (!IsVisible() && event->type() == ui::ET_MOUSE_MOVED) { 195 void ShelfTooltipManager::OnWindowDestroying(aura::Window* window) {
188 timer_.Stop(); 196 if (window == root_window_) {
189 if (should_show) 197 root_window_->RemoveObserver(this);
190 ShowTooltipWithDelay(view); 198 root_window_->RemovePreTargetHandler(this);
199 root_window_ = nullptr;
191 } 200 }
192 } 201 }
193 202
194 void ShelfTooltipManager::WillDeleteShelf() { 203 void ShelfTooltipManager::WillDeleteShelf() {
195 if (shelf_layout_manager_) 204 if (shelf_layout_manager_)
196 shelf_layout_manager_->RemoveObserver(this); 205 shelf_layout_manager_->RemoveObserver(this);
197 shelf_layout_manager_ = nullptr; 206 shelf_layout_manager_ = nullptr;
198
199 views::Widget* widget = shelf_view_ ? shelf_view_->GetWidget() : nullptr;
200 if (widget && widget->GetNativeWindow())
201 widget->GetNativeWindow()->RemovePreTargetHandler(this);
202 shelf_view_ = nullptr; 207 shelf_view_ = nullptr;
203 } 208 }
204 209
205 void ShelfTooltipManager::WillChangeVisibilityState( 210 void ShelfTooltipManager::WillChangeVisibilityState(
206 ShelfVisibilityState new_state) { 211 ShelfVisibilityState new_state) {
207 if (new_state == SHELF_HIDDEN) 212 if (new_state == SHELF_HIDDEN)
208 Close(); 213 Close();
209 } 214 }
210 215
211 void ShelfTooltipManager::OnAutoHideStateChanged(ShelfAutoHideState new_state) { 216 void ShelfTooltipManager::OnAutoHideStateChanged(ShelfAutoHideState new_state) {
212 if (new_state == SHELF_AUTO_HIDE_HIDDEN) { 217 if (new_state == SHELF_AUTO_HIDE_HIDDEN) {
213 timer_.Stop(); 218 timer_.Stop();
214 // AutoHide state change happens during an event filter, so immediate close 219 // AutoHide state change happens during an event filter, so immediate close
215 // may cause a crash in the HandleMouseEvent() after the filter. So we just 220 // may cause a crash in the HandleMouseEvent() after the filter. So we just
216 // schedule the Close here. 221 // schedule the Close here.
217 base::ThreadTaskRunnerHandle::Get()->PostTask( 222 base::ThreadTaskRunnerHandle::Get()->PostTask(
218 FROM_HERE, 223 FROM_HERE,
219 base::Bind(&ShelfTooltipManager::Close, weak_factory_.GetWeakPtr())); 224 base::Bind(&ShelfTooltipManager::Close, weak_factory_.GetWeakPtr()));
220 } 225 }
221 } 226 }
222 227
223 } // namespace ash 228 } // namespace ash
OLDNEW
« no previous file with comments | « ash/shelf/shelf_tooltip_manager.h ('k') | ash/shelf/shelf_tooltip_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698