Chromium Code Reviews| 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 |