Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

MFi gamepad input not working on macOS when built with Xcode/CMake



  • Hello,

    I am having an issue with gamepad input using the QGamepad classes when using Xcode and CMake. GamepadManager will detect when a gamepad is connected or disconnected, but neither the joysticks nor any of the buttons will identify as receiving input.

    Qt Version: 5.11.2
    macOS Version: 10.4
    Gamepad: steelseries Nimbus (MFi approved device)

    My understanding is that QGamepad uses the Apple libraries on the backend and should handle MFi devices without any configuration or setup. The application I am working on works on windows with an Xbox controller but not on Mac. To test if this was my code I went back to the Qt Gamepad Qt Quick Example. When running this example in QtCreator, all the buttons and joysticks work just fine on macOS, so I started looking at how the application was compiled.

    I copied the sample app project and changed from qmake to cmake for the build system, still using QtCreator to build and run. The app compiled, ran, and all gamepad input worked just fine. I then tried using CMake to generate a Makefile using the same CMakeList file. This also compiled, ran, and handled gamepad input exactly like expected.

    The Xcode project generated by the same CMakeList file compiles and runs. I can print out confirmation from GamepadManager when a gamepad has been connected, but none of the button or joystick input comes through.

    I have looked at the compiler arguments and I don't see anything that would stand out as being "wrong" to me. I'd appreciate any suggestions on things to try or places to look because I'm starting to run out.

    Thanks


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    You should try to start your application with the QT_DEBUG_PLUGINS environment variable set to one. This will show you whether the plugin gets loaded successfully.



  • Hi SGaist. Thanks for the welcome!

    I had not tried the debug plugins env. I'll have to add that to my debug list for future problems.

    Here is what it is printing out (Deleting non-gamepad plugins). Unless I'm reading this incorrectly, the plugins are being loaded. I'm at least not seeing any errors.

    2018-09-25 14:35:06.012767-0500 Gaempad_Testing[1459:91810] Found metadata in lib /Users//Qt/5.11.2/clang_64/qml/QtGamepad/libdeclarative_gamepad.dylib, metadata=
    {
        "IID": "org.qt-project.Qt.QQmlExtensionInterface/1.0",
        "MetaData": {
        },
        "className": "QGamepadModule",
        "debug": false,
        "uri": [
            "QtGamepad"
        ],
        "version": 330498
    }
    2018-09-25 14:35:06.019309-0500 Gaempad_Testing[1459:91810] loaded library "/Users//Qt/5.11.2/clang_64/qml/QtGamepad/libdeclarative_gamepad.dylib"
    2018-09-25 14:35:06.092815-0500 Gaempad_Testing[1459:91719] QFactoryLoader::QFactoryLoader() checking directory path "/Users//Qt/5.11.2/clang_64/plugins/gamepads" ...
    2018-09-25 14:35:06.093076-0500 Gaempad_Testing[1459:91719] QFactoryLoader::QFactoryLoader() looking at "/Users//Qt/5.11.2/clang_64/plugins/gamepads/libdarwingamepad.dylib"
    2018-09-25 14:35:06.093213-0500 Gaempad_Testing[1459:91719] Found metadata in lib /Users//Qt/5.11.2/clang_64/plugins/gamepads/libdarwingamepad.dylib, metadata=
    {
        "IID": "org.qt-project.Qt.Gamepad.QtGamepadBackendFactoryInterface.5.9",
        "MetaData": {
            "Keys": [
                "darwin"
            ]
        },
        "className": "QDarwinGamepadBackendPlugin",
        "debug": false,
        "version": 330498
    }
    2018-09-25 14:35:06.093245-0500 Gaempad_Testing[1459:91719] Got keys from plugin meta data ("darwin")
    2018-09-25 14:35:06.093257-0500 Gaempad_Testing[1459:91719] QFactoryLoader::QFactoryLoader() looking at "/Users//Qt/5.11.2/clang_64/plugins/gamepads/libdarwingamepad_debug.dylib"
    2018-09-25 14:35:06.093864-0500 Gaempad_Testing[1459:91719] Found metadata in lib /Users//Qt/5.11.2/clang_64/plugins/gamepads/libdarwingamepad_debug.dylib, metadata=
    {
        "IID": "org.qt-project.Qt.Gamepad.QtGamepadBackendFactoryInterface.5.9",
        "MetaData": {
            "Keys": [
                "darwin"
            ]
        },
        "className": "QDarwinGamepadBackendPlugin",
        "debug": true,
        "version": 330498
    }
    2018-09-25 14:35:06.093900-0500 Gaempad_Testing[1459:91719] Got keys from plugin meta data ("darwin")
    2018-09-25 14:35:06.093916-0500 Gaempad_Testing[1459:91719] QFactoryLoader::QFactoryLoader() checking directory path "/Users//Downloads/quickGamepad/build_xcode.mac/Debug/Gaempad_Testing.app/Contents/MacOS/gamepads" ...
    2018-09-25 14:35:06.102170-0500 Gaempad_Testing[1459:91719] loaded library "/Users//Qt/5.11.2/clang_64/plugins/gamepads/libdarwingamepad.dylib"
    

    It also looks like it is successfully removing the plugin at application close

    2018-09-25 15:02:55.430173-0500 Gaempad_Testing[1762:111892] QLibraryPrivate::unload succeeded on "/Users//Qt/5.11.2/clang_64/plugins/gamepads/libdarwingamepad.dylib"
    

    I appreciate the help debugging this!


  • Lifetime Qt Champion

    Looks good indeed.

    Did you check if there were any differences when loading the same application built with qmake ?



  • Just checked. Using the .pro that came with the sample app within QtCreator, I'm not seeing anything different in those plugins. Same names, dylibs, version numbers, etc. The same log statements are made in both cases.

    I only checked the plugins that I posted before. I didn't check the imageformat plugins or any of the rest. I can check the differences there if you think it might lead to something.


  • Lifetime Qt Champion

    Try with otool -L to see if there's anything different between the two executable ?



  • I ran otool -L on both the QtCreator executable and the Xcode generated one. I found a couple of system library differences. The QtCreator one included these four system libraries that the Xcode version didn't.

    /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0)
    	/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0)
    	/System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0)
    	/System/Library/Frameworks/AGL.framework/Versions/A/AGL (compatibility version 1.0.0, current version 1.0.0)
    

    I added those to the Xcode project so both executables were linking to the same libraries. All the signatures are exactly the same from otool now and the results are the same. The Xcode generated exe still registers the controller connecting and disconnecting but no button or joystick input. I was hopeful the missing IOKit.framework was the missing key, but that doesn't seem to fix anything.


  • Lifetime Qt Champion

    Strange...

    Can you share your CMakeList.txt and .pro files ?



  • It is absolutely strange. That makes the problem both interesting and incredibly frustrating :)

    I apparently don't have enough privileges to attach these as files but they are pretty short so here are the contents.

    .pro

    TEMPLATE = app
    
    QT += qml quick gamepad
    
    SOURCES += main.cpp
    
    RESOURCES += qml.qrc
    
    target.path = /Users/username/Downloads/quickGamepad
    INSTALLS += target
    
    

    And the CMakeList file

    CMAKE_MINIMUM_REQUIRED(VERSION 3.12.0)
    PROJECT(Gamepad_Testing)
    
    SET(APP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)
    
    FIND_PACKAGE(Qt5 COMPONENTS Gamepad Qml Quick)
    QT5_ADD_RESOURCES(RCC_SOURCES qml.qrc)
    
    SET(APP_TYPE )
    IF(WIN32)
    	SET(APP_TYPE WIN32)
    ELSEIF(APPLE)
    	SET(APP_TYPE MACOSX_BUNDLE)
    ENDIF(WIN32)
    
    ADD_EXECUTABLE(${PROJECT_NAME} ${APP_TYPE} ${APP_SOURCES} ${RCC_SOURCES})
    TARGET_LINK_LIBRARIES(${PROJECT_NAME} Qt5::Gamepad Qt5::Quick Qt5::Qml)
    


  • I have have not yet found a solution to this, but I have found another developer that can confirm they are seeing the same thing. He typically build with Make and could build and run using that CMakeList file to generate a Makefile on Mac. However, when trying to use the Xcode project generated by CMake, the gamepad did not work.

    It would be great if there was anyone else willing to test this to confirm. Otherwise, is there any additional steps someone might suggest?


  • Lifetime Qt Champion

    Can you provide a minimal buildable sample application that shows that behavior.



  • Absolutely. It is the Gamepad example using Qt Quick https://doc.qt.io/qt-5/qtgamepad-quickgamepad-example.html but using a CMakeList file (shown above) instead of the .pro to generate the project. I changed no other code other than that CMakeList file.

    I do not have privileges to upload a file or I would zip up the files and include them for completeness. I can use another method of including the files if there is a recommend method on this forum.



  • I have stripped down the example even further in the hopes this helps. It is zipped up and here is the dropbox link (Here). There is a stripped down CMakeList.txt file to use to build it. A single main.cpp that loads the qml file from the qrc.

    The QML just has a couple of Text objects that are hooked up to show the connecting of the Gamepad and the pressing of the A button from the MFi controller. In this case, a steel series Numbus for Mac.

    When building the application using Xcode, I am initially seeing the gamepad as not connected. The A button does not work. I can power off/on the gamepad multiple times and it always registers correctly as disconnected or connected, but the A button never shows that it works.

    When building the application using Make, I am initially seeing the gamepad as connected (different from Xcode). the A button works as expected and displays true whenever the button is pressed down and False when released. Powering off the controller show it disconnected and powering it back on shows connected again. However, the A button stops correctly showing that it has been pressed. Additionally, turning the gamepad off/on does not change the connected state. It always displays that it is connected (different from Xcode). If the controller was not connected to the computer before launching the app, the I saw the same performance as what was seen after disconnected and reconnecting the controller the first time.

    I was building this using Qt 5.11.2 on MacOS 10.14 using the 10.14 SDK. Clang was used to compile both Xcode and Make.



  • I found a fix for this. The issue was in the CMakeList file. Apparently, the application needs a bundle identifier to be defined to work. So adding this one line to the CMakeList.txt file solved the issue. Hopefully it helps someone else.

    SET(MACOSX_BUNDLE_GUI_IDENTIFIER "com.company.appname")
    

Log in to reply