Commit ba20af04 authored by domlaskowski's avatar domlaskowski Committed by Commit Bot

exo: Fix multi-display hardware cursor

This CL fixes crashes in extended desktop mode caused by incorrect
parenting of the cursor surface, as well as cases where the cursor
was captured with an incorrect transform or hotspot:

  1) The mouse enters a display with a different DSF or UI scale.
  2) The internal display is not the primary display.
  3) The display is rotated.

It also adds a TODO for an accessibility regression.

BUG=631136
BUG=642894
TEST=caroline: Cursor parenting and scaling is correct for each display.
TEST=caroline: Cursor on rotated displays has correct orientation.

Review-Url: https://codereview.chromium.org/2780623002
Cr-Commit-Position: refs/heads/master@{#476353}
parent c3cf4c7d
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "components/arc/common/accessibility_helper.mojom.h" #include "components/arc/common/accessibility_helper.mojom.h"
#include "components/exo/wm_helper.h" #include "components/exo/wm_helper.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "ui/display/display.h"
#include "ui/display/manager/managed_display_info.h" #include "ui/display/manager/managed_display_info.h"
namespace arc { namespace arc {
...@@ -24,16 +25,23 @@ class ArcAccessibilityHelperBridgeTest : public testing::Test { ...@@ -24,16 +25,23 @@ class ArcAccessibilityHelperBridgeTest : public testing::Test {
FakeWMHelper() = default; FakeWMHelper() = default;
private: private:
const display::ManagedDisplayInfo GetDisplayInfo( const display::ManagedDisplayInfo& GetDisplayInfo(
int64_t display_id) const override { int64_t display_id) const override {
return display::ManagedDisplayInfo(display_id, "", false); static const display::ManagedDisplayInfo info;
return info;
}
aura::Window* GetPrimaryDisplayContainer(int container_id) override {
return nullptr;
} }
aura::Window* GetContainer(int container_id) override { return nullptr; }
aura::Window* GetActiveWindow() const override { return nullptr; } aura::Window* GetActiveWindow() const override { return nullptr; }
aura::Window* GetFocusedWindow() const override { return nullptr; } aura::Window* GetFocusedWindow() const override { return nullptr; }
ui::CursorSetType GetCursorSet() const override { ui::CursorSetType GetCursorSet() const override {
return ui::CursorSetType::CURSOR_SET_NORMAL; return ui::CursorSetType::CURSOR_SET_NORMAL;
} }
const display::Display& GetCursorDisplay() const override {
static const display::Display display;
return display;
}
void AddPreTargetHandler(ui::EventHandler* handler) override {} void AddPreTargetHandler(ui::EventHandler* handler) override {}
void PrependPreTargetHandler(ui::EventHandler* handler) override {} void PrependPreTargetHandler(ui::EventHandler* handler) override {}
void RemovePreTargetHandler(ui::EventHandler* handler) override {} void RemovePreTargetHandler(ui::EventHandler* handler) override {}
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "ui/aura/client/cursor_client.h" #include "ui/aura/client/cursor_client.h"
#include "ui/aura/env.h" #include "ui/aura/env.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/base/cursor/cursor_util.h"
#include "ui/display/manager/display_manager.h" #include "ui/display/manager/display_manager.h"
#include "ui/display/manager/managed_display_info.h" #include "ui/display/manager/managed_display_info.h"
#include "ui/display/screen.h" #include "ui/display/screen.h"
...@@ -34,7 +35,16 @@ ...@@ -34,7 +35,16 @@
namespace exo { namespace exo {
namespace { 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; 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); const double kLocatedEventEpsilonSquared = 1.0 / (2000.0 * 2000.0);
// Synthesized events typically lack floating point precision so to avoid // Synthesized events typically lack floating point precision so to avoid
...@@ -113,17 +123,14 @@ void Pointer::SetCursor(Surface* surface, const gfx::Point& hotspot) { ...@@ -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 // snapshot. Where in the tree is not important but we might as well use
// the cursor container. // the cursor container.
WMHelper::GetInstance() WMHelper::GetInstance()
->GetContainer(ash::kShellWindowId_MouseCursorContainer) ->GetPrimaryDisplayContainer(ash::kShellWindowId_MouseCursorContainer)
->AddChild(surface_->window()); ->AddChild(surface_->window());
} }
cursor_changed = true; cursor_changed = true;
} }
// Update hotspot. if (hotspot != hotspot_)
if (hotspot != hotspot_) {
hotspot_ = hotspot;
cursor_changed = true; cursor_changed = true;
}
// Early out if cursor did not change. // Early out if cursor did not change.
if (!cursor_changed) if (!cursor_changed)
...@@ -132,10 +139,10 @@ void Pointer::SetCursor(Surface* surface, const gfx::Point& hotspot) { ...@@ -132,10 +139,10 @@ void Pointer::SetCursor(Surface* surface, const gfx::Point& hotspot) {
// If |surface_| is set then asynchronously capture a snapshot of cursor, // If |surface_| is set then asynchronously capture a snapshot of cursor,
// otherwise cancel pending capture and immediately set the cursor to "none". // otherwise cancel pending capture and immediately set the cursor to "none".
if (surface_) { if (surface_) {
CaptureCursor(); CaptureCursor(hotspot);
} else { } else {
cursor_bitmap_.reset();
cursor_capture_weak_ptr_factory_.InvalidateWeakPtrs(); cursor_capture_weak_ptr_factory_.InvalidateWeakPtrs();
cursor_ = ui::CursorType::kNone;
UpdateCursor(); UpdateCursor();
} }
} }
...@@ -251,7 +258,6 @@ void Pointer::OnMouseEvent(ui::MouseEvent* event) { ...@@ -251,7 +258,6 @@ void Pointer::OnMouseEvent(ui::MouseEvent* event) {
} }
last_event_type_ = event->type(); last_event_type_ = event->type();
UpdateCursorScale();
} }
void Pointer::OnScrollEvent(ui::ScrollEvent* event) { void Pointer::OnScrollEvent(ui::ScrollEvent* event) {
...@@ -263,7 +269,12 @@ void Pointer::OnScrollEvent(ui::ScrollEvent* event) { ...@@ -263,7 +269,12 @@ void Pointer::OnScrollEvent(ui::ScrollEvent* event) {
void Pointer::OnCursorSetChanged(ui::CursorSetType cursor_set) { void Pointer::OnCursorSetChanged(ui::CursorSetType cursor_set) {
if (focus_) if (focus_)
UpdateCursorScale(); UpdateCursor();
}
void Pointer::OnCursorDisplayChanged(const display::Display& display) {
if (focus_)
UpdateCursor();
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
...@@ -275,7 +286,7 @@ void Pointer::OnSurfaceCommit() { ...@@ -275,7 +286,7 @@ void Pointer::OnSurfaceCommit() {
// Capture new cursor to reflect result of commit. // Capture new cursor to reflect result of commit.
if (focus_) if (focus_)
CaptureCursor(); CaptureCursor(hotspot_);
} }
bool Pointer::IsSurfaceSynchronized() const { bool Pointer::IsSurfaceSynchronized() const {
...@@ -307,62 +318,25 @@ Surface* Pointer::GetEffectiveTargetForEvent(ui::Event* event) const { ...@@ -307,62 +318,25 @@ Surface* Pointer::GetEffectiveTargetForEvent(ui::Event* event) const {
return delegate_->CanAcceptPointerEventsForSurface(target) ? target : nullptr; return delegate_->CanAcceptPointerEventsForSurface(target) ? target : nullptr;
} }
void Pointer::UpdateCursorScale() { void Pointer::CaptureCursor(const gfx::Point& hotspot) {
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() {
DCHECK(surface_); DCHECK(surface_);
DCHECK(focus_); DCHECK(focus_);
// Set UI scale before submitting capture request. // Surface size is in DIPs, while layer size is in pseudo-DIP units that
surface_->window()->layer()->SetTransform( // depend on the DSF of the display mode. Scale the layer to capture the
gfx::GetScaleTransform(gfx::Point(), cursor_scale_)); // surface at a constant pixel size, regardless of the primary display's
// UI scale and display mode DSF.
float primary_device_scale_factor = display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay();
display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor(); 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 = std::unique_ptr<cc::CopyOutputRequest> request =
cc::CopyOutputRequest::CreateBitmapRequest( cc::CopyOutputRequest::CreateBitmapRequest(
base::Bind(&Pointer::OnCursorCaptured, base::Bind(&Pointer::OnCursorCaptured,
cursor_capture_weak_ptr_factory_.GetWeakPtr(), cursor_capture_weak_ptr_factory_.GetWeakPtr(), hotspot));
gfx::ScaleToFlooredPoint(
hotspot_,
// |hotspot_| is in surface coordinate space so apply
// both device scale and UI scale.
cursor_scale_ * primary_device_scale_factor)));
request->set_source(cursor_capture_source_id_); request->set_source(cursor_capture_source_id_);
surface_->window()->layer()->RequestCopyOfOutput(std::move(request)); surface_->window()->layer()->RequestCopyOfOutput(std::move(request));
} }
...@@ -372,19 +346,46 @@ void Pointer::OnCursorCaptured(const gfx::Point& hotspot, ...@@ -372,19 +346,46 @@ void Pointer::OnCursorCaptured(const gfx::Point& hotspot,
if (!focus_) if (!focus_)
return; return;
cursor_ = ui::CursorType::kNone; if (result->IsEmpty()) {
if (!result->IsEmpty()) { cursor_bitmap_.reset();
} else {
DCHECK(result->HasBitmap()); 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; ui::PlatformCursor platform_cursor;
#if defined(USE_OZONE) #if defined(USE_OZONE)
// TODO(reveman): Add interface for creating cursors from GpuMemoryBuffers // TODO(reveman): Add interface for creating cursors from GpuMemoryBuffers
// and use that here instead of the current bitmap API. crbug.com/686600 // and use that here instead of the current bitmap API. crbug.com/686600
platform_cursor = ui::CursorFactoryOzone::GetInstance()->CreateImageCursor( platform_cursor = ui::CursorFactoryOzone::GetInstance()->CreateImageCursor(
*bitmap.get(), hotspot, cursor_scale_); bitmap, hotspot, 0);
#elif defined(USE_X11) #elif defined(USE_X11)
XcursorImage* image = ui::SkBitmapToXcursorImage(bitmap.get(), hotspot); XcursorImage* image = ui::SkBitmapToXcursorImage(&bitmap, hotspot);
platform_cursor = ui::CreateReffedCustomXCursor(image); platform_cursor = ui::CreateReffedCustomXCursor(image);
#endif #endif
cursor_ = ui::CursorType::kCustom; cursor_ = ui::CursorType::kCustom;
...@@ -396,12 +397,6 @@ void Pointer::OnCursorCaptured(const gfx::Point& hotspot, ...@@ -396,12 +397,6 @@ void Pointer::OnCursorCaptured(const gfx::Point& hotspot,
#endif #endif
} }
UpdateCursor();
}
void Pointer::UpdateCursor() {
DCHECK(focus_);
aura::Window* root_window = focus_->window()->GetRootWindow(); aura::Window* root_window = focus_->window()->GetRootWindow();
if (!root_window) if (!root_window)
return; return;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "components/exo/surface_delegate.h" #include "components/exo/surface_delegate.h"
#include "components/exo/surface_observer.h" #include "components/exo/surface_observer.h"
#include "components/exo/wm_helper.h" #include "components/exo/wm_helper.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/cursor/cursor.h" #include "ui/base/cursor/cursor.h"
#include "ui/events/event_constants.h" #include "ui/events/event_constants.h"
#include "ui/events/event_handler.h" #include "ui/events/event_handler.h"
...@@ -59,6 +60,7 @@ class Pointer : public ui::EventHandler, ...@@ -59,6 +60,7 @@ class Pointer : public ui::EventHandler,
// Overridden from WMHelper::CursorObserver: // Overridden from WMHelper::CursorObserver:
void OnCursorSetChanged(ui::CursorSetType cursor_set) override; void OnCursorSetChanged(ui::CursorSetType cursor_set) override;
void OnCursorDisplayChanged(const display::Display& display) override;
// Overridden from SurfaceDelegate: // Overridden from SurfaceDelegate:
void OnSurfaceCommit() override; void OnSurfaceCommit() override;
...@@ -71,17 +73,14 @@ class Pointer : public ui::EventHandler, ...@@ -71,17 +73,14 @@ class Pointer : public ui::EventHandler,
// Returns the effective target for |event|. // Returns the effective target for |event|.
Surface* GetEffectiveTargetForEvent(ui::Event* event) const; Surface* GetEffectiveTargetForEvent(ui::Event* event) const;
// Recompute cursor scale and update cursor if scale changed.
void UpdateCursorScale();
// Asynchronously update the cursor by capturing a snapshot of |surface_|. // Asynchronously update the cursor by capturing a snapshot of |surface_|.
void CaptureCursor(); void CaptureCursor(const gfx::Point& hotspot);
// Called when cursor snapshot has been captured. // Called when cursor snapshot has been captured.
void OnCursorCaptured(const gfx::Point& hotspot, void OnCursorCaptured(const gfx::Point& hotspot,
std::unique_ptr<cc::CopyOutputResult> result); std::unique_ptr<cc::CopyOutputResult> result);
// Update cursor to reflect the current value of |cursor_|. // Update |cursor_| to |cursor_bitmap_| transformed for the current display.
void UpdateCursor(); void UpdateCursor();
// The delegate instance that all events are dispatched to. // The delegate instance that all events are dispatched to.
...@@ -96,12 +95,12 @@ class Pointer : public ui::EventHandler, ...@@ -96,12 +95,12 @@ class Pointer : public ui::EventHandler,
// The location of the pointer in the current focus surface. // The location of the pointer in the current focus surface.
gfx::PointF location_; gfx::PointF location_;
// The scale applied to the cursor to compensate for the UI scale.
float cursor_scale_ = 1.0f;
// The position of the pointer surface relative to the pointer location. // The position of the pointer surface relative to the pointer location.
gfx::Point hotspot_; gfx::Point hotspot_;
// Latest cursor snapshot.
SkBitmap cursor_bitmap_;
// The current cursor. // The current cursor.
ui::Cursor cursor_; ui::Cursor cursor_;
......
...@@ -1148,7 +1148,8 @@ void ShellSurface::CreateShellSurfaceWidget(ui::WindowShowState show_state) { ...@@ -1148,7 +1148,8 @@ void ShellSurface::CreateShellSurfaceWidget(ui::WindowShowState show_state) {
params.show_state = show_state; params.show_state = show_state;
// Make shell surface a transient child if |parent_| has been set. // Make shell surface a transient child if |parent_| has been set.
params.parent = params.parent =
parent_ ? parent_ : WMHelper::GetInstance()->GetContainer(container_); parent_ ? parent_
: WMHelper::GetInstance()->GetPrimaryDisplayContainer(container_);
params.bounds = gfx::Rect(origin_, gfx::Size()); params.bounds = gfx::Rect(origin_, gfx::Size());
bool activatable = activatable_; bool activatable = activatable_;
// ShellSurfaces in system modal container are only activatable if input // ShellSurfaces in system modal container are only activatable if input
......
...@@ -103,6 +103,11 @@ void WMHelper::NotifyCursorSetChanged(ui::CursorSetType cursor_set) { ...@@ -103,6 +103,11 @@ void WMHelper::NotifyCursorSetChanged(ui::CursorSetType cursor_set) {
observer.OnCursorSetChanged(cursor_set); observer.OnCursorSetChanged(cursor_set);
} }
void WMHelper::NotifyCursorDisplayChanged(const display::Display& display) {
for (CursorObserver& observer : cursor_observers_)
observer.OnCursorDisplayChanged(display);
}
void WMHelper::NotifyMaximizeModeStarted() { void WMHelper::NotifyMaximizeModeStarted() {
for (MaximizeModeObserver& observer : maximize_mode_observers_) for (MaximizeModeObserver& observer : maximize_mode_observers_)
observer.OnMaximizeModeStarted(); observer.OnMaximizeModeStarted();
......
...@@ -14,6 +14,7 @@ class Window; ...@@ -14,6 +14,7 @@ class Window;
} }
namespace display { namespace display {
class Display;
class ManagedDisplayInfo; class ManagedDisplayInfo;
} }
...@@ -48,6 +49,7 @@ class WMHelper { ...@@ -48,6 +49,7 @@ class WMHelper {
public: public:
virtual void OnCursorVisibilityChanged(bool is_visible) {} virtual void OnCursorVisibilityChanged(bool is_visible) {}
virtual void OnCursorSetChanged(ui::CursorSetType cursor_set) {} virtual void OnCursorSetChanged(ui::CursorSetType cursor_set) {}
virtual void OnCursorDisplayChanged(const display::Display& display) {}
protected: protected:
virtual ~CursorObserver() {} virtual ~CursorObserver() {}
...@@ -98,12 +100,13 @@ class WMHelper { ...@@ -98,12 +100,13 @@ class WMHelper {
void RemoveDisplayConfigurationObserver( void RemoveDisplayConfigurationObserver(
DisplayConfigurationObserver* observer); DisplayConfigurationObserver* observer);
virtual const display::ManagedDisplayInfo GetDisplayInfo( virtual const display::ManagedDisplayInfo& GetDisplayInfo(
int64_t display_id) const = 0; int64_t display_id) const = 0;
virtual aura::Window* GetContainer(int container_id) = 0; virtual aura::Window* GetPrimaryDisplayContainer(int container_id) = 0;
virtual aura::Window* GetActiveWindow() const = 0; virtual aura::Window* GetActiveWindow() const = 0;
virtual aura::Window* GetFocusedWindow() const = 0; virtual aura::Window* GetFocusedWindow() const = 0;
virtual ui::CursorSetType GetCursorSet() const = 0; virtual ui::CursorSetType GetCursorSet() const = 0;
virtual const display::Display& GetCursorDisplay() const = 0;
virtual void AddPreTargetHandler(ui::EventHandler* handler) = 0; virtual void AddPreTargetHandler(ui::EventHandler* handler) = 0;
virtual void PrependPreTargetHandler(ui::EventHandler* handler) = 0; virtual void PrependPreTargetHandler(ui::EventHandler* handler) = 0;
virtual void RemovePreTargetHandler(ui::EventHandler* handler) = 0; virtual void RemovePreTargetHandler(ui::EventHandler* handler) = 0;
...@@ -120,6 +123,7 @@ class WMHelper { ...@@ -120,6 +123,7 @@ class WMHelper {
aura::Window* lost_focus); aura::Window* lost_focus);
void NotifyCursorVisibilityChanged(bool is_visible); void NotifyCursorVisibilityChanged(bool is_visible);
void NotifyCursorSetChanged(ui::CursorSetType cursor_set); void NotifyCursorSetChanged(ui::CursorSetType cursor_set);
void NotifyCursorDisplayChanged(const display::Display& display);
void NotifyMaximizeModeStarted(); void NotifyMaximizeModeStarted();
void NotifyMaximizeModeEnding(); void NotifyMaximizeModeEnding();
void NotifyMaximizeModeEnded(); void NotifyMaximizeModeEnded();
......
...@@ -51,14 +51,12 @@ WMHelperAsh::~WMHelperAsh() { ...@@ -51,14 +51,12 @@ WMHelperAsh::~WMHelperAsh() {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// WMHelperAsh, private: // WMHelperAsh, private:
const display::ManagedDisplayInfo WMHelperAsh::GetDisplayInfo( const display::ManagedDisplayInfo& WMHelperAsh::GetDisplayInfo(
int64_t display_id) const { int64_t display_id) const {
return ash::Shell::Get()->display_manager()->GetDisplayInfo(display_id); return ash::Shell::Get()->display_manager()->GetDisplayInfo(display_id);
} }
aura::Window* WMHelperAsh::GetContainer(int container_id) { aura::Window* WMHelperAsh::GetPrimaryDisplayContainer(int container_id) {
// TODO(domlaskowski): Use target root window once multi-display support lands
// in ARC. See crbug.com/718627.
return ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(), return ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(),
container_id); container_id);
} }
...@@ -80,6 +78,15 @@ ui::CursorSetType WMHelperAsh::GetCursorSet() const { ...@@ -80,6 +78,15 @@ ui::CursorSetType WMHelperAsh::GetCursorSet() const {
return ash::Shell::Get()->cursor_manager()->GetCursorSet(); return ash::Shell::Get()->cursor_manager()->GetCursorSet();
} }
const display::Display& WMHelperAsh::GetCursorDisplay() const {
// TODO(crbug.com/631103): Mushrome doesn't have a cursor manager yet.
if (ash::ShellPort::Get()->GetAshConfig() == ash::Config::MUS) {
static const display::Display display;
return display;
}
return ash::Shell::Get()->cursor_manager()->GetDisplay();
}
void WMHelperAsh::AddPreTargetHandler(ui::EventHandler* handler) { void WMHelperAsh::AddPreTargetHandler(ui::EventHandler* handler) {
ash::Shell::Get()->AddPreTargetHandler(handler); ash::Shell::Get()->AddPreTargetHandler(handler);
} }
...@@ -126,6 +133,10 @@ void WMHelperAsh::OnCursorSetChanged(ui::CursorSetType cursor_set) { ...@@ -126,6 +133,10 @@ void WMHelperAsh::OnCursorSetChanged(ui::CursorSetType cursor_set) {
NotifyCursorSetChanged(cursor_set); NotifyCursorSetChanged(cursor_set);
} }
void WMHelperAsh::OnCursorDisplayChanged(const display::Display& display) {
NotifyCursorDisplayChanged(display);
}
void WMHelperAsh::OnMaximizeModeStarted() { void WMHelperAsh::OnMaximizeModeStarted() {
NotifyMaximizeModeStarted(); NotifyMaximizeModeStarted();
} }
......
...@@ -29,12 +29,13 @@ class WMHelperAsh : public WMHelper, ...@@ -29,12 +29,13 @@ class WMHelperAsh : public WMHelper,
~WMHelperAsh() override; ~WMHelperAsh() override;
// Overridden from WMHelper: // Overridden from WMHelper:
const display::ManagedDisplayInfo GetDisplayInfo( const display::ManagedDisplayInfo& GetDisplayInfo(
int64_t display_id) const override; int64_t display_id) const override;
aura::Window* GetContainer(int container_id) override; aura::Window* GetPrimaryDisplayContainer(int container_id) override;
aura::Window* GetActiveWindow() const override; aura::Window* GetActiveWindow() const override;
aura::Window* GetFocusedWindow() const override; aura::Window* GetFocusedWindow() const override;
ui::CursorSetType GetCursorSet() const override; ui::CursorSetType GetCursorSet() const override;
const display::Display& GetCursorDisplay() const override;
void AddPreTargetHandler(ui::EventHandler* handler) override; void AddPreTargetHandler(ui::EventHandler* handler) override;
void PrependPreTargetHandler(ui::EventHandler* handler) override; void PrependPreTargetHandler(ui::EventHandler* handler) override;
void RemovePreTargetHandler(ui::EventHandler* handler) override; void RemovePreTargetHandler(ui::EventHandler* handler) override;
...@@ -54,6 +55,7 @@ class WMHelperAsh : public WMHelper, ...@@ -54,6 +55,7 @@ class WMHelperAsh : public WMHelper,
// Overridden from aura::client::CursorClientObserver: // Overridden from aura::client::CursorClientObserver:
void OnCursorVisibilityChanged(bool is_visible) override; void OnCursorVisibilityChanged(bool is_visible) override;
void OnCursorSetChanged(ui::CursorSetType cursor_set) override; void OnCursorSetChanged(ui::CursorSetType cursor_set) override;
void OnCursorDisplayChanged(const display::Display& display) override;
// Overridden from ash::ShellObserver: // Overridden from ash::ShellObserver:
void OnMaximizeModeStarted() override; void OnMaximizeModeStarted() override;
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "ui/aura/mus/focus_synchronizer.h" #include "ui/aura/mus/focus_synchronizer.h"
#include "ui/aura/mus/window_tree_client.h" #include "ui/aura/mus/window_tree_client.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/display/display.h"
#include "ui/display/manager/managed_display_info.h" #include "ui/display/manager/managed_display_info.h"
#include "ui/views/mus/mus_client.h" #include "ui/views/mus/mus_client.h"
#include "ui/wm/public/activation_client.h" #include "ui/wm/public/activation_client.h"
...@@ -37,13 +38,14 @@ WMHelperMus::~WMHelperMus() { ...@@ -37,13 +38,14 @@ WMHelperMus::~WMHelperMus() {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// WMHelperMus, private: // WMHelperMus, private:
const display::ManagedDisplayInfo WMHelperMus::GetDisplayInfo( const display::ManagedDisplayInfo& WMHelperMus::GetDisplayInfo(
int64_t display_id) const { int64_t display_id) const {
// TODO(penghuang): Return real display info when it is supported in mus. // TODO(penghuang): Return real display info when it is supported in mus.
return display::ManagedDisplayInfo(display_id, "", false); static const display::ManagedDisplayInfo info;
return info;
} }
aura::Window* WMHelperMus::GetContainer(int container_id) { aura::Window* WMHelperMus::GetPrimaryDisplayContainer(int container_id) {
NOTIMPLEMENTED(); NOTIMPLEMENTED();
return nullptr; return nullptr;
} }
...@@ -61,6 +63,13 @@ ui::CursorSetType WMHelperMus::GetCursorSet() const { ...@@ -61,6 +63,13 @@ ui::CursorSetType WMHelperMus::GetCursorSet() const {
return ui::CursorSetType::CURSOR_SET_NORMAL; return ui::CursorSetType::CURSOR_SET_NORMAL;
} }
const display::Display& WMHelperMus::GetCursorDisplay() const {
NOTIMPLEMENTED();
// TODO(penghuang): Return real display when supported in mus.
static const display::Display display;
return display;
}
void WMHelperMus::AddPreTargetHandler(ui::EventHandler* handler) { void WMHelperMus::AddPreTargetHandler(ui::EventHandler* handler) {
aura::Env::GetInstance()->AddPreTargetHandler(handler); aura::Env::GetInstance()->AddPreTargetHandler(handler);
} }
......
...@@ -28,12 +28,13 @@ class WMHelperMus : public WMHelper, ...@@ -28,12 +28,13 @@ class WMHelperMus : public WMHelper,
~WMHelperMus() override; ~WMHelperMus() override;
// Overridden from WMHelper: // Overridden from WMHelper:
const display::ManagedDisplayInfo GetDisplayInfo( const display::ManagedDisplayInfo& GetDisplayInfo(
int64_t display_id) const override; int64_t display_id) const override;
aura::Window* GetContainer(int container_id) override; aura::Window* GetPrimaryDisplayContainer(int container_id) override;
aura::Window* GetActiveWindow() const override; aura::Window* GetActiveWindow() const override;
aura::Window* GetFocusedWindow() const override; aura::Window* GetFocusedWindow() const override;
ui::CursorSetType GetCursorSet() const override; ui::CursorSetType GetCursorSet() const override;
const display::Display& GetCursorDisplay() const override;
void AddPreTargetHandler(ui::EventHandler* handler) override; void AddPreTargetHandler(ui::EventHandler* handler) override;
void PrependPreTargetHandler(ui::EventHandler* handler) override; void PrependPreTargetHandler(ui::EventHandler* handler) override;
void RemovePreTargetHandler(ui::EventHandler* handler) override; void RemovePreTargetHandler(ui::EventHandler* handler) override;
......
...@@ -61,6 +61,9 @@ class AURA_EXPORT CursorClient { ...@@ -61,6 +61,9 @@ class AURA_EXPORT CursorClient {
// Sets the display for the cursor. // Sets the display for the cursor.
virtual void SetDisplay(const display::Display& display) = 0; virtual void SetDisplay(const display::Display& display) = 0;
// Returns the display where the cursor is located.
virtual const display::Display& GetDisplay() const = 0;
// Locks the cursor change. The cursor type, cursor visibility, and mouse // Locks the cursor change. The cursor type, cursor visibility, and mouse
// events enable state never change as long as lock is held by anyone. // events enable state never change as long as lock is held by anyone.
virtual void LockCursor() = 0; virtual void LockCursor() = 0;
......
...@@ -8,6 +8,10 @@ ...@@ -8,6 +8,10 @@
#include "ui/aura/aura_export.h" #include "ui/aura/aura_export.h"
#include "ui/base/cursor/cursor.h" #include "ui/base/cursor/cursor.h"
namespace display {
class Display;
}
namespace aura { namespace aura {
namespace client { namespace client {
...@@ -15,6 +19,7 @@ class AURA_EXPORT CursorClientObserver { ...@@ -15,6 +19,7 @@ class AURA_EXPORT CursorClientObserver {
public: public:
virtual void OnCursorVisibilityChanged(bool is_visible) {} virtual void OnCursorVisibilityChanged(bool is_visible) {}
virtual void OnCursorSetChanged(ui::CursorSetType cursor_set) {} virtual void OnCursorSetChanged(ui::CursorSetType cursor_set) {}
virtual void OnCursorDisplayChanged(const display::Display& display) {}
protected: protected:
virtual ~CursorClientObserver() {} virtual ~CursorClientObserver() {}
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "ui/aura/test/test_cursor_client.h" #include "ui/aura/test/test_cursor_client.h"
#include "ui/aura/client/cursor_client_observer.h" #include "ui/aura/client/cursor_client_observer.h"
#include "ui/display/display.h"
namespace aura { namespace aura {
namespace test { namespace test {
...@@ -68,6 +69,11 @@ bool TestCursorClient::IsMouseEventsEnabled() const { ...@@ -68,6 +69,11 @@ bool TestCursorClient::IsMouseEventsEnabled() const {
void TestCursorClient::SetDisplay(const display::Display& display) {} void TestCursorClient::SetDisplay(const display::Display& display) {}
const display::Display& TestCursorClient::GetDisplay() const {
static const display::Display display;
return display;
}
void TestCursorClient::LockCursor() { void TestCursorClient::LockCursor() {
cursor_lock_count_++; cursor_lock_count_++;
} }
......
...@@ -43,6 +43,7 @@ class TestCursorClient : public aura::client::CursorClient { ...@@ -43,6 +43,7 @@ class TestCursorClient : public aura::client::CursorClient {
void DisableMouseEvents() override; void DisableMouseEvents() override;
bool IsMouseEventsEnabled() const override; bool IsMouseEventsEnabled() const override;
void SetDisplay(const display::Display& display) override; void SetDisplay(const display::Display& display) override;
const display::Display& GetDisplay() const override;
void LockCursor() override; void LockCursor() override;
void UnlockCursor() override; void UnlockCursor() override;
bool IsCursorLocked() const override; bool IsCursorLocked() const override;
......
...@@ -165,9 +165,17 @@ bool CursorManager::IsMouseEventsEnabled() const { ...@@ -165,9 +165,17 @@ bool CursorManager::IsMouseEventsEnabled() const {
} }
void CursorManager::SetDisplay(const display::Display& display) { void CursorManager::SetDisplay(const display::Display& display) {
display_ = display;
for (auto& observer : observers_)
observer.OnCursorDisplayChanged(display);
delegate_->SetDisplay(display, this); delegate_->SetDisplay(display, this);
} }
const display::Display& CursorManager::GetDisplay() const {
return display_;
}
void CursorManager::LockCursor() { void CursorManager::LockCursor() {
cursor_lock_count_++; cursor_lock_count_++;
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "base/observer_list.h" #include "base/observer_list.h"
#include "ui/aura/client/cursor_client.h" #include "ui/aura/client/cursor_client.h"
#include "ui/base/cursor/cursor.h" #include "ui/base/cursor/cursor.h"
#include "ui/display/display.h"
#include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/point.h"
#include "ui/gfx/native_widget_types.h" #include "ui/gfx/native_widget_types.h"
#include "ui/wm/core/native_cursor_manager_delegate.h" #include "ui/wm/core/native_cursor_manager_delegate.h"
...@@ -54,6 +55,7 @@ class WM_CORE_EXPORT CursorManager : public aura::client::CursorClient, ...@@ -54,6 +55,7 @@ class WM_CORE_EXPORT CursorManager : public aura::client::CursorClient,
void DisableMouseEvents() override; void DisableMouseEvents() override;
bool IsMouseEventsEnabled() const override; bool IsMouseEventsEnabled() const override;
void SetDisplay(const display::Display& display) override; void SetDisplay(const display::Display& display) override;
const display::Display& GetDisplay() const override;
void LockCursor() override; void LockCursor() override;
void UnlockCursor() override; void UnlockCursor() override;
bool IsCursorLocked() const override; bool IsCursorLocked() const override;
...@@ -70,6 +72,9 @@ class WM_CORE_EXPORT CursorManager : public aura::client::CursorClient, ...@@ -70,6 +72,9 @@ class WM_CORE_EXPORT CursorManager : public aura::client::CursorClient,
std::unique_ptr<NativeCursorManager> delegate_; std::unique_ptr<NativeCursorManager> delegate_;
// Display where the cursor is located.
display::Display display_;
// Number of times LockCursor() has been invoked without a corresponding // Number of times LockCursor() has been invoked without a corresponding
// UnlockCursor(). // UnlockCursor().
int cursor_lock_count_; int cursor_lock_count_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment