Skip to content

Commit 386473a

Browse files
committed
fix: modifier keys shift, ctrl, alt are not released when a different key is released, related to #1313
1 parent f2b887d commit 386473a

File tree

2 files changed

+52
-10
lines changed

2 files changed

+52
-10
lines changed

fxgl-core/src/main/kotlin/com/almasb/fxgl/input/Input.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,10 @@ class Input {
400400
}
401401

402402
private fun handleReleased(event: InputEvent) {
403-
val releasedTriggers = activeTriggers.filter { it.isReleased(event) || (it is KeyTrigger && isIllegal(it.key)) }
403+
val releasedTriggers = activeTriggers.filter {
404+
// input modifiers are never released under the standard check, so we need the second branch
405+
it.isReleased(event) || (it is KeyTrigger && isIllegal(it.key) && event is KeyEvent && event.code == it.key)
406+
}
404407
releasedTriggers.forEach {
405408
handleTriggerReleased(it)
406409
}

fxgl-core/src/test/kotlin/com/almasb/fxgl/input/InputModifierTest.kt

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import org.hamcrest.CoreMatchers.`is`
1111
import org.hamcrest.MatcherAssert.assertThat
1212
import org.junit.jupiter.api.Assertions.assertFalse
1313
import org.junit.jupiter.api.Assertions.assertTrue
14+
import org.junit.jupiter.api.BeforeEach
1415
import org.junit.jupiter.api.Test
1516

1617
/**
@@ -20,6 +21,13 @@ import org.junit.jupiter.api.Test
2021
*/
2122
class InputModifierTest {
2223

24+
private lateinit var input: Input
25+
26+
@BeforeEach
27+
fun setUp() {
28+
input = Input()
29+
}
30+
2331
@Test
2432
fun `Convert Shift from MouseEvent`() {
2533
val e = mouseEvent(true, false, false)
@@ -116,13 +124,44 @@ class InputModifierTest {
116124
assertTrue(InputModifier.NONE.toKeyCode() == KeyCode.ALPHANUMERIC)
117125
}
118126

119-
// private fun mouseEvent(shift: Boolean, ctrl: Boolean, alt: Boolean): MouseEvent {
120-
// return MouseEvent(MouseEvent.ANY, 0.0, 0.0, 0.0, 0.0, MouseButton.PRIMARY, 1,
121-
// shift, ctrl, alt,
122-
// false, false, false, false, false, false, false, null)
123-
// }
124-
//
125-
// private fun keyEvent(shift: Boolean, ctrl: Boolean, alt: Boolean): KeyEvent {
126-
// return KeyEvent(KeyEvent.ANY, "", "", KeyCode.A, shift, ctrl, alt, false)
127-
// }
127+
@Test
128+
fun `Do not release illegal keys when main key is released`() {
129+
var callsShift = 0
130+
131+
input.addTriggerListener(object : TriggerListener() {
132+
override fun onKey(keyTrigger: KeyTrigger) {
133+
if (keyTrigger.key == KeyCode.SHIFT) {
134+
callsShift++
135+
}
136+
}
137+
138+
override fun onKeyEnd(keyTrigger: KeyTrigger) {
139+
if (keyTrigger.key == KeyCode.SHIFT) {
140+
callsShift = 999
141+
}
142+
}
143+
})
144+
145+
input.update(0.0)
146+
assertThat(callsShift, `is`(0))
147+
148+
// press shift
149+
input.mockKeyPress(KeyCode.SHIFT)
150+
input.update(0.0)
151+
assertThat(callsShift, `is`(1))
152+
153+
// press arbitrary key
154+
input.mockKeyPress(KeyCode.D)
155+
input.update(0.0)
156+
assertThat(callsShift, `is`(2))
157+
158+
// release that arbitrary key
159+
input.mockKeyRelease(KeyCode.D)
160+
input.update(0.0)
161+
assertThat(callsShift, `is`(3))
162+
163+
// shift must still remain to be active
164+
input.update(0.0)
165+
assertThat(callsShift, `is`(4))
166+
}
128167
}

0 commit comments

Comments
 (0)