Skip to content

Commit

Permalink
Initial support of large mouse cursor on Exosphere
Browse files Browse the repository at this point in the history
This patch adds support of large mouse cursor on Exosphere. If the large cursor set is selected, exosphere enlarges the cursor.

BUG=b/29169901
TEST=Run unit_tests, and test manualy

Review-Url: https://codereview.chromium.org/2071553002
Cr-Commit-Position: refs/heads/master@{#403141}
  • Loading branch information
yoshikig authored and Commit bot committed Jun 30, 2016
1 parent 4cd3b19 commit 7aa92b1
Show file tree
Hide file tree
Showing 12 changed files with 178 additions and 67 deletions.
1 change: 1 addition & 0 deletions ash/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,7 @@ test("ash_unittests") {
"//ui/views/controls/webview:test_support",
"//ui/web_dialogs:test_support",
"//ui/wm",
"//ui/wm:test_support",
"//url",
]

Expand Down
1 change: 1 addition & 0 deletions ash/ash.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -1278,6 +1278,7 @@
'../ui/views/views.gyp:views_test_support',
'../ui/web_dialogs/web_dialogs.gyp:web_dialogs_test_support',
'../ui/wm/wm.gyp:wm',
'../ui/wm/wm.gyp:wm_test_support',
'../url/url.gyp:url_lib',
'ash',
'ash_resources.gyp:ash_resources',
Expand Down
41 changes: 18 additions & 23 deletions ash/wm/window_manager_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,30 +24,10 @@
#include "ui/wm/core/compound_event_filter.h"
#include "ui/wm/public/activation_client.h"
#include "ui/wm/public/activation_delegate.h"
#include "ui/wm/test/testing_cursor_client_observer.h"

namespace {

class TestingCursorClientObserver : public aura::client::CursorClientObserver {
public:
TestingCursorClientObserver()
: cursor_visibility_(false), did_visibility_change_(false) {}
void reset() { cursor_visibility_ = did_visibility_change_ = false; }
bool is_cursor_visible() const { return cursor_visibility_; }
bool did_visibility_change() const { return did_visibility_change_; }

// Overridden from aura::client::CursorClientObserver:
void OnCursorVisibilityChanged(bool is_visible) override {
cursor_visibility_ = is_visible;
did_visibility_change_ = true;
}

private:
bool cursor_visibility_;
bool did_visibility_change_;

DISALLOW_COPY_AND_ASSIGN(TestingCursorClientObserver);
};

base::TimeTicks getTime() {
return ui::EventTimeForNow();
}
Expand Down Expand Up @@ -797,8 +777,8 @@ TEST_F(WindowManagerTest, TestCursorClientObserver) {

// Add two observers. Both should have OnCursorVisibilityChanged()
// invoked when an event changes the visibility of the cursor.
TestingCursorClientObserver observer_a;
TestingCursorClientObserver observer_b;
::wm::TestingCursorClientObserver observer_a;
::wm::TestingCursorClientObserver observer_b;
cursor_manager->AddObserver(&observer_a);
cursor_manager->AddObserver(&observer_b);

Expand All @@ -809,6 +789,8 @@ TEST_F(WindowManagerTest, TestCursorClientObserver) {
EXPECT_FALSE(observer_b.did_visibility_change());
EXPECT_FALSE(observer_a.is_cursor_visible());
EXPECT_FALSE(observer_b.is_cursor_visible());
EXPECT_FALSE(observer_a.did_cursor_set_change());
EXPECT_FALSE(observer_b.did_cursor_set_change());

// Keypress should hide the cursor.
generator.PressKey(ui::VKEY_A, ui::EF_NONE);
Expand All @@ -817,6 +799,13 @@ TEST_F(WindowManagerTest, TestCursorClientObserver) {
EXPECT_FALSE(observer_a.is_cursor_visible());
EXPECT_FALSE(observer_b.is_cursor_visible());

// Set cursor set.
cursor_manager->SetCursorSet(ui::CURSOR_SET_LARGE);
EXPECT_TRUE(observer_a.did_cursor_set_change());
EXPECT_EQ(ui::CURSOR_SET_LARGE, observer_a.cursor_set());
EXPECT_TRUE(observer_b.did_cursor_set_change());
EXPECT_EQ(ui::CURSOR_SET_LARGE, observer_b.cursor_set());

// Mouse move should show the cursor.
observer_a.reset();
observer_b.reset();
Expand All @@ -838,6 +827,12 @@ TEST_F(WindowManagerTest, TestCursorClientObserver) {
EXPECT_FALSE(observer_b.did_visibility_change());
EXPECT_FALSE(observer_a.is_cursor_visible());

// Set back cursor set to normal.
cursor_manager->SetCursorSet(ui::CURSOR_SET_NORMAL);
EXPECT_TRUE(observer_a.did_cursor_set_change());
EXPECT_EQ(ui::CURSOR_SET_NORMAL, observer_a.cursor_set());
EXPECT_FALSE(observer_b.did_cursor_set_change());

// Mouse move should show the cursor.
observer_a.reset();
observer_b.reset();
Expand Down
66 changes: 48 additions & 18 deletions components/exo/pointer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
namespace exo {
namespace {

static constexpr float kLargeCursorScale = 2.8;

// Synthesized events typically lack floating point precision so to avoid
// generating mouse event jitter we consider the location of these events
// to be the same as |location| if floored values match.
Expand All @@ -34,8 +36,17 @@ bool SameLocation(const ui::LocatedEvent* event, const gfx::PointF& location) {
////////////////////////////////////////////////////////////////////////////////
// Pointer, public:

Pointer::Pointer(PointerDelegate* delegate) : delegate_(delegate) {
ash::Shell::GetInstance()->AddPreTargetHandler(this);
Pointer::Pointer(PointerDelegate* delegate)
: delegate_(delegate),
surface_(nullptr),
focus_(nullptr),
cursor_scale_(1.0f) {
ash::Shell* ash_shell = ash::Shell::GetInstance();
ash_shell->AddPreTargetHandler(this);

wm::CursorManager* cursor_manager = ash_shell->cursor_manager();
DCHECK(cursor_manager);
cursor_manager->AddObserver(this);
}

Pointer::~Pointer() {
Expand All @@ -48,7 +59,11 @@ Pointer::~Pointer() {
}
if (widget_)
widget_->CloseNow();
ash::Shell::GetInstance()->RemovePreTargetHandler(this);

ash::Shell* ash_shell = ash::Shell::GetInstance();
DCHECK(ash_shell->cursor_manager());
ash_shell->cursor_manager()->RemoveObserver(this);
ash_shell->RemovePreTargetHandler(this);
}

void Pointer::SetCursor(Surface* surface, const gfx::Point& hotspot) {
Expand Down Expand Up @@ -207,21 +222,7 @@ void Pointer::OnMouseEvent(ui::MouseEvent* event) {
widget_->GetNativeWindow()->SetBounds(bounds);
}

// Update cursor scale if the effective UI scale has changed since last
// mouse event.
display::Display display =
display::Screen::GetScreen()->GetDisplayNearestWindow(
widget_->GetNativeWindow());
float ui_scale = ash::Shell::GetInstance()
->display_manager()
->GetDisplayInfo(display.id())
.GetEffectiveUIScale();
if (ui_scale != cursor_scale_) {
gfx::Transform transform;
transform.Scale(ui_scale, ui_scale);
widget_->GetNativeWindow()->SetTransform(transform);
cursor_scale_ = ui_scale;
}
UpdateCursorScale();
} else {
if (widget_ && widget_->IsVisible())
widget_->Hide();
Expand All @@ -232,6 +233,10 @@ void Pointer::OnScrollEvent(ui::ScrollEvent* event) {
OnMouseEvent(event);
}

void Pointer::OnCursorSetChanged(ui::CursorSetType cursor_set) {
UpdateCursorScale();
}

////////////////////////////////////////////////////////////////////////////////
// SurfaceDelegate overrides:

Expand Down Expand Up @@ -290,4 +295,29 @@ Surface* Pointer::GetEffectiveTargetForEvent(ui::Event* event) const {
return delegate_->CanAcceptPointerEventsForSurface(target) ? target : nullptr;
}

void Pointer::UpdateCursorScale() {
if (!focus_)
return;

// Update cursor scale if the effective UI scale has changed.
display::Display display =
display::Screen::GetScreen()->GetDisplayNearestWindow(
widget_->GetNativeWindow());
float ui_scale = ash::Shell::GetInstance()
->display_manager()
->GetDisplayInfo(display.id())
.GetEffectiveUIScale();

ash::Shell* ash_shell = ash::Shell::GetInstance();
if (ash_shell->cursor_manager()->GetCursorSet() == ui::CURSOR_SET_LARGE)
ui_scale *= kLargeCursorScale;

if (ui_scale != cursor_scale_) {
gfx::Transform transform;
transform.Scale(ui_scale, ui_scale);
widget_->GetNativeWindow()->SetTransform(transform);
cursor_scale_ = ui_scale;
}
}

} // namespace exo
8 changes: 8 additions & 0 deletions components/exo/pointer.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "base/macros.h"
#include "components/exo/surface_delegate.h"
#include "components/exo/surface_observer.h"
#include "ui/aura/client/cursor_client_observer.h"
#include "ui/events/event_handler.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/point_f.h"
Expand All @@ -31,6 +32,7 @@ class Surface;
// This class implements a client pointer that represents one or more input
// devices, such as mice, which control the pointer location and pointer focus.
class Pointer : public ui::EventHandler,
public aura::client::CursorClientObserver,
public SurfaceDelegate,
public SurfaceObserver {
public:
Expand All @@ -48,6 +50,9 @@ class Pointer : public ui::EventHandler,
void OnMouseEvent(ui::MouseEvent* event) override;
void OnScrollEvent(ui::ScrollEvent* event) override;

// Overridden from aura::client::CursorClientObserver:
void OnCursorSetChanged(ui::CursorSetType cursor_set) override;

// Overridden from SurfaceDelegate:
void OnSurfaceCommit() override;
bool IsSurfaceSynchronized() const override;
Expand All @@ -59,6 +64,9 @@ class Pointer : public ui::EventHandler,
// Creates the |widget_| for pointer.
void CreatePointerWidget();

// Updates the scale of the cursor with the latest state.
void UpdateCursorScale();

// Returns the effective target for |event|.
Surface* GetEffectiveTargetForEvent(ui::Event* event) const;

Expand Down
4 changes: 3 additions & 1 deletion ui/aura/client/cursor_client_observer.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
#define UI_AURA_CLIENT_CURSOR_CLIENT_OBSERVER_H_

#include "ui/aura/aura_export.h"
#include "ui/base/cursor/cursor.h"

namespace aura {
namespace client {

class AURA_EXPORT CursorClientObserver {
public:
virtual void OnCursorVisibilityChanged(bool is_visible) = 0;
virtual void OnCursorVisibilityChanged(bool is_visible) {}
virtual void OnCursorSetChanged(ui::CursorSetType cursor_set) {}

protected:
virtual ~CursorClientObserver() {}
Expand Down
2 changes: 2 additions & 0 deletions ui/wm/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ component("wm") {
static_library("test_support") {
testonly = true
sources = [
"test/testing_cursor_client_observer.cc",
"test/testing_cursor_client_observer.h",
"test/wm_test_helper.cc",
"test/wm_test_helper.h",
]
Expand Down
5 changes: 4 additions & 1 deletion ui/wm/core/cursor_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,11 @@ bool CursorManager::IsCursorVisible() const {

void CursorManager::SetCursorSet(ui::CursorSetType cursor_set) {
state_on_unlock_->set_cursor_set(cursor_set);
if (GetCursorSet() != state_on_unlock_->cursor_set())
if (GetCursorSet() != state_on_unlock_->cursor_set()) {
delegate_->SetCursorSet(state_on_unlock_->cursor_set(), this);
FOR_EACH_OBSERVER(aura::client::CursorClientObserver, observers_,
OnCursorSetChanged(cursor_set));
}
}

ui::CursorSetType CursorManager::GetCursorSet() const {
Expand Down
49 changes: 25 additions & 24 deletions ui/wm/core/cursor_manager_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "ui/aura/client/cursor_client_observer.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/wm/core/native_cursor_manager.h"
#include "ui/wm/test/testing_cursor_client_observer.h"

namespace {

Expand Down Expand Up @@ -52,28 +53,6 @@ class CursorManagerTest : public aura::test::AuraTestBase {
wm::CursorManager cursor_manager_;
};

class TestingCursorClientObserver : public aura::client::CursorClientObserver {
public:
TestingCursorClientObserver()
: cursor_visibility_(false),
did_visibility_change_(false) {}
void reset() { cursor_visibility_ = did_visibility_change_ = false; }
bool is_cursor_visible() const { return cursor_visibility_; }
bool did_visibility_change() const { return did_visibility_change_; }

// Overridden from aura::client::CursorClientObserver:
void OnCursorVisibilityChanged(bool is_visible) override {
cursor_visibility_ = is_visible;
did_visibility_change_ = true;
}

private:
bool cursor_visibility_;
bool did_visibility_change_;

DISALLOW_COPY_AND_ASSIGN(TestingCursorClientObserver);
};

TEST_F(CursorManagerTest, ShowHideCursor) {
cursor_manager_.SetCursor(ui::kCursorCopy);
EXPECT_EQ(ui::kCursorCopy, cursor_manager_.GetCursor().native_type());
Expand Down Expand Up @@ -175,16 +154,23 @@ TEST_F(CursorManagerTest, EnableDisableMouseEvents) {
}

TEST_F(CursorManagerTest, SetCursorSet) {
wm::TestingCursorClientObserver observer;
cursor_manager_.AddObserver(&observer);

EXPECT_EQ(ui::CURSOR_SET_NORMAL, cursor_manager_.GetCursorSet());
EXPECT_EQ(ui::CURSOR_SET_NORMAL, observer.cursor_set());

cursor_manager_.SetCursorSet(ui::CURSOR_SET_NORMAL);
EXPECT_EQ(ui::CURSOR_SET_NORMAL, cursor_manager_.GetCursorSet());
EXPECT_EQ(ui::CURSOR_SET_NORMAL, observer.cursor_set());

cursor_manager_.SetCursorSet(ui::CURSOR_SET_LARGE);
EXPECT_EQ(ui::CURSOR_SET_LARGE, cursor_manager_.GetCursorSet());
EXPECT_EQ(ui::CURSOR_SET_LARGE, observer.cursor_set());

cursor_manager_.SetCursorSet(ui::CURSOR_SET_NORMAL);
EXPECT_EQ(ui::CURSOR_SET_NORMAL, cursor_manager_.GetCursorSet());
EXPECT_EQ(ui::CURSOR_SET_NORMAL, observer.cursor_set());
}

TEST_F(CursorManagerTest, IsMouseEventsEnabled) {
Expand Down Expand Up @@ -275,8 +261,8 @@ TEST_F(CursorManagerTest, MultipleEnableMouseEvents) {
TEST_F(CursorManagerTest, TestCursorClientObserver) {
// Add two observers. Both should have OnCursorVisibilityChanged()
// invoked when the visibility of the cursor changes.
TestingCursorClientObserver observer_a;
TestingCursorClientObserver observer_b;
wm::TestingCursorClientObserver observer_a;
wm::TestingCursorClientObserver observer_b;
cursor_manager_.AddObserver(&observer_a);
cursor_manager_.AddObserver(&observer_b);

Expand All @@ -287,6 +273,8 @@ TEST_F(CursorManagerTest, TestCursorClientObserver) {
EXPECT_FALSE(observer_b.did_visibility_change());
EXPECT_FALSE(observer_a.is_cursor_visible());
EXPECT_FALSE(observer_b.is_cursor_visible());
EXPECT_FALSE(observer_a.did_cursor_set_change());
EXPECT_FALSE(observer_b.did_cursor_set_change());

// Hide the cursor using HideCursor().
cursor_manager_.HideCursor();
Expand All @@ -295,6 +283,13 @@ TEST_F(CursorManagerTest, TestCursorClientObserver) {
EXPECT_FALSE(observer_a.is_cursor_visible());
EXPECT_FALSE(observer_b.is_cursor_visible());

// Set the cursor set.
cursor_manager_.SetCursorSet(ui::CURSOR_SET_LARGE);
EXPECT_TRUE(observer_a.did_cursor_set_change());
EXPECT_EQ(ui::CURSOR_SET_LARGE, observer_a.cursor_set());
EXPECT_TRUE(observer_b.did_cursor_set_change());
EXPECT_EQ(ui::CURSOR_SET_LARGE, observer_b.cursor_set());

// Show the cursor using ShowCursor().
observer_a.reset();
observer_b.reset();
Expand All @@ -316,6 +311,12 @@ TEST_F(CursorManagerTest, TestCursorClientObserver) {
EXPECT_FALSE(observer_b.did_visibility_change());
EXPECT_FALSE(observer_a.is_cursor_visible());

// Set back the cursor set to normal.
cursor_manager_.SetCursorSet(ui::CURSOR_SET_NORMAL);
EXPECT_TRUE(observer_a.did_cursor_set_change());
EXPECT_EQ(ui::CURSOR_SET_NORMAL, observer_a.cursor_set());
EXPECT_FALSE(observer_b.did_cursor_set_change());

// Show the cursor using ShowCursor().
observer_a.reset();
observer_b.reset();
Expand Down
Loading

0 comments on commit 7aa92b1

Please sign in to comment.