diff --git a/app_pojavlauncher/src/main/jni/environ/environ.h b/app_pojavlauncher/src/main/jni/environ/environ.h index c49ff8aab..4d73f1fb3 100644 --- a/app_pojavlauncher/src/main/jni/environ/environ.h +++ b/app_pojavlauncher/src/main/jni/environ/environ.h @@ -56,7 +56,7 @@ struct pojav_environ_s { JavaVM* dalvikJavaVMPtr; JNIEnv* dalvikJNIEnvPtr_ANDROID; long showingWindow; - bool isInputReady, isCursorEntered, isUseStackQueueCall, isPumpingEvents; + bool isInputReady, isCursorEntered, isUseStackQueueCall, shouldUpdateMouse; int savedWidth, savedHeight; #define ADD_CALLBACK_WWIN(NAME) \ GLFW_invoke_##NAME##_func* GLFW_invoke_##NAME; diff --git a/app_pojavlauncher/src/main/jni/input_bridge_v3.c b/app_pojavlauncher/src/main/jni/input_bridge_v3.c index ef708d250..4dff47f36 100644 --- a/app_pojavlauncher/src/main/jni/input_bridge_v3.c +++ b/app_pojavlauncher/src/main/jni/input_bridge_v3.c @@ -99,14 +99,7 @@ void handleFramebufferSizeJava(long window, int w, int h) { } void pojavPumpEvents(void* window) { - if(pojav_environ->isPumpingEvents) return; - // prevent further calls until we exit the loop - // by spec, they will be called on the same thread so no synchronization here - pojav_environ->isPumpingEvents = true; - - if((pojav_environ->cLastX != pojav_environ->cursorX || pojav_environ->cLastY != pojav_environ->cursorY) && pojav_environ->GLFW_invoke_CursorPos) { - pojav_environ->cLastX = pojav_environ->cursorX; - pojav_environ->cLastY = pojav_environ->cursorY; + if(pojav_environ->shouldUpdateMouse) { pojav_environ->GLFW_invoke_CursorPos(window, floor(pojav_environ->cursorX), floor(pojav_environ->cursorY)); } @@ -148,11 +141,10 @@ void pojavPumpEvents(void* window) { } // The out target index is updated by the rewinder - pojav_environ->isPumpingEvents = false; } -/** Setup the amount of event that will get pumped into each window */ -void pojavComputeEventTarget() { +/** Prepare the library for sending out callbacks to all windows */ +void pojavStartPumping() { size_t counter = atomic_load_explicit(&pojav_environ->eventCounter, memory_order_acquire); size_t index = pojav_environ->outEventIndex; @@ -163,14 +155,23 @@ void pojavComputeEventTarget() { // Only accessed by one unique thread, no need for atomic store pojav_environ->inEventCount = counter; pojav_environ->outTargetIndex = targetIndex; + + //PumpEvents is called for every window, so this logic should be there in order to correctly distribute events to all windows. + if((pojav_environ->cLastX != pojav_environ->cursorX || pojav_environ->cLastY != pojav_environ->cursorY) && pojav_environ->GLFW_invoke_CursorPos) { + pojav_environ->cLastX = pojav_environ->cursorX; + pojav_environ->cLastY = pojav_environ->cursorY; + pojav_environ->shouldUpdateMouse = true; + } } -/** Apply index offsets after events have been pumped */ -void pojavRewindEvents() { +/** Prepare the library for the next round of new events */ +void pojavStopPumping() { pojav_environ->outEventIndex = pojav_environ->outTargetIndex; // New events may have arrived while pumping, so remove only the difference before the start and end of execution atomic_fetch_sub_explicit(&pojav_environ->eventCounter, pojav_environ->inEventCount, memory_order_acquire); + // Make sure the next frame won't send mouse updates if it's unnecessary + pojav_environ->shouldUpdateMouse = false; } JNIEXPORT void JNICALL diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java index 467593b42..dde2f39ba 100644 --- a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java @@ -6,7 +6,6 @@ package org.lwjgl.glfw; import android.util.*; -import java.lang.annotation.Native; import java.lang.reflect.*; import java.nio.*; @@ -23,8 +22,6 @@ import static org.lwjgl.system.MemoryStack.*; import static org.lwjgl.system.MemoryUtil.*; import java.util.*; -import sun.misc.Unsafe; - public class GLFW { static FloatBuffer joystickData = (FloatBuffer)FloatBuffer.allocate(8).flip(); @@ -507,6 +504,7 @@ public class GLFW private static ArrayMap mGLFWWindowMap; public static boolean mGLFWIsInputReady; + private static boolean mGLFWInputPumping; public static final ByteBuffer keyDownBuffer = ByteBuffer.allocateDirect(317); public static final ByteBuffer mouseDownBuffer = ByteBuffer.allocateDirect(8); @@ -627,8 +625,8 @@ public class GLFW SwapBuffers = apiGetFunctionAddress(GLFW, "pojavSwapBuffers"), SwapInterval = apiGetFunctionAddress(GLFW, "pojavSwapInterval"), PumpEvents = apiGetFunctionAddress(GLFW, "pojavPumpEvents"), - RewindEvents = apiGetFunctionAddress(GLFW, "pojavRewindEvents"), - SetupEvents = apiGetFunctionAddress(GLFW, "pojavComputeEventTarget"); + StopPumping = apiGetFunctionAddress(GLFW, "pojavStopPumping"), + StartPumping = apiGetFunctionAddress(GLFW, "pojavStartPumping"); } public static SharedLibrary getLibrary() { @@ -1080,9 +1078,15 @@ public class GLFW mGLFWIsInputReady = true; CallbackBridge.nativeSetInputReady(true); } - callV(Functions.SetupEvents); + // During interactions with UI elements, Minecraft likes to update the screen as events related to those inputs arrive. + // This leads to calls to glfwPollEvents within glfwPollEvents, which is not good for our queue system. + // Prevent these with this code. + if(mGLFWInputPumping) return; + mGLFWInputPumping = true; + callV(Functions.StartPumping); for (Long ptr : mGLFWWindowMap.keySet()) callJV(ptr, Functions.PumpEvents); - callV(Functions.RewindEvents); + callV(Functions.StopPumping); + mGLFWInputPumping = false; } public static void internalWindowSizeChanged(long window, int w, int h) {