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" |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
121 cursor_changed = true; | 121 cursor_changed = true; |
122 } | 122 } |
123 | 123 |
124 // Early out if cursor did not change. | 124 // Early out if cursor did not change. |
125 if (!cursor_changed) | 125 if (!cursor_changed) |
126 return; | 126 return; |
127 | 127 |
128 // If |surface_| is set then asynchronously capture a snapshot of cursor, | 128 // If |surface_| is set then asynchronously capture a snapshot of cursor, |
129 // otherwise cancel pending capture and immediately set the cursor to "none". | 129 // otherwise cancel pending capture and immediately set the cursor to "none". |
130 if (surface_) { | 130 if (surface_) { |
131 CaptureCursor(); | 131 CaptureCursor(false); |
132 } else { | 132 } else { |
133 cursor_capture_weak_ptr_factory_.InvalidateWeakPtrs(); | 133 cursor_capture_weak_ptr_factory_.InvalidateWeakPtrs(); |
134 UpdateCursor(ui::kCursorNone); | 134 UpdateCursor(ui::kCursorNone, false); |
135 } | 135 } |
136 } | 136 } |
137 | 137 |
138 gfx::NativeCursor Pointer::GetCursor() { | 138 gfx::NativeCursor Pointer::GetCursor() { |
139 if (focus_) | 139 if (focus_) |
140 if (auto* root_window = focus_->window()->GetRootWindow()) | 140 if (auto* root_window = focus_->window()->GetRootWindow()) |
141 if (auto* cursor_client = aura::client::GetCursorClient(root_window)) | 141 if (auto* cursor_client = aura::client::GetCursorClient(root_window)) |
142 return cursor_client->GetCursor(); | 142 return cursor_client->GetCursor(); |
143 | 143 |
144 return ui::kCursorNull; | 144 return ui::kCursorNull; |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
240 void Pointer::OnScrollEvent(ui::ScrollEvent* event) { | 240 void Pointer::OnScrollEvent(ui::ScrollEvent* event) { |
241 OnMouseEvent(event); | 241 OnMouseEvent(event); |
242 } | 242 } |
243 | 243 |
244 //////////////////////////////////////////////////////////////////////////////// | 244 //////////////////////////////////////////////////////////////////////////////// |
245 // WMHelper::CursorObserver overrides: | 245 // WMHelper::CursorObserver overrides: |
246 | 246 |
247 void Pointer::OnCursorSetChanged(ui::CursorSetType cursor_set) { | 247 void Pointer::OnCursorSetChanged(ui::CursorSetType cursor_set) { |
248 cursor_scale_ = GetCursorScale(cursor_set); | 248 cursor_scale_ = GetCursorScale(cursor_set); |
249 if (focus_ && surface_) | 249 if (focus_ && surface_) |
250 CaptureCursor(); | 250 CaptureCursor(false); |
251 } | 251 } |
252 | 252 |
253 void Pointer::OnCursorDisplayChanging(const display::Display& display) { | 253 void Pointer::OnCursorDisplayChanging(const display::Display& display) { |
254 WMHelper* helper = WMHelper::GetInstance(); | 254 WMHelper* helper = WMHelper::GetInstance(); |
255 aura::Window* container = helper->GetContainer( | 255 aura::Window* container = helper->GetContainer( |
256 display.id(), ash::kShellWindowId_MouseCursorContainer); | 256 display.id(), ash::kShellWindowId_MouseCursorContainer); |
257 | 257 |
258 // Reparent the cursor to the root window where the mouse is located. | 258 // Reparent the cursor to the root window where the mouse is located. |
259 if (container->GetRootWindow() != cursor_->GetRootWindow()) { | 259 if (container->GetRootWindow() != cursor_->GetRootWindow()) { |
260 if (cursor_->parent()) | 260 if (cursor_->parent()) |
261 cursor_->parent()->RemoveChild(cursor_.get()); | 261 cursor_->parent()->RemoveChild(cursor_.get()); |
262 container->AddChild(cursor_.get()); | 262 container->AddChild(cursor_.get()); |
263 } | 263 } |
264 | 264 |
265 auto info = helper->GetDisplayInfo(display.id()); | 265 auto info = helper->GetDisplayInfo(display.id()); |
266 display_scale_ = info.GetEffectiveUIScale() * info.device_scale_factor(); | 266 display_scale_ = info.GetEffectiveUIScale() * info.device_scale_factor(); |
267 device_scale_factor_ = display.device_scale_factor(); | 267 device_scale_factor_ = display.device_scale_factor(); |
268 | |
269 if (focus_ && surface_) { | |
270 // Capture is asynchronous, so avoid rendering old cursor in the meantime. | |
reveman
2017/04/26 23:41:26
why shouldn't we keep the old cursor until a new o
Dominik Laskowski
2017/04/27 20:27:19
Because the old bitmap may have an incorrect scale
reveman
2017/04/27 21:44:14
Why is it better to transition to no cursor while
Dominik Laskowski
2017/04/27 22:22:17
Because the incorrect transform is noticeable, e.g
| |
271 cursor_capture_weak_ptr_factory_.InvalidateWeakPtrs(); | |
272 UpdateCursor(ui::kCursorNone, true); | |
273 // Force the cursor to be updated even if locked. | |
reveman
2017/04/26 23:41:26
Is "force" only needed for the case when we drag a
Dominik Laskowski
2017/04/27 20:27:20
Right, and it's only needed because the cursor is
reveman
2017/04/27 21:44:14
What does removing the lock mean?
Dominik Laskowski
2017/04/27 22:22:17
Removing the LockCursor/UnlockCursor calls, i.e. a
| |
274 CaptureCursor(true); | |
275 } | |
268 } | 276 } |
269 | 277 |
270 //////////////////////////////////////////////////////////////////////////////// | 278 //////////////////////////////////////////////////////////////////////////////// |
271 // SurfaceDelegate overrides: | 279 // SurfaceDelegate overrides: |
272 | 280 |
273 void Pointer::OnSurfaceCommit() { | 281 void Pointer::OnSurfaceCommit() { |
274 surface_->CheckIfSurfaceHierarchyNeedsCommitToNewSurfaces(); | 282 surface_->CheckIfSurfaceHierarchyNeedsCommitToNewSurfaces(); |
275 surface_->CommitSurfaceHierarchy(); | 283 surface_->CommitSurfaceHierarchy(); |
276 | 284 |
277 // Capture new cursor to reflect result of commit. | 285 // Capture new cursor to reflect result of commit. |
278 if (focus_) | 286 if (focus_) |
279 CaptureCursor(); | 287 CaptureCursor(false); |
280 } | 288 } |
281 | 289 |
282 bool Pointer::IsSurfaceSynchronized() const { | 290 bool Pointer::IsSurfaceSynchronized() const { |
283 // A pointer surface is always desynchronized. | 291 // A pointer surface is always desynchronized. |
284 return false; | 292 return false; |
285 } | 293 } |
286 | 294 |
287 //////////////////////////////////////////////////////////////////////////////// | 295 //////////////////////////////////////////////////////////////////////////////// |
288 // SurfaceObserver overrides: | 296 // SurfaceObserver overrides: |
289 | 297 |
(...skipping 11 matching lines...) Expand all Loading... | |
301 | 309 |
302 Surface* Pointer::GetEffectiveTargetForEvent(ui::Event* event) const { | 310 Surface* Pointer::GetEffectiveTargetForEvent(ui::Event* event) const { |
303 Surface* target = | 311 Surface* target = |
304 Surface::AsSurface(static_cast<aura::Window*>(event->target())); | 312 Surface::AsSurface(static_cast<aura::Window*>(event->target())); |
305 if (!target) | 313 if (!target) |
306 return nullptr; | 314 return nullptr; |
307 | 315 |
308 return delegate_->CanAcceptPointerEventsForSurface(target) ? target : nullptr; | 316 return delegate_->CanAcceptPointerEventsForSurface(target) ? target : nullptr; |
309 } | 317 } |
310 | 318 |
311 void Pointer::CaptureCursor() { | 319 void Pointer::CaptureCursor(bool force) { |
312 DCHECK(surface_); | 320 DCHECK(surface_); |
313 DCHECK(focus_); | 321 DCHECK(focus_); |
314 | 322 |
315 float scale = cursor_scale_ * display_scale_; | 323 float scale = cursor_scale_ * display_scale_; |
316 float layer_scale = scale / device_scale_factor_; | 324 float layer_scale = scale / device_scale_factor_; |
317 | 325 |
318 gfx::Transform transform; | 326 gfx::Transform transform; |
319 transform.Scale(layer_scale, layer_scale); | 327 transform.Scale(layer_scale, layer_scale); |
320 surface_->window()->SetTransform(transform); | 328 surface_->window()->SetTransform(transform); |
321 | 329 |
322 std::unique_ptr<cc::CopyOutputRequest> request = | 330 std::unique_ptr<cc::CopyOutputRequest> request = |
323 cc::CopyOutputRequest::CreateBitmapRequest( | 331 cc::CopyOutputRequest::CreateBitmapRequest( |
324 base::Bind(&Pointer::OnCursorCaptured, | 332 base::Bind(&Pointer::OnCursorCaptured, |
325 cursor_capture_weak_ptr_factory_.GetWeakPtr(), | 333 cursor_capture_weak_ptr_factory_.GetWeakPtr(), |
326 gfx::ScaleToFlooredPoint(hotspot_, scale))); | 334 gfx::ScaleToFlooredPoint(hotspot_, scale), force)); |
327 | 335 |
328 request->set_source(cursor_capture_source_id_); | 336 request->set_source(cursor_capture_source_id_); |
329 cursor_->layer()->RequestCopyOfOutput(std::move(request)); | 337 cursor_->layer()->RequestCopyOfOutput(std::move(request)); |
338 | |
339 // Prevent subsequent requests in the same frame from aborting this capture. | |
reveman
2017/04/26 23:41:26
why is this needed and correct?
Dominik Laskowski
2017/04/27 20:27:20
It's a hack to ensure that the lock is bypassed. R
reveman
2017/04/27 21:44:14
Ok, let's figure out how we can avoid this "force"
Dominik Laskowski
2017/04/27 22:22:17
Yeah, this is a non-issue with server decorations.
| |
340 if (force) | |
341 cursor_capture_source_id_ = base::UnguessableToken::Create(); | |
330 } | 342 } |
331 | 343 |
332 void Pointer::OnCursorCaptured(const gfx::Point& hotspot, | 344 void Pointer::OnCursorCaptured(const gfx::Point& hotspot, |
345 bool force, | |
333 std::unique_ptr<cc::CopyOutputResult> result) { | 346 std::unique_ptr<cc::CopyOutputResult> result) { |
334 if (!focus_) | 347 if (!focus_) |
335 return; | 348 return; |
336 | 349 |
337 gfx::NativeCursor cursor = ui::kCursorNull; | 350 gfx::NativeCursor cursor = ui::kCursorNull; |
338 if (!result->IsEmpty()) { | 351 if (!result->IsEmpty()) { |
339 DCHECK(result->HasBitmap()); | 352 DCHECK(result->HasBitmap()); |
340 std::unique_ptr<SkBitmap> bitmap = result->TakeBitmap(); | 353 std::unique_ptr<SkBitmap> bitmap = result->TakeBitmap(); |
341 | 354 |
342 ui::PlatformCursor platform_cursor; | 355 ui::PlatformCursor platform_cursor; |
343 #if defined(USE_OZONE) | 356 #if defined(USE_OZONE) |
344 // TODO(reveman): Add interface for creating cursors from GpuMemoryBuffers | 357 // TODO(reveman): Add interface for creating cursors from GpuMemoryBuffers |
345 // and use that here instead of the current bitmap API. crbug.com/686600 | 358 // and use that here instead of the current bitmap API. crbug.com/686600 |
346 platform_cursor = ui::CursorFactoryOzone::GetInstance()->CreateImageCursor( | 359 platform_cursor = ui::CursorFactoryOzone::GetInstance()->CreateImageCursor( |
347 *bitmap.get(), hotspot); | 360 *bitmap.get(), hotspot); |
348 #elif defined(USE_X11) | 361 #elif defined(USE_X11) |
349 XcursorImage* image = ui::SkBitmapToXcursorImage(bitmap.get(), hotspot); | 362 XcursorImage* image = ui::SkBitmapToXcursorImage(bitmap.get(), hotspot); |
350 platform_cursor = ui::CreateReffedCustomXCursor(image); | 363 platform_cursor = ui::CreateReffedCustomXCursor(image); |
351 #endif | 364 #endif |
352 cursor = ui::kCursorCustom; | 365 cursor = ui::kCursorCustom; |
353 cursor.SetPlatformCursor(platform_cursor); | 366 cursor.SetPlatformCursor(platform_cursor); |
354 #if defined(USE_OZONE) | 367 #if defined(USE_OZONE) |
355 ui::CursorFactoryOzone::GetInstance()->UnrefImageCursor(platform_cursor); | 368 ui::CursorFactoryOzone::GetInstance()->UnrefImageCursor(platform_cursor); |
356 #elif defined(USE_X11) | 369 #elif defined(USE_X11) |
357 ui::UnrefCustomXCursor(platform_cursor); | 370 ui::UnrefCustomXCursor(platform_cursor); |
358 #endif | 371 #endif |
359 } | 372 } |
360 | 373 |
361 UpdateCursor(cursor); | 374 UpdateCursor(cursor, force); |
362 } | 375 } |
363 | 376 |
364 void Pointer::UpdateCursor(gfx::NativeCursor cursor) { | 377 void Pointer::UpdateCursor(gfx::NativeCursor cursor, bool force) { |
365 DCHECK(focus_); | 378 DCHECK(focus_); |
366 | 379 |
367 aura::Window* root_window = focus_->window()->GetRootWindow(); | 380 aura::Window* root_window = focus_->window()->GetRootWindow(); |
368 if (!root_window) | 381 if (!root_window) |
369 return; | 382 return; |
370 | 383 |
371 aura::client::CursorClient* cursor_client = | 384 aura::client::CursorClient* cursor_client = |
372 aura::client::GetCursorClient(root_window); | 385 aura::client::GetCursorClient(root_window); |
373 if (cursor_client) | 386 if (!cursor_client) |
374 cursor_client->SetCursor(cursor); | 387 return; |
388 | |
389 cursor_client->SetCursor(cursor); | |
reveman
2017/04/26 23:41:26
can we avoid having this line? "force || cursor_cl
Dominik Laskowski
2017/04/27 20:27:20
The line below updates the current cursor, and thi
reveman
2017/04/27 21:44:14
That's confusing and deserves a comment at least.
| |
390 | |
391 if (force && cursor_client->IsCursorLocked()) | |
392 WMHelper::GetInstance()->SetCursor(cursor); | |
375 } | 393 } |
376 | 394 |
377 } // namespace exo | 395 } // namespace exo |
OLD | NEW |