Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keyboard Mapping inconsistency between lwjgl2 and 3 #942

Open
MeFisto94 opened this issue Oct 15, 2018 · 7 comments

Comments

Projects
None yet
5 participants
@MeFisto94
Copy link
Member

commented Oct 15, 2018

This issue might need further testing because I think this was different on Windows than on the linux I am currently seeing this bug. It probably also only affects non-english people but certainly those with a german (QWERTZ) layout. The problem is that lwjgl3 doesn't seem to care about to local keyboard layout and treat it as if it was an us-layout causing confusion.

package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;

/**
 * Small Testcase for (at least) german keyboards: Behavior on "y" is different from lwjgl2 to lwjgl3 (3 doesn't seem
 * to respect the local keyboard mapping)
 * @author normenhansen
 */
public class Main extends SimpleApplication implements ActionListener {

    public static void main(String[] args) {
        Main app = new Main();
        app.start();
    }

    @Override
    public void simpleInitApp() {
        inputManager.addMapping("y", new KeyTrigger(KeyInput.KEY_Y));
        inputManager.addMapping("z", new KeyTrigger(KeyInput.KEY_Z));
        inputManager.addListener(this, "y", "z");
    }

    @Override
    public void onAction(String name, boolean isPressed, float tpf) {
        System.out.println(name + ": " + isPressed);
    }
}

Run this once with lwjgl2 and once with lwjgl3 and in 3 when you press y you actually see "z" printed and vice-versa.

