diff options
author | mazda@chromium.org <mazda@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-11 20:18:35 +0000 |
---|---|---|
committer | mazda@chromium.org <mazda@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-11 20:18:35 +0000 |
commit | 151ffdff429adc13dea9afbe18602745981a9dcc (patch) | |
tree | 65ea7ff184d3e543d2a6213e29a96119eed4081b /ash | |
parent | 843fe4276bb2a001d6bdbb74dda7ef44a707cec7 (diff) | |
download | chromium_src-151ffdff429adc13dea9afbe18602745981a9dcc.zip chromium_src-151ffdff429adc13dea9afbe18602745981a9dcc.tar.gz chromium_src-151ffdff429adc13dea9afbe18602745981a9dcc.tar.bz2 |
Move ash specific cursor code to CursorManager.
Main changes are as follows.
- Move the responsibility of managing cursors to ash::CursorManager from aura::RootWindowHostLinux.
- Set the same cursor to all root windows with CursorManager so that cursor is updated properly while dragging across displays
- Introduce CursorLoader class, which implements platform specific cursor loading.
- Add SetDeviceScaleFactor to CursorClient, which sets the device scale factor used for the cursor.
BUG=132862,144756
Review URL: https://chromiumcodereview.appspot.com/10919135
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@156109 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r-- | ash/ash.gyp | 2 | ||||
-rw-r--r-- | ash/display/mouse_cursor_event_filter.cc | 2 | ||||
-rw-r--r-- | ash/drag_drop/drag_drop_controller.cc | 8 | ||||
-rw-r--r-- | ash/drag_drop/drag_drop_controller.h | 2 | ||||
-rw-r--r-- | ash/extended_desktop_unittest.cc | 6 | ||||
-rw-r--r-- | ash/shell.cc | 3 | ||||
-rw-r--r-- | ash/wm/cursor_manager.cc | 24 | ||||
-rw-r--r-- | ash/wm/cursor_manager.h | 11 | ||||
-rw-r--r-- | ash/wm/image_cursors.cc | 123 | ||||
-rw-r--r-- | ash/wm/image_cursors.h | 43 | ||||
-rw-r--r-- | ash/wm/toplevel_window_event_handler.cc | 6 |
11 files changed, 214 insertions, 16 deletions
diff --git a/ash/ash.gyp b/ash/ash.gyp index e4b0877..8d1f53b 100644 --- a/ash/ash.gyp +++ b/ash/ash.gyp @@ -274,6 +274,8 @@ 'wm/gestures/system_pinch_handler.h', 'wm/gestures/two_finger_drag_handler.cc', 'wm/gestures/two_finger_drag_handler.h', + 'wm/image_cursors.cc', + 'wm/image_cursors.h', 'wm/image_grid.cc', 'wm/image_grid.h', 'wm/maximize_bubble_controller.cc', diff --git a/ash/display/mouse_cursor_event_filter.cc b/ash/display/mouse_cursor_event_filter.cc index 2973ef8..469db41 100644 --- a/ash/display/mouse_cursor_event_filter.cc +++ b/ash/display/mouse_cursor_event_filter.cc @@ -153,6 +153,8 @@ bool MouseCursorEventFilter::WarpMouseCursorIfNecessary( if (dst_root->bounds().Contains(point_in_dst_screen)) { DCHECK_NE(dst_root, current_root); dst_root->MoveCursorTo(point_in_dst_screen); + ash::Shell::GetInstance()->cursor_manager()->SetDeviceScaleFactor( + dst_root->AsRootWindowHostDelegate()->GetDeviceScaleFactor()); return true; } return false; diff --git a/ash/drag_drop/drag_drop_controller.cc b/ash/drag_drop/drag_drop_controller.cc index eb33f3d..acecc81 100644 --- a/ash/drag_drop/drag_drop_controller.cc +++ b/ash/drag_drop/drag_drop_controller.cc @@ -62,7 +62,6 @@ int DragDropController::StartDragAndDrop(const ui::OSExchangeData& data, int operation) { DCHECK(!IsDragDropInProgress()); - drag_cursor_ = ui::kCursorPointer; drag_drop_tracker_.reset(new DragDropTracker(root_window)); drag_data_ = &data; @@ -128,7 +127,6 @@ void DragDropController::DragUpdate(aura::Window* target, cursor = ui::kCursorAlias; else if (op & ui::DragDropTypes::DRAG_MOVE) cursor = ui::kCursorMove; - drag_cursor_ = cursor; ash::Shell::GetInstance()->cursor_manager()->SetCursor(cursor); } } @@ -145,7 +143,6 @@ void DragDropController::DragUpdate(aura::Window* target, void DragDropController::Drop(aura::Window* target, const ui::LocatedEvent& event) { - drag_cursor_ = ui::kCursorPointer; ash::Shell::GetInstance()->cursor_manager()->SetCursor(ui::kCursorPointer); aura::client::DragDropDelegate* delegate = NULL; @@ -175,7 +172,6 @@ void DragDropController::Drop(aura::Window* target, } void DragDropController::DragCancel() { - drag_cursor_ = ui::kCursorPointer; ash::Shell::GetInstance()->cursor_manager()->SetCursor(ui::kCursorPointer); // |drag_window_| can be NULL if we have just started the drag and have not @@ -197,10 +193,6 @@ bool DragDropController::IsDragDropInProgress() { return !!drag_drop_tracker_.get(); } -gfx::NativeCursor DragDropController::GetDragCursor() { - return drag_cursor_; -} - bool DragDropController::PreHandleKeyEvent(aura::Window* target, ui::KeyEvent* event) { if (IsDragDropInProgress() && event->key_code() == ui::VKEY_ESCAPE) { diff --git a/ash/drag_drop/drag_drop_controller.h b/ash/drag_drop/drag_drop_controller.h index d138ef6..59f1f32 100644 --- a/ash/drag_drop/drag_drop_controller.h +++ b/ash/drag_drop/drag_drop_controller.h @@ -59,7 +59,6 @@ class ASH_EXPORT DragDropController const ui::LocatedEvent& event) OVERRIDE; virtual void DragCancel() OVERRIDE; virtual bool IsDragDropInProgress() OVERRIDE; - virtual gfx::NativeCursor GetDragCursor() OVERRIDE; // Overridden from aura::EventFilter: virtual bool PreHandleKeyEvent(aura::Window* target, @@ -92,7 +91,6 @@ class ASH_EXPORT DragDropController gfx::Point drag_image_offset_; const ui::OSExchangeData* drag_data_; int drag_operation_; - gfx::NativeCursor drag_cursor_; // Window that is currently under the drag cursor. aura::Window* drag_window_; diff --git a/ash/extended_desktop_unittest.cc b/ash/extended_desktop_unittest.cc index b1e9583..20e4115 100644 --- a/ash/extended_desktop_unittest.cc +++ b/ash/extended_desktop_unittest.cc @@ -165,17 +165,17 @@ TEST_F(ExtendedDesktopTest, SystemModal) { TEST_F(ExtendedDesktopTest, TestCursor) { UpdateDisplay("1000x600,600x400"); - Shell::GetInstance()->ShowCursor(false); + Shell::GetInstance()->cursor_manager()->ShowCursor(false); Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); EXPECT_FALSE(root_windows[0]->cursor_shown()); EXPECT_FALSE(root_windows[1]->cursor_shown()); - Shell::GetInstance()->ShowCursor(true); + Shell::GetInstance()->cursor_manager()->ShowCursor(true); EXPECT_TRUE(root_windows[0]->cursor_shown()); EXPECT_TRUE(root_windows[1]->cursor_shown()); EXPECT_EQ(ui::kCursorPointer, root_windows[0]->last_cursor().native_type()); EXPECT_EQ(ui::kCursorPointer, root_windows[1]->last_cursor().native_type()); - Shell::GetInstance()->SetCursor(ui::kCursorCopy); + Shell::GetInstance()->cursor_manager()->SetCursor(ui::kCursorCopy); EXPECT_EQ(ui::kCursorCopy, root_windows[0]->last_cursor().native_type()); EXPECT_EQ(ui::kCursorCopy, root_windows[1]->last_cursor().native_type()); } diff --git a/ash/shell.cc b/ash/shell.cc index 6c26a09..ebfa9eb 100644 --- a/ash/shell.cc +++ b/ash/shell.cc @@ -372,6 +372,9 @@ void Shell::Init() { aura::RootWindow* root_window = display_controller_->GetPrimaryRootWindow(); active_root_window_ = root_window; + cursor_manager_.SetDeviceScaleFactor( + root_window->AsRootWindowHostDelegate()->GetDeviceScaleFactor()); + #if !defined(OS_MACOSX) nested_dispatcher_controller_.reset(new NestedDispatcherController); accelerator_controller_.reset(new AcceleratorController); diff --git a/ash/wm/cursor_manager.cc b/ash/wm/cursor_manager.cc index 1ebc72b..3afee4b 100644 --- a/ash/wm/cursor_manager.cc +++ b/ash/wm/cursor_manager.cc @@ -5,8 +5,10 @@ #include "ash/wm/cursor_manager.h" #include "ash/wm/cursor_delegate.h" +#include "ash/wm/image_cursors.h" #include "base/logging.h" #include "ui/aura/env.h" +#include "ui/base/cursor/cursor.h" namespace ash { @@ -15,7 +17,9 @@ CursorManager::CursorManager() cursor_lock_count_(0), did_cursor_change_(false), cursor_to_set_on_unlock_(0), - cursor_visible_(true) { + cursor_visible_(true), + current_cursor_(ui::kCursorNone), + image_cursors_(new ImageCursors) { } CursorManager::~CursorManager() { @@ -42,7 +46,7 @@ void CursorManager::UnlockCursor() { void CursorManager::SetCursor(gfx::NativeCursor cursor) { if (cursor_lock_count_ == 0) { if (delegate_) - delegate_->SetCursor(cursor); + SetCursorInternal(cursor); } else { cursor_to_set_on_unlock_ = cursor; did_cursor_change_ = true; @@ -59,4 +63,20 @@ bool CursorManager::IsCursorVisible() const { return cursor_visible_; } +void CursorManager::SetDeviceScaleFactor(float device_scale_factor) { + if (image_cursors_->GetDeviceScaleFactor() == device_scale_factor) + return; + image_cursors_->SetDeviceScaleFactor(device_scale_factor); + SetCursorInternal(current_cursor_); +} + +void CursorManager::SetCursorInternal(gfx::NativeCursor cursor) { + DCHECK(delegate_); + current_cursor_ = cursor; + image_cursors_->SetPlatformCursor(¤t_cursor_); + current_cursor_.set_device_scale_factor( + image_cursors_->GetDeviceScaleFactor()); + delegate_->SetCursor(current_cursor_); +} + } // namespace ash diff --git a/ash/wm/cursor_manager.h b/ash/wm/cursor_manager.h index 9f2cc8b..f5b5548 100644 --- a/ash/wm/cursor_manager.h +++ b/ash/wm/cursor_manager.h @@ -7,12 +7,14 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" +#include "base/memory/scoped_ptr.h" #include "ui/aura/aura_export.h" #include "ui/aura/client/cursor_client.h" #include "ui/gfx/native_widget_types.h" namespace ash { class CursorDelegate; +class ImageCursors; // This class controls the visibility and the type of the cursor. // The cursor type can be locked so that the type stays the same @@ -33,11 +35,15 @@ class CursorManager : public aura::client::CursorClient { // Shows or hides the cursor. bool cursor_visible() const { return cursor_visible_; } + // Overridden from aura::client::CursorClient: virtual void SetCursor(gfx::NativeCursor) OVERRIDE; virtual void ShowCursor(bool show) OVERRIDE; virtual bool IsCursorVisible() const OVERRIDE; + virtual void SetDeviceScaleFactor(float device_scale_factor) OVERRIDE; private: + void SetCursorInternal(gfx::NativeCursor cursor); + CursorDelegate* delegate_; // Number of times LockCursor() has been invoked without a corresponding @@ -54,6 +60,11 @@ class CursorManager : public aura::client::CursorClient { // Is cursor visible? bool cursor_visible_; + // The cursor currently set. + gfx::NativeCursor current_cursor_; + + scoped_ptr<ImageCursors> image_cursors_; + DISALLOW_COPY_AND_ASSIGN(CursorManager); }; diff --git a/ash/wm/image_cursors.cc b/ash/wm/image_cursors.cc new file mode 100644 index 0000000..b0ec3f5 --- /dev/null +++ b/ash/wm/image_cursors.cc @@ -0,0 +1,123 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/wm/image_cursors.h" + +#include "base/logging.h" +#include "ui/base/cursor/cursor_loader.h" +#include "ui/base/cursor/cursor.h" +#include "ui/gfx/point.h" +#include "grit/ui_resources.h" + +namespace { + +const int kAnimatedCursorFrameDelayMs = 25; + +struct HotPoint { + int x; + int y; +}; + +struct CursorData { + int id; + int resource_id; + HotPoint hot_1x; + HotPoint hot_2x; +}; + +// TODO(oshima): Remove this comment (http://crbug.com/141586). +// The cursor's hot points are defined in chromeos cursor images at: +// http://folder/kuscher/projects/Chrome_OS/Pointers/focuspoint +const CursorData kImageCursors[] = { + {ui::kCursorNull, IDR_AURA_CURSOR_PTR, {4, 4}, {8, 9}}, + {ui::kCursorPointer, IDR_AURA_CURSOR_PTR, {4, 4}, {8, 9}}, + {ui::kCursorNoDrop, IDR_AURA_CURSOR_NO_DROP, {4, 4}, {8, 9}}, + {ui::kCursorNotAllowed, IDR_AURA_CURSOR_NO_DROP, {4, 4}, {8, 9}}, + {ui::kCursorCopy, IDR_AURA_CURSOR_COPY, {4, 4}, {8, 9}}, + {ui::kCursorHand, IDR_AURA_CURSOR_HAND, {9, 4}, {19, 8}}, + {ui::kCursorMove, IDR_AURA_CURSOR_MOVE, {11, 11}, {23, 23}}, + {ui::kCursorNorthEastResize, IDR_AURA_CURSOR_NORTH_EAST_RESIZE, + {12, 11}, {25, 23}}, + {ui::kCursorSouthWestResize, IDR_AURA_CURSOR_SOUTH_WEST_RESIZE, + {12, 11}, {25, 23}}, + {ui::kCursorSouthEastResize, IDR_AURA_CURSOR_SOUTH_EAST_RESIZE, + {11, 11}, {24, 23}}, + {ui::kCursorNorthWestResize, IDR_AURA_CURSOR_NORTH_WEST_RESIZE, + {11, 11}, {24, 23}}, + {ui::kCursorNorthResize, IDR_AURA_CURSOR_NORTH_RESIZE, {11, 12}, {23, 23}}, + {ui::kCursorSouthResize, IDR_AURA_CURSOR_SOUTH_RESIZE, {11, 12}, {23, 23}}, + {ui::kCursorEastResize, IDR_AURA_CURSOR_EAST_RESIZE, {12, 11}, {25, 23}}, + {ui::kCursorWestResize, IDR_AURA_CURSOR_WEST_RESIZE, {12, 11}, {25, 23}}, + {ui::kCursorIBeam, IDR_AURA_CURSOR_IBEAM, {12, 12}, {24, 25}}, + {ui::kCursorAlias, IDR_AURA_CURSOR_ALIAS, {8, 6}, {15, 11}}, + {ui::kCursorCell, IDR_AURA_CURSOR_CELL, {11, 11}, {24, 23}}, + {ui::kCursorContextMenu, IDR_AURA_CURSOR_CONTEXT_MENU, {4, 4}, {8, 9}}, + {ui::kCursorCross, IDR_AURA_CURSOR_CROSSHAIR, {12, 12}, {25, 23}}, + {ui::kCursorHelp, IDR_AURA_CURSOR_HELP, {4, 4}, {8, 9}}, + {ui::kCursorVerticalText, IDR_AURA_CURSOR_XTERM_HORIZ, {12, 11}, {26, 23}}, + {ui::kCursorZoomIn, IDR_AURA_CURSOR_ZOOM_IN, {10, 10}, {20, 20}}, + {ui::kCursorZoomOut, IDR_AURA_CURSOR_ZOOM_OUT, {10, 10}, {20, 20}}, + {ui::kCursorRowResize, IDR_AURA_CURSOR_ROW_RESIZE, {11, 12}, {23, 23}}, + {ui::kCursorColumnResize, IDR_AURA_CURSOR_COL_RESIZE, {12, 11}, {25, 23}}, + {ui::kCursorEastWestResize, IDR_AURA_CURSOR_EAST_WEST_RESIZE, + {12, 11}, {25, 23}}, + {ui::kCursorNorthSouthResize, IDR_AURA_CURSOR_NORTH_SOUTH_RESIZE, + {11, 12}, {23, 23}}, + {ui::kCursorNorthEastSouthWestResize, + IDR_AURA_CURSOR_NORTH_EAST_SOUTH_WEST_RESIZE, {12, 11}, {25, 23}}, + {ui::kCursorNorthWestSouthEastResize, + IDR_AURA_CURSOR_NORTH_WEST_SOUTH_EAST_RESIZE, {11, 11}, {24, 23}}, + {ui::kCursorGrab, IDR_AURA_CURSOR_GRAB, {8, 5}, {16, 10}}, + {ui::kCursorGrabbing, IDR_AURA_CURSOR_GRABBING, {9, 9}, {18, 18}}, +}; + +const CursorData kAnimatedCursors[] = { + {ui::kCursorWait, IDR_THROBBER, {7, 7}, {14, 14}}, + {ui::kCursorProgress, IDR_THROBBER, {7, 7}, {14, 14}}, +}; + +} // namespace + +namespace ash { + +ImageCursors::ImageCursors() + : cursor_loader_(ui::CursorLoader::Create()) { +} + +ImageCursors::~ImageCursors() { +} + +float ImageCursors::GetDeviceScaleFactor() const { + return cursor_loader_->device_scale_factor(); +} + +void ImageCursors::SetDeviceScaleFactor(float device_scale_factor) { + if (GetDeviceScaleFactor() == device_scale_factor) + return; + + cursor_loader_->UnloadAll(); + cursor_loader_->set_device_scale_factor(device_scale_factor); + + for (size_t i = 0; i < arraysize(kImageCursors); ++i) { + const HotPoint& hot = device_scale_factor == 1.0f ? + kImageCursors[i].hot_1x : kImageCursors[i].hot_2x; + cursor_loader_->LoadImageCursor(kImageCursors[i].id, + kImageCursors[i].resource_id, + gfx::Point(hot.x, hot.y)); + } + for (size_t i = 0; i < arraysize(kAnimatedCursors); ++i) { + const HotPoint& hot = device_scale_factor == 1.0f ? + kAnimatedCursors[i].hot_1x : kAnimatedCursors[i].hot_2x; + cursor_loader_->LoadAnimatedCursor(kAnimatedCursors[i].id, + kAnimatedCursors[i].resource_id, + gfx::Point(hot.x, hot.y), + kAnimatedCursorFrameDelayMs); + } +} + +void ImageCursors::SetPlatformCursor(gfx::NativeCursor* cursor) { + cursor_loader_->SetPlatformCursor(cursor); +} + +} // namespace ash diff --git a/ash/wm/image_cursors.h b/ash/wm/image_cursors.h new file mode 100644 index 0000000..a1a7c41 --- /dev/null +++ b/ash/wm/image_cursors.h @@ -0,0 +1,43 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_WM_IMAGE_CURSORS_H_ +#define ASH_WM_IMAGE_CURSORS_H_ + +#include "ash/ash_export.h" +#include "base/memory/scoped_ptr.h" +#include "ui/gfx/native_widget_types.h" + +namespace ui { +class CursorLoader; +} + +namespace ash { + +// A utility class that provides cursors for NativeCursors for which we have +// image resources. +class ASH_EXPORT ImageCursors { + public: + ImageCursors(); + ~ImageCursors(); + + // Returns the device scale factor of cursors. + float GetDeviceScaleFactor() const; + + // Sets the device scale factor of the cursors with |device_scale_factor| and + // reloads the cursor images if necessary. + void SetDeviceScaleFactor(float device_scale_factor); + + // Sets the platform cursor based on the native type of |cursor|. + void SetPlatformCursor(gfx::NativeCursor* cursor); + + private: + scoped_ptr<ui::CursorLoader> cursor_loader_; + + DISALLOW_COPY_AND_ASSIGN(ImageCursors); +}; + +} // namespace ash + +#endif // ASH_WM_IMAGE_CURSORS_H_ diff --git a/ash/wm/toplevel_window_event_handler.cc b/ash/wm/toplevel_window_event_handler.cc index aa0f754..ce4be53 100644 --- a/ash/wm/toplevel_window_event_handler.cc +++ b/ash/wm/toplevel_window_event_handler.cc @@ -14,6 +14,7 @@ #include "base/message_loop.h" #include "base/run_loop.h" #include "ui/aura/client/aura_constants.h" +#include "ui/aura/client/cursor_client.h" #include "ui/aura/env.h" #include "ui/aura/root_window.h" #include "ui/aura/window.h" @@ -276,7 +277,10 @@ aura::client::WindowMoveResult ToplevelWindowEventHandler::RunMoveLoop( root_window, source->parent(), &drag_location); } CreateScopedWindowResizer(source, drag_location, HTCAPTION); - source->GetRootWindow()->SetCursor(ui::kCursorPointer); + aura::client::CursorClient* cursor_client = + aura::client::GetCursorClient(root_window); + if (cursor_client) + cursor_client->SetCursor(ui::kCursorPointer); #if !defined(OS_MACOSX) MessageLoopForUI* loop = MessageLoopForUI::current(); MessageLoop::ScopedNestableTaskAllower allow_nested(loop); |