OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "components/exo/pointer.h" | 5 #include "components/exo/pointer.h" |
6 | 6 |
7 #include "ash/public/cpp/shell_window_ids.h" | 7 #include "ash/public/cpp/shell_window_ids.h" |
8 #include "cc/output/copy_output_request.h" | 8 #include "cc/output/copy_output_request.h" |
9 #include "cc/output/copy_output_result.h" | 9 #include "cc/output/copy_output_result.h" |
10 #include "components/exo/pointer_delegate.h" | 10 #include "components/exo/pointer_delegate.h" |
11 #include "components/exo/pointer_stylus_delegate.h" | 11 #include "components/exo/pointer_stylus_delegate.h" |
12 #include "components/exo/surface.h" | 12 #include "components/exo/surface.h" |
13 #include "components/exo/wm_helper.h" | 13 #include "components/exo/wm_helper.h" |
14 #include "ui/aura/client/cursor_client.h" | 14 #include "ui/aura/client/cursor_client.h" |
15 #include "ui/aura/env.h" | 15 #include "ui/aura/env.h" |
16 #include "ui/aura/window.h" | 16 #include "ui/aura/window.h" |
17 #include "ui/display/manager/display_manager.h" | 17 #include "ui/display/manager/display_manager.h" |
18 #include "ui/display/manager/managed_display_info.h" | 18 #include "ui/display/manager/managed_display_info.h" |
19 #include "ui/display/screen.h" | 19 #include "ui/display/screen.h" |
20 #include "ui/events/event.h" | 20 #include "ui/events/event.h" |
21 #include "ui/gfx/geometry/vector2d_conversions.h" | 21 #include "ui/gfx/geometry/vector2d_conversions.h" |
22 #include "ui/gfx/transform_util.h" | 22 #include "ui/gfx/transform.h" |
23 | 23 |
24 #if defined(USE_OZONE) | 24 #if defined(USE_OZONE) |
25 #include "ui/ozone/public/cursor_factory_ozone.h" | 25 #include "ui/ozone/public/cursor_factory_ozone.h" |
26 #endif | 26 #endif |
27 | 27 |
28 #if defined(USE_X11) | 28 #if defined(USE_X11) |
29 #include "ui/base/cursor/cursor_loader_x11.h" | 29 #include "ui/base/cursor/cursor_loader_x11.h" |
30 #endif | 30 #endif |
31 | 31 |
32 namespace exo { | 32 namespace exo { |
33 namespace { | 33 namespace { |
34 | 34 |
35 const float kLargeCursorScale = 2.8f; | 35 // TODO(oshima): Some accessibility features, including large cursors, disable |
36 // hardware cursors. Ash does not support compositing for custom cursors, so it | |
37 // replaces them with the default cursor. As a result, this scale has no effect | |
38 // for now. See crbug.com/708378. | |
39 float GetCursorScale(ui::CursorSetType cursor_set) { | |
40 return cursor_set == ui::CURSOR_SET_LARGE ? 2.8f : 1.0f; | |
41 } | |
36 | 42 |
37 // Synthesized events typically lack floating point precision so to avoid | 43 // Synthesized events typically lack floating point precision so to avoid |
38 // generating mouse event jitter we consider the location of these events | 44 // generating mouse event jitter we consider the location of these events |
39 // to be the same as |location| if floored values match. | 45 // to be the same as |location| if floored values match. |
40 bool SameLocation(const ui::LocatedEvent* event, const gfx::PointF& location) { | 46 bool SameLocation(const ui::LocatedEvent* event, const gfx::PointF& location) { |
41 if (event->flags() & ui::EF_IS_SYNTHESIZED) | 47 if (event->flags() & ui::EF_IS_SYNTHESIZED) |
42 return event->location() == gfx::ToFlooredPoint(location); | 48 return event->location() == gfx::ToFlooredPoint(location); |
43 | 49 |
44 return event->location_f() == location; | 50 return event->location_f() == location; |
45 } | 51 } |
46 | 52 |
47 } // namespace | 53 } // namespace |
48 | 54 |
49 //////////////////////////////////////////////////////////////////////////////// | 55 //////////////////////////////////////////////////////////////////////////////// |
50 // Pointer, public: | 56 // Pointer, public: |
51 | 57 |
52 Pointer::Pointer(PointerDelegate* delegate) | 58 Pointer::Pointer(PointerDelegate* delegate) |
53 : delegate_(delegate), | 59 : delegate_(delegate), |
54 cursor_(ui::kCursorNull), | 60 cursor_(new aura::Window(nullptr)), |
55 cursor_capture_source_id_(base::UnguessableToken::Create()), | 61 cursor_capture_source_id_(base::UnguessableToken::Create()), |
56 cursor_capture_weak_ptr_factory_(this) { | 62 cursor_capture_weak_ptr_factory_(this) { |
57 auto* helper = WMHelper::GetInstance(); | 63 auto* helper = WMHelper::GetInstance(); |
58 helper->AddPreTargetHandler(this); | 64 helper->AddPreTargetHandler(this); |
59 helper->AddCursorObserver(this); | 65 helper->AddCursorObserver(this); |
66 | |
67 cursor_scale_ = GetCursorScale(helper->GetCursorSet()); | |
68 | |
69 cursor_->SetName("ExoCursor"); | |
70 cursor_->Init(ui::LAYER_NOT_DRAWN); | |
71 cursor_->set_owned_by_parent(false); | |
72 OnCursorDisplayChanging(display::Screen::GetScreen()->GetPrimaryDisplay()); | |
60 } | 73 } |
61 | 74 |
62 Pointer::~Pointer() { | 75 Pointer::~Pointer() { |
63 delegate_->OnPointerDestroying(this); | 76 delegate_->OnPointerDestroying(this); |
64 if (surface_) | 77 if (surface_) |
65 surface_->RemoveSurfaceObserver(this); | 78 surface_->RemoveSurfaceObserver(this); |
66 if (focus_) { | 79 if (focus_) { |
67 focus_->RemoveSurfaceObserver(this); | 80 focus_->RemoveSurfaceObserver(this); |
68 focus_->UnregisterCursorProvider(this); | 81 focus_->UnregisterCursorProvider(this); |
69 } | 82 } |
(...skipping 11 matching lines...) Expand all Loading... | |
81 bool cursor_changed = false; | 94 bool cursor_changed = false; |
82 | 95 |
83 // If surface is different than the current pointer surface then remove the | 96 // If surface is different than the current pointer surface then remove the |
84 // current surface and add the new surface. | 97 // current surface and add the new surface. |
85 if (surface != surface_) { | 98 if (surface != surface_) { |
86 if (surface && surface->HasSurfaceDelegate()) { | 99 if (surface && surface->HasSurfaceDelegate()) { |
87 DLOG(ERROR) << "Surface has already been assigned a role"; | 100 DLOG(ERROR) << "Surface has already been assigned a role"; |
88 return; | 101 return; |
89 } | 102 } |
90 if (surface_) { | 103 if (surface_) { |
91 surface_->window()->SetTransform(gfx::Transform()); | 104 cursor_->RemoveChild(surface_->window()); |
92 WMHelper::GetInstance() | |
93 ->GetContainer(ash::kShellWindowId_MouseCursorContainer) | |
94 ->RemoveChild(surface_->window()); | |
95 surface_->SetSurfaceDelegate(nullptr); | 105 surface_->SetSurfaceDelegate(nullptr); |
96 surface_->RemoveSurfaceObserver(this); | 106 surface_->RemoveSurfaceObserver(this); |
97 } | 107 } |
98 surface_ = surface; | 108 surface_ = surface; |
99 if (surface_) { | 109 if (surface_) { |
100 surface_->SetSurfaceDelegate(this); | 110 surface_->SetSurfaceDelegate(this); |
101 surface_->AddSurfaceObserver(this); | 111 surface_->AddSurfaceObserver(this); |
102 // Note: Surface window needs to be added to the tree so we can take a | 112 cursor_->AddChild(surface_->window()); |
103 // snapshot. Where in the tree is not important but we might as well use | 113 surface_->window()->Show(); |
104 // the cursor container. | |
105 WMHelper::GetInstance() | |
106 ->GetContainer(ash::kShellWindowId_MouseCursorContainer) | |
107 ->AddChild(surface_->window()); | |
108 } | 114 } |
109 cursor_changed = true; | 115 cursor_changed = true; |
110 } | 116 } |
111 | 117 |
112 // Update hotspot. | 118 // Update hotspot. |
113 if (hotspot != hotspot_) { | 119 if (hotspot != hotspot_) { |
114 hotspot_ = hotspot; | 120 hotspot_ = hotspot; |
115 cursor_changed = true; | 121 cursor_changed = true; |
116 } | 122 } |
117 | 123 |
118 // Early out if cursor did not change. | 124 // Early out if cursor did not change. |
119 if (!cursor_changed) | 125 if (!cursor_changed) |
120 return; | 126 return; |
121 | 127 |
122 // If |surface_| is set then asynchronously capture a snapshot of cursor, | 128 // If |surface_| is set then asynchronously capture a snapshot of cursor, |
123 // otherwise cancel pending capture and immediately set the cursor to "none". | 129 // otherwise cancel pending capture and immediately set the cursor to "none". |
124 if (surface_) { | 130 if (surface_) { |
125 CaptureCursor(); | 131 CaptureCursor(); |
126 } else { | 132 } else { |
127 cursor_capture_weak_ptr_factory_.InvalidateWeakPtrs(); | 133 cursor_capture_weak_ptr_factory_.InvalidateWeakPtrs(); |
128 cursor_ = ui::kCursorNone; | 134 UpdateCursor(ui::kCursorNone); |
129 UpdateCursor(); | |
130 } | 135 } |
131 } | 136 } |
132 | 137 |
133 gfx::NativeCursor Pointer::GetCursor() { | 138 gfx::NativeCursor Pointer::GetCursor() { |
134 return cursor_; | 139 if (focus_) |
140 if (auto* root_window = focus_->window()->GetRootWindow()) | |
141 if (auto* cursor_client = aura::client::GetCursorClient(root_window)) | |
142 return cursor_client->GetCursor(); | |
143 | |
144 return ui::kCursorNull; | |
135 } | 145 } |
136 | 146 |
137 //////////////////////////////////////////////////////////////////////////////// | 147 //////////////////////////////////////////////////////////////////////////////// |
138 // ui::EventHandler overrides: | 148 // ui::EventHandler overrides: |
139 | 149 |
140 void Pointer::OnMouseEvent(ui::MouseEvent* event) { | 150 void Pointer::OnMouseEvent(ui::MouseEvent* event) { |
141 Surface* target = GetEffectiveTargetForEvent(event); | 151 Surface* target = GetEffectiveTargetForEvent(event); |
142 | 152 |
143 // If target is different than the current pointer focus then we need to | 153 // If target is different than the current pointer focus then we need to |
144 // generate enter and leave events. | 154 // generate enter and leave events. |
145 if (target != focus_) { | 155 if (target != focus_) { |
146 // First generate a leave event if we currently have a target in focus. | 156 // First generate a leave event if we currently have a target in focus. |
147 if (focus_) { | 157 if (focus_) { |
148 delegate_->OnPointerLeave(focus_); | 158 delegate_->OnPointerLeave(focus_); |
149 focus_->RemoveSurfaceObserver(this); | 159 focus_->RemoveSurfaceObserver(this); |
150 // Require SetCursor() to be called and cursor to be re-defined in | 160 // Require SetCursor() to be called and cursor to be re-defined in |
151 // response to each OnPointerEnter() call. | 161 // response to each OnPointerEnter() call. |
152 focus_->UnregisterCursorProvider(this); | 162 focus_->UnregisterCursorProvider(this); |
153 focus_ = nullptr; | 163 focus_ = nullptr; |
154 cursor_ = ui::kCursorNull; | |
155 cursor_capture_weak_ptr_factory_.InvalidateWeakPtrs(); | 164 cursor_capture_weak_ptr_factory_.InvalidateWeakPtrs(); |
156 } | 165 } |
157 // Second generate an enter event if focus moved to a new target. | 166 // Second generate an enter event if focus moved to a new target. |
158 if (target) { | 167 if (target) { |
159 delegate_->OnPointerEnter(target, event->location_f(), | 168 delegate_->OnPointerEnter(target, event->location_f(), |
160 event->button_flags()); | 169 event->button_flags()); |
161 location_ = event->location_f(); | 170 location_ = event->location_f(); |
162 focus_ = target; | 171 focus_ = target; |
163 focus_->AddSurfaceObserver(this); | 172 focus_->AddSurfaceObserver(this); |
164 focus_->RegisterCursorProvider(this); | 173 focus_->RegisterCursorProvider(this); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
219 case ui::ET_MOUSE_MOVED: | 228 case ui::ET_MOUSE_MOVED: |
220 case ui::ET_MOUSE_DRAGGED: | 229 case ui::ET_MOUSE_DRAGGED: |
221 case ui::ET_MOUSE_ENTERED: | 230 case ui::ET_MOUSE_ENTERED: |
222 case ui::ET_MOUSE_EXITED: | 231 case ui::ET_MOUSE_EXITED: |
223 case ui::ET_MOUSE_CAPTURE_CHANGED: | 232 case ui::ET_MOUSE_CAPTURE_CHANGED: |
224 break; | 233 break; |
225 default: | 234 default: |
226 NOTREACHED(); | 235 NOTREACHED(); |
227 break; | 236 break; |
228 } | 237 } |
229 | |
230 UpdateCursorScale(); | |
231 } | 238 } |
232 | 239 |
233 void Pointer::OnScrollEvent(ui::ScrollEvent* event) { | 240 void Pointer::OnScrollEvent(ui::ScrollEvent* event) { |
234 OnMouseEvent(event); | 241 OnMouseEvent(event); |
235 } | 242 } |
236 | 243 |
237 //////////////////////////////////////////////////////////////////////////////// | 244 //////////////////////////////////////////////////////////////////////////////// |
238 // WMHelper::CursorObserver overrides: | 245 // WMHelper::CursorObserver overrides: |
239 | 246 |
240 void Pointer::OnCursorSetChanged(ui::CursorSetType cursor_set) { | 247 void Pointer::OnCursorSetChanged(ui::CursorSetType cursor_set) { |
241 if (focus_) | 248 cursor_scale_ = GetCursorScale(cursor_set); |
242 UpdateCursorScale(); | 249 if (focus_ && surface_) |
250 CaptureCursor(); | |
251 } | |
252 | |
253 void Pointer::OnCursorDisplayChanging(const display::Display& display) { | |
254 WMHelper* helper = WMHelper::GetInstance(); | |
255 aura::Window* container = helper->GetContainer( | |
256 display.id(), ash::kShellWindowId_MouseCursorContainer); | |
257 | |
258 // Reparent the cursor to the root window where the mouse is located. | |
reveman
2017/04/10 21:47:13
is this re-parenting really needed?
Dominik Laskowski
2017/04/11 04:42:55
Yes. Layer size is in DIPs, which depends on the D
reveman
2017/04/11 19:25:13
Ok. Can we parent the cursor surface at the first
Dominik Laskowski
2017/04/11 20:40:37
That would break client-side dragging, i.e. we wou
reveman
2017/04/11 22:25:34
Why would it break client side dragging? The compo
| |
259 if (container->GetRootWindow() != cursor_->GetRootWindow()) { | |
260 if (cursor_->parent()) | |
261 cursor_->parent()->RemoveChild(cursor_.get()); | |
262 container->AddChild(cursor_.get()); | |
263 } | |
264 | |
265 auto info = helper->GetDisplayInfo(display.id()); | |
266 display_scale_ = info.GetEffectiveUIScale() * info.device_scale_factor(); | |
267 device_scale_factor_ = display.device_scale_factor(); | |
243 } | 268 } |
244 | 269 |
245 //////////////////////////////////////////////////////////////////////////////// | 270 //////////////////////////////////////////////////////////////////////////////// |
246 // SurfaceDelegate overrides: | 271 // SurfaceDelegate overrides: |
247 | 272 |
248 void Pointer::OnSurfaceCommit() { | 273 void Pointer::OnSurfaceCommit() { |
249 surface_->CheckIfSurfaceHierarchyNeedsCommitToNewSurfaces(); | 274 surface_->CheckIfSurfaceHierarchyNeedsCommitToNewSurfaces(); |
250 surface_->CommitSurfaceHierarchy(); | 275 surface_->CommitSurfaceHierarchy(); |
251 | 276 |
252 // Capture new cursor to reflect result of commit. | 277 // Capture new cursor to reflect result of commit. |
(...skipping 23 matching lines...) Expand all Loading... | |
276 | 301 |
277 Surface* Pointer::GetEffectiveTargetForEvent(ui::Event* event) const { | 302 Surface* Pointer::GetEffectiveTargetForEvent(ui::Event* event) const { |
278 Surface* target = | 303 Surface* target = |
279 Surface::AsSurface(static_cast<aura::Window*>(event->target())); | 304 Surface::AsSurface(static_cast<aura::Window*>(event->target())); |
280 if (!target) | 305 if (!target) |
281 return nullptr; | 306 return nullptr; |
282 | 307 |
283 return delegate_->CanAcceptPointerEventsForSurface(target) ? target : nullptr; | 308 return delegate_->CanAcceptPointerEventsForSurface(target) ? target : nullptr; |
284 } | 309 } |
285 | 310 |
286 void Pointer::UpdateCursorScale() { | |
287 DCHECK(focus_); | |
288 | |
289 display::Screen* screen = display::Screen::GetScreen(); | |
290 WMHelper* helper = WMHelper::GetInstance(); | |
291 | |
292 // Update cursor scale if the effective UI scale has changed. | |
293 display::Display display = screen->GetDisplayNearestWindow(focus_->window()); | |
294 float scale = helper->GetDisplayInfo(display.id()).GetEffectiveUIScale(); | |
295 | |
296 if (display::Display::HasInternalDisplay()) { | |
297 float primary_device_scale_factor = | |
298 screen->GetPrimaryDisplay().device_scale_factor(); | |
299 // The size of the cursor surface is the quotient of its physical size and | |
300 // the DSF of the primary display. The physical size is proportional to the | |
301 // DSF of the internal display. For external displays (and the internal | |
302 // display when secondary to a display with a different DSF), scale the | |
303 // cursor so its physical size matches with the single display case. | |
304 if (!display.IsInternal() || | |
305 display.device_scale_factor() != primary_device_scale_factor) { | |
306 scale *= primary_device_scale_factor / | |
307 helper->GetDisplayInfo(display::Display::InternalDisplayId()) | |
308 .device_scale_factor(); | |
309 } | |
310 } | |
311 | |
312 if (helper->GetCursorSet() == ui::CURSOR_SET_LARGE) | |
313 scale *= kLargeCursorScale; | |
314 | |
315 if (scale != cursor_scale_) { | |
316 cursor_scale_ = scale; | |
317 if (surface_) | |
318 CaptureCursor(); | |
319 } | |
320 } | |
321 | |
322 void Pointer::CaptureCursor() { | 311 void Pointer::CaptureCursor() { |
323 DCHECK(surface_); | 312 DCHECK(surface_); |
324 DCHECK(focus_); | 313 DCHECK(focus_); |
325 | 314 |
326 // Set UI scale before submitting capture request. | 315 float scale = cursor_scale_ * display_scale_; |
327 surface_->window()->layer()->SetTransform( | 316 float layer_scale = scale / device_scale_factor_; |
328 gfx::GetScaleTransform(gfx::Point(), cursor_scale_)); | |
329 | 317 |
330 float primary_device_scale_factor = | 318 gfx::Transform transform; |
331 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor(); | 319 transform.Scale(layer_scale, layer_scale); |
320 surface_->window()->SetTransform(transform); | |
332 | 321 |
333 std::unique_ptr<cc::CopyOutputRequest> request = | 322 std::unique_ptr<cc::CopyOutputRequest> request = |
334 cc::CopyOutputRequest::CreateBitmapRequest( | 323 cc::CopyOutputRequest::CreateBitmapRequest( |
335 base::Bind(&Pointer::OnCursorCaptured, | 324 base::Bind(&Pointer::OnCursorCaptured, |
336 cursor_capture_weak_ptr_factory_.GetWeakPtr(), | 325 cursor_capture_weak_ptr_factory_.GetWeakPtr(), |
337 gfx::ScaleToFlooredPoint( | 326 gfx::ScaleToFlooredPoint(hotspot_, scale))); |
338 hotspot_, | 327 |
339 // |hotspot_| is in surface coordinate space so apply | |
340 // both device scale and UI scale. | |
341 cursor_scale_ * primary_device_scale_factor))); | |
342 request->set_source(cursor_capture_source_id_); | 328 request->set_source(cursor_capture_source_id_); |
343 surface_->window()->layer()->RequestCopyOfOutput(std::move(request)); | 329 cursor_->layer()->RequestCopyOfOutput(std::move(request)); |
344 } | 330 } |
345 | 331 |
346 void Pointer::OnCursorCaptured(const gfx::Point& hotspot, | 332 void Pointer::OnCursorCaptured(const gfx::Point& hotspot, |
347 std::unique_ptr<cc::CopyOutputResult> result) { | 333 std::unique_ptr<cc::CopyOutputResult> result) { |
348 if (!focus_) | 334 if (!focus_) |
349 return; | 335 return; |
350 | 336 |
351 cursor_ = ui::kCursorNone; | 337 gfx::NativeCursor cursor = ui::kCursorNull; |
352 if (!result->IsEmpty()) { | 338 if (!result->IsEmpty()) { |
353 DCHECK(result->HasBitmap()); | 339 DCHECK(result->HasBitmap()); |
354 std::unique_ptr<SkBitmap> bitmap = result->TakeBitmap(); | 340 std::unique_ptr<SkBitmap> bitmap = result->TakeBitmap(); |
355 | 341 |
356 ui::PlatformCursor platform_cursor; | 342 ui::PlatformCursor platform_cursor; |
357 #if defined(USE_OZONE) | 343 #if defined(USE_OZONE) |
358 // TODO(reveman): Add interface for creating cursors from GpuMemoryBuffers | 344 // TODO(reveman): Add interface for creating cursors from GpuMemoryBuffers |
359 // and use that here instead of the current bitmap API. crbug.com/686600 | 345 // and use that here instead of the current bitmap API. crbug.com/686600 |
360 platform_cursor = ui::CursorFactoryOzone::GetInstance()->CreateImageCursor( | 346 platform_cursor = ui::CursorFactoryOzone::GetInstance()->CreateImageCursor( |
361 *bitmap.get(), hotspot); | 347 *bitmap.get(), hotspot); |
362 #elif defined(USE_X11) | 348 #elif defined(USE_X11) |
363 XcursorImage* image = ui::SkBitmapToXcursorImage(bitmap.get(), hotspot); | 349 XcursorImage* image = ui::SkBitmapToXcursorImage(bitmap.get(), hotspot); |
364 platform_cursor = ui::CreateReffedCustomXCursor(image); | 350 platform_cursor = ui::CreateReffedCustomXCursor(image); |
365 #endif | 351 #endif |
366 cursor_ = ui::kCursorCustom; | 352 cursor = ui::kCursorCustom; |
367 cursor_.SetPlatformCursor(platform_cursor); | 353 cursor.SetPlatformCursor(platform_cursor); |
368 #if defined(USE_OZONE) | 354 #if defined(USE_OZONE) |
369 ui::CursorFactoryOzone::GetInstance()->UnrefImageCursor(platform_cursor); | 355 ui::CursorFactoryOzone::GetInstance()->UnrefImageCursor(platform_cursor); |
370 #elif defined(USE_X11) | 356 #elif defined(USE_X11) |
371 ui::UnrefCustomXCursor(platform_cursor); | 357 ui::UnrefCustomXCursor(platform_cursor); |
372 #endif | 358 #endif |
373 } | 359 } |
374 | 360 |
375 UpdateCursor(); | 361 UpdateCursor(cursor); |
376 } | 362 } |
377 | 363 |
378 void Pointer::UpdateCursor() { | 364 void Pointer::UpdateCursor(gfx::NativeCursor cursor) { |
379 DCHECK(focus_); | 365 DCHECK(focus_); |
380 | 366 |
381 aura::Window* root_window = focus_->window()->GetRootWindow(); | 367 aura::Window* root_window = focus_->window()->GetRootWindow(); |
382 if (!root_window) | 368 if (!root_window) |
383 return; | 369 return; |
384 | 370 |
385 aura::client::CursorClient* cursor_client = | 371 aura::client::CursorClient* cursor_client = |
386 aura::client::GetCursorClient(root_window); | 372 aura::client::GetCursorClient(root_window); |
387 if (cursor_client) | 373 if (cursor_client) |
388 cursor_client->SetCursor(cursor_); | 374 cursor_client->SetCursor(cursor); |
389 } | 375 } |
390 | 376 |
391 } // namespace exo | 377 } // namespace exo |
OLD | NEW |