Skip to content

Commit 1e0aa74

Browse files
committed
fix(Pointer/Capture): Make non-opportunistic grabbing opt-in
Adds a new config option whether or not you want your mouse to be able to click your touch controls! Default is you can! Should also now let DeX users get their cursor out of the window by just moving it by default. This reverts commit 7631e3c.
1 parent 9c15bba commit 1e0aa74

6 files changed

Lines changed: 84 additions & 6 deletions

File tree

app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import android.util.ArrayMap;
3636
import android.util.DisplayMetrics;
3737
import android.util.Log;
38+
import android.view.InputDevice;
3839
import android.view.View;
3940
import android.view.WindowManager;
4041
import android.widget.EditText;
@@ -1506,5 +1507,18 @@ public static void hasNoOnlineProfileDialog(Activity activity, String customTitl
15061507
hasNoOnlineProfileDialog(activity, null, customTitle, customMessage);
15071508
}
15081509

1509-
1510+
public static boolean isPointerDeviceConnected() {
1511+
int[] deviceIds = InputDevice.getDeviceIds();
1512+
for (int id : deviceIds) {
1513+
InputDevice device = InputDevice.getDevice(id);
1514+
if (device == null) continue;
1515+
int sources = device.getSources();
1516+
if ((sources & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE
1517+
|| (sources & InputDevice.SOURCE_TOUCHPAD) == InputDevice.SOURCE_TOUCHPAD
1518+
|| (sources & InputDevice.SOURCE_TRACKBALL) == InputDevice.SOURCE_TRACKBALL) {
1519+
return true;
1520+
}
1521+
}
1522+
return false;
1523+
}
15101524
}

app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/mouse/AndroidPointerCapture.java

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
package net.kdt.pojavlaunch.customcontrols.mouse;
22

3+
import android.content.SharedPreferences;
34
import android.os.Build;
45
import android.view.InputDevice;
56
import android.view.MotionEvent;
67
import android.view.View;
78
import android.view.ViewTreeObserver;
89

10+
import androidx.annotation.Nullable;
911
import androidx.annotation.RequiresApi;
1012

13+
import net.kdt.pojavlaunch.GrabListener;
1114
import net.kdt.pojavlaunch.MinecraftGLSurface;
1215
import net.kdt.pojavlaunch.Tools;
1316
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
1417

1518
import org.lwjgl.glfw.CallbackBridge;
1619

