| Index: ash/display/display_manager.cc
|
| diff --git a/ash/display/display_manager.cc b/ash/display/display_manager.cc
|
| index fb4bd6eeb46e7be72f7b24226e2582cddc5da607..6fd818a5eb0f7c4878251c742ac3af3c47645b4b 100644
|
| --- a/ash/display/display_manager.cc
|
| +++ b/ash/display/display_manager.cc
|
| @@ -9,6 +9,7 @@
|
| #include <string>
|
| #include <vector>
|
|
|
| +#include "ash/accelerometer/accelerometer_controller.h"
|
| #include "ash/ash_switches.h"
|
| #include "ash/display/display_layout_store.h"
|
| #include "ash/display/screen_ash.h"
|
| @@ -28,6 +29,7 @@
|
| #include "ui/gfx/rect.h"
|
| #include "ui/gfx/screen.h"
|
| #include "ui/gfx/size_conversions.h"
|
| +#include "ui/gfx/vector3d_f.h"
|
|
|
| #if defined(USE_X11)
|
| #include "ui/base/x/x11_util.h"
|
| @@ -66,6 +68,10 @@ const float kUIScalesFor2x[] =
|
| const float kUIScalesFor1280[] = {0.5f, 0.625f, 0.8f, 1.0f, 1.125f };
|
| const float kUIScalesFor1366[] = {0.5f, 0.6f, 0.75f, 1.0f, 1.125f };
|
|
|
| +// The angle which the screen has to be rotated past before the display will
|
| +// rotate to match it (i.e. 45.0f is no stickiness).
|
| +const float kDisplayRotationStickyAngleDegrees = 60.0f;
|
| +
|
| struct DisplaySortFunctor {
|
| bool operator()(const gfx::Display& a, const gfx::Display& b) {
|
| return a.id() < b.id();
|
| @@ -969,6 +975,62 @@ void DisplayManager::CreateScreenForShutdown() const {
|
| }
|
| }
|
|
|
| +void DisplayManager::OnAccelerometerUpdated(const gfx::Vector3dF& base,
|
| + const gfx::Vector3dF& lid) {
|
| + gfx::Vector3dF lid_flattened(lid.x(), lid.y(), 0.0f);
|
| + float lid_flattened_length = lid_flattened.Length();
|
| + // When the lid is close to being flat, don't change rotation as it is too
|
| + // sensitive to slight movements.
|
| + if (lid_flattened_length < 0.3)
|
| + return;
|
| +
|
| + // The reference vector is the angle of gravity when the device is rotated
|
| + // clockwise by 45 degrees. Computing the angle between this vector and
|
| + // gravity we can easily determine the expected display rotation.
|
| + gfx::Vector3dF reference(-1.0f, 1.0f, 0.0f);
|
| +
|
| + // Set the down vector to match the expected direction of gravity given the
|
| + // last configured rotation. This is used to enforce a stickiness that the
|
| + // user must overcome to rotate the display and prevents frequent rotations
|
| + // when holding the device near 45 degrees.
|
| + gfx::Display::Rotation current_rotation =
|
| + GetDisplayInfo(gfx::Display::InternalDisplayId()).rotation();
|
| + gfx::Vector3dF down(0.0f, 0.0f, 0.0f);
|
| + if (current_rotation == gfx::Display::ROTATE_0)
|
| + down.set_x(-1.0f);
|
| + else if (current_rotation == gfx::Display::ROTATE_90)
|
| + down.set_y(1.0f);
|
| + else if (current_rotation == gfx::Display::ROTATE_180)
|
| + down.set_x(1.0f);
|
| + else
|
| + down.set_y(-1.0f);
|
| +
|
| + // Don't rotate if the screen has not passed the threshold.
|
| + float sticky_angle = acos(gfx::DotProduct(down, lid_flattened) /
|
| + down.Length() / lid_flattened_length) * 180.0 / 3.1415965;
|
| + if (sticky_angle < kDisplayRotationStickyAngleDegrees)
|
| + return;
|
| +
|
| + float angle = acos(gfx::DotProduct(reference, lid_flattened) /
|
| + reference.Length() / lid_flattened_length) * 180.0 / 3.1415965;
|
| +
|
| + gfx::Vector3dF cross(reference);
|
| + cross.Cross(lid);
|
| + float sign = gfx::DotProduct(cross, gfx::Vector3dF(0.0f, 0.0f, 1.0f));
|
| + if (sign < 0.0f)
|
| + angle = 360.0f - angle;
|
| +
|
| + gfx::Display::Rotation new_rotation = gfx::Display::ROTATE_90;
|
| + if (angle < 90.0f)
|
| + new_rotation = gfx::Display::ROTATE_0;
|
| + else if (angle < 180.0f)
|
| + new_rotation = gfx::Display::ROTATE_270;
|
| + else if (angle < 270.0f)
|
| + new_rotation = gfx::Display::ROTATE_180;
|
| +
|
| + SetDisplayRotation(gfx::Display::InternalDisplayId(), new_rotation);
|
| +}
|
| +
|
| gfx::Display* DisplayManager::FindDisplayForId(int64 id) {
|
| for (DisplayList::iterator iter = displays_.begin();
|
| iter != displays_.end(); ++iter) {
|
|
|