Index: ui/aura/root_window_host_linux.cc |
diff --git a/ui/aura/root_window_host_linux.cc b/ui/aura/root_window_host_linux.cc |
index 864ebb71a572996052e2f85661d793bb7da5fe9d..c69d92679eb2f93650afb9f4122ec70c6e962dc4 100644 |
--- a/ui/aura/root_window_host_linux.cc |
+++ b/ui/aura/root_window_host_linux.cc |
@@ -33,6 +33,7 @@ |
#include "ui/compositor/layer.h" |
#include "ui/gfx/codec/png_codec.h" |
#include "ui/gfx/image/image.h" |
+#include "ui/gfx/image/image_skia.h" |
using ui::X11AtomCache; |
using std::max; |
@@ -296,13 +297,46 @@ bool ShouldSendCharEventForKeyboardCode(ui::KeyboardCode keycode) { |
// image resources. |
class RootWindowHostLinux::ImageCursors { |
public: |
- ImageCursors() { |
- LoadImageCursor(ui::kCursorNoDrop, IDR_AURA_CURSOR_NO_DROP); |
- LoadImageCursor(ui::kCursorCopy, IDR_AURA_CURSOR_COPY); |
+ ImageCursors() : scale_factor_(0.0) { |
+ } |
+ |
+ void Reload(float scale_factor) { |
+ if (scale_factor_ == scale_factor) |
+ return; |
+ scale_factor_ = scale_factor; |
+ UnloadAll(); |
+ // The cursor's hot points are defined in chromeos's |
+ // src/platforms/assets/cursors/*.cfg files. |
+ LoadImageCursor(ui::kCursorNull, IDR_AURA_CURSOR_PTR, 9, 5); |
+ LoadImageCursor(ui::kCursorPointer, IDR_AURA_CURSOR_PTR, 9, 5); |
+ LoadImageCursor(ui::kCursorNoDrop, IDR_AURA_CURSOR_NO_DROP, 9, 5); |
+ LoadImageCursor(ui::kCursorCopy, IDR_AURA_CURSOR_COPY, 9, 5); |
+ LoadImageCursor(ui::kCursorHand, IDR_AURA_CURSOR_HAND, 9, 4); |
+ LoadImageCursor(ui::kCursorMove, IDR_AURA_CURSOR_MOVE, 12, 12); |
+ LoadImageCursor(ui::kCursorNorthEastResize, |
+ IDR_AURA_CURSOR_NORTH_EAST_RESIZE, 12, 11); |
+ LoadImageCursor(ui::kCursorSouthWestResize, |
+ IDR_AURA_CURSOR_SOUTH_WEST_RESIZE, 12, 11); |
+ LoadImageCursor(ui::kCursorSouthEastResize, |
+ IDR_AURA_CURSOR_SOUTH_EAST_RESIZE, 11, 11); |
+ LoadImageCursor(ui::kCursorNorthWestResize, |
+ IDR_AURA_CURSOR_NORTH_WEST_RESIZE, 11, 11); |
+ LoadImageCursor(ui::kCursorNorthResize, |
+ IDR_AURA_CURSOR_NORTH_RESIZE, 11, 10); |
+ LoadImageCursor(ui::kCursorSouthResize, |
+ IDR_AURA_CURSOR_SOUTH_RESIZE, 11, 10); |
+ LoadImageCursor(ui::kCursorEastResize, IDR_AURA_CURSOR_EAST_RESIZE, 11, 11); |
+ LoadImageCursor(ui::kCursorWestResize, IDR_AURA_CURSOR_WEST_RESIZE, 11, 11); |
+ LoadImageCursor(ui::kCursorIBeam, IDR_AURA_CURSOR_IBEAM, 12, 11); |
+ |
// TODO (varunjain): add more cursors once we have assets. |
} |
~ImageCursors() { |
+ UnloadAll(); |
+ } |
+ |
+ void UnloadAll() { |
std::map<int, Cursor>::const_iterator it; |
for (it = cursors_.begin(); it != cursors_.end(); ++it) |
ui::UnrefCustomXCursor(it->second); |
@@ -321,19 +355,32 @@ class RootWindowHostLinux::ImageCursors { |
private: |
// Creates an X Cursor from an image resource and puts it in the cursor map. |
- void LoadImageCursor(int id, int resource_id) { |
- const SkBitmap* bitmap = |
- ui::ResourceBundle::GetSharedInstance().GetImageNamed( |
- resource_id).ToSkBitmap(); |
- |
- XcursorImage* image = ui::SkBitmapToXcursorImage(bitmap, gfx::Point(0, 0)); |
- cursors_[id] = ui::CreateReffedCustomXCursor(image); |
+ void LoadImageCursor(int id, int resource_id, int hot_x, int hot_y) { |
+ const gfx::ImageSkia* image = |
+ ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id); |
+ float actual_scale = 0; |
+ const SkBitmap& bitmap = image->GetBitmapForScale(scale_factor_, |
sky
2012/05/22 19:49:12
nit: you have two spaces here.
oshima
2012/05/22 19:53:08
oops, fixed. Thanks
|
+ scale_factor_, |
+ &actual_scale); |
+ // We never use scaled cursor, but the following DCHECK fails |
+ // because the method above coputes the actual scale from the image |
+ // size instead of obtaining from the resource data, and the some |
+ // of cursors are indeed not 2x size of the 2x images. |
+ // TODO(oshima): Fix this and enable the following DCHECK. |
+ // DCHECK_EQ(actual_scale, scale_factor_); |
+ XcursorImage* x_image = |
+ ui::SkBitmapToXcursorImage(&bitmap, gfx::Point(0, 0)); |
+ x_image->xhot = hot_x * actual_scale; |
+ x_image->yhot = hot_y * actual_scale; |
+ cursors_[id] = ui::CreateReffedCustomXCursor(x_image); |
// |bitmap| is owned by the resource bundle. So we do not need to free it. |
} |
// A map to hold all image cursors. It maps the cursor ID to the X Cursor. |
std::map<int, Cursor> cursors_; |
+ float scale_factor_; |
+ |
DISALLOW_COPY_AND_ASSIGN(ImageCursors); |
}; |
@@ -640,6 +687,8 @@ bool RootWindowHostLinux::Dispatch(const base::NativeEvent& event) { |
void RootWindowHostLinux::SetRootWindow(RootWindow* root_window) { |
root_window_ = root_window; |
+ // The device scale factor is now accessible, so load cursors now. |
+ image_cursors_->Reload(root_window_->layer()->device_scale_factor()); |
} |
RootWindow* RootWindowHostLinux::GetRootWindow() { |
@@ -872,6 +921,11 @@ void RootWindowHostLinux::PostNativeEvent( |
XSendEvent(xdisplay_, xwindow_, False, 0, &xevent); |
} |
+void RootWindowHostLinux::OnDeviceScaleFactorChanged( |
+ float device_scale_factor) { |
+ image_cursors_->Reload(device_scale_factor); |
+} |
+ |
bool RootWindowHostLinux::IsWindowManagerPresent() { |
// Per ICCCM 2.8, "Manager Selections", window managers should take ownership |
// of WM_Sn selections (where n is a screen number). |
@@ -884,11 +938,9 @@ void RootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) { |
::Cursor xcursor = |
image_cursors_->IsImageCursor(cursor) ? |
image_cursors_->ImageCursorFromNative(cursor) : |
- cursor == ui::kCursorNone ? |
- invisible_cursor_ : |
- cursor == ui::kCursorCustom ? |
- cursor.platform() : |
- ui::GetXCursor(CursorShapeFromNative(cursor)); |
+ (cursor == ui::kCursorNone ? invisible_cursor_ : |
+ (cursor == ui::kCursorCustom ? cursor.platform() : |
+ ui::GetXCursor(CursorShapeFromNative(cursor)))); |
XDefineCursor(xdisplay_, xwindow_, xcursor); |
} |