Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 37 additions & 13 deletions app/src/main/java/com/limelight/Game.java
Original file line number Diff line number Diff line change
Expand Up @@ -1826,18 +1826,41 @@ else if (event.getAction() == MotionEvent.ACTION_UP) {
// dealing with a stylus without hover support, our position might be
// significantly different than before.
if (inputCaptureProvider.eventHasRelativeMouseAxes(event)) {
// Send the deltas straight from the motion event
short deltaX = (short)inputCaptureProvider.getRelativeAxisX(event);
short deltaY = (short)inputCaptureProvider.getRelativeAxisY(event);

if (deltaX != 0 || deltaY != 0) {
if (prefConfig.absoluteMouseMode) {
// NB: view may be null, but we can unconditionally use streamView because we don't need to adjust
// relative axis deltas for the position of the streamView within the parent's coordinate system.
conn.sendMouseMoveAsMousePosition(deltaX, deltaY, (short)streamView.getWidth(), (short)streamView.getHeight());
float rawX = inputCaptureProvider.getRelativeAxisX(event);
float rawY = inputCaptureProvider.getRelativeAxisY(event);

// Some keyboard trackpads (e.g. Samsung Galaxy Tab S11 Ultra Pro Keyboard)
// report AXIS_RELATIVE_X/Y rotated 90° clockwise: the driver sends physical-Y
// as AXIS_RELATIVE_X and physical-X as AXIS_RELATIVE_Y. Correcting means
// reading Y as X and negating the new Y.
if (prefConfig.rotateTouchpadAxes && eventSource == InputDevice.SOURCE_TOUCHPAD) {
float tmp = rawX;
rawX = rawY;
rawY = -tmp;
}

// Samsung keyboard trackpads send two-finger scroll as ACTION_MOVE with
// getPointerCount() == 2, using the same REL_X/REL_Y axes as cursor movement
// rather than ACTION_SCROLL with AXIS_VSCROLL/HSCROLL.
if (eventSource == InputDevice.SOURCE_TOUCHPAD && event.getPointerCount() == 2) {
if (rawX != 0 || rawY != 0) {
int scrollDir = prefConfig.naturalScroll ? 1 : -1;
conn.sendMouseHighResScroll((short)(rawY * 10 * scrollDir));
conn.sendMouseHighResHScroll((short)(-rawX * 10 * scrollDir));
}
else {
conn.sendMouseMove(deltaX, deltaY);
} else {
short deltaX = (short) rawX;
short deltaY = (short) rawY;

if (deltaX != 0 || deltaY != 0) {
if (prefConfig.absoluteMouseMode) {
// NB: view may be null, but we can unconditionally use streamView because we don't need to adjust
// relative axis deltas for the position of the streamView within the parent's coordinate system.
conn.sendMouseMoveAsMousePosition(deltaX, deltaY, (short)streamView.getWidth(), (short)streamView.getHeight());
}
else {
conn.sendMouseMove(deltaX, deltaY);
}
}
}
}
Expand Down Expand Up @@ -1878,8 +1901,9 @@ else if (view != null) {

if (event.getActionMasked() == MotionEvent.ACTION_SCROLL) {
// Send the vertical scroll packet
conn.sendMouseHighResScroll((short)(event.getAxisValue(MotionEvent.AXIS_VSCROLL) * 120));
conn.sendMouseHighResHScroll((short)(event.getAxisValue(MotionEvent.AXIS_HSCROLL) * 120));
int scrollDir = prefConfig.naturalScroll ? -1 : 1;
conn.sendMouseHighResScroll((short)(event.getAxisValue(MotionEvent.AXIS_VSCROLL) * 120 * scrollDir));
conn.sendMouseHighResHScroll((short)(event.getAxisValue(MotionEvent.AXIS_HSCROLL) * 120 * scrollDir));
}

if ((changedButtons & MotionEvent.BUTTON_PRIMARY) != 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ public enum AnalogStickForScrolling {
private static final String GAMEPAD_TOUCHPAD_AS_MOUSE_PREF_STRING = "checkbox_gamepad_touchpad_as_mouse";
private static final String GAMEPAD_MOTION_SENSORS_PREF_STRING = "checkbox_gamepad_motion_sensors";
private static final String GAMEPAD_MOTION_FALLBACK_PREF_STRING = "checkbox_gamepad_motion_fallback";
private static final String ROTATE_TOUCHPAD_AXES_PREF_STRING = "checkbox_rotate_touchpad_axes";
private static final String NATURAL_SCROLL_PREF_STRING = "checkbox_natural_scroll";

static final String DEFAULT_RESOLUTION = "1280x720";
static final String DEFAULT_FPS = "60";
Expand Down Expand Up @@ -108,6 +110,8 @@ public enum AnalogStickForScrolling {
private static final boolean DEFAULT_GAMEPAD_TOUCHPAD_AS_MOUSE = false;
private static final boolean DEFAULT_GAMEPAD_MOTION_SENSORS = true;
private static final boolean DEFAULT_GAMEPAD_MOTION_FALLBACK = false;
private static final boolean DEFAULT_ROTATE_TOUCHPAD_AXES = false;
private static final boolean DEFAULT_NATURAL_SCROLL = false;

public static final int FRAME_PACING_MIN_LATENCY = 0;
public static final int FRAME_PACING_BALANCED = 1;
Expand Down Expand Up @@ -155,6 +159,8 @@ public enum AnalogStickForScrolling {
public boolean gamepadMotionSensors;
public boolean gamepadTouchpadAsMouse;
public boolean gamepadMotionSensorsFallbackToDevice;
public boolean rotateTouchpadAxes;
public boolean naturalScroll;

public static boolean isNativeResolution(int width, int height) {
// It's not a native resolution if it matches an existing resolution option
Expand Down Expand Up @@ -601,6 +607,8 @@ else if (audioConfig.equals("51")) {
config.gamepadTouchpadAsMouse = prefs.getBoolean(GAMEPAD_TOUCHPAD_AS_MOUSE_PREF_STRING, DEFAULT_GAMEPAD_TOUCHPAD_AS_MOUSE);
config.gamepadMotionSensors = prefs.getBoolean(GAMEPAD_MOTION_SENSORS_PREF_STRING, DEFAULT_GAMEPAD_MOTION_SENSORS);
config.gamepadMotionSensorsFallbackToDevice = prefs.getBoolean(GAMEPAD_MOTION_FALLBACK_PREF_STRING, DEFAULT_GAMEPAD_MOTION_FALLBACK);
config.rotateTouchpadAxes = prefs.getBoolean(ROTATE_TOUCHPAD_AXES_PREF_STRING, DEFAULT_ROTATE_TOUCHPAD_AXES);
config.naturalScroll = prefs.getBoolean(NATURAL_SCROLL_PREF_STRING, DEFAULT_NATURAL_SCROLL);

return config;
}
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,10 @@
<string name="summary_checkbox_touchscreen_trackpad">If enabled, the touchscreen acts like a trackpad. If disabled, the touchscreen directly controls the mouse cursor.</string>
<string name="title_checkbox_absolute_mouse_mode">Remote desktop mouse mode</string>
<string name="summary_checkbox_absolute_mouse_mode">This can make mouse acceleration behave more naturally for remote desktop usage, but it is incompatible with many games.</string>
<string name="title_checkbox_rotate_touchpad_axes">Rotate external trackpad axes</string>
<string name="summary_checkbox_rotate_touchpad_axes">Enable if your keyboard trackpad moves the cursor in the wrong direction (e.g. up/down movement causes left/right movement). Fixes devices like the Samsung Galaxy Tab Pro Keyboard.</string>
<string name="title_checkbox_natural_scroll">Invert scroll direction</string>
<string name="summary_checkbox_natural_scroll">Reverses the scroll direction for trackpad and mouse scroll wheel.</string>
<string name="title_checkbox_mouse_nav_buttons">Enable back and forward mouse buttons</string>
<string name="summary_checkbox_mouse_nav_buttons">Enabling this option may break right clicking on some buggy devices</string>

Expand Down
10 changes: 10 additions & 0 deletions app/src/main/res/xml/preferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,16 @@
android:title="@string/title_checkbox_absolute_mouse_mode"
android:summary="@string/summary_checkbox_absolute_mouse_mode"
android:defaultValue="false" />
<CheckBoxPreference
android:key="checkbox_rotate_touchpad_axes"
android:title="@string/title_checkbox_rotate_touchpad_axes"
android:summary="@string/summary_checkbox_rotate_touchpad_axes"
android:defaultValue="false" />
<CheckBoxPreference
android:key="checkbox_natural_scroll"
android:title="@string/title_checkbox_natural_scroll"
android:summary="@string/summary_checkbox_natural_scroll"
android:defaultValue="false" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/category_on_screen_controls_settings"
android:key="category_onscreen_controls">
Expand Down