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" />
+