mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-09-14 07:05:40 -04:00
Fix[capture]: modify trackpad touch handling, read relative axes only if they are supported
This commit is contained in:
parent
7631e3c9e7
commit
181f81131f
@ -1,6 +1,7 @@
|
||||
package net.kdt.pojavlaunch.customcontrols.mouse;
|
||||
|
||||
import android.os.Build;
|
||||
import android.view.InputDevice;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewTreeObserver;
|
||||
@ -20,7 +21,12 @@ public class AndroidPointerCapture implements ViewTreeObserver.OnWindowFocusChan
|
||||
private final View mHostView;
|
||||
private final float mScaleFactor;
|
||||
private final float mMousePrescale = Tools.dpToPx(1);
|
||||
private final PointerTracker mPointerTracker = new PointerTracker();
|
||||
private final Scroller mScroller = new Scroller(TOUCHPAD_SCROLL_THRESHOLD);
|
||||
private final float[] mVector = mPointerTracker.getMotionVector();
|
||||
|
||||
private int mInputDeviceIdentifier;
|
||||
private boolean mDeviceSupportsRelativeAxis;
|
||||
|
||||
public AndroidPointerCapture(AbstractTouchpad touchpad, View hostView, float scaleFactor) {
|
||||
this.mScaleFactor = scaleFactor;
|
||||
@ -44,26 +50,45 @@ public class AndroidPointerCapture implements ViewTreeObserver.OnWindowFocusChan
|
||||
|
||||
@Override
|
||||
public boolean onCapturedPointer(View view, MotionEvent event) {
|
||||
checkSameDevice(event.getDevice());
|
||||
// Yes, we actually not only receive relative mouse events here, but also absolute touchpad ones!
|
||||
// Read from relative axis directly to work around.
|
||||
float relX = event.getAxisValue(MotionEvent.AXIS_RELATIVE_X);
|
||||
float relY = event.getAxisValue(MotionEvent.AXIS_RELATIVE_Y);
|
||||
// Therefore, we need to know when it's a touchpad and when it's a mouse.
|
||||
|
||||
if((event.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) {
|
||||
// If the source claims to be a relative device by belonging to the trackball class,
|
||||
// use its coordinates directly.
|
||||
if(mDeviceSupportsRelativeAxis) {
|
||||
// If some OEM decides to do a funny and make an absolute touchpad report itself as
|
||||
// a trackball, we will at least have semi-valid relative positions
|
||||
mVector[0] = event.getAxisValue(MotionEvent.AXIS_RELATIVE_X);
|
||||
mVector[1] = event.getAxisValue(MotionEvent.AXIS_RELATIVE_Y);
|
||||
}else {
|
||||
// Otherwise trust the OS, i guess??
|
||||
mVector[0] = event.getX();
|
||||
mVector[1] = event.getY();
|
||||
}
|
||||
}else {
|
||||
// If it's not a trackball, it's likely a touchpad and needs tracking like a touchscreen.
|
||||
mPointerTracker.trackEvent(event);
|
||||
// The relative position will already be written down into the mVector variable.
|
||||
}
|
||||
|
||||
if(!CallbackBridge.isGrabbing()) {
|
||||
enableTouchpadIfNecessary();
|
||||
// Yes, if the user's touchpad is multi-touch we will also receive events for that.
|
||||
// So, handle the scrolling gesture ourselves.
|
||||
relX *= mMousePrescale;
|
||||
relY *= mMousePrescale;
|
||||
mVector[0] *= mMousePrescale;
|
||||
mVector[1] *= mMousePrescale;
|
||||
if(event.getPointerCount() < 2) {
|
||||
mTouchpad.applyMotionVector(relX, relY);
|
||||
mTouchpad.applyMotionVector(mVector);
|
||||
mScroller.resetScrollOvershoot();
|
||||
} else {
|
||||
mScroller.performScroll(relX, relY);
|
||||
mScroller.performScroll(mVector);
|
||||
}
|
||||
} else {
|
||||
// Position is updated by many events, hence it is send regardless of the event value
|
||||
CallbackBridge.mouseX += (relX * mScaleFactor);
|
||||
CallbackBridge.mouseY += (relY * mScaleFactor);
|
||||
CallbackBridge.mouseX += (mVector[0] * mScaleFactor);
|
||||
CallbackBridge.mouseY += (mVector[1] * mScaleFactor);
|
||||
CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY);
|
||||
}
|
||||
|
||||
@ -80,11 +105,29 @@ public class AndroidPointerCapture implements ViewTreeObserver.OnWindowFocusChan
|
||||
event.getAxisValue(MotionEvent.AXIS_VSCROLL)
|
||||
);
|
||||
return true;
|
||||
case MotionEvent.ACTION_UP:
|
||||
mPointerTracker.cancelTracking();
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void checkSameDevice(InputDevice inputDevice) {
|
||||
int newIdentifier = inputDevice.getId();
|
||||
if(mInputDeviceIdentifier != newIdentifier) {
|
||||
reinitializeDeviceSpecificProperties(inputDevice);
|
||||
mInputDeviceIdentifier = newIdentifier;
|
||||
}
|
||||
}
|
||||
|
||||
private void reinitializeDeviceSpecificProperties(InputDevice inputDevice) {
|
||||
mPointerTracker.cancelTracking();
|
||||
boolean relativeXSupported = inputDevice.getMotionRange(MotionEvent.AXIS_RELATIVE_X) != null;
|
||||
boolean relativeYSupported = inputDevice.getMotionRange(MotionEvent.AXIS_RELATIVE_Y) != null;
|
||||
mDeviceSupportsRelativeAxis = relativeXSupported && relativeYSupported;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowFocusChanged(boolean hasFocus) {
|
||||
if(hasFocus && MainActivity.isAndroid8OrHigher()) mHostView.requestPointerCapture();
|
||||
|
@ -24,7 +24,8 @@
|
||||
android:id="@+id/main_game_render_view"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
/>
|
||||
android:defaultFocusHighlightEnabled="false"
|
||||
tools:ignore="UnusedAttribute" />
|
||||
|
||||
<net.kdt.pojavlaunch.customcontrols.mouse.Touchpad
|
||||
android:layout_height="match_parent"
|
||||
|
Loading…
x
Reference in New Issue
Block a user