How to get unhandled input from within a Viewport inside SplitContainer?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By mburkard

I have the following node tree where my spatial is a packed scene. node tree

I have static bodies in my scene with the following code.

func _input_event(camera, event, click_position, click_normal, shape_idx):
	if event is InputEventMouseButton and event.button_index == BUTTON_LEFT:
		print("clicked %s" % self)

In order for this to work the mouse input must be unhandled. By default the HSplitContainer will handle any mouse button inputs. I can set the mouse filter to ignore on the HSplitContainer but then I can no longer resize the HSplitContainer since I can’t click on the grabber.

If there’s a way to explicitly set an event as unhandled I can’t find it.

How can I get unhandled mouse inputs inside of my spatial without ignoring mouse events for HSplitContainer?

Hi, did you found a solution?

manuelrivas | 2022-03-24 05:54

I came up with something that worked at least for my use case. In the left pane of my split view I had a HBoxContainer, in the right I had the viewport.

I added some code to change mouse_filter of the splitview to MOUSE_FILTER_IGNORE when the mouse had a greater x value than the left pane of the splitview.

My splitview has the following script attached.

var _divider_offset = 10

func _input(event) -> void:
	if event.position.x < $HBoxContainer.rect_size.x + _divider_offset:
		mouse_filter = MOUSE_FILTER_PASS
	else:
		mouse_filter = MOUSE_FILTER_IGNORE

I was never very happy with this but it works.

mburkard | 2022-03-24 14:59

this is brilliant for a non-native solution, thank you so much!

for anyone wondering in C#, this is my implementation on a script extending VSplitContainer:

	public override void _Input(InputEvent @event)
    {
	    if (@event is InputEventMouseMotion motion)
	    {
		    MouseFilter = (motion.Position.y > _panel.RectSize.y + 10)
                        ? MouseFilterEnum.Ignore 
                        : MouseFilterEnum.Stop;
	    }
	
	    base._Input(@event);
    }

In this case, the _panel is the first panel in my VSplitContainer, I’m dragging a window down from the top.

domportera | 2023-02-01 07:44

I noticed an annoying problem - sometimes I’d lose grip on my VSplitContainer! so I revised the function:

bool _canToggleMouseFilter = true;
public override void _Input(InputEvent @event)
{
	switch (@event)
	{
		case InputEventMouseButton buttonPress:
			_canToggleMouseFilter = !buttonPress.Pressed;
			break;
		case InputEventMouseMotion motion:
			if (_canToggleMouseFilter)
			{
				MouseFilter = motion.Position.y > _panel.RectSize.y + 12
					? MouseFilterEnum.Ignore
					: MouseFilterEnum.Stop;
			}
			break;
	}
	
	base._Input(@event);
}

Feels great to me :slight_smile:

domportera | 2023-02-01 08:17

:bust_in_silhouette: Reply From: Lopy

There is a SceneTree.set_input_as_handled() but no reverse function.

If you override _input(event), it should not matter whether or not the input is marked as handled, only for _unhandled_input(event) or _gui_input(event).

If you really need to, you could set up a “bridge”. Detect the input in a script inside your Node named Node, then transfer the information down to your Spatial.

Hi, can you show how to do that?

manuelrivas | 2022-03-24 05:54