Skip to content

Commit 10bca75

Browse files
authored
Implement SDL focus-aware mouse delta handling
1 parent b3be1a2 commit 10bca75

2 files changed

Lines changed: 59 additions & 0 deletions

File tree

jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/SdlMouseInput.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ public class SdlMouseInput implements MouseInput {
9292
private float windowCoordHeight = 1f;
9393

9494
private boolean cursorVisible = true;
95+
private boolean windowFocused = true;
9596
private boolean x11WarpGrabMode;
9697
private boolean ignoreNextX11WarpEvent;
9798
private boolean initialized;
@@ -131,15 +132,20 @@ public void onSDLEvent(SDL_Event event) {
131132

132133
if (type == SDL_EVENT_WINDOW_FOCUS_GAINED) {
133134
if (event.window().windowID() == context.getWindowId()) {
135+
windowFocused = true;
136+
refreshWindowMetrics();
137+
initCurrentMousePosition();
134138
setCursorVisible(cursorVisible);
135139
}
136140
return;
137141
}
138142

139143
if (type == SDL_EVENT_WINDOW_FOCUS_LOST) {
140144
if (event.window().windowID() == context.getWindowId()) {
145+
windowFocused = false;
141146
x11WarpGrabMode = false;
142147
ignoreNextX11WarpEvent = false;
148+
mouseMotionEvents.clear();
143149
SDL_CaptureMouse(false);
144150
SDL_SetWindowMouseGrab(context.getWindowHandle(), false);
145151
SDL_SetWindowRelativeMouseMode(context.getWindowHandle(), false);
@@ -154,6 +160,9 @@ public void onSDLEvent(SDL_Event event) {
154160
if (event.motion().windowID() != context.getWindowId()) {
155161
return;
156162
}
163+
if (!windowFocused) {
164+
return;
165+
}
157166
refreshWindowMetrics();
158167
final boolean relativeMode = SDL_GetWindowRelativeMouseMode(context.getWindowHandle());
159168
final int x;
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.jme3.input.lwjgl;
2+
3+
import com.jme3.system.lwjgl.LwjglWindow;
4+
import java.lang.reflect.Field;
5+
import java.util.Queue;
6+
import org.junit.jupiter.api.Test;
7+
import org.lwjgl.sdl.SDL_Event;
8+
9+
import static org.junit.jupiter.api.Assertions.assertTrue;
10+
import static org.lwjgl.sdl.SDLEvents.SDL_EVENT_MOUSE_MOTION;
11+
import static org.mockito.Mockito.mock;
12+
import static org.mockito.Mockito.when;
13+
14+
public class SdlMouseInputTest {
15+
16+
@Test
17+
public void shouldIgnoreMouseMotionWhenWindowIsUnfocused() throws Exception {
18+
LwjglWindow context = mock(LwjglWindow.class);
19+
when(context.getWindowId()).thenReturn(7);
20+
21+
SdlMouseInput mouseInput = new SdlMouseInput(context);
22+
setField(mouseInput, "windowFocused", false);
23+
24+
SDL_Event event = SDL_Event.calloc();
25+
try {
26+
event.type(SDL_EVENT_MOUSE_MOTION);
27+
event.motion().windowID(7);
28+
29+
mouseInput.onSDLEvent(event);
30+
} finally {
31+
event.free();
32+
}
33+
34+
Queue<?> mouseMotionEvents = getField(mouseInput, "mouseMotionEvents");
35+
assertTrue(mouseMotionEvents.isEmpty());
36+
}
37+
38+
private static void setField(Object target, String fieldName, Object value) throws Exception {
39+
Field field = target.getClass().getDeclaredField(fieldName);
40+
field.setAccessible(true);
41+
field.set(target, value);
42+
}
43+
44+
@SuppressWarnings("unchecked")
45+
private static <T> T getField(Object target, String fieldName) throws Exception {
46+
Field field = target.getClass().getDeclaredField(fieldName);
47+
field.setAccessible(true);
48+
return (T) field.get(target);
49+
}
50+
}

0 commit comments

Comments
 (0)