From da756869a9672c77f1a30443aebe4cf399b17d7b Mon Sep 17 00:00:00 2001 From: alex Date: Mon, 20 Jul 2026 20:16:40 +0300 Subject: [PATCH] fix: fullscreen button did nothing in portrait on large screens Android 12L+ devices with sw >= 600dp (tablets, unfolded foldables like Galaxy Fold) ignore setRequestedOrientation(), so the screen rotation button silently failed when it tried to rotate to landscape instead of toggling fullscreen. Detect this case and toggle fullscreen directly, and skip the auto exit-fullscreen paths that rely on forced rotation. --- .../fragments/detail/VideoDetailFragment.java | 18 ++++++++++++------ .../java/org/schabi/newpipe/player/Player.java | 3 +++ .../org/schabi/newpipe/util/DeviceUtils.java | 13 +++++++++++++ 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java index 9e9695725..72be11cc6 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java @@ -263,8 +263,10 @@ public void onServiceConnected(final Player connectedPlayer, // let's make the video in fullscreen again checkLandscape(); } else if (player.isFullscreen() && !player.isVerticalVideo() - // Tablet UI has orientation-independent fullscreen - && !DeviceUtils.isTablet(activity)) { + // Tablet UI has orientation-independent fullscreen, + // large screens can't be rotated programmatically anyway + && !DeviceUtils.isTablet(activity) + && !DeviceUtils.isOrientationRequestIgnored(activity)) { // Device is in portrait orientation after rotation but UI is in fullscreen. // Return back to non-fullscreen state player.toggleFullscreen(); @@ -2286,13 +2288,17 @@ public void onScreenRotationButtonClicked() { final boolean isTablet = DeviceUtils.isTablet(activity); final boolean autoLocked = globalScreenOrientationLocked(activity); - // 1. 平板且(系统可自动旋转 或 当前已横),直接切播放器全屏/非全屏 - if (isTablet && (!autoLocked || isLandscape)) { + // 1. Tablet with auto-rotate enabled (or already in landscape): toggle player + // fullscreen directly. On large screens (sw >= 600dp, e.g. unfolded foldables) + // the system ignores setRequestedOrientation(), so rotating programmatically + // is impossible — toggle fullscreen directly there as well + if (isTablet && (!autoLocked || isLandscape) + || DeviceUtils.isOrientationRequestIgnored(requireContext())) { player.toggleFullscreen(); return; } - // 2. 手机 or 平板但系统锁定了自动旋转,就去真正设置屏幕方向 + // 2. Phone (or tablet with auto-rotate locked): actually change screen orientation if (!autoLocked) { if (isLandscape) { player.toggleFullscreen(); @@ -2300,7 +2306,7 @@ public void onScreenRotationButtonClicked() { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE); } } else { - // 系统锁定时,再用“强制模式”来切 + // Auto-rotate is locked, force the orientation change activity.setRequestedOrientation( isLandscape ? ActivityInfo.SCREEN_ORIENTATION_PORTRAIT diff --git a/app/src/main/java/org/schabi/newpipe/player/Player.java b/app/src/main/java/org/schabi/newpipe/player/Player.java index e8b1f6da3..bf9a10f7e 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -5002,6 +5002,9 @@ public void onVideoSizeChanged(@NonNull final VideoSize videoSize) { && service.isLandscape() == isVerticalVideo && !DeviceUtils.isTv(context) && !DeviceUtils.isTablet(context) + // can't rotate large screens programmatically, and with the + // fallback to toggleFullscreen() this would exit fullscreen + && !DeviceUtils.isOrientationRequestIgnored(context) && fragmentListener != null) { // set correct orientation fragmentListener.onScreenRotationButtonClicked(); diff --git a/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java b/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java index d6bd77e1c..3e4f422ca 100644 --- a/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java +++ b/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java @@ -170,6 +170,19 @@ public static boolean isTablet(@NonNull final Context context) { & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE; } + /** + * Whether the system ignores {@link android.app.Activity#setRequestedOrientation(int)}. + * + *

Since Android 12L, devices with a display at least 600dp wide (tablets, unfolded + * foldables) may ignore fixed-orientation requests; since Android 16 with targetSdk 36 + * this is guaranteed. On such screens fullscreen has to be toggled without trying to + * change the screen orientation.

+ */ + public static boolean isOrientationRequestIgnored(@NonNull final Context context) { + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S_V2 + && context.getResources().getConfiguration().smallestScreenWidthDp >= 600; + } + public static boolean isConfirmKey(final int keyCode) { switch (keyCode) { case KeyEvent.KEYCODE_DPAD_CENTER: