| Index: components/exo/pointer.cc
|
| diff --git a/components/exo/pointer.cc b/components/exo/pointer.cc
|
| index 273a74208214f2b2ab82ffb7c1ed1a3cc69cc6cb..7f1d352bd13f2bbd033db9fde2afaf30d1d60eb6 100644
|
| --- a/components/exo/pointer.cc
|
| +++ b/components/exo/pointer.cc
|
| @@ -16,6 +16,7 @@
|
| #include "ui/aura/client/cursor_client.h"
|
| #include "ui/aura/env.h"
|
| #include "ui/aura/window.h"
|
| +#include "ui/base/cursor/cursor_util.h"
|
| #include "ui/display/manager/display_manager.h"
|
| #include "ui/display/manager/managed_display_info.h"
|
| #include "ui/display/screen.h"
|
| @@ -34,7 +35,16 @@
|
| namespace exo {
|
| namespace {
|
|
|
| +// TODO(oshima): Some accessibility features, including large cursors, disable
|
| +// hardware cursors. Ash does not support compositing for custom cursors, so it
|
| +// replaces them with the default cursor. As a result, this scale has no effect
|
| +// for now. See crbug.com/708378.
|
| const float kLargeCursorScale = 2.8f;
|
| +
|
| +// Scale at which cursor snapshot is captured. The resulting bitmap is scaled on
|
| +// displays whose DSF does not match this scale.
|
| +const float kCursorCaptureScale = 2.0f;
|
| +
|
| const double kLocatedEventEpsilonSquared = 1.0 / (2000.0 * 2000.0);
|
|
|
| // Synthesized events typically lack floating point precision so to avoid
|
| @@ -113,17 +123,14 @@ void Pointer::SetCursor(Surface* surface, const gfx::Point& hotspot) {
|
| // snapshot. Where in the tree is not important but we might as well use
|
| // the cursor container.
|
| WMHelper::GetInstance()
|
| - ->GetContainer(ash::kShellWindowId_MouseCursorContainer)
|
| + ->GetPrimaryDisplayContainer(ash::kShellWindowId_MouseCursorContainer)
|
| ->AddChild(surface_->window());
|
| }
|
| cursor_changed = true;
|
| }
|
|
|
| - // Update hotspot.
|
| - if (hotspot != hotspot_) {
|
| - hotspot_ = hotspot;
|
| + if (hotspot != hotspot_)
|
| cursor_changed = true;
|
| - }
|
|
|
| // Early out if cursor did not change.
|
| if (!cursor_changed)
|
| @@ -132,10 +139,10 @@ void Pointer::SetCursor(Surface* surface, const gfx::Point& hotspot) {
|
| // If |surface_| is set then asynchronously capture a snapshot of cursor,
|
| // otherwise cancel pending capture and immediately set the cursor to "none".
|
| if (surface_) {
|
| - CaptureCursor();
|
| + CaptureCursor(hotspot);
|
| } else {
|
| + cursor_bitmap_.reset();
|
| cursor_capture_weak_ptr_factory_.InvalidateWeakPtrs();
|
| - cursor_ = ui::CursorType::kNone;
|
| UpdateCursor();
|
| }
|
| }
|
| @@ -251,7 +258,6 @@ void Pointer::OnMouseEvent(ui::MouseEvent* event) {
|
| }
|
|
|
| last_event_type_ = event->type();
|
| - UpdateCursorScale();
|
| }
|
|
|
| void Pointer::OnScrollEvent(ui::ScrollEvent* event) {
|
| @@ -263,7 +269,12 @@ void Pointer::OnScrollEvent(ui::ScrollEvent* event) {
|
|
|
| void Pointer::OnCursorSetChanged(ui::CursorSetType cursor_set) {
|
| if (focus_)
|
| - UpdateCursorScale();
|
| + UpdateCursor();
|
| +}
|
| +
|
| +void Pointer::OnCursorDisplayChanged(const display::Display& display) {
|
| + if (focus_)
|
| + UpdateCursor();
|
| }
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
| @@ -275,7 +286,7 @@ void Pointer::OnSurfaceCommit() {
|
|
|
| // Capture new cursor to reflect result of commit.
|
| if (focus_)
|
| - CaptureCursor();
|
| + CaptureCursor(hotspot_);
|
| }
|
|
|
| bool Pointer::IsSurfaceSynchronized() const {
|
| @@ -307,62 +318,25 @@ Surface* Pointer::GetEffectiveTargetForEvent(ui::Event* event) const {
|
| return delegate_->CanAcceptPointerEventsForSurface(target) ? target : nullptr;
|
| }
|
|
|
| -void Pointer::UpdateCursorScale() {
|
| - DCHECK(focus_);
|
| -
|
| - display::Screen* screen = display::Screen::GetScreen();
|
| - WMHelper* helper = WMHelper::GetInstance();
|
| -
|
| - // Update cursor scale if the effective UI scale has changed.
|
| - display::Display display = screen->GetDisplayNearestWindow(focus_->window());
|
| - float scale = helper->GetDisplayInfo(display.id()).GetEffectiveUIScale();
|
| -
|
| - if (display::Display::HasInternalDisplay()) {
|
| - float primary_device_scale_factor =
|
| - screen->GetPrimaryDisplay().device_scale_factor();
|
| - // The size of the cursor surface is the quotient of its physical size and
|
| - // the DSF of the primary display. The physical size is proportional to the
|
| - // DSF of the internal display. For external displays (and the internal
|
| - // display when secondary to a display with a different DSF), scale the
|
| - // cursor so its physical size matches with the single display case.
|
| - if (!display.IsInternal() ||
|
| - display.device_scale_factor() != primary_device_scale_factor) {
|
| - scale *= primary_device_scale_factor /
|
| - helper->GetDisplayInfo(display::Display::InternalDisplayId())
|
| - .device_scale_factor();
|
| - }
|
| - }
|
| -
|
| - if (helper->GetCursorSet() == ui::CURSOR_SET_LARGE)
|
| - scale *= kLargeCursorScale;
|
| -
|
| - if (scale != cursor_scale_) {
|
| - cursor_scale_ = scale;
|
| - if (surface_)
|
| - CaptureCursor();
|
| - }
|
| -}
|
| -
|
| -void Pointer::CaptureCursor() {
|
| +void Pointer::CaptureCursor(const gfx::Point& hotspot) {
|
| DCHECK(surface_);
|
| DCHECK(focus_);
|
|
|
| - // Set UI scale before submitting capture request.
|
| - surface_->window()->layer()->SetTransform(
|
| - gfx::GetScaleTransform(gfx::Point(), cursor_scale_));
|
| -
|
| - float primary_device_scale_factor =
|
| - display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
|
| + // Surface size is in DIPs, while layer size is in pseudo-DIP units that
|
| + // depend on the DSF of the display mode. Scale the layer to capture the
|
| + // surface at a constant pixel size, regardless of the primary display's
|
| + // UI scale and display mode DSF.
|
| + display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay();
|
| + auto* helper = WMHelper::GetInstance();
|
| + float scale = helper->GetDisplayInfo(display.id()).GetEffectiveUIScale() *
|
| + kCursorCaptureScale / display.device_scale_factor();
|
| + surface_->window()->SetTransform(gfx::GetScaleTransform(gfx::Point(), scale));
|
|
|
| std::unique_ptr<cc::CopyOutputRequest> request =
|
| cc::CopyOutputRequest::CreateBitmapRequest(
|
| base::Bind(&Pointer::OnCursorCaptured,
|
| - cursor_capture_weak_ptr_factory_.GetWeakPtr(),
|
| - gfx::ScaleToFlooredPoint(
|
| - hotspot_,
|
| - // |hotspot_| is in surface coordinate space so apply
|
| - // both device scale and UI scale.
|
| - cursor_scale_ * primary_device_scale_factor)));
|
| + cursor_capture_weak_ptr_factory_.GetWeakPtr(), hotspot));
|
| +
|
| request->set_source(cursor_capture_source_id_);
|
| surface_->window()->layer()->RequestCopyOfOutput(std::move(request));
|
| }
|
| @@ -372,19 +346,46 @@ void Pointer::OnCursorCaptured(const gfx::Point& hotspot,
|
| if (!focus_)
|
| return;
|
|
|
| - cursor_ = ui::CursorType::kNone;
|
| - if (!result->IsEmpty()) {
|
| + if (result->IsEmpty()) {
|
| + cursor_bitmap_.reset();
|
| + } else {
|
| DCHECK(result->HasBitmap());
|
| - std::unique_ptr<SkBitmap> bitmap = result->TakeBitmap();
|
| + cursor_bitmap_ = *result->TakeBitmap();
|
| + hotspot_ = hotspot;
|
| + }
|
| +
|
| + UpdateCursor();
|
| +}
|
| +
|
| +void Pointer::UpdateCursor() {
|
| + DCHECK(focus_);
|
| +
|
| + if (cursor_bitmap_.drawsNothing()) {
|
| + cursor_ = ui::CursorType::kNone;
|
| + } else {
|
| + SkBitmap bitmap = cursor_bitmap_;
|
| + gfx::Point hotspot =
|
| + gfx::ScaleToFlooredPoint(hotspot_, kCursorCaptureScale);
|
| +
|
| + auto* helper = WMHelper::GetInstance();
|
| + const display::Display& display = helper->GetCursorDisplay();
|
| + float scale = helper->GetDisplayInfo(display.id()).device_scale_factor() /
|
| + kCursorCaptureScale;
|
| +
|
| + if (helper->GetCursorSet() == ui::CURSOR_SET_LARGE)
|
| + scale *= kLargeCursorScale;
|
| +
|
| + ui::ScaleAndRotateCursorBitmapAndHotpoint(scale, display.rotation(),
|
| + &bitmap, &hotspot);
|
|
|
| ui::PlatformCursor platform_cursor;
|
| #if defined(USE_OZONE)
|
| // TODO(reveman): Add interface for creating cursors from GpuMemoryBuffers
|
| // and use that here instead of the current bitmap API. crbug.com/686600
|
| platform_cursor = ui::CursorFactoryOzone::GetInstance()->CreateImageCursor(
|
| - *bitmap.get(), hotspot, cursor_scale_);
|
| + bitmap, hotspot, 0);
|
| #elif defined(USE_X11)
|
| - XcursorImage* image = ui::SkBitmapToXcursorImage(bitmap.get(), hotspot);
|
| + XcursorImage* image = ui::SkBitmapToXcursorImage(&bitmap, hotspot);
|
| platform_cursor = ui::CreateReffedCustomXCursor(image);
|
| #endif
|
| cursor_ = ui::CursorType::kCustom;
|
| @@ -396,12 +397,6 @@ void Pointer::OnCursorCaptured(const gfx::Point& hotspot,
|
| #endif
|
| }
|
|
|
| - UpdateCursor();
|
| -}
|
| -
|
| -void Pointer::UpdateCursor() {
|
| - DCHECK(focus_);
|
| -
|
| aura::Window* root_window = focus_->window()->GetRootWindow();
|
| if (!root_window)
|
| return;
|
|
|