diff --git a/app/src/main/java/com/limelight/Game.java b/app/src/main/java/com/limelight/Game.java
index c4f69d18..0787a9f5 100644
--- a/app/src/main/java/com/limelight/Game.java
+++ b/app/src/main/java/com/limelight/Game.java
@@ -526,18 +526,55 @@ public class Game extends Activity implements SurfaceHolder.Callback,
}
private void setPreferredOrientationForCurrentDisplay() {
- // If the display is somewhat square and OSC is disabled, allow any orientation. Otherwise, request landscape.
- // The OSC code assumes a landscape display, so we force landscape if OSC is enabled.
Display display = getWindowManager().getDefaultDisplay();
- if (!prefConfig.onscreenController && PreferenceConfiguration.isSquarishScreen(display.getWidth(), display.getHeight())) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
- setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_USER);
+
+ // For semi-square displays, we use more complex logic to determine which orientation to use (if any)
+ if (PreferenceConfiguration.isSquarishScreen(display)) {
+ int desiredOrientation = Configuration.ORIENTATION_UNDEFINED;
+
+ // OSC doesn't properly support portrait displays, so don't use it in portrait mode by default
+ if (prefConfig.onscreenController) {
+ desiredOrientation = Configuration.ORIENTATION_LANDSCAPE;
+ }
+
+ // For native resolution, we will lock the orientation to the one that matches the specified resolution
+ if (PreferenceConfiguration.isNativeResolution(prefConfig.width, prefConfig.height)) {
+ if (prefConfig.width > prefConfig.height) {
+ desiredOrientation = Configuration.ORIENTATION_LANDSCAPE;
+ }
+ else {
+ desiredOrientation = Configuration.ORIENTATION_PORTRAIT;
+ }
+ }
+
+ if (desiredOrientation == Configuration.ORIENTATION_LANDSCAPE) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
+ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE);
+ }
+ else {
+ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
+ }
+ }
+ else if (desiredOrientation == Configuration.ORIENTATION_PORTRAIT) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
+ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT);
+ }
+ else {
+ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
+ }
}
else {
- setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
+ // If we don't have a reason to lock to portrait or landscape, allow any orientation
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
+ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_USER);
+ }
+ else {
+ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
+ }
}
}
else {
+ // For regular displays, we always request landscape
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE);
}
diff --git a/app/src/main/java/com/limelight/preferences/PreferenceConfiguration.java b/app/src/main/java/com/limelight/preferences/PreferenceConfiguration.java
index 42b76333..3e248564 100644
--- a/app/src/main/java/com/limelight/preferences/PreferenceConfiguration.java
+++ b/app/src/main/java/com/limelight/preferences/PreferenceConfiguration.java
@@ -5,6 +5,7 @@ import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Build;
import android.preference.PreferenceManager;
+import android.view.Display;
import com.limelight.nvstream.jni.MoonBridge;
@@ -158,6 +159,21 @@ public class PreferenceConfiguration {
return longDim / shortDim < 1.3f;
}
+ public static boolean isSquarishScreen(Display display) {
+ int width, height;
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ width = display.getMode().getPhysicalWidth();
+ height = display.getMode().getPhysicalHeight();
+ }
+ else {
+ width = display.getWidth();
+ height = display.getHeight();
+ }
+
+ return isSquarishScreen(width, height);
+ }
+
private static String convertFromLegacyResolutionString(String resString) {
if (resString.equalsIgnoreCase("360p")) {
return RES_360P;
diff --git a/app/src/main/java/com/limelight/preferences/StreamSettings.java b/app/src/main/java/com/limelight/preferences/StreamSettings.java
index 800aee33..b25510b8 100644
--- a/app/src/main/java/com/limelight/preferences/StreamSettings.java
+++ b/app/src/main/java/com/limelight/preferences/StreamSettings.java
@@ -106,7 +106,7 @@ public class StreamSettings extends Activity {
pref.setValue(value);
}
- private void addNativeResolutionEntry(int nativeWidth, int nativeHeight, boolean insetsRemoved) {
+ private void addNativeResolutionEntry(int nativeWidth, int nativeHeight, boolean insetsRemoved, boolean portrait) {
ListPreference pref = (ListPreference) findPreference(PreferenceConfiguration.RESOLUTION_PREF_STRING);
String newName;
@@ -118,6 +118,15 @@ public class StreamSettings extends Activity {
newName = getResources().getString(R.string.resolution_prefix_native);
}
+ if (PreferenceConfiguration.isSquarishScreen(nativeWidth, nativeHeight)) {
+ if (portrait) {
+ newName += " " + getResources().getString(R.string.resolution_prefix_native_portrait);
+ }
+ else {
+ newName += " " + getResources().getString(R.string.resolution_prefix_native_landscape);
+ }
+ }
+
newName += " ("+nativeWidth+"x"+nativeHeight+")";
String newValue = nativeWidth+"x"+nativeHeight;
@@ -147,6 +156,13 @@ public class StreamSettings extends Activity {
}
}
+ private void addNativeResolutionEntries(int nativeWidth, int nativeHeight, boolean insetsRemoved) {
+ addNativeResolutionEntry(nativeWidth, nativeHeight, insetsRemoved, false);
+ if (PreferenceConfiguration.isSquarishScreen(nativeWidth, nativeHeight)) {
+ addNativeResolutionEntry(nativeHeight, nativeWidth, insetsRemoved, true);
+ }
+ }
+
private void removeValue(String preferenceKey, String value, Runnable onMatched) {
int matchingCount = 0;
@@ -300,7 +316,7 @@ public class StreamSettings extends Activity {
int width = Math.max(metrics.widthPixels - widthInsets, metrics.heightPixels - heightInsets);
int height = Math.min(metrics.widthPixels - widthInsets, metrics.heightPixels - heightInsets);
- addNativeResolutionEntry(width, height, false);
+ addNativeResolutionEntries(width, height, false);
hasInsets = true;
}
}
@@ -325,7 +341,7 @@ public class StreamSettings extends Activity {
// unless they report greater than 4K resolutions.
if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEVISION) ||
(width > 3840 || height > 2160)) {
- addNativeResolutionEntry(width, height, hasInsets);
+ addNativeResolutionEntries(width, height, hasInsets);
}
if ((width >= 3840 || height >= 2160) && maxSupportedResW < 3840) {
@@ -435,7 +451,7 @@ public class StreamSettings extends Activity {
getActivity().getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
int width = Math.max(metrics.widthPixels, metrics.heightPixels);
int height = Math.min(metrics.widthPixels, metrics.heightPixels);
- addNativeResolutionEntry(width, height, false);
+ addNativeResolutionEntries(width, height, false);
}
else {
// On Android 4.1, we have to resort to reflection to invoke hidden APIs
@@ -446,7 +462,7 @@ public class StreamSettings extends Activity {
Method getRawWidthFunc = Display.class.getMethod("getRawWidth");
int width = (Integer) getRawWidthFunc.invoke(display);
int height = (Integer) getRawHeightFunc.invoke(display);
- addNativeResolutionEntry(Math.max(width, height), Math.min(width, height), false);
+ addNativeResolutionEntries(Math.max(width, height), Math.min(width, height), false);
} catch (Exception e) {
e.printStackTrace();
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index ed1827bd..73d664ae 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -152,6 +152,8 @@
Stretch video to full-screen
Native
Native Full-Screen
+ (Landscape)
+ (Portrait)
Audio Settings
Surround sound configuration