Skip to content
Merged
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
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -193,6 +194,13 @@ public boolean onTouchEvent(MotionEvent e) {
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;
}
Expand Down Expand Up @@ -241,9 +249,9 @@ public boolean dispatchGenericMotionEvent(MotionEvent event) {

// 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);
Expand Down
16 changes: 16 additions & 0 deletions app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
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;
Expand Down Expand Up @@ -1557,4 +1558,19 @@ public static Integer mcVersiontoInt(String mcVersion){
}
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;
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
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;

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;
Expand All @@ -32,14 +39,46 @@ public AndroidPointerCapture(AbstractTouchpad touchpad, View hostView) {
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();
Expand Down Expand Up @@ -128,7 +167,11 @@ private void reinitializeDeviceSpecificProperties(InputDevice inputDevice) {

@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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ public void applyMotionVector(float x, float y) {
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();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -114,6 +116,7 @@ public static void loadPreferences(Context ctx) {
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)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
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;
Expand All @@ -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;

Expand Down Expand Up @@ -65,6 +66,7 @@ private void bindLayout() {
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);
Expand All @@ -86,6 +88,7 @@ private void setupListeners() {
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;
Expand All @@ -96,6 +99,7 @@ private void setupListeners() {
mGyroXSwitch.setChecked(mOriginalGyroXEnabled);
mGyroYSwitch.setChecked(mOriginalGyroYEnabled);
mGestureSwitch.setChecked(mOriginalGestureDisabled);
mMouseGrabSwitch.setChecked(mOriginalMouseGrab);

mGyroSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
PREF_ENABLE_GYRO = isChecked;
Expand All @@ -122,6 +126,11 @@ private void setupListeners() {
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);
Expand Down Expand Up @@ -156,6 +165,7 @@ private void setupListeners() {
setSeekTextPercent(mResolutionText, mResolutionBar.getProgress());


updateMouseGrabVisibility();
updateGyroVisibility(mOriginalGyroEnabled);
updateGestureVisibility(mOriginalGestureDisabled);
}
Expand All @@ -172,6 +182,10 @@ private static void setSeekText(TextView target, int format, int value) {
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);
Expand Down Expand Up @@ -202,6 +216,7 @@ private void removeListeners() {
mGyroXSwitch.setOnCheckedChangeListener(null);
mGyroYSwitch.setOnCheckedChangeListener(null);
mGestureSwitch.setOnCheckedChangeListener(null);
mMouseGrabSwitch.setOnCheckedChangeListener(null);

mGyroSensitivityBar.setOnSeekBarChangeListener(null);
mMouseSpeedBar.setOnSeekBarChangeListener(null);
Expand All @@ -225,6 +240,7 @@ public void cancel() {
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;
Expand Down
11 changes: 11 additions & 0 deletions app_pojavlauncher/src/main/res/layout/dialog_quick_setting.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
2 changes: 2 additions & 0 deletions app_pojavlauncher/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
5 changes: 5 additions & 0 deletions app_pojavlauncher/src/main/res/xml/pref_control.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading