Merge pull request #8316 from han-sz/fix_video_mouse_hover_overlay
Fix persistent hover overlay when in desktop/DeX mode or using a mouse/non-touch input
This commit is contained in:
commit
627c6e29a2
|
@ -642,19 +642,7 @@ public final class VideoDetailFragment
|
||||||
? View.VISIBLE
|
? View.VISIBLE
|
||||||
: View.GONE
|
: View.GONE
|
||||||
);
|
);
|
||||||
|
accommodateForTvAndDesktopMode();
|
||||||
if (DeviceUtils.isTv(getContext())) {
|
|
||||||
// remove ripple effects from detail controls
|
|
||||||
final int transparent = ContextCompat.getColor(requireContext(),
|
|
||||||
R.color.transparent_background_color);
|
|
||||||
binding.detailControlsPlaylistAppend.setBackgroundColor(transparent);
|
|
||||||
binding.detailControlsBackground.setBackgroundColor(transparent);
|
|
||||||
binding.detailControlsPopup.setBackgroundColor(transparent);
|
|
||||||
binding.detailControlsDownload.setBackgroundColor(transparent);
|
|
||||||
binding.detailControlsShare.setBackgroundColor(transparent);
|
|
||||||
binding.detailControlsOpenInBrowser.setBackgroundColor(transparent);
|
|
||||||
binding.detailControlsPlayWithKodi.setBackgroundColor(transparent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -2118,6 +2106,30 @@ public final class VideoDetailFragment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make changes to the UI to accommodate for better usability on bigger screens such as TVs
|
||||||
|
* or in Android's desktop mode (DeX etc).
|
||||||
|
*/
|
||||||
|
private void accommodateForTvAndDesktopMode() {
|
||||||
|
if (DeviceUtils.isTv(getContext())) {
|
||||||
|
// remove ripple effects from detail controls
|
||||||
|
final int transparent = ContextCompat.getColor(requireContext(),
|
||||||
|
R.color.transparent_background_color);
|
||||||
|
binding.detailControlsPlaylistAppend.setBackgroundColor(transparent);
|
||||||
|
binding.detailControlsBackground.setBackgroundColor(transparent);
|
||||||
|
binding.detailControlsPopup.setBackgroundColor(transparent);
|
||||||
|
binding.detailControlsDownload.setBackgroundColor(transparent);
|
||||||
|
binding.detailControlsShare.setBackgroundColor(transparent);
|
||||||
|
binding.detailControlsOpenInBrowser.setBackgroundColor(transparent);
|
||||||
|
binding.detailControlsPlayWithKodi.setBackgroundColor(transparent);
|
||||||
|
}
|
||||||
|
if (DeviceUtils.isDesktopMode(getContext())) {
|
||||||
|
// Remove the "hover" overlay (since it is visible on all mouse events and interferes
|
||||||
|
// with the video content being played)
|
||||||
|
binding.detailThumbnailRootLayout.setForeground(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void checkLandscape() {
|
private void checkLandscape() {
|
||||||
if ((!player.isPlaying() && player.getPlayQueue() != playQueue)
|
if ((!player.isPlaying() && player.getPlayQueue() != playQueue)
|
||||||
|| player.getPlayQueue() == null) {
|
|| player.getPlayQueue() == null) {
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
package org.schabi.newpipe.util;
|
package org.schabi.newpipe.util;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.app.UiModeManager;
|
import android.app.UiModeManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
|
import android.hardware.input.InputManager;
|
||||||
import android.os.BatteryManager;
|
import android.os.BatteryManager;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
|
import android.view.InputDevice;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.WindowInsets;
|
import android.view.WindowInsets;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
@ -22,6 +25,10 @@ import androidx.preference.PreferenceManager;
|
||||||
import org.schabi.newpipe.App;
|
import org.schabi.newpipe.App;
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import static android.content.Context.INPUT_SERVICE;
|
||||||
|
|
||||||
public final class DeviceUtils {
|
public final class DeviceUtils {
|
||||||
|
|
||||||
private static final String AMAZON_FEATURE_FIRE_TV = "amazon.hardware.fire_tv";
|
private static final String AMAZON_FEATURE_FIRE_TV = "amazon.hardware.fire_tv";
|
||||||
|
@ -84,6 +91,78 @@ public final class DeviceUtils {
|
||||||
return DeviceUtils.isTV;
|
return DeviceUtils.isTV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the device is in desktop or DeX mode. This function should only
|
||||||
|
* be invoked once on view load as it is using reflection for the DeX checks.
|
||||||
|
* @param context the context to use for services and config.
|
||||||
|
* @return true if the Android device is in desktop mode or using DeX.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("JavaReflectionMemberAccess")
|
||||||
|
public static boolean isDesktopMode(@NonNull final Context context) {
|
||||||
|
// Adapted from https://stackoverflow.com/a/64615568
|
||||||
|
// to check for all input devices that have an active cursor
|
||||||
|
final InputManager im = (InputManager) context.getSystemService(INPUT_SERVICE);
|
||||||
|
for (final int id : im.getInputDeviceIds()) {
|
||||||
|
final InputDevice inputDevice = im.getInputDevice(id);
|
||||||
|
if (inputDevice.supportsSource(InputDevice.SOURCE_BLUETOOTH_STYLUS)
|
||||||
|
|| inputDevice.supportsSource(InputDevice.SOURCE_MOUSE)
|
||||||
|
|| inputDevice.supportsSource(InputDevice.SOURCE_STYLUS)
|
||||||
|
|| inputDevice.supportsSource(InputDevice.SOURCE_TOUCHPAD)
|
||||||
|
|| inputDevice.supportsSource(InputDevice.SOURCE_TRACKBALL)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final UiModeManager uiModeManager =
|
||||||
|
ContextCompat.getSystemService(context, UiModeManager.class);
|
||||||
|
if (uiModeManager != null
|
||||||
|
&& uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_DESK) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeX check for standalone and multi-window mode, from:
|
||||||
|
// https://developer.samsung.com/samsung-dex/modify-optimizing.html
|
||||||
|
try {
|
||||||
|
final Configuration config = context.getResources().getConfiguration();
|
||||||
|
final Class<?> configClass = config.getClass();
|
||||||
|
final int semDesktopModeEnabledConst =
|
||||||
|
configClass.getField("SEM_DESKTOP_MODE_ENABLED").getInt(configClass);
|
||||||
|
final int currentMode =
|
||||||
|
configClass.getField("semDesktopModeEnabled").getInt(config);
|
||||||
|
if (semDesktopModeEnabledConst == currentMode) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (final NoSuchFieldException | IllegalAccessException ignored) {
|
||||||
|
// Device doesn't seem to support DeX
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("WrongConstant") final Object desktopModeManager = context
|
||||||
|
.getApplicationContext()
|
||||||
|
.getSystemService("desktopmode");
|
||||||
|
|
||||||
|
if (desktopModeManager != null) {
|
||||||
|
try {
|
||||||
|
final Method getDesktopModeStateMethod = desktopModeManager.getClass()
|
||||||
|
.getDeclaredMethod("getDesktopModeState");
|
||||||
|
final Object desktopModeState = getDesktopModeStateMethod
|
||||||
|
.invoke(desktopModeManager);
|
||||||
|
final Class<?> desktopModeStateClass = desktopModeState.getClass();
|
||||||
|
final Method getEnabledMethod = desktopModeStateClass
|
||||||
|
.getDeclaredMethod("getEnabled");
|
||||||
|
final int enabledStatus = (int) getEnabledMethod.invoke(desktopModeState);
|
||||||
|
if (enabledStatus == desktopModeStateClass
|
||||||
|
.getDeclaredField("ENABLED").getInt(desktopModeStateClass)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (final Exception ignored) {
|
||||||
|
// Device does not support DeX 3.0 or something went wrong when trying to determine
|
||||||
|
// if it supports this feature
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isTablet(@NonNull final Context context) {
|
public static boolean isTablet(@NonNull final Context context) {
|
||||||
final String tabletModeSetting = PreferenceManager.getDefaultSharedPreferences(context)
|
final String tabletModeSetting = PreferenceManager.getDefaultSharedPreferences(context)
|
||||||
.getString(context.getString(R.string.tablet_mode_key), "");
|
.getString(context.getString(R.string.tablet_mode_key), "");
|
||||||
|
|
Loading…
Reference in New Issue