orientation: Correct handling of orientation on threshold
The old code gave a priority to portrait orientation, so that if rotation reached the portrait threshold, it switched straight away. This is problematic if the device you're dealing with isn't a mostly portrait phone, but a tablet that can be used in both orientations equally. Landscape thresholds and portrait thresholds can (and they do) overlap. In the overlapping area we should try to keep the previous orientation until that threshold has passed. [Bastien Nocera: Added test change]
This commit is contained in:
@@ -65,38 +65,42 @@ orientation_calc (OrientationUp prev,
|
|||||||
int in_x, int in_y, int in_z,
|
int in_x, int in_y, int in_z,
|
||||||
gdouble scale)
|
gdouble scale)
|
||||||
{
|
{
|
||||||
int rotation;
|
|
||||||
OrientationUp ret = prev;
|
OrientationUp ret = prev;
|
||||||
int x, y, z;
|
int x, y, z;
|
||||||
|
int portrait_rotation;
|
||||||
|
int landscape_rotation;
|
||||||
|
|
||||||
/* this code expects 1G ~= 256 */
|
/* this code expects 1G ~= 256 */
|
||||||
x = SCALE(in_x);
|
x = SCALE(in_x);
|
||||||
y = SCALE(in_y);
|
y = SCALE(in_y);
|
||||||
z = SCALE(in_z);
|
z = SCALE(in_z);
|
||||||
|
|
||||||
/* Portrait check */
|
portrait_rotation = round(atan2(x, sqrt(y * y + z * z)) * RADIANS_TO_DEGREES);
|
||||||
rotation = round(atan((double) x / sqrt(y * y + z * z)) * RADIANS_TO_DEGREES);
|
landscape_rotation = round(atan2(y, sqrt(x * x + z * z)) * RADIANS_TO_DEGREES);
|
||||||
|
|
||||||
if (abs(rotation) > THRESHOLD_PORTRAIT) {
|
/* Don't change orientation if we are on the common border of two thresholds */
|
||||||
ret = (rotation > 0) ? ORIENTATION_LEFT_UP : ORIENTATION_RIGHT_UP;
|
if (abs(portrait_rotation) > THRESHOLD_PORTRAIT && abs(landscape_rotation) > THRESHOLD_LANDSCAPE)
|
||||||
|
return prev;
|
||||||
|
|
||||||
|
/* Portrait check */
|
||||||
|
if (abs(portrait_rotation) > THRESHOLD_PORTRAIT) {
|
||||||
|
ret = (portrait_rotation > 0) ? ORIENTATION_LEFT_UP : ORIENTATION_RIGHT_UP;
|
||||||
|
|
||||||
/* Some threshold to switching between portrait modes */
|
/* Some threshold to switching between portrait modes */
|
||||||
if (prev == ORIENTATION_LEFT_UP || prev == ORIENTATION_RIGHT_UP) {
|
if (prev == ORIENTATION_LEFT_UP || prev == ORIENTATION_RIGHT_UP) {
|
||||||
if (abs(rotation) < SAME_AXIS_LIMIT) {
|
if (abs(portrait_rotation) < SAME_AXIS_LIMIT) {
|
||||||
ret = prev;
|
ret = prev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* Landscape check */
|
/* Landscape check */
|
||||||
rotation = round(atan((double) y / sqrt(x * x + z * z)) * RADIANS_TO_DEGREES);
|
if (abs(landscape_rotation) > THRESHOLD_LANDSCAPE) {
|
||||||
|
ret = (landscape_rotation > 0) ? ORIENTATION_BOTTOM_UP : ORIENTATION_NORMAL;
|
||||||
if (abs(rotation) > THRESHOLD_LANDSCAPE) {
|
|
||||||
ret = (rotation > 0) ? ORIENTATION_BOTTOM_UP : ORIENTATION_NORMAL;
|
|
||||||
|
|
||||||
/* Some threshold to switching between landscape modes */
|
/* Some threshold to switching between landscape modes */
|
||||||
if (prev == ORIENTATION_BOTTOM_UP || prev == ORIENTATION_NORMAL) {
|
if (prev == ORIENTATION_BOTTOM_UP || prev == ORIENTATION_NORMAL) {
|
||||||
if (abs(rotation) < SAME_AXIS_LIMIT) {
|
if (abs(landscape_rotation) < SAME_AXIS_LIMIT) {
|
||||||
ret = prev;
|
ret = prev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -68,9 +68,9 @@ test_orientation_threshold (void)
|
|||||||
OrientationUp expected;
|
OrientationUp expected;
|
||||||
} orientations[] = {
|
} orientations[] = {
|
||||||
{ 0, -ONEG, 0, ORIENTATION_NORMAL },
|
{ 0, -ONEG, 0, ORIENTATION_NORMAL },
|
||||||
{ 183, -ONEG, 0, ORIENTATION_LEFT_UP },
|
{ 183, -ONEG, 0, ORIENTATION_NORMAL },
|
||||||
{ 176, -ONEG, 0, ORIENTATION_NORMAL },
|
{ 176, -ONEG, 0, ORIENTATION_NORMAL },
|
||||||
{ 183, -ONEG, 0, ORIENTATION_LEFT_UP },
|
{ 183, -ONEG, 0, ORIENTATION_NORMAL },
|
||||||
};
|
};
|
||||||
guint i, num_failures;
|
guint i, num_failures;
|
||||||
OrientationUp prev;
|
OrientationUp prev;
|
||||||
|
Reference in New Issue
Block a user