Commit db821e71 authored by oshima@chromium.org's avatar oshima@chromium.org

2x Cursor support.

BUG=110394
TEST=manual

Review URL: https://chromiumcodereview.appspot.com/10399118

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@138354 0039d316-1c4b-4281-b951-d872f2087c98
parent 603e1f39
......@@ -265,7 +265,7 @@
},
],
}],
['OS != "mac" and enable_hidpi == 1', {
['(OS != "mac" and enable_hidpi == 1) or chromeos == 1', {
'copies': [
{
'destination': '<(PRODUCT_DIR)',
......
......@@ -584,6 +584,18 @@ void RootWindow::OnCompositingEnded(ui::Compositor*) {
}
}
////////////////////////////////////////////////////////////////////////////////
// RootWindow, ui::LayerDelegate implementation:
void RootWindow::OnDeviceScaleFactorChanged(
float device_scale_factor) {
if (cursor_shown_)
ShowCursor(false);
host_->OnDeviceScaleFactorChanged(device_scale_factor);
Window::OnDeviceScaleFactorChanged(device_scale_factor);
if (cursor_shown_)
ShowCursor(true);
}
////////////////////////////////////////////////////////////////////////////////
// RootWindow, private:
......
......@@ -259,6 +259,9 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
virtual void OnCompositingStarted(ui::Compositor*) OVERRIDE;
virtual void OnCompositingEnded(ui::Compositor*) OVERRIDE;
// Overridden from ui::LayerDelegate:
virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE;
private:
friend class Window;
friend class CompositorLock;
......
......@@ -99,6 +99,9 @@ class RootWindowHost {
#if !defined(OS_MACOSX)
virtual void PostNativeEvent(const base::NativeEvent& native_event) = 0;
#endif
// Called when the device scale factor of the root window has chagned.
virtual void OnDeviceScaleFactorChanged(float device_scale_factor) = 0;
};
} // namespace aura
......
......@@ -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 std::max;
using std::min;
......@@ -295,13 +296,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);
......@@ -320,19 +354,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_,
scale_factor_,
&actual_scale);
// We never use scaled cursor, but the following DCHECK fails
// because the method above computes 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);
};
......@@ -639,6 +686,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() {
......@@ -871,6 +920,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).
......@@ -883,11 +937,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);
}
......
......@@ -54,6 +54,7 @@ class RootWindowHostLinux : public RootWindowHost,
const gfx::Rect& snapshot_bounds,
std::vector<unsigned char>* png_representation) OVERRIDE;
virtual void PostNativeEvent(const base::NativeEvent& event) OVERRIDE;
virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE;
// Returns true if there's an X window manager present... in most cases. Some
// window managers (notably, ion3) don't implement enough of ICCCM for us to
......
......@@ -293,6 +293,11 @@ void RootWindowHostWin::PostNativeEvent(const base::NativeEvent& native_event) {
hwnd(), native_event.message, native_event.wParam, native_event.lParam);
}
void RootWindowHostWin::OnDeviceScaleFactorChanged(
float device_scale_factor) {
NOTIMPLEMENTED();
}
void RootWindowHostWin::OnClose() {
// TODO: this obviously shouldn't be here.
MessageLoopForUI::current()->Quit();
......
......@@ -43,6 +43,7 @@ class RootWindowHostWin : public RootWindowHost, public ui::WindowImpl {
const gfx::Rect& snapshot_bounds,
std::vector<unsigned char>* png_representation) OVERRIDE;
virtual void PostNativeEvent(const base::NativeEvent& native_event) OVERRIDE;
virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE;
private:
BEGIN_MSG_MAP_EX(RootWindowHostWin)
......
......@@ -335,6 +335,9 @@ class AURA_EXPORT Window : public ui::LayerDelegate,
// Type of a function to delete a property that this window owns.
typedef void (*PropertyDeallocator)(intptr_t value);
// Overridden from ui::LayerDelegate:
virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE;
private:
friend class LayoutManager;
......@@ -395,7 +398,6 @@ class AURA_EXPORT Window : public ui::LayerDelegate,
// Overridden from ui::LayerDelegate:
virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE;
virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE;
// Updates the layer name with a name based on the window's name and id.
void UpdateLayerName(const std::string& name);
......
......@@ -40,6 +40,8 @@ void ResourceBundle::LoadCommonResources() {
ResourceHandle::kScaleFactor100x);
AddDataPack(GetResourcesPakFilePath("ui_resources_standard.pak"),
ResourceHandle::kScaleFactor100x);
AddDataPack(GetResourcesPakFilePath("ui_resources_2x.pak"),
ResourceHandle::kScaleFactor200x);
}
}
......
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