Skip to content

Commit

Permalink
Added improved mouse pointer capture under API 26. (Thanks Rachel!)
Browse files Browse the repository at this point in the history
  • Loading branch information
slouken committed Jun 5, 2018
1 parent 113801b commit 7c5f3cf
Show file tree
Hide file tree
Showing 2 changed files with 184 additions and 1 deletion.
Expand Up @@ -87,6 +87,9 @@ public enum NativeState {

protected static SDLGenericMotionListener_API12 getMotionListener() {
if (mMotionListener == null) {
if (Build.VERSION.SDK_INT >= 26) {
mMotionListener = new SDLGenericMotionListener_API26();
} else
if (Build.VERSION.SDK_INT >= 24) {
mMotionListener = new SDLGenericMotionListener_API24();
} else {
Expand Down Expand Up @@ -301,6 +304,7 @@ public void onWindowFocusChanged(boolean hasFocus) {
SDLActivity.mHasFocus = hasFocus;
if (hasFocus) {
mNextNativeState = NativeState.RESUMED;
SDLActivity.getMotionListener().reclaimRelativeMouseModeIfNeeded();
} else {
mNextNativeState = NativeState.PAUSED;
}
Expand Down Expand Up @@ -635,7 +639,6 @@ public void setOrientationBis(int w, int h, boolean resizable, String hint)
}
}


/**
* This method is called by SDL using JNI.
*/
Expand Down Expand Up @@ -736,6 +739,12 @@ public static boolean getManifestEnvironmentVariables() {
return false;
}

// This method is called by SDLControllerManager's API 26 Generic Motion Handler.
public static View getContentView()
{
return mSingleton.mLayout;
}

static class ShowTextInputTask implements Runnable {
/*
* This is used to regulate the pan&scan method to have some offset from
Expand Down Expand Up @@ -1270,6 +1279,10 @@ public SDLSurface(Context context) {
setOnGenericMotionListener(SDLActivity.getMotionListener());
}

if (Build.VERSION.SDK_INT >= 26) {
setOnCapturedPointerListener(new SDLCapturedPointerListener_API26());
}

// Some arbitrary defaults to avoid a potential division by zero
mWidth = 1.0f;
mHeight = 1.0f;
Expand Down
Expand Up @@ -569,6 +569,11 @@ public boolean setRelativeMouseEnabled(boolean enabled) {
return false;
}

public void reclaimRelativeMouseModeIfNeeded()
{

}

public float getEventX(MotionEvent event) {
return event.getX(0);
}
Expand Down Expand Up @@ -633,19 +638,23 @@ public boolean onGenericMotion(View v, MotionEvent event) {
return false;
}

@Override
public boolean supportsRelativeMouse() {
return true;
}

@Override
public boolean inRelativeMode() {
return mRelativeModeEnabled;
}

@Override
public boolean setRelativeMouseEnabled(boolean enabled) {
mRelativeModeEnabled = enabled;
return true;
}

@Override
public float getEventX(MotionEvent event) {
if (mRelativeModeEnabled) {
return event.getAxisValue(MotionEvent.AXIS_RELATIVE_X);
Expand All @@ -655,6 +664,7 @@ public float getEventX(MotionEvent event) {
}
}

@Override
public float getEventY(MotionEvent event) {
if (mRelativeModeEnabled) {
return event.getAxisValue(MotionEvent.AXIS_RELATIVE_Y);
Expand All @@ -665,3 +675,163 @@ public float getEventY(MotionEvent event) {
}
}


class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 {
// Generic Motion (mouse hover, joystick...) events go here
private boolean mRelativeModeEnabled;

@Override
public boolean onGenericMotion(View v, MotionEvent event) {
float x, y;
int action;

switch ( event.getSource() ) {
case InputDevice.SOURCE_JOYSTICK:
case InputDevice.SOURCE_GAMEPAD:
case InputDevice.SOURCE_DPAD:
return SDLControllerManager.handleJoystickMotionEvent(event);

case InputDevice.SOURCE_MOUSE:
if (!SDLActivity.mSeparateMouseAndTouch) {
break;
}

action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_SCROLL:
x = event.getAxisValue(MotionEvent.AXIS_HSCROLL, 0);
y = event.getAxisValue(MotionEvent.AXIS_VSCROLL, 0);
SDLActivity.onNativeMouse(0, action, x, y, false);
return true;

case MotionEvent.ACTION_HOVER_MOVE:
x = event.getX(0);
y = event.getY(0);
SDLActivity.onNativeMouse(0, action, x, y, false);
return true;

default:
break;
}
break;

case InputDevice.SOURCE_MOUSE_RELATIVE:
if (!SDLActivity.mSeparateMouseAndTouch) {
break;
}
action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_SCROLL:
x = event.getAxisValue(MotionEvent.AXIS_HSCROLL, 0);
y = event.getAxisValue(MotionEvent.AXIS_VSCROLL, 0);
SDLActivity.onNativeMouse(0, action, x, y, false);
return true;

case MotionEvent.ACTION_HOVER_MOVE:
x = event.getX(0);
y = event.getY(0);
SDLActivity.onNativeMouse(0, action, x, y, true);
return true;

default:
break;
}
break;

default:
break;
}

// Event was not managed
return false;
}

@Override
public boolean supportsRelativeMouse() {
return true;
}

@Override
public boolean inRelativeMode() {
return mRelativeModeEnabled;
}

@Override
public boolean setRelativeMouseEnabled(boolean enabled) {
if (enabled) {
SDLActivity.getContentView().requestPointerCapture();
}
else {
SDLActivity.getContentView().releasePointerCapture();
}
mRelativeModeEnabled = enabled;
return true;
}

@Override
public void reclaimRelativeMouseModeIfNeeded()
{
if (mRelativeModeEnabled) {
SDLActivity.getContentView().requestPointerCapture();
}
}

@Override
public float getEventX(MotionEvent event) {
// Relative mouse in capture mode will only have relative for X/Y
return event.getX(0);
}

@Override
public float getEventY(MotionEvent event) {
// Relative mouse in capture mode will only have relative for X/Y
return event.getY(0);
}
}

class SDLCapturedPointerListener_API26 implements View.OnCapturedPointerListener
{
@Override
public boolean onCapturedPointer(View view, MotionEvent event)
{
int action = event.getActionMasked();

float x, y;
switch (action) {
case MotionEvent.ACTION_SCROLL:
x = event.getAxisValue(MotionEvent.AXIS_HSCROLL, 0);
y = event.getAxisValue(MotionEvent.AXIS_VSCROLL, 0);
SDLActivity.onNativeMouse(0, action, x, y, false);
return true;

case MotionEvent.ACTION_HOVER_MOVE:
case MotionEvent.ACTION_MOVE:
x = event.getX(0);
y = event.getY(0);
SDLActivity.onNativeMouse(0, action, x, y, true);
return true;

case MotionEvent.ACTION_BUTTON_PRESS:
case MotionEvent.ACTION_BUTTON_RELEASE:

// Change our action value to what SDL's code expects.
if (action == MotionEvent.ACTION_BUTTON_PRESS) {
action = MotionEvent.ACTION_DOWN;
}
else if (action == MotionEvent.ACTION_BUTTON_RELEASE) {
action = MotionEvent.ACTION_UP;
}

x = event.getX(0);
y = event.getY(0);
int button = event.getButtonState();

SDLActivity.onNativeMouse(button, action, x, y, true);
return true;

}

return false;
}
}

0 comments on commit 7c5f3cf

Please sign in to comment.