Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(201)

Side by Side Diff: ash/display/cursor_window_controller.cc

Issue 145313003: Implement cursor compositing mode on Ash (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Get rid of current_cursor_set_ and requested_cursor_set_ Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ash/display/cursor_window_controller.h"
6
7 #include "ash/shell.h"
8 #include "ui/aura/env.h"
9 #include "ui/aura/root_window.h"
10 #include "ui/aura/window_delegate.h"
11 #include "ui/base/cursor/cursors_aura.h"
12 #include "ui/base/hit_test.h"
13 #include "ui/base/resource/resource_bundle.h"
14 #include "ui/compositor/dip_util.h"
15 #include "ui/gfx/canvas.h"
16 #include "ui/gfx/display.h"
17 #include "ui/gfx/image/image_skia.h"
18 #include "ui/gfx/image/image_skia_operations.h"
19
20 namespace ash {
21 namespace internal {
22
23 class CursorWindowDelegate : public aura::WindowDelegate {
24 public:
25 CursorWindowDelegate() : is_cursor_compositing_enabled_(false) {}
26 virtual ~CursorWindowDelegate() {}
27
28 // aura::WindowDelegate overrides:
29 virtual gfx::Size GetMinimumSize() const OVERRIDE { return size_; }
30 virtual gfx::Size GetMaximumSize() const OVERRIDE { return size_; }
31 virtual void OnBoundsChanged(const gfx::Rect& old_bounds,
32 const gfx::Rect& new_bounds) OVERRIDE {}
33 virtual gfx::NativeCursor GetCursor(const gfx::Point& point) OVERRIDE {
34 return gfx::kNullCursor;
35 }
36 virtual int GetNonClientComponent(
37 const gfx::Point& point) const OVERRIDE {
38 return HTNOWHERE;
39 }
40 virtual bool ShouldDescendIntoChildForEventHandling(
41 aura::Window* child,
42 const gfx::Point& location) OVERRIDE {
43 return false;
44 }
45 virtual bool CanFocus() OVERRIDE { return false; }
46 virtual void OnCaptureLost() OVERRIDE {}
47 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
48 canvas->DrawImageInt(cursor_image_, 0, 0);
49 }
50 virtual void OnDeviceScaleFactorChanged(
51 float device_scale_factor) OVERRIDE {}
52 virtual void OnWindowDestroying() OVERRIDE {}
53 virtual void OnWindowDestroyed() OVERRIDE {}
54 virtual void OnWindowTargetVisibilityChanged(bool visible) OVERRIDE {}
55 virtual bool HasHitTestMask() const OVERRIDE { return false; }
56 virtual void GetHitTestMask(gfx::Path* mask) const OVERRIDE {}
57 virtual void DidRecreateLayer(ui::Layer* old_layer,
58 ui::Layer* new_layer) OVERRIDE {}
59
60 // Sets cursor compositing mode on/off.
61 void SetCursorCompositingEnabled(bool enabled) {
62 is_cursor_compositing_enabled_ = enabled;
63 }
64
65 // Sets the cursor image for the |display|'s scale factor.
66 void SetCursorImage(const gfx::ImageSkia& image,
67 const gfx::Display& display) {
68 float scale_factor = display.device_scale_factor();
69 const gfx::ImageSkiaRep& image_rep = image.GetRepresentation(scale_factor);
70 if (!is_cursor_compositing_enabled_) {
71 // Note that mirror window's scale factor is always 1.0f, therefore we
72 // need to take 2x's image and paint as if it's 1x image.
73 size_ = image_rep.pixel_size();
74 cursor_image_ = gfx::ImageSkia::CreateFrom1xBitmap(image_rep.sk_bitmap());
75 } else {
76 size_ = image.size();
77 cursor_image_ = gfx::ImageSkia(
78 gfx::ImageSkiaRep(image_rep.sk_bitmap(), scale_factor));
79 }
80 }
81
82 const gfx::Size size() const { return size_; }
83
84 private:
85 bool is_cursor_compositing_enabled_;
86 gfx::ImageSkia cursor_image_;
87 gfx::Size size_;
88
89 DISALLOW_COPY_AND_ASSIGN(CursorWindowDelegate);
90 };
91
92 CursorWindowController::CursorWindowController()
93 : is_cursor_compositing_enabled_(false),
94 container_(NULL),
95 cursor_type_(ui::kCursorNone),
96 cursor_set_(ui::CURSOR_SET_NORMAL),
97 cursor_rotation_(gfx::Display::ROTATE_0),
98 delegate_(new CursorWindowDelegate()) {
99 }
100
101 CursorWindowController::~CursorWindowController() {
102 SetContainer(NULL);
103 }
104
105 void CursorWindowController::SetCursorCompositingEnabled(bool enabled) {
106 if (is_cursor_compositing_enabled_ != enabled) {
107 is_cursor_compositing_enabled_ = enabled;
108 delegate_->SetCursorCompositingEnabled(enabled);
109 UpdateCursorImage();
110 }
111 }
112
113 void CursorWindowController::SetContainer(aura::Window* container) {
114 if (container_ == container)
115 return;
116
117 container_ = container;
118 if (!container) {
119 cursor_window_.reset();
120 return;
121 }
122
123 if (!cursor_window_) {
124 cursor_window_.reset(new aura::Window(delegate_.get()));
125 cursor_window_->SetTransparent(true);
126 cursor_window_->Init(aura::WINDOW_LAYER_TEXTURED);
127 cursor_window_->set_ignore_events(true);
128 cursor_window_->set_owned_by_parent(false);
129 }
130
131 container->AddChild(cursor_window_.get());
132 cursor_window_->Show();
133 SetBoundsInScreen(container->bounds());
134 }
135
136 void CursorWindowController::SetBoundsInScreen(const gfx::Rect& bounds) {
137 bounds_in_screen_ = bounds;
138 UpdateLocation();
139 }
140
141 void CursorWindowController::UpdateLocation() {
142 if (!cursor_window_)
143 return;
144
145 gfx::Point point = aura::Env::GetInstance()->last_mouse_location();
146 if (!is_cursor_compositing_enabled_) {
147 Shell::GetPrimaryRootWindow()->GetDispatcher()->host()->ConvertPointToHost(
148 &point);
149 } else {
150 point.Offset(-bounds_in_screen_.x(), -bounds_in_screen_.y());
151 }
152 point.Offset(-hot_point_.x(), -hot_point_.y());
153 gfx::Rect bounds = cursor_window_->bounds();
154 bounds.set_origin(point);
155 cursor_window_->SetBounds(bounds);
156 }
157
158 void CursorWindowController::SetCursor(gfx::NativeCursor cursor) {
159 const gfx::Display& display = Shell::GetScreen()->GetPrimaryDisplay();
160 if (cursor_type_ == cursor.native_type() &&
161 cursor_rotation_ == display.rotation())
162 return;
163 cursor_type_ = cursor.native_type();
164 cursor_rotation_ = display.rotation();
165 UpdateCursorImage();
166 }
167
168 void CursorWindowController::SetCursorSet(ui::CursorSetType cursor_set) {
169 cursor_set_ = cursor_set;
170 UpdateCursorImage();
171 }
172
173 void CursorWindowController::SetVisibility(bool visible) {
174 if (!cursor_window_)
175 return;
176 if (visible)
177 cursor_window_->Show();
178 else
179 cursor_window_->Hide();
180 }
181
182 void CursorWindowController::UpdateCursorImage() {
183 const gfx::Display& display = Shell::GetScreen()->GetPrimaryDisplay();
oshima 2014/02/05 23:43:39 hmm, this looks wrong. I guess you need to use cur
hshi1 2014/02/06 00:48:44 Done.
184 int resource_id;
185 // TODO(hshi): support custom cursor set.
186 bool success = ui::GetCursorDataFor(
187 cursor_set_,
188 cursor_type_,
189 display.device_scale_factor(),
190 &resource_id,
191 &hot_point_);
192 if (!success)
193 return;
194 const gfx::ImageSkia* image =
195 ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id);
196 gfx::ImageSkia rotated = *image;
197 if (!is_cursor_compositing_enabled_) {
198 switch (cursor_rotation_) {
199 case gfx::Display::ROTATE_0:
200 break;
201 case gfx::Display::ROTATE_90:
202 rotated = gfx::ImageSkiaOperations::CreateRotatedImage(
203 *image, SkBitmapOperations::ROTATION_90_CW);
204 hot_point_.SetPoint(
205 rotated.width() - hot_point_.y(),
206 hot_point_.x());
207 break;
208 case gfx::Display::ROTATE_180:
209 rotated = gfx::ImageSkiaOperations::CreateRotatedImage(
210 *image, SkBitmapOperations::ROTATION_180_CW);
211 hot_point_.SetPoint(
212 rotated.height() - hot_point_.x(),
213 rotated.width() - hot_point_.y());
214 break;
215 case gfx::Display::ROTATE_270:
216 rotated = gfx::ImageSkiaOperations::CreateRotatedImage(
217 *image, SkBitmapOperations::ROTATION_270_CW);
218 hot_point_.SetPoint(
219 hot_point_.y(),
220 rotated.height() - hot_point_.x());
221 break;
222 }
223 } else {
224 hot_point_ = ui::ConvertPointToDIP(Shell::GetPrimaryRootWindow()->layer(),
225 hot_point_);
226 }
227 delegate_->SetCursorImage(rotated, display);
228 if (cursor_window_) {
229 cursor_window_->SetBounds(gfx::Rect(delegate_->size()));
230 cursor_window_->SchedulePaintInRect(
231 gfx::Rect(cursor_window_->bounds().size()));
232 UpdateLocation();
233 }
234 }
235
236 } // namespace internal
237 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698