gamepads_linux 0.1.2
gamepads_linux: ^0.1.2 copied to clipboard
Linux implementation of gamepads, a Flutter plugin to handle gamepad input across multiple platforms.
gamepads #
A Flutter plugin to handle gamepad input across multiple platforms.
Gamepads is a Flutter plugin to handle gamepad (or joystick) input across multiple platforms.
It supports multiple simultaneously connected gamepads, and will automatically detect and listen to new connections.
Platform Support #
| Platform | Status |
|---|---|
| Android | Supported |
| iOS | Supported |
| macOS | Supported |
| Linux | Supported |
| Windows | Supported |
| Web | Supported |
Getting Started #
The list method will list all currently connected gamepads:
final gamepads = await Gamepads.list();
// ...
This uses the data class GamepadController, which has an id and a user-facing name.
Listen to normalizedEvents for gamepad input with consistent
button/axis names and value ranges across all platforms:
Gamepads.normalizedEvents.listen((event) {
if (event.button == GamepadButton.a && event.value != 0) {
print('A button pressed!');
}
if (event.axis == GamepadAxis.leftStickX) {
print('Left stick X: ${event.value}');
}
});
The platform is auto-detected. The normalizedEvents stream
is lazy — normalization only runs while there is an active
listener. When nobody is listening, no normalized events are
created.
To override the auto-detected platform, set a custom
normalizer before accessing normalizedEvents:
Gamepads.normalizer = GamepadNormalizer.forPlatform(
GamepadPlatform.linux,
);
Raw Events #
If you need access to the underlying platform-specific events,
use the events stream instead. Note that raw key names and
value ranges differ across platforms (e.g., the A button is
"0" on Linux, "a" on Windows, "buttonA" on iOS,
"KEYCODE_BUTTON_A" on Android, and "button 0" on Web).
Gamepads.events.listen((event) {
// ...
});
You can also listen to events only for a specific gamepad with eventsByGamepad.
Events are described by the data class GamepadEvent:
class GamepadEvent {
/// The id of the gamepad controller that fired the event.
final String gamepadId;
/// The timestamp in which the event was fired, in milliseconds since epoch.
final int timestamp;
/// The [KeyType] of the key that was triggered.
final KeyType type;
/// A platform-dependant identifier for the key that was triggered.
final String key;
/// The current value of the key.
final double value;
// ...
}
Normalized events always preserve the original raw event via
NormalizedGamepadEvent.rawEvent, so you can fall back to
platform-specific handling when needed.
Standard Gamepad Model #
Buttons and axes follow the Xbox/standard gamepad layout:
| Type | Values | Range |
|---|---|---|
Button |
a, b, x, y |
0.0 or 1.0 |
Button |
leftBumper, rightBumper |
0.0 or 1.0 |
Button |
leftTrigger, rightTrigger |
0.0 or 1.0 |
Button |
back, start, home |
0.0 or 1.0 |
Button |
leftStick, rightStick |
0.0 or 1.0 |
Button |
dpadUp/Down/Left/Right |
0.0 or 1.0 |
Axis |
leftStickX, leftStickY |
-1.0 to 1.0 |
Axis |
rightStickX, rightStickY |
-1.0 to 1.0 |
Axis |
leftTrigger, rightTrigger |
0.0 to 1.0 |
Buttons use 0.0 (released) and 1.0 (pressed). Stick conventions: Left/Down = -1, Right/Up = +1.
Platform Details #
iOS / macOS — Uses the GCController API. Button and axis
names are SF Symbols strings (e.g. a.circle, l.joystick),
which the normalizer matches by pattern.
Android — Uses KeyEvent and MotionEvent with
platform-defined key codes (e.g. KEYCODE_BUTTON_A,
AXIS_X). No device-specific lookup needed.
Web — Uses the W3C Gamepad API with the standard mapping.
Buttons and axes are reported as numeric indices (button 0,
analog 0).
Windows — Uses the
GameInput API
v0 which provides consistent named keys (e.g. a, leftThumbstickX)
for all controllers. To compile for windows you need Windows SDK which
gets installed when you setup Windows target for Flutter.
End users do not need Windows SDK.
Linux — Uses raw numeric joystick indices that vary by
controller hardware. The normalizer uses a bundled copy of
the community-maintained
SDL GameController DB
to select the correct mapping by vendor/product ID (1500+
controllers). Unknown controllers fall back to an Xbox-like
layout. You can load additional mappings at runtime via
ControllerDatabase.loadSdlMappings().
Contributing #
If you are interested in helping, please reach out! You can use GitHub or our Discord server.
Android Integration #
The Android implementation requires the application's Activity to forward input events (and input devices) to the plugin. Below is an example of a MainActivity for a clean Flutter project that has implemented the required boilerplate code. For many projects it will be possible to simply duplicate this setup.
package [YOUR_PACKAGE_NAME]
import android.hardware.input.InputManager
import android.os.Handler
import android.view.InputDevice
import android.view.KeyEvent
import android.view.MotionEvent
import io.flutter.embedding.android.FlutterActivity
import org.flame_engine.gamepads_android.GamepadsCompatibleActivity
class MainActivity: FlutterActivity(), GamepadsCompatibleActivity {
var keyListener: ((KeyEvent) -> Boolean)? = null
var motionListener: ((MotionEvent) -> Boolean)? = null
override fun dispatchGenericMotionEvent(motionEvent: MotionEvent): Boolean {
return motionListener?.invoke(motionEvent) ?: false
}
override fun dispatchKeyEvent(keyEvent: KeyEvent): Boolean {
if (keyListener?.invoke(keyEvent) == true) {
return true
}
return super.dispatchKeyEvent(keyEvent)
}
override fun registerInputDeviceListener(
listener: InputManager.InputDeviceListener, handler: Handler?) {
val inputManager = getSystemService(INPUT_SERVICE) as InputManager
inputManager.registerInputDeviceListener(listener, null)
}
override fun registerKeyEventHandler(handler: (KeyEvent) -> Boolean) {
keyListener = handler
}
override fun registerMotionEventHandler(handler: (MotionEvent) -> Boolean) {
motionListener = handler
}
}
Windows troubleshooting #
If you get a compilation error due to missing "GameInput.h" it is because it doesn't find your Windows SDK installation.
Make sure you have setup Windows target for Flutter. It is specifically the step to setup C++ for desktop development that installs Windows SDK.
Neither package users (developers) nor end users needs GameInput redistributable. This is because gamepads uses GameInput API v0 which is statically linked.
Support #
The simplest way to show us your support is by giving the project a star! ⭐
If you want, you can also support us monetarily by donating through OpenCollective:
Through GitHub Sponsors:
Or by becoming a patron on Patreon: