diff --git a/app/src/main/java/com/limelight/Game.java b/app/src/main/java/com/limelight/Game.java index cde6fa50..b194615c 100644 --- a/app/src/main/java/com/limelight/Game.java +++ b/app/src/main/java/com/limelight/Game.java @@ -620,23 +620,9 @@ public class Game extends Activity implements SurfaceHolder.Callback, // lifted while focus was not on us. Clear the modifier state. this.modifierFlags = 0; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - // Capture is lost when focus is lost, so it must be requested again - // when focus is regained. - if (inputCaptureProvider.isCapturingEnabled() && hasFocus) { - // Recapture the pointer if focus was regained. On Android Q, - // we have to delay a bit before requesting capture because otherwise - // we'll hit the "requestPointerCapture called for a window that has no focus" - // error and it will not actually capture the cursor. - Handler h = new Handler(); - h.postDelayed(new Runnable() { - @Override - public void run() { - streamView.requestPointerCapture(); - } - }, 500); - } - } + // With Android native pointer capture, capture is lost when focus is lost, + // so it must be requested again when focus is regained. + inputCaptureProvider.onWindowFocusChanged(hasFocus); } private boolean isRefreshRateGoodMatch(float refreshRate) { diff --git a/app/src/main/java/com/limelight/binding/input/capture/AndroidNativePointerCaptureProvider.java b/app/src/main/java/com/limelight/binding/input/capture/AndroidNativePointerCaptureProvider.java index 555a3290..e3ae1842 100644 --- a/app/src/main/java/com/limelight/binding/input/capture/AndroidNativePointerCaptureProvider.java +++ b/app/src/main/java/com/limelight/binding/input/capture/AndroidNativePointerCaptureProvider.java @@ -3,6 +3,7 @@ package com.limelight.binding.input.capture; import android.annotation.TargetApi; import android.app.Activity; import android.os.Build; +import android.os.Handler; import android.view.InputDevice; import android.view.MotionEvent; import android.view.View; @@ -36,6 +37,25 @@ public class AndroidNativePointerCaptureProvider extends AndroidPointerIconCaptu targetView.releasePointerCapture(); } + @Override + public void onWindowFocusChanged(boolean focusActive) { + if (!focusActive || !isCapturing) { + return; + } + + // Recapture the pointer if focus was regained. On Android Q, + // we have to delay a bit before requesting capture because otherwise + // we'll hit the "requestPointerCapture called for a window that has no focus" + // error and it will not actually capture the cursor. + Handler h = new Handler(); + h.postDelayed(new Runnable() { + @Override + public void run() { + targetView.requestPointerCapture(); + } + }, 500); + } + @Override public boolean eventHasRelativeMouseAxes(MotionEvent event) { // SOURCE_MOUSE_RELATIVE is how SOURCE_MOUSE appears when our view has pointer capture. diff --git a/app/src/main/java/com/limelight/binding/input/capture/InputCaptureProvider.java b/app/src/main/java/com/limelight/binding/input/capture/InputCaptureProvider.java index fb35aeae..b4e16f42 100644 --- a/app/src/main/java/com/limelight/binding/input/capture/InputCaptureProvider.java +++ b/app/src/main/java/com/limelight/binding/input/capture/InputCaptureProvider.java @@ -33,4 +33,6 @@ public abstract class InputCaptureProvider { public float getRelativeAxisY(MotionEvent event) { return 0; } + + public void onWindowFocusChanged(boolean focusActive) {} }