diff --git a/CHANGELOG.md b/CHANGELOG.md index 500ccee7fe..57d0ec3c99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Fixed issues in Kitty terminal after exiting app https://github.com/Textualize/textual/issues/4779 - Fixed exception when removing Selects https://github.com/Textualize/textual/pull/4786 +- Fixed issue with non-clickable Footer keys https://github.com/Textualize/textual/pull/4798 ## [0.73.0] - 2024-07-18 diff --git a/src/textual/app.py b/src/textual/app.py index 7aab856659..1fa10ef0ce 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -3029,7 +3029,7 @@ def simulate_key(self, key: str) -> None: Args: key: Key to simulate. May also be the name of a key, e.g. "space". """ - self.call_later(self._check_bindings, key) + self.post_message(events.Key(key, None)) async def _check_bindings(self, key: str, priority: bool = False) -> bool: """Handle a key press. diff --git a/tests/footer/test_footer.py b/tests/footer/test_footer.py new file mode 100644 index 0000000000..d4ed2d59f8 --- /dev/null +++ b/tests/footer/test_footer.py @@ -0,0 +1,58 @@ +from textual.app import App, ComposeResult +from textual.binding import Binding +from textual.widget import Widget +from textual.widgets import Button, Footer + + +async def test_footer_bindings() -> None: + app_binding_count = 0 + + class TestWidget(Widget, can_focus=True): + BINDINGS = [ + Binding("b", "widget_binding", "Overridden Binding"), + ] + + DEFAULT_CSS = """ + TestWidget { + border: tall $background; + width: 50%; + height: 50%; + content-align: center middle; + + &:focus { + border: tall $accent; + } + } + """ + + def action_widget_binding(self) -> None: + assert False, "should never be called since there is a priority binding" + + class PriorityBindingApp(App): + BINDINGS = [ + Binding("b", "app_binding", "Priority Binding", priority=True), + ] + + CSS = """ + Screen { + align: center middle; + } + """ + + def compose(self) -> ComposeResult: + yield TestWidget() + yield Button("Move Focus") + yield Footer() + + def action_app_binding(self) -> None: + nonlocal app_binding_count + app_binding_count += 1 + + app = PriorityBindingApp() + async with app.run_test() as pilot: + await pilot.pause() + assert app_binding_count == 0 + await pilot.click("Footer", offset=(1, 0)) + assert app_binding_count == 1 + await pilot.click("Footer") + assert app_binding_count == 2