Repository navigation
Understanding focus logic in ContentSwitcher #6136
|
I'm using #!/usr/bin/env -S uv run --script
# /// script
# dependencies = [
# "textual>=6.1.0",
# ]
# ///
from textual.app import App
from textual.widgets import ContentSwitcher
from textual.widgets import Input
from textual.widgets import Static
from textual.containers import Container
class TestApp(App):
def on_input_submitted(self):
cs = self.query_one(ContentSwitcher)
if cs.current == 'input-0':
cs.current = 'input-1'
else:
self.app.exit()
def compose(self):
with ContentSwitcher(initial='input-0'):
yield Input(id='input-0')
yield Input(id='input-1')
if __name__ == '__main__':
TestApp().run(inline=True)This works fine, as the user fills in the first input and submits, the second input will automatically receive the focus. However, if one of the #!/usr/bin/env -S uv run --script
# /// script
# dependencies = [
# "textual>=6.1.0",
# ]
# ///
from textual.app import App
from textual.widgets import ContentSwitcher
from textual.widgets import Input
from textual.widgets import Static
from textual.containers import Container
class TestApp(App):
def on_input_submitted(self):
cs = self.query_one(ContentSwitcher)
if cs.current == 'input-0':
cs.current = 'input-1'
else:
self.app.exit()
def compose(self):
with ContentSwitcher(initial='input-0'):
with Container(id='input-0'):
yield Input()
yield Input(id='input-1')
if __name__ == '__main__':
TestApp().run(inline=True)I know I can manually focus the second input, but I was wondering why the second input does not receive the focus automatically in the second example. |
Replies: 1 comment 1 reply
|
The automatic focus move in the first example comes from hiding the focused
For a form with a known next step, explicitly focus the next input after def on_input_submitted(self):
cs = self.query_one(ContentSwitcher)
if cs.current == "input-0":
cs.current = "input-1"
self.query_one("#input-1", Input).focus()
else:
self.exit()I reproduced both examples with Textual 6.1.0 and 8.2.8 using The relevant implementation is |
The automatic focus move in the first example comes from hiding the focused
Input, rather thanContentSwitcherselecting the next form field.ContentSwitcher.currentchanges which immediate child is displayed. When theold input becomes hidden, Textual resets its focus. In the reset path for a
widget that's no longer in the focus chain, it looks for a visible, focusable
sibling. In your first example,
input-1is a sibling ofinput-0. In thesecond, the focused input is inside the container, so
input-1is not itssibling. That path leaves the app with no focused widget.
For a form with a known next step, explicitly focus the next input after
switching: