+1 vote

I'm wondering if it's possible to prevent a Control from losing focus when a direction ("up", "down", "left", or "right") is pressed.

Problem: I've made a console GUI with an InputField and I'd like the KEY_UP and KEY_DOWN event scancodes to replace its text with the next element from the command history, while retaining the input focus. The problem is that pressing a direction transfers the input focus to a neighbor Control node in the scene.

Failed Attempt: I tried forcing focus back on the InputField when a direction was pressed, but the transfer seems to happen after the InputField processes the event. For example, the following code does not maintain the input focus:

func _input(event):
    if ( <KEY_UP is pressed, etc.> ):
        var inp = get_node("InputField")
        inp.grab_focus()

# The neighbor above the "InputField" is still selected afterward

Is it possible to make Controls opt out of being selected due to direction input?

I realize it's possible to bounce back focus to the InputField by adding a script to its neighbors, but I'd rather not have to do this for each of a given Control's neighbors every time I'd like to implement a "sticky" input focus behavior.

in Engine by (51 points)
edited by

1 Answer

+1 vote
Best answer

Update: I was able to achieve "sticky" input focus by simply setting the Control's Focus Neighbours to itself. This can be done in a couple of ways:

  • Inspector: Control > Neighbour Focus > ... and assign each neighbour to itself
  • or, with gdscript:

    var sticky_node = get_node("StickyInputNode")
    var node_path = sticky_node.get_path()
    sticky_node.set_focus_neighbour(MARGIN_TOP, node_path)
    sticky_node.set_focus_neighbour(MARGIN_BOTTOM, node_path)
    sticky_node.set_focus_neighbour(MARGIN_LEFT, node_path)
    sticky_node.set_focus_neighbour(MARGIN_RIGHT, node_path)
    
by (51 points)
edited by

I tried your solution and it's not working.

Which Control type did you use to implement your command line? I'd like to do the same.

I'm also trying to use arrow keys to move through command line history, but I ran into a different problem.

I'm using a LineEdit (inherits from Control). Instead of losing focus, pressing Up moves the cursor to the beginning of the text in the LineEdit, and pressing Down moves it to the end.

I tried shortcut_keys_enabled=false but it has no effect on the behavior of the arrow keys.

For now I'm using Alt+P and Alt+N as my history previous/next.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.