-
-
Save geekley/5e6daf62d2e86b566c4886f20b604d21 to your computer and use it in GitHub Desktop.
# Public domain, as per The Unlicense. NO WARRANTY. See https://unlicense.org | |
extends Node | |
## Solves a [url=https://github.com/godotengine/godot/issues/59250]bug[/url] where touchpad devices | |
## can be detected as a joypad. | |
## | |
## This script should be autoloaded in the project settings. | |
## This is merely a workaround, not intended for use in production code. | |
func _enter_tree() -> void: | |
_connect_joy_check() | |
queue_free() | |
static func _connect_joy_check() -> void: | |
var _Self: GDScript = (func() -> void:).get_object() as GDScript | |
if Input.joy_connection_changed.connect(Callable(_Self, joy_check.get_method())) != OK: | |
assert(false) | |
pass | |
## Validates a joypad connection. Called for every joypad device connected. | |
## Device names matching the pattern will be disabled (remapped to an empty mapping). | |
static func joy_check(device: int, connected: bool) -> void: | |
if not connected: | |
return | |
var device_name: String = Input.get_joy_name(device) | |
# Uncomment the line below to debug problematic devices: | |
# print('Connected device ', device, ': ', device_name) | |
if not is_banned(device_name): | |
return | |
# If name has matched any banned word, this joypad device should be ignored. | |
var guid: String = Input.get_joy_guid(device) | |
# Disable input by mapping no axes or buttons. Will ignore future joypad input from this device. | |
var mapping: String = guid + ',' + device_name.replace(',', '') | |
Input.add_joy_mapping(mapping, true) | |
# Past input events might have been sent. Reset this device sending 0 on all SDL axes and buttons. | |
for axis: JoyAxis in range(JOY_AXIS_SDL_MAX) as Array[JoyAxis]: | |
var event: InputEventJoypadMotion = InputEventJoypadMotion.new() | |
event.device = device | |
event.axis = axis | |
Input.parse_input_event(event) | |
for button_index: JoyButton in range(JOY_BUTTON_SDL_MAX) as Array[JoyButton]: | |
var event: InputEventJoypadButton = InputEventJoypadButton.new() | |
event.device = device | |
event.button_index = button_index | |
Input.parse_input_event(event) | |
prints('Ignoring joypad device:', mapping) # you can comment out or remove this line | |
## True only if the device name contains a banned word, case-insensitively. | |
## A banned substring only matches if it's guaranteed to be a separate word. | |
static func is_banned(device_name: String) -> bool: | |
for word: String in banned_words: | |
var i: int = device_name.findn(word) | |
if i < 0: | |
continue # this banned word was not found as a substring | |
if i > 0 and not is_ascii_non_letter(device_name[i - 1]): | |
continue # substring found, but it's not guaranteed to start a word | |
var j: int = i + word.length() | |
if j < device_name.length() and not is_ascii_non_letter(device_name[j]): | |
continue # it starts a word, but it's not guaranteed to also end it | |
return true # substring found and guaranteed to form a separate word | |
return false # no banned word found | |
## True only if the character is ASCII and not a letter. | |
static func is_ascii_non_letter(c: String) -> bool: | |
return c.unicode_at(0) < 128 and not (c >= 'a' and c <= 'z' or c >= 'A' and c <= 'Z') | |
## List of words forbidden in joypad names. | |
const banned_words: PackedStringArray = [ | |
'touchpad', 'trackpad', 'clickpad', 'synaptics', | |
'mouse', | |
'pen', 'finger', # drawing tablets | |
'keyboard', | |
'led', | |
] |
Well, neither this list nor this repo's files include this word, so I guess I'll consider it safe to include. I'll update it, thanks @MultisampledNight!
If possible, it would very helpful if you can please confirm it doesn't break accessing multi-touch input as such if desired - e.g. are InputEventScreenTouch and similar events still received?
Btw, if anyone else finds any other devices as false positives or false negatives, please let me know by commenting here too.
I opened a PR to fix the issue in the engine:
Thanks for providing the list of banned words 🙂
Revised to match the PR godotengine/godot#101260, see also godotengine/godot#59250 (comment)
Adding synaptics
as a banned word, since the device name no longer includes "touchpad" after a system update on Linux.
Are you using Linux? A recent (kernel?) update changed the name on the touchpad device in my laptop. [...]
For me, the device name wasSynPS/2 Synaptics TouchPad
, but becameSynaptics TM2768-001
.
Hi! On the Acer Spin 5 on NixOS,
Wacom HID 495F Finger
is also a joypad registered by godot, which is actually the touchscreen. I guess it might make sense to ban the wordfinger
as well?