Chromium Code Reviews| 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 "ash/magnifier/partial_magnification_controller.h" | 5 #include "ash/magnifier/partial_magnification_controller.h" |
| 6 | 6 |
| 7 #include "ash/common/system/chromeos/palette/palette_utils.h" | 7 #include "ash/common/system/chromeos/palette/palette_utils.h" |
| 8 #include "ash/shell.h" | 8 #include "ash/shell.h" |
| 9 #include "third_party/skia/include/core/SkDrawLooper.h" | |
| 9 #include "ui/aura/window_event_dispatcher.h" | 10 #include "ui/aura/window_event_dispatcher.h" |
| 10 #include "ui/aura/window_tree_host.h" | 11 #include "ui/aura/window_tree_host.h" |
| 11 #include "ui/compositor/layer.h" | 12 #include "ui/compositor/layer.h" |
| 12 #include "ui/compositor/paint_recorder.h" | 13 #include "ui/compositor/paint_recorder.h" |
| 13 #include "ui/events/event.h" | 14 #include "ui/events/event.h" |
| 14 #include "ui/events/event_constants.h" | 15 #include "ui/events/event_constants.h" |
| 15 #include "ui/views/widget/widget.h" | 16 #include "ui/views/widget/widget.h" |
| 16 #include "ui/wm/core/coordinate_conversion.h" | 17 #include "ui/wm/core/coordinate_conversion.h" |
| 17 | 18 |
| 18 namespace ash { | 19 namespace ash { |
| 19 namespace { | 20 namespace { |
| 20 | 21 |
| 21 // Ratio of magnifier scale. | 22 // Ratio of magnifier scale. |
| 22 const float kMagnificationScale = 2.f; | 23 const float kMagnificationScale = 2.f; |
| 23 // Radius of the magnifying glass in DIP. | 24 // Radius of the magnifying glass in DIP. This does not include the thickness |
| 24 const int kMagnifierRadius = 200; | 25 // of the magnifying glass shadow and border. |
| 26 const int kMagnifierRadius = 188; | |
| 25 // Size of the border around the magnifying glass in DIP. | 27 // Size of the border around the magnifying glass in DIP. |
| 26 const int kBorderSize = 10; | 28 const int kBorderSize = 10; |
| 27 // Thickness of the outline around magnifying glass border in DIP. | 29 // Thickness of the outline around magnifying glass border in DIP. |
| 28 const int kBorderOutlineThickness = 2; | 30 const int kBorderOutlineThickness = 1; |
| 31 // Thickness of the shadow around the magnifying glass in DIP. | |
| 32 const int kShadowThickness = 24; | |
| 33 // Offset of the shadow around the magnifying glass in DIP. One of the shadows | |
| 34 // is lowered a bit, so we have to include |kShadowOffset| in our calculations | |
| 35 // to compensate. | |
| 36 const int kShadowOffset = 24; | |
| 29 // The color of the border and its outlines. The border has an outline on both | 37 // The color of the border and its outlines. The border has an outline on both |
| 30 // sides, producing a black/white/black ring. | 38 // sides, producing a black/white/black ring. |
| 31 const SkColor kBorderColor = SK_ColorWHITE; | 39 const SkColor kBorderColor = SkColorSetARGB(204, 255, 255, 255); |
| 32 const SkColor kBorderOutlineColor = SK_ColorBLACK; | 40 const SkColor kBorderOutlineColor = SkColorSetARGB(51, 0, 0, 0); |
| 41 // The colors of the two shadow around the magnifiying glass. | |
| 42 const SkColor kTopShadowColor = SkColorSetARGB(26, 0, 0, 0); | |
| 43 const SkColor kBottomShadowColor = SkColorSetARGB(61, 0, 0, 0); | |
| 33 // Inset on the zoom filter. | 44 // Inset on the zoom filter. |
| 34 const int kZoomInset = 0; | 45 const int kZoomInset = 0; |
| 35 // Vertical offset between the center of the magnifier and the tip of the | 46 // Vertical offset between the center of the magnifier and the tip of the |
| 36 // pointer. TODO(jdufault): The vertical offset should only apply to the window | 47 // pointer. TODO(jdufault): The vertical offset should only apply to the window |
| 37 // location, not the magnified contents. See crbug.com/637617. | 48 // location, not the magnified contents. See crbug.com/637617. |
| 38 const int kVerticalOffset = 0; | 49 const int kVerticalOffset = 0; |
| 39 | 50 |
| 40 // Name of the magnifier window. | 51 // Name of the magnifier window. |
| 41 const char kPartialMagniferWindowName[] = "PartialMagnifierWindow"; | 52 const char kPartialMagniferWindowName[] = "PartialMagnifierWindow"; |
| 42 | 53 |
| 43 gfx::Size GetWindowSize() { | 54 gfx::Size GetWindowSize() { |
| 44 return gfx::Size(kMagnifierRadius * 2, kMagnifierRadius * 2); | 55 // The diameter of the window is the diameter of the magnifier, border and |
| 56 // shadow combined. We apply |kShadowOffset| on all sides even though the | |
| 57 // shadow is only thicker on the bottom so as to keep the circle centered in | |
| 58 // the view and keep calculations (border rendering and content masking) | |
| 59 // simpler. | |
| 60 int window_diameter = | |
| 61 (kMagnifierRadius + kBorderSize + kShadowThickness + kShadowOffset) * 2; | |
| 62 return gfx::Size(window_diameter, window_diameter); | |
| 45 } | 63 } |
| 46 | 64 |
| 47 gfx::Rect GetBounds(gfx::Point mouse) { | 65 gfx::Rect GetBounds(gfx::Point mouse) { |
| 48 gfx::Size size = GetWindowSize(); | 66 gfx::Size size = GetWindowSize(); |
| 49 gfx::Point origin(mouse.x() - (size.width() / 2), | 67 gfx::Point origin(mouse.x() - (size.width() / 2), |
| 50 mouse.y() - (size.height() / 2) - kVerticalOffset); | 68 mouse.y() - (size.height() / 2) - kVerticalOffset); |
| 51 return gfx::Rect(origin, size); | 69 return gfx::Rect(origin, size); |
| 52 } | 70 } |
| 53 | 71 |
| 54 aura::Window* GetCurrentRootWindow() { | 72 aura::Window* GetCurrentRootWindow() { |
| 55 aura::Window::Windows root_windows = ash::Shell::GetAllRootWindows(); | 73 aura::Window::Windows root_windows = ash::Shell::GetAllRootWindows(); |
| 56 for (aura::Window* root_window : root_windows) { | 74 for (aura::Window* root_window : root_windows) { |
| 57 if (root_window->ContainsPointInRoot( | 75 if (root_window->ContainsPointInRoot( |
| 58 root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot())) | 76 root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot())) |
| 59 return root_window; | 77 return root_window; |
| 60 } | 78 } |
| 61 return nullptr; | 79 return nullptr; |
| 62 } | 80 } |
| 63 | 81 |
| 64 } // namespace | 82 } // namespace |
| 65 | 83 |
| 66 // The content mask provides a clipping layer for the magnification window so we | 84 // The content mask provides a clipping layer for the magnification window so we |
| 67 // can show a circular magnifier. | 85 // can show a circular magnifier. |
| 68 class PartialMagnificationController::ContentMask : public ui::LayerDelegate { | 86 class PartialMagnificationController::ContentMask : public ui::LayerDelegate { |
| 69 public: | 87 public: |
| 70 // If |stroke| is true, the circle will be a stroke. This is useful if we wish | 88 // If |is_border| is true, the circle will be a stroke. This is useful if we |
| 71 // to clip a border. | 89 // wish to clip a border. |
| 72 ContentMask(bool stroke, gfx::Size mask_bounds) | 90 ContentMask(bool is_border, gfx::Size mask_bounds) |
| 73 : layer_(ui::LAYER_TEXTURED), stroke_(stroke) { | 91 : layer_(ui::LAYER_TEXTURED), is_border_(is_border) { |
| 74 layer_.set_delegate(this); | 92 layer_.set_delegate(this); |
| 75 layer_.SetFillsBoundsOpaquely(false); | 93 layer_.SetFillsBoundsOpaquely(false); |
| 76 layer_.SetBounds(gfx::Rect(mask_bounds)); | 94 layer_.SetBounds(gfx::Rect(mask_bounds)); |
| 77 } | 95 } |
| 78 | 96 |
| 79 ~ContentMask() override { layer_.set_delegate(nullptr); } | 97 ~ContentMask() override { layer_.set_delegate(nullptr); } |
| 80 | 98 |
| 81 ui::Layer* layer() { return &layer_; } | 99 ui::Layer* layer() { return &layer_; } |
| 82 | 100 |
| 83 private: | 101 private: |
| 84 // ui::LayerDelegate: | 102 // ui::LayerDelegate: |
| 85 void OnPaintLayer(const ui::PaintContext& context) override { | 103 void OnPaintLayer(const ui::PaintContext& context) override { |
| 86 ui::PaintRecorder recorder(context, layer()->size()); | 104 ui::PaintRecorder recorder(context, layer()->size()); |
| 87 | 105 |
| 88 SkPaint paint; | 106 SkPaint paint; |
| 89 paint.setAlpha(255); | 107 paint.setAlpha(255); |
| 90 paint.setAntiAlias(true); | 108 paint.setAntiAlias(true); |
| 91 paint.setStrokeWidth(kBorderSize); | 109 // Stroke is used for clipping the border which consists of the rendered |
| 92 paint.setStyle(stroke_ ? SkPaint::kStroke_Style : SkPaint::kFill_Style); | 110 // border |kBorderSize| and the magnifier shadow |kShadowThickness| and |
| 111 // |kShadowOffset|. | |
| 112 paint.setStrokeWidth(kBorderSize + kShadowThickness + kShadowOffset); | |
| 113 paint.setStyle(is_border_ ? SkPaint::kStroke_Style : SkPaint::kFill_Style); | |
| 93 | 114 |
| 115 // If we want to clip the magnifier zone use the magnifiers radius. | |
| 116 // Otherwise we want to clip the border, shadow and shadow offset so we | |
| 117 // start | |
| 118 // at the halfway point of the stroke width. | |
| 94 gfx::Rect rect(layer()->bounds().size()); | 119 gfx::Rect rect(layer()->bounds().size()); |
| 95 recorder.canvas()->DrawCircle(rect.CenterPoint(), | 120 int clipping_radius = kMagnifierRadius; |
| 96 rect.width() / 2 - kBorderSize / 2, paint); | 121 if (is_border_) |
| 122 clipping_radius += (kShadowThickness + kShadowOffset + kBorderSize) / 2; | |
| 123 recorder.canvas()->DrawCircle(rect.CenterPoint(), clipping_radius, paint); | |
| 97 } | 124 } |
| 98 | 125 |
| 99 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {} | 126 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {} |
| 100 | 127 |
| 101 void OnDeviceScaleFactorChanged(float device_scale_factor) override { | 128 void OnDeviceScaleFactorChanged(float device_scale_factor) override { |
| 102 // Redrawing will take care of scale factor change. | 129 // Redrawing will take care of scale factor change. |
| 103 } | 130 } |
| 104 | 131 |
| 105 base::Closure PrepareForLayerBoundsChange() override { | 132 base::Closure PrepareForLayerBoundsChange() override { |
| 106 return base::Closure(); | 133 return base::Closure(); |
| 107 } | 134 } |
| 108 | 135 |
| 109 ui::Layer layer_; | 136 ui::Layer layer_; |
| 110 bool stroke_; | 137 bool is_border_; |
| 111 | |
| 112 DISALLOW_COPY_AND_ASSIGN(ContentMask); | 138 DISALLOW_COPY_AND_ASSIGN(ContentMask); |
| 113 }; | 139 }; |
| 114 | 140 |
| 115 // The border renderer draws the border as well as outline on both the outer and | 141 // The border renderer draws the border as well as outline on both the outer and |
| 116 // inner radius to increase visibility. | 142 // inner radius to increase visibility. The border renderer also handles drawing |
| 143 // the shadow. | |
| 117 class PartialMagnificationController::BorderRenderer | 144 class PartialMagnificationController::BorderRenderer |
| 118 : public ui::LayerDelegate { | 145 : public ui::LayerDelegate { |
| 119 public: | 146 public: |
| 120 explicit BorderRenderer(const gfx::Rect& magnifier_bounds) | 147 explicit BorderRenderer(const gfx::Rect& window_bounds) |
| 121 : magnifier_bounds_(magnifier_bounds) {} | 148 : magnifier_window_bounds_(window_bounds) { |
| 149 magnifier_shadows_.push_back(gfx::ShadowValue( | |
| 150 gfx::Vector2d(0, kShadowOffset), kShadowThickness, kBottomShadowColor)); | |
| 151 magnifier_shadows_.push_back(gfx::ShadowValue( | |
| 152 gfx::Vector2d(0, 0), kShadowThickness, kTopShadowColor)); | |
| 153 } | |
| 122 | 154 |
| 123 ~BorderRenderer() override {} | 155 ~BorderRenderer() override {} |
| 124 | 156 |
| 125 private: | 157 private: |
| 126 // ui::LayerDelegate: | 158 // ui::LayerDelegate: |
| 127 void OnPaintLayer(const ui::PaintContext& context) override { | 159 void OnPaintLayer(const ui::PaintContext& context) override { |
| 128 ui::PaintRecorder recorder(context, magnifier_bounds_.size()); | 160 ui::PaintRecorder recorder(context, magnifier_window_bounds_.size()); |
| 129 | 161 |
| 130 SkPaint paint; | 162 // Draw the shadow. |
| 131 paint.setAntiAlias(true); | 163 SkPaint shadow_paint; |
| 132 paint.setStyle(SkPaint::kStroke_Style); | 164 shadow_paint.setAntiAlias(true); |
| 165 shadow_paint.setColor(SK_ColorTRANSPARENT); | |
| 166 shadow_paint.setLooper(gfx::CreateShadowDrawLooper(magnifier_shadows_)); | |
|
James Cook
2016/10/05 19:42:35
I am not familiar with CreateShadowDrawLooper() bu
sammiequon
2016/10/05 19:56:30
Done.
| |
| 167 gfx::Rect shadow_bounds(magnifier_window_bounds_.size()); | |
| 168 recorder.canvas()->DrawCircle( | |
| 169 shadow_bounds.CenterPoint(), | |
| 170 shadow_bounds.width() / 2 - kShadowThickness - kShadowOffset, | |
| 171 shadow_paint); | |
| 133 | 172 |
| 134 const int magnifier_radius = magnifier_bounds_.width() / 2; | 173 SkPaint border_paint; |
| 174 border_paint.setAntiAlias(true); | |
| 175 border_paint.setStyle(SkPaint::kStroke_Style); | |
| 176 | |
| 177 // The radius of the magnifier and its border. | |
| 178 const int magnifier_radius = kMagnifierRadius + kBorderSize; | |
| 179 | |
| 135 // Draw the inner border. | 180 // Draw the inner border. |
| 136 paint.setStrokeWidth(kBorderSize); | 181 border_paint.setStrokeWidth(kBorderSize); |
| 137 paint.setColor(kBorderColor); | 182 border_paint.setColor(kBorderColor); |
| 138 recorder.canvas()->DrawCircle(magnifier_bounds_.CenterPoint(), | 183 recorder.canvas()->DrawCircle(magnifier_window_bounds_.CenterPoint(), |
| 139 magnifier_radius - kBorderSize / 2, paint); | 184 magnifier_radius - kBorderSize / 2, |
| 185 border_paint); | |
| 140 | 186 |
| 141 // Draw border outer outline and then draw the border inner outline. | 187 // Draw border outer outline and then draw the border inner outline. |
| 142 paint.setStrokeWidth(kBorderOutlineThickness); | 188 border_paint.setStrokeWidth(kBorderOutlineThickness); |
| 143 paint.setColor(kBorderOutlineColor); | 189 border_paint.setColor(kBorderOutlineColor); |
| 144 recorder.canvas()->DrawCircle( | 190 recorder.canvas()->DrawCircle( |
| 145 magnifier_bounds_.CenterPoint(), | 191 magnifier_window_bounds_.CenterPoint(), |
| 146 magnifier_radius - kBorderOutlineThickness / 2, paint); | 192 magnifier_radius - kBorderOutlineThickness / 2, border_paint); |
| 147 recorder.canvas()->DrawCircle( | 193 recorder.canvas()->DrawCircle( |
| 148 magnifier_bounds_.CenterPoint(), | 194 magnifier_window_bounds_.CenterPoint(), |
| 149 magnifier_radius - kBorderSize + kBorderOutlineThickness / 2, paint); | 195 magnifier_radius - kBorderSize + kBorderOutlineThickness / 2, |
| 196 border_paint); | |
| 150 } | 197 } |
| 151 | 198 |
| 152 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {} | 199 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {} |
| 153 | 200 |
| 154 void OnDeviceScaleFactorChanged(float device_scale_factor) override {} | 201 void OnDeviceScaleFactorChanged(float device_scale_factor) override {} |
| 155 | 202 |
| 156 base::Closure PrepareForLayerBoundsChange() override { | 203 base::Closure PrepareForLayerBoundsChange() override { |
| 157 return base::Closure(); | 204 return base::Closure(); |
| 158 } | 205 } |
| 159 | 206 |
| 160 gfx::Rect magnifier_bounds_; | 207 gfx::Rect magnifier_window_bounds_; |
| 208 std::vector<gfx::ShadowValue> magnifier_shadows_; | |
| 161 | 209 |
| 162 DISALLOW_COPY_AND_ASSIGN(BorderRenderer); | 210 DISALLOW_COPY_AND_ASSIGN(BorderRenderer); |
| 163 }; | 211 }; |
| 164 | 212 |
| 165 PartialMagnificationController::PartialMagnificationController() { | 213 PartialMagnificationController::PartialMagnificationController() { |
| 166 Shell::GetInstance()->AddPreTargetHandler(this); | 214 Shell::GetInstance()->AddPreTargetHandler(this); |
| 167 } | 215 } |
| 168 | 216 |
| 169 PartialMagnificationController::~PartialMagnificationController() { | 217 PartialMagnificationController::~PartialMagnificationController() { |
| 170 CloseMagnifierWindow(); | 218 CloseMagnifierWindow(); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 225 CloseMagnifierWindow(); | 273 CloseMagnifierWindow(); |
| 226 } | 274 } |
| 227 } | 275 } |
| 228 | 276 |
| 229 void PartialMagnificationController::OnLocatedEvent( | 277 void PartialMagnificationController::OnLocatedEvent( |
| 230 ui::LocatedEvent* event, | 278 ui::LocatedEvent* event, |
| 231 const ui::PointerDetails& pointer_details) { | 279 const ui::PointerDetails& pointer_details) { |
| 232 if (!is_enabled_) | 280 if (!is_enabled_) |
| 233 return; | 281 return; |
| 234 | 282 |
| 235 if (pointer_details.pointer_type != ui::EventPointerType::POINTER_TYPE_PEN) | 283 if (pointer_details.pointer_type == ui::EventPointerType::POINTER_TYPE_PEN) |
|
James Cook
2016/10/05 19:42:35
For my edification: What's going on here?
It look
sammiequon
2016/10/05 19:56:30
My mistake I was testing the magnifier and i forgo
| |
| 236 return; | 284 return; |
| 237 | 285 |
| 238 // Compute the event location in screen space. | 286 // Compute the event location in screen space. |
| 239 aura::Window* target = static_cast<aura::Window*>(event->target()); | 287 aura::Window* target = static_cast<aura::Window*>(event->target()); |
| 240 aura::Window* event_root = target->GetRootWindow(); | 288 aura::Window* event_root = target->GetRootWindow(); |
| 241 gfx::Point screen_point = event->root_location(); | 289 gfx::Point screen_point = event->root_location(); |
| 242 wm::ConvertPointToScreen(event_root, &screen_point); | 290 wm::ConvertPointToScreen(event_root, &screen_point); |
| 243 | 291 |
| 244 // If the stylus is pressed on the palette icon or widget, do not activate. | 292 // If the stylus is pressed on the palette icon or widget, do not activate. |
| 245 if (event->type() == ui::ET_MOUSE_PRESSED && | 293 if (event->type() == ui::ET_MOUSE_PRESSED && |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 304 | 352 |
| 305 zoom_layer_.reset(new ui::Layer(ui::LayerType::LAYER_SOLID_COLOR)); | 353 zoom_layer_.reset(new ui::Layer(ui::LayerType::LAYER_SOLID_COLOR)); |
| 306 zoom_layer_->SetBounds(gfx::Rect(GetWindowSize())); | 354 zoom_layer_->SetBounds(gfx::Rect(GetWindowSize())); |
| 307 zoom_layer_->SetBackgroundZoom(kMagnificationScale, kZoomInset); | 355 zoom_layer_->SetBackgroundZoom(kMagnificationScale, kZoomInset); |
| 308 root_layer->Add(zoom_layer_.get()); | 356 root_layer->Add(zoom_layer_.get()); |
| 309 | 357 |
| 310 border_layer_.reset(new ui::Layer(ui::LayerType::LAYER_TEXTURED)); | 358 border_layer_.reset(new ui::Layer(ui::LayerType::LAYER_TEXTURED)); |
| 311 border_layer_->SetBounds(gfx::Rect(GetWindowSize())); | 359 border_layer_->SetBounds(gfx::Rect(GetWindowSize())); |
| 312 border_renderer_.reset(new BorderRenderer(gfx::Rect(GetWindowSize()))); | 360 border_renderer_.reset(new BorderRenderer(gfx::Rect(GetWindowSize()))); |
| 313 border_layer_->set_delegate(border_renderer_.get()); | 361 border_layer_->set_delegate(border_renderer_.get()); |
| 362 border_layer_->SetFillsBoundsOpaquely(false); | |
| 314 root_layer->Add(border_layer_.get()); | 363 root_layer->Add(border_layer_.get()); |
| 315 | 364 |
| 316 border_mask_.reset(new ContentMask(true, GetWindowSize())); | 365 border_mask_.reset(new ContentMask(true, GetWindowSize())); |
| 317 border_layer_->SetMaskLayer(border_mask_->layer()); | 366 border_layer_->SetMaskLayer(border_mask_->layer()); |
| 318 | 367 |
| 319 zoom_mask_.reset(new ContentMask(false, GetWindowSize())); | 368 zoom_mask_.reset(new ContentMask(false, GetWindowSize())); |
| 320 zoom_layer_->SetMaskLayer(zoom_mask_->layer()); | 369 zoom_layer_->SetMaskLayer(zoom_mask_->layer()); |
| 321 | 370 |
| 322 host_widget_->AddObserver(this); | 371 host_widget_->AddObserver(this); |
| 323 } | 372 } |
| 324 | 373 |
| 325 void PartialMagnificationController::CloseMagnifierWindow() { | 374 void PartialMagnificationController::CloseMagnifierWindow() { |
| 326 if (host_widget_) { | 375 if (host_widget_) { |
| 327 RemoveZoomWidgetObservers(); | 376 RemoveZoomWidgetObservers(); |
| 328 host_widget_->Close(); | 377 host_widget_->Close(); |
| 329 host_widget_ = nullptr; | 378 host_widget_ = nullptr; |
| 330 } | 379 } |
| 331 } | 380 } |
| 332 | 381 |
| 333 void PartialMagnificationController::RemoveZoomWidgetObservers() { | 382 void PartialMagnificationController::RemoveZoomWidgetObservers() { |
| 334 DCHECK(host_widget_); | 383 DCHECK(host_widget_); |
| 335 host_widget_->RemoveObserver(this); | 384 host_widget_->RemoveObserver(this); |
| 336 aura::Window* root_window = host_widget_->GetNativeView()->GetRootWindow(); | 385 aura::Window* root_window = host_widget_->GetNativeView()->GetRootWindow(); |
| 337 DCHECK(root_window); | 386 DCHECK(root_window); |
| 338 root_window->RemoveObserver(this); | 387 root_window->RemoveObserver(this); |
| 339 } | 388 } |
| 340 | 389 |
| 341 } // namespace ash | 390 } // namespace ash |
| OLD | NEW |