1720
@RequiresApi(api = Build.VERSION_CODES.O)
18-
public class AndroidPointerCapture implements ViewTreeObserver.OnWindowFocusChangeListener, View.OnCapturedPointerListener {
21+
public class AndroidPointerCapture implements ViewTreeObserver.OnWindowFocusChangeListener, View.OnCapturedPointerListener, GrabListener, SharedPreferences.OnSharedPreferenceChangeListener {
1922
private static final float TOUCHPAD_SCROLL_THRESHOLD = 1;
2023
private final AbstractTouchpad mTouchpad;
2124
private final View mHostView;
@@ -32,14 +35,44 @@ public AndroidPointerCapture(AbstractTouchpad touchpad, View hostView) {
3235
this.mHostView = hostView;
3336
hostView.setOnCapturedPointerListener(this);
3437
hostView.getViewTreeObserver().addOnWindowFocusChangeListener(this);
38+
if (!LauncherPreferences.DEFAULT_PREF.getBoolean("always_grab_mouse", false))
39+
CallbackBridge.addGrabListener(this);
3540
}
3641

3742
private void enableTouchpadIfNecessary() {
38-
if(!mTouchpad.getDisplayState()) mTouchpad.enable(true);
43+
if(!mTouchpad.getDisplayState() && !Tools.isPointerDeviceConnected()) mTouchpad.enable(true);
44+
}
45+
46+
// Needed so it releases the cursor when inside game menu
47+
@Override
48+
public void onGrabState(boolean isGrabbing) {
49+
updateCursorState(isGrabbing);
50+
}
51+
// It's only here so the side-dialog changes it live
52+
@Override
53+
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, @Nullable String key) {
54+
updateCursorState(CallbackBridge.isGrabbing());
55+
}
56+
private void updateCursorState(boolean isGrabbing) {
57+
if (!isGrabbing // Only capture if not in menu and user said so
58+
&& !LauncherPreferences.DEFAULT_PREF.getBoolean("always_grab_mouse", false)) {
59+
mHostView.releasePointerCapture(); // Release the capture since user said so
60+
}
61+
// Capture the pointer when not inside a menu
62+
// So user doesn't have to click to get rid of cursor
63+
handleAutomaticCapture();
3964
}
4065

4166
public void handleAutomaticCapture() {
42-
if(!mHostView.hasWindowFocus()) {
67+
if (!CallbackBridge.isGrabbing() // Only capture if not in menu and user said so
68+
&& !LauncherPreferences.DEFAULT_PREF.getBoolean("always_grab_mouse", false)) {
69+
return;
70+
}
71+
if (mHostView.hasPointerCapture()) {
72+
enableTouchpadIfNecessary();
73+
return;
74+
}
75+
if (!mHostView.hasWindowFocus()) {
4376
mHostView.requestFocus();
4477
} else {
4578
mHostView.requestPointerCapture();
@@ -128,7 +161,11 @@ private void reinitializeDeviceSpecificProperties(InputDevice inputDevice) {
128161

129162
@Override
130163
public void onWindowFocusChanged(boolean hasFocus) {
131-
if(hasFocus && Tools.isAndroid8OrHigher()) mHostView.requestPointerCapture();
164+
if (!CallbackBridge.isGrabbing() // Only capture if not in menu and user said so
165+
&& !LauncherPreferences.DEFAULT_PREF.getBoolean("always_grab_mouse", false)) {
166+
return;
167+
}
168+
if (hasFocus && Tools.isAndroid8OrHigher()) mHostView.requestPointerCapture();
132169
}
133170

134171
public void detach() {

app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/QuickSettingSideDialog.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import android.annotation.SuppressLint;
1313
import android.content.Context;
1414
import android.content.SharedPreferences;
15+
import android.view.InputDevice;
1516
import android.view.View;
1617
import android.view.ViewGroup;
1718
import android.widget.Switch;
@@ -21,8 +22,11 @@
2122

2223
import net.kdt.pojavlaunch.R;
2324
import net.kdt.pojavlaunch.Tools;
25+
import net.kdt.pojavlaunch.customcontrols.mouse.AndroidPointerCapture;
2426
import net.kdt.pojavlaunch.utils.interfaces.SimpleSeekBarListener;
2527

28+
import org.lwjgl.glfw.CallbackBridge;
29+
2630
/**
2731
* Side dialog for quick settings that you can change in game
2832
* The implementation has to take action on some preference changes
@@ -31,7 +35,7 @@ public abstract class QuickSettingSideDialog extends com.kdt.SideDialogView {
3135

3236
private SharedPreferences.Editor mEditor;
3337
@SuppressLint("UseSwitchCompatOrMaterialCode")
34-
private Switch mGyroSwitch, mGyroXSwitch, mGyroYSwitch, mGestureSwitch;
38+
private Switch mGyroSwitch, mGyroXSwitch, mGyroYSwitch, mGestureSwitch, mMouseGrabSwitch;
3539
private CustomSeekbar mGyroSensitivityBar, mMouseSpeedBar, mGestureDelayBar, mResolutionBar;
3640
private TextView mGyroSensitivityText, mGyroSensitivityDisplayText, mMouseSpeedText, mGestureDelayText, mGestureDelayDisplayText, mResolutionText;
3741

@@ -65,6 +69,7 @@ private void bindLayout() {
6569
mGyroXSwitch = mDialogContent.findViewById(R.id.checkboxGyroX);
6670
mGyroYSwitch = mDialogContent.findViewById(R.id.checkboxGyroY);
6771
mGestureSwitch = mDialogContent.findViewById(R.id.checkboxGesture);
72+
mMouseGrabSwitch = mDialogContent.findViewById(R.id.always_grab_mouse_side_dialog);
6873

6974
mGyroSensitivityBar = mDialogContent.findViewById(R.id.editGyro_seekbar);
7075
mMouseSpeedBar = mDialogContent.findViewById(R.id.editMouseSpeed_seekbar);
@@ -122,6 +127,10 @@ private void setupListeners() {
122127
mEditor.putBoolean("disableGestures", isChecked);
123128
});
124129

130+
mMouseGrabSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
131+
mEditor.putBoolean("always_grab_mouse", isChecked);
132+
});
133+
125134
mGyroSensitivityBar.setOnSeekBarChangeListener((SimpleSeekBarListener) (seekBar, progress, fromUser) -> {
126135
PREF_GYRO_SENSITIVITY = progress / 100f;
127136
mEditor.putInt("gyroSensitivity", progress);

app_pojavlauncher/src/main/res/layout/dialog_quick_setting.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,4 +202,15 @@
202202
app:layout_constraintEnd_toEndOf="parent"
203203
app:layout_constraintTop_toTopOf="@id/editGestureDelay_textView" />
204204

205+
<Switch
206+
android:id="@+id/always_grab_mouse_side_dialog"
207+
android:layout_width="match_parent"
208+
android:layout_height="@dimen/_36sdp"
209+
android:text="@string/mcl_setting_title_grab_mouse"
210+
211+
212+
app:layout_constraintBottom_toBottomOf="parent"
213+
app:layout_constraintTop_toBottomOf="@+id/editGestureDelay_seekbar"
214+
tools:ignore="UseSwitchCompatOrMaterialXml" />
215+
205216
</androidx.constraintlayout.widget.ConstraintLayout>

app_pojavlauncher/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,4 +469,6 @@
469469
<string name="preference_force_enable_touchcontroller_description">Force enable TouchController integration, even if mod file is not found.</string>
470470
<string name="preference_touchcontroller_vibrate_length_title">TouchController vibrate length</string>
471471
<string name="preference_touchcontroller_vibrate_length_description">Set the length of the vibration when using TouchController.</string>
472+
<string name="mcl_setting_title_grab_mouse">Mouse grabbing</string>
473+
<string name="mcl_setting_subtitle_grab_mouse">Grabs the mouse to ensure it stays inside the game window. Prevents mouse from clicking touch control layout.</string>
472474
</resources>

app_pojavlauncher/src/main/res/xml/pref_control.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@
9797
android:title="@string/preference_mouse_start_title"
9898
android:summary="@string/preference_mouse_start_description"
9999
/>
100+
<SwitchPreference
101+
android:key="always_grab_mouse"
102+
android:title="@string/mcl_setting_title_grab_mouse"
103+
android:summary="@string/mcl_setting_subtitle_grab_mouse"
104+
android:defaultValue="false"/>
100105
</PreferenceCategory>
101106

102107
<PreferenceCategory

0 commit comments

Comments
 (0)