From bb5fbcc2f9b4d110675b8e4efadb05a8eb6e5944 Mon Sep 17 00:00:00 2001 From: Nikita Malyavin Date: Sat, 10 Aug 2019 03:51:21 +1000 Subject: [PATCH] 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] --- src/orientation.c | 26 +++++++++++++++----------- src/test-orientation.c | 4 ++-- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/orientation.c b/src/orientation.c index c843a79..05ab7eb 100644 --- a/src/orientation.c +++ b/src/orientation.c @@ -65,38 +65,42 @@ orientation_calc (OrientationUp prev, int in_x, int in_y, int in_z, gdouble scale) { - int rotation; OrientationUp ret = prev; int x, y, z; + int portrait_rotation; + int landscape_rotation; /* this code expects 1G ~= 256 */ x = SCALE(in_x); y = SCALE(in_y); z = SCALE(in_z); - /* Portrait check */ - rotation = round(atan((double) x / sqrt(y * y + z * z)) * RADIANS_TO_DEGREES); + portrait_rotation = round(atan2(x, sqrt(y * y + z * z)) * RADIANS_TO_DEGREES); + landscape_rotation = round(atan2(y, sqrt(x * x + z * z)) * RADIANS_TO_DEGREES); + + /* Don't change orientation if we are on the common border of two thresholds */ + if (abs(portrait_rotation) > THRESHOLD_PORTRAIT && abs(landscape_rotation) > THRESHOLD_LANDSCAPE) + return prev; - if (abs(rotation) > THRESHOLD_PORTRAIT) { - ret = (rotation > 0) ? ORIENTATION_LEFT_UP : ORIENTATION_RIGHT_UP; + /* 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 */ if (prev == ORIENTATION_LEFT_UP || prev == ORIENTATION_RIGHT_UP) { - if (abs(rotation) < SAME_AXIS_LIMIT) { + if (abs(portrait_rotation) < SAME_AXIS_LIMIT) { ret = prev; } } } else { /* Landscape check */ - rotation = round(atan((double) y / sqrt(x * x + z * z)) * RADIANS_TO_DEGREES); - - if (abs(rotation) > THRESHOLD_LANDSCAPE) { - ret = (rotation > 0) ? ORIENTATION_BOTTOM_UP : ORIENTATION_NORMAL; + if (abs(landscape_rotation) > THRESHOLD_LANDSCAPE) { + ret = (landscape_rotation > 0) ? ORIENTATION_BOTTOM_UP : ORIENTATION_NORMAL; /* Some threshold to switching between landscape modes */ if (prev == ORIENTATION_BOTTOM_UP || prev == ORIENTATION_NORMAL) { - if (abs(rotation) < SAME_AXIS_LIMIT) { + if (abs(landscape_rotation) < SAME_AXIS_LIMIT) { ret = prev; } } diff --git a/src/test-orientation.c b/src/test-orientation.c index 3ec1b46..145106f 100644 --- a/src/test-orientation.c +++ b/src/test-orientation.c @@ -68,9 +68,9 @@ test_orientation_threshold (void) OrientationUp expected; } orientations[] = { { 0, -ONEG, 0, ORIENTATION_NORMAL }, - { 183, -ONEG, 0, ORIENTATION_LEFT_UP }, + { 183, -ONEG, 0, ORIENTATION_NORMAL }, { 176, -ONEG, 0, ORIENTATION_NORMAL }, - { 183, -ONEG, 0, ORIENTATION_LEFT_UP }, + { 183, -ONEG, 0, ORIENTATION_NORMAL }, }; guint i, num_failures; OrientationUp prev;