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

Side by Side Diff: ash/tooltips/tooltip_controller.cc

Issue 10832194: aura: Fix crash when the aura window hosting a tooltip is destroyed. We fix (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: patch Created 8 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | ash/tooltips/tooltip_controller_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 (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 "ash/tooltips/tooltip_controller.h" 5 #include "ash/tooltips/tooltip_controller.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "ash/ash_switches.h" 9 #include "ash/ash_switches.h"
10 #include "ash/shell.h" 10 #include "ash/shell.h"
(...skipping 10 matching lines...) Expand all
21 #include "ui/base/resource/resource_bundle.h" 21 #include "ui/base/resource/resource_bundle.h"
22 #include "ui/base/text/text_elider.h" 22 #include "ui/base/text/text_elider.h"
23 #include "ui/gfx/font.h" 23 #include "ui/gfx/font.h"
24 #include "ui/gfx/point.h" 24 #include "ui/gfx/point.h"
25 #include "ui/gfx/rect.h" 25 #include "ui/gfx/rect.h"
26 #include "ui/gfx/screen.h" 26 #include "ui/gfx/screen.h"
27 #include "ui/views/background.h" 27 #include "ui/views/background.h"
28 #include "ui/views/border.h" 28 #include "ui/views/border.h"
29 #include "ui/views/controls/label.h" 29 #include "ui/views/controls/label.h"
30 #include "ui/views/widget/widget.h" 30 #include "ui/views/widget/widget.h"
31 #include "ui/views/widget/widget_observer.h"
31 32
32 namespace { 33 namespace {
33 34
34 const SkColor kTooltipBackground = 0xFFFFFFCC; 35 const SkColor kTooltipBackground = 0xFFFFFFCC;
35 const SkColor kTooltipBorder = 0xFF646450; 36 const SkColor kTooltipBorder = 0xFF646450;
36 const int kTooltipBorderWidth = 1; 37 const int kTooltipBorderWidth = 1;
37 const int kTooltipHorizontalPadding = 3; 38 const int kTooltipHorizontalPadding = 3;
38 39
39 // Max visual tooltip width. If a tooltip is greater than this width, it will 40 // Max visual tooltip width. If a tooltip is greater than this width, it will
40 // be wrapped. 41 // be wrapped.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 75
75 // Creates a widget of type TYPE_TOOLTIP 76 // Creates a widget of type TYPE_TOOLTIP
76 views::Widget* CreateTooltip() { 77 views::Widget* CreateTooltip() {
77 views::Widget* widget = new views::Widget; 78 views::Widget* widget = new views::Widget;
78 views::Widget::InitParams params; 79 views::Widget::InitParams params;
79 // For aura, since we set the type to TOOLTIP_TYPE, the widget will get 80 // For aura, since we set the type to TOOLTIP_TYPE, the widget will get
80 // auto-parented to the MenuAndTooltipsContainer. 81 // auto-parented to the MenuAndTooltipsContainer.
81 params.type = views::Widget::InitParams::TYPE_TOOLTIP; 82 params.type = views::Widget::InitParams::TYPE_TOOLTIP;
82 params.keep_on_top = true; 83 params.keep_on_top = true;
83 params.accept_events = false; 84 params.accept_events = false;
84 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
85 widget->Init(params); 85 widget->Init(params);
86 return widget; 86 return widget;
87 } 87 }
88 88
89 } // namespace 89 } // namespace
90 90
91 namespace ash { 91 namespace ash {
92 namespace internal { 92 namespace internal {
93 93
94 // Displays a widget with tooltip using a views::Label. 94 // Displays a widget with tooltip using a views::Label.
95 class TooltipController::Tooltip { 95 class TooltipController::Tooltip : public views::WidgetObserver {
96 public: 96 public:
97 Tooltip() { 97 Tooltip() : widget_(NULL) {
98 label_.set_background( 98 label_.set_background(
99 views::Background::CreateSolidBackground(kTooltipBackground)); 99 views::Background::CreateSolidBackground(kTooltipBackground));
100 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAuraNoShadows)) { 100 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAuraNoShadows)) {
101 label_.set_border( 101 label_.set_border(
102 views::Border::CreateSolidBorder(kTooltipBorderWidth, 102 views::Border::CreateSolidBorder(kTooltipBorderWidth,
103 kTooltipBorder)); 103 kTooltipBorder));
104 } 104 }
105 label_.set_owned_by_client(); 105 label_.set_owned_by_client();
106 widget_.reset(CreateTooltip());
107 widget_->SetContentsView(&label_);
108 } 106 }
109 107
110 ~Tooltip() { 108 ~Tooltip() {
111 widget_->Close(); 109 if (widget_) {
110 widget_->RemoveObserver(this);
111 widget_->Close();
112 }
112 } 113 }
113 114
114 // Updates the text on the tooltip and resizes to fit. 115 // Updates the text on the tooltip and resizes to fit.
115 void SetText(string16 tooltip_text, gfx::Point location) { 116 void SetText(string16 tooltip_text, gfx::Point location) {
116 int max_width, line_count; 117 int max_width, line_count;
117 TrimTooltipToFit(&tooltip_text, &max_width, &line_count, 118 TrimTooltipToFit(&tooltip_text, &max_width, &line_count,
118 location.x(), location.y()); 119 location.x(), location.y());
119 label_.SetText(tooltip_text); 120 label_.SetText(tooltip_text);
120 121
121 int width = max_width + 2 * kTooltipHorizontalPadding; 122 int width = max_width + 2 * kTooltipHorizontalPadding;
122 int height = label_.GetPreferredSize().height() + 123 int height = label_.GetPreferredSize().height() +
123 2 * kTooltipVerticalPadding; 124 2 * kTooltipVerticalPadding;
124 if (CommandLine::ForCurrentProcess()->HasSwitch( 125 if (CommandLine::ForCurrentProcess()->HasSwitch(
125 switches::kAuraNoShadows)) { 126 switches::kAuraNoShadows)) {
126 width += 2 * kTooltipBorderWidth; 127 width += 2 * kTooltipBorderWidth;
127 height += 2 * kTooltipBorderWidth; 128 height += 2 * kTooltipBorderWidth;
128 } 129 }
129 SetTooltipBounds(location, width, height); 130 SetTooltipBounds(location, width, height);
130 } 131 }
131 132
132 // Shows the tooltip. 133 // Shows the tooltip.
133 void Show() { 134 void Show() {
134 widget_->Show(); 135 GetWidget()->Show();
135 } 136 }
136 137
137 // Hides the tooltip. 138 // Hides the tooltip.
138 void Hide() { 139 void Hide() {
139 widget_->Hide(); 140 if (widget_)
141 widget_->Hide();
140 } 142 }
141 143
142 bool IsVisible() { 144 bool IsVisible() {
143 return widget_->IsVisible(); 145 return widget_? widget_->IsVisible() : false;
146 }
147
148 // Overriden from views::WidgetObserver.
149 virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE {
150 DCHECK_EQ(widget_, widget);
151 widget_ = NULL;
144 } 152 }
145 153
146 private: 154 private:
147 views::Label label_; 155 views::Label label_;
148 scoped_ptr<views::Widget> widget_; 156 views::Widget* widget_;
149 157
150 // Adjusts the bounds given by the arguments to fit inside the desktop 158 // Adjusts the bounds given by the arguments to fit inside the desktop
151 // and applies the adjusted bounds to the label_. 159 // and applies the adjusted bounds to the label_.
152 void SetTooltipBounds(gfx::Point mouse_pos, 160 void SetTooltipBounds(gfx::Point mouse_pos,
153 int tooltip_width, 161 int tooltip_width,
154 int tooltip_height) { 162 int tooltip_height) {
155 gfx::Rect tooltip_rect(mouse_pos.x(), mouse_pos.y(), tooltip_width, 163 gfx::Rect tooltip_rect(mouse_pos.x(), mouse_pos.y(), tooltip_width,
156 tooltip_height); 164 tooltip_height);
157 165
158 tooltip_rect.Offset(kCursorOffsetX, kCursorOffsetY); 166 tooltip_rect.Offset(kCursorOffsetX, kCursorOffsetY);
159 gfx::Rect display_bounds = 167 gfx::Rect display_bounds =
160 gfx::Screen::GetDisplayNearestPoint(tooltip_rect.origin()).bounds(); 168 gfx::Screen::GetDisplayNearestPoint(tooltip_rect.origin()).bounds();
161 169
162 // If tooltip is out of bounds on the x axis, we simply shift it 170 // If tooltip is out of bounds on the x axis, we simply shift it
163 // horizontally by the offset. 171 // horizontally by the offset.
164 if (tooltip_rect.right() > display_bounds.right()) { 172 if (tooltip_rect.right() > display_bounds.right()) {
165 int h_offset = tooltip_rect.right() - display_bounds.right(); 173 int h_offset = tooltip_rect.right() - display_bounds.right();
166 tooltip_rect.Offset(-h_offset, 0); 174 tooltip_rect.Offset(-h_offset, 0);
167 } 175 }
168 176
169 // If tooltip is out of bounds on the y axis, we flip it to appear above the 177 // If tooltip is out of bounds on the y axis, we flip it to appear above the
170 // mouse cursor instead of below. 178 // mouse cursor instead of below.
171 if (tooltip_rect.bottom() > display_bounds.bottom()) 179 if (tooltip_rect.bottom() > display_bounds.bottom())
172 tooltip_rect.set_y(mouse_pos.y() - tooltip_height); 180 tooltip_rect.set_y(mouse_pos.y() - tooltip_height);
173 181
174 widget_->SetBounds(tooltip_rect.AdjustToFit(display_bounds)); 182 GetWidget()->SetBounds(tooltip_rect.AdjustToFit(display_bounds));
175 } 183 }
176 184
185 views::Widget* GetWidget() {
186 if (!widget_) {
187 widget_ = CreateTooltip();
188 widget_->SetContentsView(&label_);
189 widget_->AddObserver(this);
190 }
191 return widget_;
192 }
177 }; 193 };
178 194
179 //////////////////////////////////////////////////////////////////////////////// 195 ////////////////////////////////////////////////////////////////////////////////
180 // TooltipController public: 196 // TooltipController public:
181 197
182 TooltipController::TooltipController( 198 TooltipController::TooltipController(
183 aura::client::DragDropClient* drag_drop_client) 199 aura::client::DragDropClient* drag_drop_client)
184 : drag_drop_client_(drag_drop_client), 200 : drag_drop_client_(drag_drop_client),
185 tooltip_window_(NULL), 201 tooltip_window_(NULL),
186 tooltip_window_at_mouse_press_(NULL), 202 tooltip_window_at_mouse_press_(NULL),
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 } 472 }
457 473
458 TooltipController::Tooltip* TooltipController::GetTooltip() { 474 TooltipController::Tooltip* TooltipController::GetTooltip() {
459 if (!tooltip_.get()) 475 if (!tooltip_.get())
460 tooltip_.reset(new Tooltip); 476 tooltip_.reset(new Tooltip);
461 return tooltip_.get(); 477 return tooltip_.get();
462 } 478 }
463 479
464 } // namespace internal 480 } // namespace internal
465 } // namespace ash 481 } // namespace ash
OLDNEW
« no previous file with comments | « no previous file | ash/tooltips/tooltip_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698