mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-08-02 23:26:43 -04:00
Merge pull request #51 from AngelAuraMC/fix/revert-forced-grabbing
fix(Pointer/Capture): Make non-opportunistic grabbing opt-in
This commit is contained in:
commit
974a039c07
@ -1,6 +1,7 @@
|
||||
package net.kdt.pojavlaunch;
|
||||
|
||||
import static net.kdt.pojavlaunch.MainActivity.touchCharInput;
|
||||
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_MOUSE_GRAB_FORCE;
|
||||
import static net.kdt.pojavlaunch.utils.MCOptionUtils.getMcScale;
|
||||
import static org.lwjgl.glfw.CallbackBridge.sendMouseButton;
|
||||
import static org.lwjgl.glfw.CallbackBridge.windowHeight;
|
||||
@ -193,6 +194,13 @@ public class MinecraftGLSurface extends View implements GrabListener, DirectGame
|
||||
if(toolType == MotionEvent.TOOL_TYPE_MOUSE) {
|
||||
if(Tools.isAndroid8OrHigher() &&
|
||||
mPointerCapture != null) {
|
||||
// Can't handleAutomaticCapture if mouse isn't captured
|
||||
if (!CallbackBridge.isGrabbing() // Only capture if not in menu and user said so
|
||||
&& !PREF_MOUSE_GRAB_FORCE) {
|
||||
// This returns true but we really can't consume this.
|
||||
// Else we don't receive ACTION_MOVE
|
||||
return !dispatchGenericMotionEvent(e);
|
||||
}
|
||||
mPointerCapture.handleAutomaticCapture();
|
||||
return true;
|
||||
}
|
||||
@ -241,9 +249,9 @@ public class MinecraftGLSurface extends View implements GrabListener, DirectGame
|
||||
|
||||
// Make sure we grabbed the mouse if necessary
|
||||
updateGrabState(CallbackBridge.isGrabbing());
|
||||
|
||||
switch(event.getActionMasked()) {
|
||||
case MotionEvent.ACTION_HOVER_MOVE:
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
CallbackBridge.mouseX = (event.getX(mouseCursorIndex) * LauncherPreferences.PREF_SCALE_FACTOR);
|
||||
CallbackBridge.mouseY = (event.getY(mouseCursorIndex) * LauncherPreferences.PREF_SCALE_FACTOR);
|
||||
CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY);
|
||||
|
@ -35,6 +35,7 @@ import android.provider.OpenableColumns;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.InputDevice;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.EditText;
|
||||
@ -1557,4 +1558,19 @@ public final class Tools {
|
||||
}
|
||||
return Integer.parseInt(iVersionArray[0] + iVersionArray[1] + iVersionArray[2]);
|
||||
}
|
||||
|
||||
public static boolean isPointerDeviceConnected() {
|
||||
int[] deviceIds = InputDevice.getDeviceIds();
|
||||
for (int id : deviceIds) {
|
||||
InputDevice device = InputDevice.getDevice(id);
|
||||
if (device == null) continue;
|
||||
int sources = device.getSources();
|
||||
if ((sources & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE
|
||||
|| (sources & InputDevice.SOURCE_TOUCHPAD) == InputDevice.SOURCE_TOUCHPAD
|
||||
|| (sources & InputDevice.SOURCE_TRACKBALL) == InputDevice.SOURCE_TRACKBALL) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,20 @@
|
||||
package net.kdt.pojavlaunch.customcontrols.mouse;
|
||||
|
||||
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.DEFAULT_PREF;
|
||||
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_MOUSE_GRAB_FORCE;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.view.InputDevice;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewTreeObserver;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import net.kdt.pojavlaunch.GrabListener;
|
||||
import net.kdt.pojavlaunch.MinecraftGLSurface;
|
||||
import net.kdt.pojavlaunch.Tools;
|
||||
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
|
||||
@ -15,7 +22,7 @@ import net.kdt.pojavlaunch.prefs.LauncherPreferences;
|
||||
import org.lwjgl.glfw.CallbackBridge;
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
public class AndroidPointerCapture implements ViewTreeObserver.OnWindowFocusChangeListener, View.OnCapturedPointerListener {
|
||||
public class AndroidPointerCapture implements ViewTreeObserver.OnWindowFocusChangeListener, View.OnCapturedPointerListener, GrabListener, SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
private static final float TOUCHPAD_SCROLL_THRESHOLD = 1;
|
||||
private final AbstractTouchpad mTouchpad;
|
||||
private final View mHostView;
|
||||
@ -32,14 +39,46 @@ public class AndroidPointerCapture implements ViewTreeObserver.OnWindowFocusChan
|
||||
this.mHostView = hostView;
|
||||
hostView.setOnCapturedPointerListener(this);
|
||||
hostView.getViewTreeObserver().addOnWindowFocusChangeListener(this);
|
||||
DEFAULT_PREF.registerOnSharedPreferenceChangeListener(this);
|
||||
if (!PREF_MOUSE_GRAB_FORCE)
|
||||
CallbackBridge.addGrabListener(this);
|
||||
}
|
||||
|
||||
private void enableTouchpadIfNecessary() {
|
||||
if(!mTouchpad.getDisplayState()) mTouchpad.enable(true);
|
||||
if(!mTouchpad.getDisplayState() && PREF_MOUSE_GRAB_FORCE) mTouchpad.enable(true);
|
||||
}
|
||||
|
||||
// Needed so it releases the cursor when inside game menu
|
||||
@Override
|
||||
public void onGrabState(boolean isGrabbing) {
|
||||
updateCursorState(isGrabbing);
|
||||
}
|
||||
// It's only here so the side-dialog changes it live
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, @Nullable String key) {
|
||||
updateCursorState(CallbackBridge.isGrabbing());
|
||||
}
|
||||
private void updateCursorState(boolean isGrabbing) {
|
||||
if (!isGrabbing // Only capture if not in menu and user said so
|
||||
&& !PREF_MOUSE_GRAB_FORCE) {
|
||||
mHostView.releasePointerCapture(); // Release the capture since user said so
|
||||
}
|
||||
// Capture the pointer when not inside a menu
|
||||
// So user doesn't have to click to get rid of cursor
|
||||
handleAutomaticCapture();
|
||||
}
|
||||
|
||||
public void handleAutomaticCapture() {
|
||||
if(!mHostView.hasWindowFocus()) {
|
||||
if (!CallbackBridge.isGrabbing() // Only capture if not in menu and user said so
|
||||
&& !PREF_MOUSE_GRAB_FORCE) {
|
||||
mTouchpad.disable();
|
||||
return;
|
||||
}
|
||||
if (mHostView.hasPointerCapture()) {
|
||||
enableTouchpadIfNecessary();
|
||||
return;
|
||||
}
|
||||
if (!mHostView.hasWindowFocus()) {
|
||||
mHostView.requestFocus();
|
||||
} else {
|
||||
mHostView.requestPointerCapture();
|
||||
@ -128,7 +167,11 @@ public class AndroidPointerCapture implements ViewTreeObserver.OnWindowFocusChan
|
||||
|
||||
@Override
|
||||
public void onWindowFocusChanged(boolean hasFocus) {
|
||||
if(hasFocus && Tools.isAndroid8OrHigher()) mHostView.requestPointerCapture();
|
||||
if (!CallbackBridge.isGrabbing() // Only capture if not in menu and user said so
|
||||
&& !PREF_MOUSE_GRAB_FORCE) {
|
||||
return;
|
||||
}
|
||||
if (hasFocus && Tools.isAndroid8OrHigher()) mHostView.requestPointerCapture();
|
||||
}
|
||||
|
||||
public void detach() {
|
||||
|
@ -132,7 +132,7 @@ public class Touchpad extends View implements GrabListener, AbstractTouchpad {
|
||||
public void enable(boolean supposed) {
|
||||
if(mDisplayState) return;
|
||||
mDisplayState = true;
|
||||
if(supposed && CallbackBridge.isGrabbing()) return;
|
||||
if(supposed && CallbackBridge.isGrabbing() && LauncherPreferences.PREF_MOUSE_GRAB_FORCE) return;
|
||||
_enable();
|
||||
}
|
||||
|
||||
|
@ -72,6 +72,8 @@ public class LauncherPreferences {
|
||||
public static boolean PREF_FORCE_ENABLE_TOUCHCONTROLLER = false;
|
||||
public static int PREF_TOUCHCONTROLLER_VIBRATE_LENGTH = 100;
|
||||
|
||||
public static boolean PREF_MOUSE_GRAB_FORCE = false;
|
||||
|
||||
|
||||
public static void loadPreferences(Context ctx) {
|
||||
//Required for CTRLDEF_FILE and MultiRT
|
||||
@ -114,6 +116,7 @@ public class LauncherPreferences {
|
||||
PREF_VSYNC_IN_ZINK = DEFAULT_PREF.getBoolean("vsync_in_zink", true);
|
||||
PREF_FORCE_ENABLE_TOUCHCONTROLLER = DEFAULT_PREF.getBoolean("forceEnableTouchController", false);
|
||||
PREF_TOUCHCONTROLLER_VIBRATE_LENGTH = DEFAULT_PREF.getInt("touchControllerVibrateLength", 100);
|
||||
PREF_MOUSE_GRAB_FORCE = DEFAULT_PREF.getBoolean("always_grab_mouse", false);
|
||||
|
||||
String argLwjglLibname = "-Dorg.lwjgl.opengl.libname=";
|
||||
for (String arg : JREUtils.parseJavaArguments(PREF_CUSTOM_JAVA_ARGS)) {
|
||||
|
@ -7,6 +7,7 @@ import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_GYRO_INVERT_Y;
|
||||
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_GYRO_SENSITIVITY;
|
||||
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_LONGPRESS_TRIGGER;
|
||||
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_MOUSESPEED;
|
||||
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_MOUSE_GRAB_FORCE;
|
||||
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_SCALE_FACTOR;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
@ -31,11 +32,11 @@ public abstract class QuickSettingSideDialog extends com.kdt.SideDialogView {
|
||||
|
||||
private SharedPreferences.Editor mEditor;
|
||||
@SuppressLint("UseSwitchCompatOrMaterialCode")
|
||||
private Switch mGyroSwitch, mGyroXSwitch, mGyroYSwitch, mGestureSwitch;
|
||||
private Switch mGyroSwitch, mGyroXSwitch, mGyroYSwitch, mGestureSwitch, mMouseGrabSwitch;
|
||||
private CustomSeekbar mGyroSensitivityBar, mMouseSpeedBar, mGestureDelayBar, mResolutionBar;
|
||||
private TextView mGyroSensitivityText, mGyroSensitivityDisplayText, mMouseSpeedText, mGestureDelayText, mGestureDelayDisplayText, mResolutionText;
|
||||
|
||||
private boolean mOriginalGyroEnabled, mOriginalGyroXEnabled, mOriginalGyroYEnabled, mOriginalGestureDisabled;
|
||||
private boolean mOriginalGyroEnabled, mOriginalGyroXEnabled, mOriginalGyroYEnabled, mOriginalGestureDisabled, mOriginalMouseGrab;
|
||||
private float mOriginalGyroSensitivity, mOriginalMouseSpeed, mOriginalResolution;
|
||||
private int mOriginalGestureDelay;
|
||||
|
||||
@ -65,6 +66,7 @@ public abstract class QuickSettingSideDialog extends com.kdt.SideDialogView {
|
||||
mGyroXSwitch = mDialogContent.findViewById(R.id.checkboxGyroX);
|
||||
mGyroYSwitch = mDialogContent.findViewById(R.id.checkboxGyroY);
|
||||
mGestureSwitch = mDialogContent.findViewById(R.id.checkboxGesture);
|
||||
mMouseGrabSwitch = mDialogContent.findViewById(R.id.always_grab_mouse_side_dialog);
|
||||
|
||||
mGyroSensitivityBar = mDialogContent.findViewById(R.id.editGyro_seekbar);
|
||||
mMouseSpeedBar = mDialogContent.findViewById(R.id.editMouseSpeed_seekbar);
|
||||
@ -86,6 +88,7 @@ public abstract class QuickSettingSideDialog extends com.kdt.SideDialogView {
|
||||
mOriginalGyroXEnabled = PREF_GYRO_INVERT_X;
|
||||
mOriginalGyroYEnabled = PREF_GYRO_INVERT_Y;
|
||||
mOriginalGestureDisabled = PREF_DISABLE_GESTURES;
|
||||
mOriginalMouseGrab = PREF_MOUSE_GRAB_FORCE;
|
||||
|
||||
mOriginalGyroSensitivity = PREF_GYRO_SENSITIVITY;
|
||||
mOriginalMouseSpeed = PREF_MOUSESPEED;
|
||||
@ -96,6 +99,7 @@ public abstract class QuickSettingSideDialog extends com.kdt.SideDialogView {
|
||||
mGyroXSwitch.setChecked(mOriginalGyroXEnabled);
|
||||
mGyroYSwitch.setChecked(mOriginalGyroYEnabled);
|
||||
mGestureSwitch.setChecked(mOriginalGestureDisabled);
|
||||
mMouseGrabSwitch.setChecked(mOriginalMouseGrab);
|
||||
|
||||
mGyroSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
PREF_ENABLE_GYRO = isChecked;
|
||||
@ -122,6 +126,11 @@ public abstract class QuickSettingSideDialog extends com.kdt.SideDialogView {
|
||||
mEditor.putBoolean("disableGestures", isChecked);
|
||||
});
|
||||
|
||||
mMouseGrabSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
PREF_MOUSE_GRAB_FORCE = isChecked;
|
||||
mEditor.putBoolean("always_grab_mouse", isChecked);
|
||||
});
|
||||
|
||||
mGyroSensitivityBar.setOnSeekBarChangeListener((SimpleSeekBarListener) (seekBar, progress, fromUser) -> {
|
||||
PREF_GYRO_SENSITIVITY = progress / 100f;
|
||||
mEditor.putInt("gyroSensitivity", progress);
|
||||
@ -156,6 +165,7 @@ public abstract class QuickSettingSideDialog extends com.kdt.SideDialogView {
|
||||
setSeekTextPercent(mResolutionText, mResolutionBar.getProgress());
|
||||
|
||||
|
||||
updateMouseGrabVisibility();
|
||||
updateGyroVisibility(mOriginalGyroEnabled);
|
||||
updateGestureVisibility(mOriginalGestureDisabled);
|
||||
}
|
||||
@ -172,6 +182,10 @@ public abstract class QuickSettingSideDialog extends com.kdt.SideDialogView {
|
||||
target.setText(target.getContext().getString(format, value));
|
||||
}
|
||||
|
||||
private void updateMouseGrabVisibility(){
|
||||
mMouseGrabSwitch.setVisibility(Tools.isPointerDeviceConnected()? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
private void updateGyroVisibility(boolean isEnabled) {
|
||||
int visibility = isEnabled ? View.VISIBLE : View.GONE;
|
||||
mGyroXSwitch.setVisibility(visibility);
|
||||
@ -202,6 +216,7 @@ public abstract class QuickSettingSideDialog extends com.kdt.SideDialogView {
|
||||
mGyroXSwitch.setOnCheckedChangeListener(null);
|
||||
mGyroYSwitch.setOnCheckedChangeListener(null);
|
||||
mGestureSwitch.setOnCheckedChangeListener(null);
|
||||
mMouseGrabSwitch.setOnCheckedChangeListener(null);
|
||||
|
||||
mGyroSensitivityBar.setOnSeekBarChangeListener(null);
|
||||
mMouseSpeedBar.setOnSeekBarChangeListener(null);
|
||||
@ -225,6 +240,7 @@ public abstract class QuickSettingSideDialog extends com.kdt.SideDialogView {
|
||||
PREF_GYRO_INVERT_X = mOriginalGyroXEnabled;
|
||||
PREF_GYRO_INVERT_Y = mOriginalGyroYEnabled;
|
||||
PREF_DISABLE_GESTURES = mOriginalGestureDisabled;
|
||||
PREF_MOUSE_GRAB_FORCE = mOriginalMouseGrab;
|
||||
|
||||
PREF_GYRO_SENSITIVITY = mOriginalGyroSensitivity;
|
||||
PREF_MOUSESPEED = mOriginalMouseSpeed;
|
||||
|
@ -202,4 +202,15 @@
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/editGestureDelay_textView" />
|
||||
|
||||
<Switch
|
||||
android:id="@+id/always_grab_mouse_side_dialog"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/_36sdp"
|
||||
android:text="@string/mcl_setting_title_grab_mouse"
|
||||
|
||||
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/editGestureDelay_seekbar"
|
||||
tools:ignore="UseSwitchCompatOrMaterialXml" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -171,6 +171,8 @@
|
||||
<string name="mcl_disable_swap_hand_subtitle">Disables double tapping on the hotbar item to swap it in the second hand.</string>
|
||||
<string name="mcl_setting_title_mousespeed">Mouse Speed</string>
|
||||
<string name="mcl_setting_subtitle_mousespeed">Changes the speed of the virtual mouse.</string>
|
||||
<string name="mcl_setting_title_grab_mouse">Use virtual cursor</string>
|
||||
<string name="mcl_setting_subtitle_grab_mouse">Ensures the cursor stays inside the game. Prevents mouse from clicking touch control layout.</string>
|
||||
<string name="customctrl_passthru">Mouse pass-thru</string>
|
||||
<string name="customctrl_swipeable">Swipeable</string>
|
||||
<string name="customctrl_forward_lock">Forward lock</string>
|
||||
|
@ -97,6 +97,11 @@
|
||||
android:title="@string/preference_mouse_start_title"
|
||||
android:summary="@string/preference_mouse_start_description"
|
||||
/>
|
||||
<SwitchPreference
|
||||
android:key="always_grab_mouse"
|
||||
android:title="@string/mcl_setting_title_grab_mouse"
|
||||
android:summary="@string/mcl_setting_subtitle_grab_mouse"
|
||||
android:defaultValue="false"/>
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
|
Loading…
x
Reference in New Issue
Block a user