diff --git a/app/src/main/java/com/limelight/binding/input/touch/AbsoluteTouchContext.java b/app/src/main/java/com/limelight/binding/input/touch/AbsoluteTouchContext.java index f185f004..cfc76591 100644 --- a/app/src/main/java/com/limelight/binding/input/touch/AbsoluteTouchContext.java +++ b/app/src/main/java/com/limelight/binding/input/touch/AbsoluteTouchContext.java @@ -1,5 +1,7 @@ package com.limelight.binding.input.touch; +import android.os.Handler; +import android.os.Looper; import android.view.View; import com.limelight.nvstream.NvConnection; @@ -26,6 +28,14 @@ public class AbsoluteTouchContext implements TouchContext { private final NvConnection conn; private final int actionIndex; private final View targetView; + private final Handler handler; + + private final Runnable leftButtonUpRunnable = new Runnable() { + @Override + public void run() { + conn.sendMouseButtonUp(MouseButtonPacket.BUTTON_LEFT); + } + }; private static final int SCROLL_SPEED_FACTOR = 3; @@ -43,6 +53,7 @@ public class AbsoluteTouchContext implements TouchContext { this.conn = conn; this.actionIndex = actionIndex; this.targetView = view; + this.handler = new Handler(Looper.getMainLooper()); } @Override @@ -112,18 +123,11 @@ public class AbsoluteTouchContext implements TouchContext { // deadzone time. We'll need to send the touch down and up events now at the // original touch down position. tapConfirmed(); - try { - // FIXME: Sleeping on the main thread sucks - Thread.sleep(50); - } catch (InterruptedException e) { - e.printStackTrace(); - // InterruptedException clears the thread's interrupt status. Since we can't - // handle that here, we will re-interrupt the thread to set the interrupt - // status back to true. - Thread.currentThread().interrupt(); - } - conn.sendMouseButtonUp(MouseButtonPacket.BUTTON_LEFT); + // Release the left mouse button in 100ms to allow for apps that use polling + // to detect mouse button presses. + handler.removeCallbacks(leftButtonUpRunnable); + handler.postDelayed(leftButtonUpRunnable, 100); } } diff --git a/app/src/main/java/com/limelight/binding/input/touch/RelativeTouchContext.java b/app/src/main/java/com/limelight/binding/input/touch/RelativeTouchContext.java index c354cb4b..2d619919 100644 --- a/app/src/main/java/com/limelight/binding/input/touch/RelativeTouchContext.java +++ b/app/src/main/java/com/limelight/binding/input/touch/RelativeTouchContext.java @@ -1,5 +1,7 @@ package com.limelight.binding.input.touch; +import android.os.Handler; +import android.os.Looper; import android.view.View; import com.limelight.nvstream.NvConnection; @@ -31,6 +33,41 @@ public class RelativeTouchContext implements TouchContext { private final int referenceHeight; private final View targetView; private final PreferenceConfiguration prefConfig; + private final Handler handler; + + // Indexed by MouseButtonPacket.BUTTON_XXX - 1 + private final Runnable[] buttonUpRunnables = new Runnable[] { + new Runnable() { + @Override + public void run() { + conn.sendMouseButtonUp(MouseButtonPacket.BUTTON_LEFT); + } + }, + new Runnable() { + @Override + public void run() { + conn.sendMouseButtonUp(MouseButtonPacket.BUTTON_MIDDLE); + } + }, + new Runnable() { + @Override + public void run() { + conn.sendMouseButtonUp(MouseButtonPacket.BUTTON_RIGHT); + } + }, + new Runnable() { + @Override + public void run() { + conn.sendMouseButtonUp(MouseButtonPacket.BUTTON_X1); + } + }, + new Runnable() { + @Override + public void run() { + conn.sendMouseButtonUp(MouseButtonPacket.BUTTON_X2); + } + } + }; private static final int TAP_MOVEMENT_THRESHOLD = 20; private static final int TAP_DISTANCE_THRESHOLD = 25; @@ -49,6 +86,7 @@ public class RelativeTouchContext implements TouchContext { this.referenceHeight = referenceHeight; this.targetView = view; this.prefConfig = prefConfig; + this.handler = new Handler(Looper.getMainLooper()); } @Override @@ -138,21 +176,11 @@ public class RelativeTouchContext implements TouchContext { // Lower the mouse button conn.sendMouseButtonDown(buttonIndex); - // We need to sleep a bit here because some games - // do input detection by polling - try { - Thread.sleep(100); - } catch (InterruptedException e) { - e.printStackTrace(); - - // InterruptedException clears the thread's interrupt status. Since we can't - // handle that here, we will re-interrupt the thread to set the interrupt - // status back to true. - Thread.currentThread().interrupt(); - } - - // Raise the mouse button - conn.sendMouseButtonUp(buttonIndex); + // Release the mouse button in 100ms to allow for apps that use polling + // to detect mouse button presses. + Runnable buttonUpRunnable = buttonUpRunnables[buttonIndex - 1]; + handler.removeCallbacks(buttonUpRunnable); + handler.postDelayed(buttonUpRunnable, 100); } }