godot-cpp icon indicating copy to clipboard operation
godot-cpp copied to clipboard

`Control::gui_input` is not exposed

Open GreenCrowDev opened this issue 1 year ago • 5 comments

Godot version

4.2.1

godot-cpp version

4.2

System information

Windows 11

Issue description

Control::gui_input is not exposed and Control::_gui_input is not its GDExtension counterpart, not allowing sending events to other Control nodes with specific behaviours.

The use case is trying to reproduce the behaviour of Godot visual shader editor add node dialogue, where you can filter the options with a LineEdit on focus, while also being able to go up and down with the keyboard among the filtered member options in the Tree.

immagine

This is the code you want to be able to call to sent events to Tree *member (from https://github.com/godotengine/godot/blob/master/editor/plugins/visual_shader_editor_plugin.cpp)...

void VisualShaderEditor::_sbox_input(const Ref<InputEvent> &p_ie) {
	Ref<InputEventKey> ie = p_ie;
	if (ie.is_valid() && (ie->get_keycode() == Key::UP || ie->get_keycode() == Key::DOWN || ie->get_keycode() == Key::ENTER || ie->get_keycode() == Key::KP_ENTER)) {
		members->gui_input(ie);
		node_filter->accept_event();
	}
}

...but changing members->gui_input(ie); to members->_gui_input(ie); has not the same results, as _gui_input() in GDExtension has only overriding purposes as of now.

I'll quote a comment by @Zylann from https://github.com/Zylann/godot_voxel/blob/master/editor/graph/voxel_graph_node_dialog.cpp as it seems he found the same issue:

// TODO GDX: Control::gui_input() is not exposed to GDExtension, can't forward events. // This is what VisualShaderEditor::_sbox_input does. // _gui_input is exposed, but that's only for user implementation, not for calling directly... // Also gui_input is a name already taken in GDScript, so if it gets exposed some day, it will need a // different name. // // _tree->gui_input(key_event);

Will it be exposed correctly in the future?

Steps to reproduce

As explained in the description, try to use _gui_input() on any Control child class.

Minimal reproduction project

No minimal reproduction project needed.

GreenCrowDev avatar Mar 29 '24 13:03 GreenCrowDev

The gui_input method isn't exposed to scripting, and therefore also not exposed to extensions, sending _gui_input directly in GDScript is not recommended, the virtual callbacks shouldn't be handled that way, so this would first have to be exposed as some input passing method in scripting, but I'm not sure simulating input events is something we should allow

This isn't a bug but a missing feature, so this should be a proposal as it's not specific to GDExtension either

AThousandShips avatar Mar 29 '24 14:03 AThousandShips

I'm not sure simulating input events is something we should allow

If that's the case then core tools shouldn't be allowed to do that either, it's a hack. Instead there should be a regular way of doing it that anyone can use (in particular plugins and extensions).

One thing to note, simulating input can also be useful for writing automatic tests (unless that already exists in some other form?)

Zylann avatar Mar 29 '24 14:03 Zylann

The core tools are different IMO, there's plenty of things that are done on the C++ side, and modules, so I'd say it's not a hack as such when the engine itself does things like this, in controlled ways, though this specific case could probably be handled better by using other features of Tree

But I'm not against adding ways to pass input control like that, but it should be a proposal and be discussed in one

AThousandShips avatar Mar 29 '24 14:03 AThousandShips

As a note, this pattern is also how GridMap filters the list of tiles. Focus is on the LineEdit box, but if you press page up/down, or up/down its forwarded to the ItemList.

https://github.com/godotengine/godot/blob/33c30b9e63a58b860cb2f36957c5e25cee34a627/modules/gridmap/editor/grid_map_editor_plugin.cpp#L817-L825

Has anyone come up with an alternate workflow for extensions to control the ItemList from another Control's _gui_input()?

dmlary avatar Aug 15 '24 00:08 dmlary

I wonder if you could use some focus shenanigans with the Input singleton and it work?

_tree->grab_focus();
Input::get_singleton()->parse_input_event(p_event);
_line_edit->grab_focus();

We used a similar tactic for some similar "action simulation" tasks between different controls and it worked well, but this may be slightly different, so its just a theory.

Naros avatar Aug 15 '24 02:08 Naros