For convenience I've added a slightly modified version of Stephens "BasicGame-on-Gradle" so that it works with the commandline, you just need to comment out lwjgl3 and execute ./gradlew run:
(Gradle doesn't automatically add run otherwise and the mainclass is also a different property)

apply plugin: 'java'
apply plugin: 'application'

// select one source-code option
//sourceCompatibility = '1.6'
//sourceCompatibility = '1.7'
sourceCompatibility = '1.8'

gradle.projectsEvaluated {
    tasks.withType(JavaCompile) {
        options.compilerArgs << '-Xdiags:verbose'
        options.compilerArgs << '-Xlint:unchecked'
        options.deprecation = true
        options.encoding = 'UTF-8'
    }
    tasks.withType(JavaExec) {
        args = []
        classpath sourceSets.main.runtimeClasspath
        //debug true
        enableAssertions true
        jvmArgs '-XX:+UseConcMarkSweepGC'
        //jvmArgs '-XX:+UseG1GC', '-XX:MaxGCPauseMillis=10'
    }
}

// select one version of the Engine
//ext.jmonkeyengineVersion = '3.1.0-stable' // from jcenter
//ext.jmonkeyengineVersion = '3.2.0-stable' // from jcenter
ext.jmonkeyengineVersion = '3.2.1-stable' // from jcenter
//ext.jmonkeyengineVersion = '3.2.1-SNAPSHOT' // from mavenLocal

// NetBeans will automatically add "run" and "debug" tasks relying on the
// "mainClass" property. You may however define the property prior executing
// tasks by passing a "-PmainClass=<QUALIFIED_CLASS_NAME>" argument.
//
// Note however, that you may define your own "run" and "debug" task if you
// prefer. In this case NetBeans will not add these tasks but you may rely on
// your own implementation.
if (!hasProperty('mainClass')) {
    mainClassName = 'mygame.Main'
}

repositories {
    //mavenLocal()
    jcenter()
    //maven { url 'http://nifty-gui.sourceforge.net/nifty-maven-repo' }
    //maven { url 'https://dl.bintray.com/stephengold/org.jmonkeyengine' }
    //google()
    //mavenCentral()
    // Read more about repositories here:
    //   https://docs.gradle.org/current/userguide/dependency_management.html#sec:repositories
}

dependencies {
    // You can read more about how to add dependencies here:
    //   https://docs.gradle.org/current/userguide/dependency_management.html#sec:how_to_declare_your_dependencies

    // from jcenter (or mavenLocal) repositories:
    compile "org.jmonkeyengine:jme3-core:$jmonkeyengineVersion"
    runtime "org.jmonkeyengine:jme3-blender:$jmonkeyengineVersion"
    //compile "org.jmonkeyengine:jme3-bullet:$jmonkeyengineVersion"
    //runtime "org.jmonkeyengine:jme3-bullet-native:$jmonkeyengineVersion"
    runtime "org.jmonkeyengine:jme3-desktop:$jmonkeyengineVersion"
    //compile "org.jmonkeyengine:jme3-effects:$jmonkeyengineVersion"
    //runtime "org.jmonkeyengine:jme3-jogg:$jmonkeyengineVersion"
    //compile "org.jmonkeyengine:jme3-jogl:$jmonkeyengineVersion"
    //compile "org.jmonkeyengine:jme3-networking:$jmonkeyengineVersion"
    //compile "org.jmonkeyengine:jme3-niftygui:$jmonkeyengineVersion"
    runtime "org.jmonkeyengine:jme3-plugins:$jmonkeyengineVersion"
    //compile "org.jmonkeyengine:jme3-terrain:$jmonkeyengineVersion"

    // select one version of LWJGL (from jcenter or mavenLocal)
    //runtime "org.jmonkeyengine:jme3-lwjgl:$jmonkeyengineVersion"
    runtime "org.jmonkeyengine:jme3-lwjgl3:$jmonkeyengineVersion"

    // from stephengold's bintray repositories:
    //runtime 'org.jmonkeyengine:jme3-testdata:3.1.0-stable'
}

// cleanup tasks
clean { dependsOn 'cleanDLLs', 'cleanSOs' }
task cleanDLLs(type: Delete) {
    delete fileTree(dir: '.', include: '*.dll')
}
task cleanSOs(type: Delete) {
    delete fileTree(dir: '.', include: '*.so')
}

I am not sure if this issue isn't within lwjgl3 itself though or rather our "configuration". Maybe it's also already fixed upstream and we just need a newer version

@grizeldi

This comment has been minimized.

Copy link
Contributor

commented Nov 4, 2018

Can confirm, happens with Slovenian QWERTZ keyboard too.

@MeFisto94

This comment has been minimized.

Copy link
Member Author

commented Nov 4, 2018

Great, and he is using Ubuntu 18.10 on Gnome and I was using Kubuntu on 18.04 (KDE), so it's not desktop manage specific. We'd really appreciate a Windows test result, because then maybe our linux lwjgl3 is older (with bullet we had the same issue of not being updated), I'd like to rule that out before contacting the lwjgl guys for advice.

Is someone knowledged about our build system there? @empirephoenix maybe?

@empirephoenix

This comment has been minimized.

Copy link
Contributor

commented Nov 9, 2018

Lwjgl is build by lwjgl itself, we only consume the release jars, while we compile bullet ourselves (as we maintain the wrapper). So it should not be a version issue between operating systems.

I just tested with lwjgl3, my application surprisingly seem to correctly work. On Arch with Xfce, german keyboard

@MeFisto94

This comment has been minimized.

Copy link
Member Author

commented Nov 18, 2018

Soo, I have not read the entire issue but found out it's an intended feature of lwjgl:
glfw/glfw#114

Probably Phoenix had no problems because he was running an older version of lwjgl3?

But we should also find a solution for the described use case, namely:
I code an FPS and want jme to translate the key codes of WASD to the user's current locale key characters. Or maybe have both input listeners for key codes (which would be the absolute position, like keyCode == fromKeyboardLayout(KeyboardLayout.US).W) and for key chars.

This is at least relevant for chat and all so tbh I'd prefer to at least use the key character and the french guys have an uncomfortable layout :P I could actually guess that most gamers use the us layout anyway.

@pspeed42 How would you change/design the jme input system to support both key codes and key chars?

Edit: Ironically these are rather key characters, not as told key codes (as there is no keycode for {).

@pspeed42

This comment has been minimized.

Copy link
Contributor

commented Nov 18, 2018

It already supports key codes and key chars... but note the key chars are adjusted based on modifiers, etc... KEY_M on my keyboard means 'm' and Shift + KEY_M on my keyboard means 'M'.

I'm not sure what the issue is. If you bind your game directly to WASD then that's not going to work on french keyboards no matter what... because their keys are in different places. This is a "Game doesn't let me remap key inputs" issue and not a "JME is broken" issue.

Games should allow players to remap input. If they don't then they only plan to support folks with the same keyboard/mouse/etc. setup that they have.

Or is there some other underlying issue with lwjgl3?

@pspeed42

This comment has been minimized.

Copy link
Contributor

commented Nov 18, 2018

Reading that thread... is your issue that the character code comes in a different event now or something?

@MeFisto94

This comment has been minimized.

Copy link
Member Author

commented Nov 18, 2018

I'm not sure what the issue is. If you bind your game directly to WASD then that's not going to work on french keyboards no matter what... because their keys are in different places.

The real issue is that lwjgl3.2.1 started to always use the US-Layout for key chars to support that use case, where to me the real solution would've been the legacy behavior (if I want to have the key which is on the same position as the US-W, I'd use the key code, otherwise the key char). And I think we should restore that behavior for exact that reason. Otherwise on a non-us-layout you're screwed. Can't display "Press W", can't have a textinput.

Reading that thread... is your issue that the character code comes in a different event now or something?

No, but jme's input events are now related to the US-Layout, no matter what keyboard I have.

Re-reading the issue it might be that I got that wrong. Their issue was that the scancode wasn't propagated to the keycode in earlier versions, which means the keycode reflected the key character. Either way jme's input events don't correlate to the active user layout, probably

final KeyInputEvent released = new KeyInputEvent(KeyInput.KEY_UNKNOWN, keyChar, false, false);
at least the char is only there for KeyInputEvents with KEY_UNKNOWN

Edit: glfw/glfw#114 (comment)
This is all a bit confusing to me, it seems to be related to our gluing code in GlfwKeyInput

@stephengold stephengold changed the title Keyboard Mapping inconsitency between lwjgl2 and 3 Keyboard Mapping inconsistency between lwjgl2 and 3 Mar 6, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.