diff --git a/runelite-client/src/main/java/net/runelite/client/config/Keybind.java b/runelite-client/src/main/java/net/runelite/client/config/Keybind.java index 47bbd64343..23696022d9 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/Keybind.java +++ b/runelite-client/src/main/java/net/runelite/client/config/Keybind.java @@ -28,6 +28,7 @@ import com.google.common.collect.BiMap; import com.google.common.collect.ImmutableBiMap; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; +import javax.annotation.Nullable; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -39,7 +40,7 @@ import lombok.Getter; @EqualsAndHashCode public class Keybind { - private static final BiMap modifierToKeyCode = new ImmutableBiMap.Builder() + private static final BiMap MODIFIER_TO_KEY_CODE = new ImmutableBiMap.Builder() .put(InputEvent.CTRL_DOWN_MASK, KeyEvent.VK_CONTROL) .put(InputEvent.ALT_DOWN_MASK, KeyEvent.VK_ALT) .put(InputEvent.SHIFT_DOWN_MASK, KeyEvent.VK_SHIFT) @@ -47,7 +48,7 @@ public class Keybind .build(); // Bitmask of all supported modifers - private static final int KEYBOARD_MODIFIER_MASK = modifierToKeyCode.keySet().stream() + private static final int KEYBOARD_MODIFIER_MASK = MODIFIER_TO_KEY_CODE.keySet().stream() .reduce((a, b) -> a | b).get(); public static final Keybind NOT_SET = new Keybind(KeyEvent.VK_UNDEFINED, 0); @@ -65,7 +66,7 @@ public class Keybind // If the keybind is just modifiers we don't want the keyCode to contain the modifier too, // becasue this breaks if you do the keycode backwards - Integer mf = modifierToKeyCode.inverse().get(keyCode); + Integer mf = getModifierForKeyCode(keyCode); if (mf != null) { assert (modifiers & mf) != 0; @@ -102,13 +103,18 @@ public class Keybind int keyCode = e.getExtendedKeyCode(); int modifiers = e.getModifiersEx() & KEYBOARD_MODIFIER_MASK; - Integer mf = modifierToKeyCode.inverse().get(keyCode); + Integer mf = getModifierForKeyCode(keyCode); if (mf != null) { modifiers |= mf; keyCode = KeyEvent.VK_UNDEFINED; } + if (e.getID() == KeyEvent.KEY_RELEASED && keyCode != KeyEvent.VK_UNDEFINED) + { + return this.keyCode == keyCode; + } + return this.keyCode == keyCode && this.modifiers == modifiers; } @@ -177,4 +183,10 @@ public class Keybind } return buf.toString(); } + + @Nullable + public static Integer getModifierForKeyCode(int keyCode) + { + return MODIFIER_TO_KEY_CODE.inverse().get(keyCode); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/util/HotkeyListener.java b/runelite-client/src/main/java/net/runelite/client/util/HotkeyListener.java index b8aeaba730..08e26cb871 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/HotkeyListener.java +++ b/runelite-client/src/main/java/net/runelite/client/util/HotkeyListener.java @@ -39,9 +39,15 @@ public abstract class HotkeyListener implements KeyListener @Getter private boolean isPressed = false; + private boolean isConsumingTyped = false; + @Override public void keyTyped(KeyEvent e) { + if (isConsumingTyped) + { + e.consume(); + } } @Override @@ -49,8 +55,18 @@ public abstract class HotkeyListener implements KeyListener { if (keybind.get().matches(e)) { + boolean wasPressed = isPressed; isPressed = true; - hotkeyPressed(); + if (!wasPressed) + { + hotkeyPressed(); + } + if (Keybind.getModifierForKeyCode(e.getKeyCode()) == null) + { + isConsumingTyped = true; + // Only consume non modifier keys + e.consume(); + } } } @@ -60,7 +76,13 @@ public abstract class HotkeyListener implements KeyListener if (keybind.get().matches(e)) { isPressed = false; + isConsumingTyped = false; hotkeyReleased(); + if (Keybind.getModifierForKeyCode(e.getKeyCode()) == null) + { + // Only consume non modifier keys + e.consume(); + } } }