I am upgrading some input handling code from Godot 3.5 to 4.0 and noticed that some parts are not working as expected. So was wondering to check if this might be a bug or intended behaviour which I am not aware of.

Here is the C++ code which I am using in 3.5 to separate generic input events into key, mouse button and mouse motion events.

void _input(Variant event) {
	Ref<InputEvent> input_event = event;

	if (input_event != nullptr) {
		Ref<InputEventKey> input_event_key = event;

		if (input_event_key != nullptr) {
			if (input_event_key->is_pressed()) {
				// Handle keyboard key press
			} else {
				// Handle keyboard key release
			}
		}

		Ref<InputEventMouseButton> input_mouse_button = event;

		if (input_mouse_button != nullptr) {
			int button_index = input_mouse_button->get_button_index();

			if (input_mouse_button->is_pressed()) {
				// Handle left and right mouse button press, and mouse wheel scrolls
				
			} else {
				// Handle left and right mouse button release
			}
		}

		Ref<InputEventMouseMotion> input_mouse_motion = event;

		if (input_mouse_motion != nullptr) {
			// Handle mouse motion
		}
	}
}

This was working well in 3.5. However, when running this in 4.0 all nullptr checks return false and it never goes into if statements. I also tried casting with these ones but it also does not allow me to separate between key, mouse button and mouse motion events. I.e. using static_cast I am never getting nullptr while using dynamic_cast and cast_to always comes as nullptr.

So was wondering if this is intended or it might be a bug? If it's intended then was wondering how could I distinguish between key, mouse button and mouse motion events?

So after some investigation I find out how to handle this separation by using combo of static_cast and is_class. I guess that is a bit more similar to what GDScript is using with is keyword in official docs (i.e. https://docs.godotengine.org/en/stable/tutorials/inputs/input_examples.html). Anyways, here is the code which works in Godot 4 just in case others are strugling with input.

void _input(InputEvent *input_event) {
	bool is_input_event_key = input_event->is_class("InputEventKey");

	if (is_input_event_key) {
		InputEventKey *input_event_key = static_cast<InputEventKey *>(input_event);
		if (input_event_key->is_pressed()) {
			// Handle keyboard key press
		} else {
			// Handle keyboard key release
		}
	}

	bool is_input_event_mouse_button = input_event->is_class("InputEventMouseButton");

	if (is_input_event_mouse_button) {
		InputEventMouseButton *input_event_mouse_button = static_cast<InputEventMouseButton *>(input_event);

		if (input_event_mouse_button->is_pressed()) {
			// Handle left and right mouse button press, and mouse wheel scrolls
			
		} else {
			// Handle left and right mouse button release
		}
	}

	bool is_input_event_mouse_motion = input_event->is_class("InputEventMouseMotion");

	if (is_input_event_mouse_motion) {
		InputEventMouseMotion *input_event_mouse_motion = static_cast<InputEventMouseMotion *>(input_event);
		// Handle mouse motion
	}
}