diff --git a/app/src/main/java/com/limelight/Game.java b/app/src/main/java/com/limelight/Game.java index bfab6c8c..4ee27c87 100644 --- a/app/src/main/java/com/limelight/Game.java +++ b/app/src/main/java/com/limelight/Game.java @@ -452,7 +452,7 @@ public class Game extends Activity implements SurfaceHolder.Callback, else { touchContextMap[i] = new RelativeTouchContext(conn, i, REFERENCE_HORIZ_RES, REFERENCE_VERT_RES, - streamView); + streamView, prefConfig); } } @@ -1244,7 +1244,12 @@ public class Game extends Activity implements SurfaceHolder.Callback, short deltaY = (short)inputCaptureProvider.getRelativeAxisY(event); if (deltaX != 0 || deltaY != 0) { - conn.sendMouseMove(deltaX, deltaY); + if (prefConfig.absoluteMouseMode) { + conn.sendMouseMoveAsMousePosition(deltaX, deltaY, (short)view.getWidth(), (short)view.getHeight()); + } + else { + conn.sendMouseMove(deltaX, deltaY); + } } } else if ((eventSource & InputDevice.SOURCE_CLASS_POSITION) != 0) { diff --git a/app/src/main/java/com/limelight/binding/input/touch/RelativeTouchContext.java b/app/src/main/java/com/limelight/binding/input/touch/RelativeTouchContext.java index 2ed34c9d..ff0af071 100644 --- a/app/src/main/java/com/limelight/binding/input/touch/RelativeTouchContext.java +++ b/app/src/main/java/com/limelight/binding/input/touch/RelativeTouchContext.java @@ -5,6 +5,7 @@ import android.view.View; import com.limelight.nvstream.NvConnection; import com.limelight.nvstream.input.MouseButtonPacket; +import com.limelight.preferences.PreferenceConfiguration; import java.util.Timer; import java.util.TimerTask; @@ -30,6 +31,7 @@ public class RelativeTouchContext implements TouchContext { private final int referenceWidth; private final int referenceHeight; private final View targetView; + private final PreferenceConfiguration prefConfig; private static final int TAP_MOVEMENT_THRESHOLD = 20; private static final int TAP_DISTANCE_THRESHOLD = 25; @@ -39,13 +41,15 @@ public class RelativeTouchContext implements TouchContext { private static final int SCROLL_SPEED_FACTOR = 5; public RelativeTouchContext(NvConnection conn, int actionIndex, - int referenceWidth, int referenceHeight, View view) + int referenceWidth, int referenceHeight, + View view, PreferenceConfiguration prefConfig) { this.conn = conn; this.actionIndex = actionIndex; this.referenceWidth = referenceWidth; this.referenceHeight = referenceHeight; this.targetView = view; + this.prefConfig = prefConfig; } @Override @@ -258,7 +262,16 @@ public class RelativeTouchContext implements TouchContext { conn.sendMouseHighResScroll((short)(deltaY * SCROLL_SPEED_FACTOR)); } } else { - conn.sendMouseMove((short) deltaX, (short) deltaY); + if (prefConfig.absoluteMouseMode) { + conn.sendMouseMoveAsMousePosition( + (short) deltaX, + (short) deltaY, + (short) targetView.getWidth(), + (short) targetView.getHeight()); + } + else { + conn.sendMouseMove((short) deltaX, (short) deltaY); + } } // If the scaling factor ended up rounding deltas to zero, wait until they are diff --git a/app/src/main/java/com/limelight/preferences/PreferenceConfiguration.java b/app/src/main/java/com/limelight/preferences/PreferenceConfiguration.java index f9e02cc6..a1b7c361 100644 --- a/app/src/main/java/com/limelight/preferences/PreferenceConfiguration.java +++ b/app/src/main/java/com/limelight/preferences/PreferenceConfiguration.java @@ -44,6 +44,7 @@ public class PreferenceConfiguration { private static final String TOUCHSCREEN_TRACKPAD_PREF_STRING = "checkbox_touchscreen_trackpad"; private static final String LATENCY_TOAST_PREF_STRING = "checkbox_enable_post_stream_toast"; private static final String FRAME_PACING_PREF_STRING = "frame_pacing"; + private static final String ABSOLUTE_MOUSE_MODE_PREF_STRING = "checkbox_absolute_mouse_mode"; static final String DEFAULT_RESOLUTION = "1280x720"; static final String DEFAULT_FPS = "60"; @@ -73,6 +74,7 @@ public class PreferenceConfiguration { private static final String DEFAULT_AUDIO_CONFIG = "2"; // Stereo private static final boolean DEFAULT_LATENCY_TOAST = false; private static final String DEFAULT_FRAME_PACING = "latency"; + private static final boolean DEFAULT_ABSOLUTE_MOUSE_MODE = false; public static final int FORCE_H265_ON = -1; public static final int AUTOSELECT_H265 = 0; @@ -114,6 +116,7 @@ public class PreferenceConfiguration { public boolean touchscreenTrackpad; public MoonBridge.AudioConfiguration audioConfiguration; public int framePacing; + public boolean absoluteMouseMode; public static boolean isNativeResolution(int width, int height) { // It's not a native resolution if it matches an existing resolution option @@ -454,6 +457,7 @@ public class PreferenceConfiguration { config.flipFaceButtons = prefs.getBoolean(FLIP_FACE_BUTTONS_PREF_STRING, DEFAULT_FLIP_FACE_BUTTONS); config.touchscreenTrackpad = prefs.getBoolean(TOUCHSCREEN_TRACKPAD_PREF_STRING, DEFAULT_TOUCHSCREEN_TRACKPAD); config.enableLatencyToast = prefs.getBoolean(LATENCY_TOAST_PREF_STRING, DEFAULT_LATENCY_TOAST); + config.absoluteMouseMode = prefs.getBoolean(ABSOLUTE_MOUSE_MODE_PREF_STRING, DEFAULT_ABSOLUTE_MOUSE_MODE); return config; } diff --git a/app/src/main/java/com/limelight/preferences/StreamSettings.java b/app/src/main/java/com/limelight/preferences/StreamSettings.java index 61ccbd8d..4b1f36d8 100644 --- a/app/src/main/java/com/limelight/preferences/StreamSettings.java +++ b/app/src/main/java/com/limelight/preferences/StreamSettings.java @@ -222,6 +222,15 @@ public class StreamSettings extends Activity { } } + // Hide remote desktop mouse mode on pre-Oreo (which doesn't have pointer capture) + // and NVIDIA SHIELD devices (which support raw mouse input in pointer capture mode) + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O || + getActivity().getPackageManager().hasSystemFeature("com.nvidia.feature.shield")) { + PreferenceCategory category = + (PreferenceCategory) findPreference("category_input_settings"); + category.removePreference(findPreference("checkbox_absolute_mouse_mode")); + } + // Remove PiP mode on devices pre-Oreo, where the feature is not available (some low RAM devices), // and on Fire OS where it violates the Amazon App Store guidelines for some reason. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O || diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 400b4679..a17469c5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -180,6 +180,8 @@ Enabling this option may break right clicking on some buggy devices Flip face buttons Switches the face buttons A/B and X/Y for gamepads and the on-screen controls + Remote desktop optimized mouse mode + This can make mouse acceleration behave more naturally for remote desktop usage, but it is incompatible with many games. On-screen Controls Settings Show on-screen controls diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index c1ea6340..98ad679d 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -100,6 +100,11 @@ android:title="@string/title_checkbox_flip_face_buttons" android:summary="@string/summary_checkbox_flip_face_buttons" android:defaultValue="false" /> +