fix, refactor: double click on touchpad, scroll without triggering click (#5456)

* fix,refactor: double click on touchpad, scroll without triggering click

Signed-off-by: Mathias-Boulay <mathiasboulay@free.fr>

* cleanup: remove unused code

Signed-off-by: Mathias-Boulay <mathiasboulay@free.fr>

* fix(GUIEventProcessor): dragging when taking events on the fly

Signed-off-by: Mathias-Boulay <mathiasboulay@free.fr>

---------

Signed-off-by: Mathias-Boulay <mathiasboulay@free.fr>
This commit is contained in:
Mathias Boulay 2024-05-18 22:53:12 +02:00 committed by GitHub
parent 85a9f217e5
commit 3443b049b6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 51 additions and 13 deletions

View File

@ -51,6 +51,7 @@ import net.kdt.pojavlaunch.customcontrols.CustomControls;
import net.kdt.pojavlaunch.customcontrols.EditorExitable; import net.kdt.pojavlaunch.customcontrols.EditorExitable;
import net.kdt.pojavlaunch.customcontrols.keyboard.LwjglCharSender; import net.kdt.pojavlaunch.customcontrols.keyboard.LwjglCharSender;
import net.kdt.pojavlaunch.customcontrols.keyboard.TouchCharInput; import net.kdt.pojavlaunch.customcontrols.keyboard.TouchCharInput;
import net.kdt.pojavlaunch.customcontrols.mouse.GyroControl;
import net.kdt.pojavlaunch.customcontrols.mouse.Touchpad; import net.kdt.pojavlaunch.customcontrols.mouse.Touchpad;
import net.kdt.pojavlaunch.lifecycle.ContextExecutor; import net.kdt.pojavlaunch.lifecycle.ContextExecutor;
import net.kdt.pojavlaunch.prefs.LauncherPreferences; import net.kdt.pojavlaunch.prefs.LauncherPreferences;

View File

@ -3,6 +3,8 @@ package net.kdt.pojavlaunch;
import android.view.*; import android.view.*;
import android.view.GestureDetector.*; import android.view.GestureDetector.*;
import androidx.annotation.NonNull;
public class SingleTapConfirm extends SimpleOnGestureListener { public class SingleTapConfirm extends SimpleOnGestureListener {
@Override @Override
public boolean onSingleTapUp(MotionEvent event) { public boolean onSingleTapUp(MotionEvent event) {

View File

@ -1,4 +1,4 @@
package net.kdt.pojavlaunch; package net.kdt.pojavlaunch.customcontrols.mouse;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
@ -10,6 +10,7 @@ import android.view.OrientationEventListener;
import android.view.Surface; import android.view.Surface;
import android.view.WindowManager; import android.view.WindowManager;
import net.kdt.pojavlaunch.GrabListener;
import net.kdt.pojavlaunch.prefs.LauncherPreferences; import net.kdt.pojavlaunch.prefs.LauncherPreferences;
import org.lwjgl.glfw.CallbackBridge; import org.lwjgl.glfw.CallbackBridge;

View File

@ -12,7 +12,6 @@ import android.view.ViewParent;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import net.kdt.pojavlaunch.LwjglGlfwKeycode; import net.kdt.pojavlaunch.LwjglGlfwKeycode;
import net.kdt.pojavlaunch.TapDetector;
import net.kdt.pojavlaunch.prefs.LauncherPreferences; import net.kdt.pojavlaunch.prefs.LauncherPreferences;
import net.kdt.pojavlaunch.utils.MCOptionUtils; import net.kdt.pojavlaunch.utils.MCOptionUtils;
import net.kdt.pojavlaunch.utils.MathUtils; import net.kdt.pojavlaunch.utils.MathUtils;

View File

@ -12,16 +12,21 @@ import org.lwjgl.glfw.CallbackBridge;
public class InGUIEventProcessor implements TouchEventProcessor { public class InGUIEventProcessor implements TouchEventProcessor {
public static final float FINGER_SCROLL_THRESHOLD = Tools.dpToPx(6); public static final float FINGER_SCROLL_THRESHOLD = Tools.dpToPx(6);
public static final float FINGER_STILL_THRESHOLD = Tools.dpToPx(5);
private final PointerTracker mTracker = new PointerTracker(); private final PointerTracker mTracker = new PointerTracker();
private final GestureDetector mSingleTapDetector; private final TapDetector mSingleTapDetector;
private AbstractTouchpad mTouchpad; private AbstractTouchpad mTouchpad;
private boolean mIsMouseDown = false; private boolean mIsMouseDown = false;
private float mStartX, mStartY;
private final float mScaleFactor; private final float mScaleFactor;
private final Scroller mScroller = new Scroller(FINGER_SCROLL_THRESHOLD); private final Scroller mScroller = new Scroller(FINGER_SCROLL_THRESHOLD);
public InGUIEventProcessor(float scaleFactor) { public InGUIEventProcessor(float scaleFactor) {
mSingleTapDetector = new GestureDetector(null, new SingleTapConfirm()); mSingleTapDetector = new TapDetector(1, TapDetector.DETECTION_METHOD_BOTH);
mScaleFactor = scaleFactor; mScaleFactor = scaleFactor;
} }
@Override @Override
public boolean processTouchEvent(MotionEvent motionEvent) { public boolean processTouchEvent(MotionEvent motionEvent) {
switch (motionEvent.getActionMasked()) { switch (motionEvent.getActionMasked()) {
@ -29,30 +34,45 @@ public class InGUIEventProcessor implements TouchEventProcessor {
mTracker.startTracking(motionEvent); mTracker.startTracking(motionEvent);
if(!touchpadDisplayed()) { if(!touchpadDisplayed()) {
sendTouchCoordinates(motionEvent.getX(), motionEvent.getY()); sendTouchCoordinates(motionEvent.getX(), motionEvent.getY());
enableMouse();
// disabled gestures means no scrolling possible, send gesture early
if (LauncherPreferences.PREF_DISABLE_GESTURES) enableMouse();
else setGestureStart(motionEvent);
} }
break; break;
case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_MOVE:
int pointerCount = motionEvent.getPointerCount(); int pointerCount = motionEvent.getPointerCount();
int pointerIndex = mTracker.trackEvent(motionEvent); int pointerIndex = mTracker.trackEvent(motionEvent);
if(pointerCount == 1 || LauncherPreferences.PREF_DISABLE_GESTURES) { if(pointerCount == 1 || LauncherPreferences.PREF_DISABLE_GESTURES) {
if(touchpadDisplayed()) { if(touchpadDisplayed()) {
mTouchpad.applyMotionVector(mTracker.getMotionVector()); mTouchpad.applyMotionVector(mTracker.getMotionVector());
}else { } else {
float mainPointerX = motionEvent.getX(pointerIndex); float mainPointerX = motionEvent.getX(pointerIndex);
float mainPointerY = motionEvent.getY(pointerIndex); float mainPointerY = motionEvent.getY(pointerIndex);
sendTouchCoordinates(mainPointerX, mainPointerY); sendTouchCoordinates(mainPointerX, mainPointerY);
if(!mIsMouseDown) enableMouse();
if(!mIsMouseDown) {
if(!hasGestureStarted()) setGestureStart(motionEvent);
if(!LeftClickGesture.isFingerStill(mStartX, mStartY, FINGER_STILL_THRESHOLD))
enableMouse();
}
} }
} else mScroller.performScroll(mTracker.getMotionVector()); } else mScroller.performScroll(mTracker.getMotionVector());
break; break;
case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP: case MotionEvent.ACTION_UP:
mScroller.resetScrollOvershoot(); mScroller.resetScrollOvershoot();
mTracker.cancelTracking(); mTracker.cancelTracking();
if(mIsMouseDown) disableMouse(); if(mIsMouseDown) disableMouse();
resetGesture();
}
if((!LauncherPreferences.PREF_DISABLE_GESTURES || touchpadDisplayed()) && mSingleTapDetector.onTouchEvent(motionEvent)) {
clickMouse();
} }
if(touchpadDisplayed() && mSingleTapDetector.onTouchEvent(motionEvent)) clickMouse();
return true; return true;
} }
@ -83,6 +103,19 @@ public class InGUIEventProcessor implements TouchEventProcessor {
CallbackBridge.sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT, false); CallbackBridge.sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT, false);
} }
private void setGestureStart(MotionEvent event) {
mStartX = event.getX();
mStartY = event.getY();
}
private void resetGesture() {
mStartX = mStartY = -1;
}
private boolean hasGestureStarted() {
return mStartX != -1 || mStartY != -1;
}
@Override @Override
public void cancelPendingActions() { public void cancelPendingActions() {
mScroller.resetScrollOvershoot(); mScroller.resetScrollOvershoot();

View File

@ -29,7 +29,7 @@ public class LeftClickGesture extends ValidatorGesture {
@Override @Override
public boolean checkAndTrigger() { public boolean checkAndTrigger() {
boolean fingerStill = LeftClickGesture.isFingerStill(mGestureStartX, mGestureStartY); boolean fingerStill = LeftClickGesture.isFingerStill(mGestureStartX, mGestureStartY, FINGER_STILL_THRESHOLD);
// If the finger is still, fire the gesture. // If the finger is still, fire the gesture.
if(fingerStill) { if(fingerStill) {
sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT, true); sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT, true);
@ -53,12 +53,12 @@ public class LeftClickGesture extends ValidatorGesture {
* @param startY the starting Y of the gesture * @param startY the starting Y of the gesture
* @return whether the finger's position counts as "still" or not * @return whether the finger's position counts as "still" or not
*/ */
public static boolean isFingerStill(float startX, float startY) { public static boolean isFingerStill(float startX, float startY, float threshold) {
return MathUtils.dist( return MathUtils.dist(
CallbackBridge.mouseX, CallbackBridge.mouseX,
CallbackBridge.mouseY, CallbackBridge.mouseY,
startX, startX,
startY startY
) <= FINGER_STILL_THRESHOLD; ) <= threshold;
} }
} }

View File

@ -38,7 +38,7 @@ public class RightClickGesture extends ValidatorGesture{
public void onGestureCancelled(boolean isSwitching) { public void onGestureCancelled(boolean isSwitching) {
mGestureEnabled = true; mGestureEnabled = true;
if(!mGestureValid || isSwitching) return; if(!mGestureValid || isSwitching) return;
boolean fingerStill = LeftClickGesture.isFingerStill(mGestureStartX, mGestureStartY); boolean fingerStill = LeftClickGesture.isFingerStill(mGestureStartX, mGestureStartY, LeftClickGesture.FINGER_STILL_THRESHOLD);
if(!fingerStill) return; if(!fingerStill) return;
CallbackBridge.sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_RIGHT, true); CallbackBridge.sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_RIGHT, true);
CallbackBridge.sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_RIGHT, false); CallbackBridge.sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_RIGHT, false);

View File

@ -1,4 +1,4 @@
package net.kdt.pojavlaunch; package net.kdt.pojavlaunch.customcontrols.mouse;
import android.view.MotionEvent; import android.view.MotionEvent;
@ -7,6 +7,8 @@ import static android.view.MotionEvent.ACTION_POINTER_DOWN;
import static android.view.MotionEvent.ACTION_POINTER_UP; import static android.view.MotionEvent.ACTION_POINTER_UP;
import static android.view.MotionEvent.ACTION_UP; import static android.view.MotionEvent.ACTION_UP;
import net.kdt.pojavlaunch.Tools;
/** /**
* Class aiming at better detecting X-tap events regardless of the POINTERS * Class aiming at better detecting X-tap events regardless of the POINTERS
* Only uses the least amount of events possible, * Only uses the least amount of events possible,