diff --git a/src/textual/app.py b/src/textual/app.py
index f7296edb6f..e88b52e5f9 100644
--- a/src/textual/app.py
+++ b/src/textual/app.py
@@ -600,7 +600,7 @@ def children(self) -> Sequence["Widget"]:
A sequence of widgets.
"""
try:
- return (self.screen,)
+ return (CommandPalette.current_screen(self),)
except ScreenError:
return ()
diff --git a/src/textual/command.py b/src/textual/command.py
index 1922c296ea..13accb74cb 100644
--- a/src/textual/command.py
+++ b/src/textual/command.py
@@ -475,6 +475,21 @@ def is_open(app: App) -> bool:
"""
return app.screen.id == CommandPalette._PALETTE_ID
+ @staticmethod
+ def current_screen(app: App) -> Screen:
+ """Get the current screen.
+
+ This method gets the current screen for the app, ignoring the
+ command palette.
+
+ Args:
+ app: The app to get the screen for.
+
+ Returns:
+ The current screen for the application, excluding the command palette.
+ """
+ return app.screen_stack[-2] if CommandPalette.is_open(app) else app.screen
+
@property
def _provider_classes(self) -> set[type[Provider]]:
"""The currently available command providers.
@@ -519,8 +534,8 @@ def _on_click(self, event: Click) -> None:
self.dismiss()
def on_mount(self, _: Mount) -> None:
- """Capture the calling screen."""
- self._calling_screen = self.app.screen_stack[-2]
+ """Configure the command palette once the DOM is ready."""
+ self._calling_screen = self.current_screen(self.app)
match_style = self.get_component_rich_style(
"command-palette--highlight", partial=True
diff --git a/tests/command_palette/test_click_away.py b/tests/command_palette/test_click_away.py
index 383f39cdb2..ad8f989113 100644
--- a/tests/command_palette/test_click_away.py
+++ b/tests/command_palette/test_click_away.py
@@ -20,6 +20,6 @@ def on_mount(self) -> None:
async def test_clicking_outside_command_palette_closes_it() -> None:
"""Clicking 'outside' the command palette should make it go away."""
async with CommandPaletteApp().run_test() as pilot:
- assert len(pilot.app.query(CommandPalette)) == 1
+ assert isinstance(pilot.app.screen, CommandPalette)
await pilot.click()
- assert len(pilot.app.query(CommandPalette)) == 0
+ assert not isinstance(pilot.app.screen, CommandPalette)
diff --git a/tests/command_palette/test_command_source_environment.py b/tests/command_palette/test_command_source_environment.py
index af9b691d70..b34d9fff04 100644
--- a/tests/command_palette/test_command_source_environment.py
+++ b/tests/command_palette/test_command_source_environment.py
@@ -31,7 +31,7 @@ def on_mount(self) -> None:
async def test_command_source_environment() -> None:
"""The command source should see the app and default screen."""
async with CommandPaletteApp().run_test() as pilot:
- base_screen = pilot.app.query_one(CommandPalette)._calling_screen
+ base_screen = CommandPalette.current_screen(pilot.app)
assert base_screen is not None
await pilot.press(*"test")
assert len(SimpleSource.environment) == 1
diff --git a/tests/command_palette/test_declare_sources.py b/tests/command_palette/test_declare_sources.py
index c5bae17904..fd411d4c5e 100644
--- a/tests/command_palette/test_declare_sources.py
+++ b/tests/command_palette/test_declare_sources.py
@@ -28,7 +28,8 @@ class AppWithNoSources(AppWithActiveCommandPalette):
async def test_no_app_command_sources() -> None:
"""An app with no sources declared should work fine."""
async with AppWithNoSources().run_test() as pilot:
- assert pilot.app.query_one(CommandPalette)._provider_classes == App.COMMANDS
+ assert isinstance(pilot.app.screen, CommandPalette)
+ assert pilot.app.screen._provider_classes == App.COMMANDS
class AppWithSources(AppWithActiveCommandPalette):
@@ -38,10 +39,8 @@ class AppWithSources(AppWithActiveCommandPalette):
async def test_app_command_sources() -> None:
"""Command sources declared on an app should be in the command palette."""
async with AppWithSources().run_test() as pilot:
- assert (
- pilot.app.query_one(CommandPalette)._provider_classes
- == AppWithSources.COMMANDS
- )
+ assert isinstance(pilot.app.screen, CommandPalette)
+ assert pilot.app.screen._provider_classes == AppWithSources.COMMANDS
class AppWithInitialScreen(App[None]):
@@ -61,7 +60,8 @@ def on_mount(self) -> None:
async def test_no_screen_command_sources() -> None:
"""An app with a screen with no sources declared should work fine."""
async with AppWithInitialScreen(ScreenWithNoSources()).run_test() as pilot:
- assert pilot.app.query_one(CommandPalette)._provider_classes == App.COMMANDS
+ assert isinstance(pilot.app.screen, CommandPalette)
+ assert pilot.app.screen._provider_classes == App.COMMANDS
class ScreenWithSources(ScreenWithNoSources):
@@ -71,8 +71,9 @@ class ScreenWithSources(ScreenWithNoSources):
async def test_screen_command_sources() -> None:
"""Command sources declared on a screen should be in the command palette."""
async with AppWithInitialScreen(ScreenWithSources()).run_test() as pilot:
+ assert isinstance(pilot.app.screen, CommandPalette)
assert (
- pilot.app.query_one(CommandPalette)._provider_classes
+ pilot.app.screen._provider_classes
== App.COMMANDS | ScreenWithSources.COMMANDS
)
@@ -91,7 +92,8 @@ def on_mount(self) -> None:
async def test_app_and_screen_command_sources_combine() -> None:
"""If an app and the screen have command sources they should combine."""
async with CombinedSourceApp().run_test() as pilot:
+ assert isinstance(pilot.app.screen, CommandPalette)
assert (
- pilot.app.query_one(CommandPalette)._provider_classes
+ pilot.app.screen._provider_classes
== CombinedSourceApp.COMMANDS | ScreenWithSources.COMMANDS
)
diff --git a/tests/command_palette/test_escaping.py b/tests/command_palette/test_escaping.py
index 2ac2013b6c..83bf36ad15 100644
--- a/tests/command_palette/test_escaping.py
+++ b/tests/command_palette/test_escaping.py
@@ -20,31 +20,31 @@ def on_mount(self) -> None:
async def test_escape_closes_when_no_list_visible() -> None:
"""Pressing escape when no list is visible should close the command palette."""
async with CommandPaletteApp().run_test() as pilot:
- assert len(pilot.app.query(CommandPalette)) == 1
+ assert CommandPalette.is_open(pilot.app)
await pilot.press("escape")
- assert len(pilot.app.query(CommandPalette)) == 0
+ assert not CommandPalette.is_open(pilot.app)
async def test_escape_does_not_close_when_list_visible() -> None:
"""Pressing escape when a hit list is visible should not close the command palette."""
async with CommandPaletteApp().run_test() as pilot:
- assert len(pilot.app.query(CommandPalette)) == 1
+ assert CommandPalette.is_open(pilot.app)
await pilot.press("a")
await pilot.press("escape")
- assert len(pilot.app.query(CommandPalette)) == 1
+ assert CommandPalette.is_open(pilot.app)
await pilot.press("escape")
- assert len(pilot.app.query(CommandPalette)) == 0
+ assert not CommandPalette.is_open(pilot.app)
async def test_down_arrow_should_undo_closing_of_list_via_escape() -> None:
"""Down arrow should reopen the hit list if escape closed it before."""
async with CommandPaletteApp().run_test() as pilot:
- assert len(pilot.app.query(CommandPalette)) == 1
+ assert CommandPalette.is_open(pilot.app)
await pilot.press("a")
await pilot.press("escape")
- assert len(pilot.app.query(CommandPalette)) == 1
+ assert CommandPalette.is_open(pilot.app)
await pilot.press("down")
await pilot.press("escape")
- assert len(pilot.app.query(CommandPalette)) == 1
+ assert CommandPalette.is_open(pilot.app)
await pilot.press("escape")
- assert len(pilot.app.query(CommandPalette)) == 0
+ assert not CommandPalette.is_open(pilot.app)
diff --git a/tests/command_palette/test_interaction.py b/tests/command_palette/test_interaction.py
index d243a35565..f5d64093b4 100644
--- a/tests/command_palette/test_interaction.py
+++ b/tests/command_palette/test_interaction.py
@@ -21,46 +21,46 @@ def on_mount(self) -> None:
async def test_initial_list_no_highlight() -> None:
"""When the list initially appears, nothing will be highlighted."""
async with CommandPaletteApp().run_test() as pilot:
- assert len(pilot.app.query(CommandPalette)) == 1
- assert pilot.app.query_one(CommandList).visible is False
+ assert CommandPalette.is_open(pilot.app)
+ assert pilot.app.screen.query_one(CommandList).visible is False
await pilot.press("a")
- assert pilot.app.query_one(CommandList).visible is True
- assert pilot.app.query_one(CommandList).highlighted is None
+ assert pilot.app.screen.query_one(CommandList).visible is True
+ assert pilot.app.screen.query_one(CommandList).highlighted is None
async def test_down_arrow_selects_an_item() -> None:
"""Typing in a search value then pressing down should select a command."""
async with CommandPaletteApp().run_test() as pilot:
- assert len(pilot.app.query(CommandPalette)) == 1
- assert pilot.app.query_one(CommandList).visible is False
+ assert CommandPalette.is_open(pilot.app)
+ assert pilot.app.screen.query_one(CommandList).visible is False
await pilot.press("a")
- assert pilot.app.query_one(CommandList).visible is True
- assert pilot.app.query_one(CommandList).highlighted is None
+ assert pilot.app.screen.query_one(CommandList).visible is True
+ assert pilot.app.screen.query_one(CommandList).highlighted is None
await pilot.press("down")
- assert pilot.app.query_one(CommandList).highlighted is not None
+ assert pilot.app.screen.query_one(CommandList).highlighted is not None
async def test_enter_selects_an_item() -> None:
"""Typing in a search value then pressing enter should select a command."""
async with CommandPaletteApp().run_test() as pilot:
- assert len(pilot.app.query(CommandPalette)) == 1
- assert pilot.app.query_one(CommandList).visible is False
+ assert CommandPalette.is_open(pilot.app)
+ assert pilot.app.screen.query_one(CommandList).visible is False
await pilot.press("a")
- assert pilot.app.query_one(CommandList).visible is True
- assert pilot.app.query_one(CommandList).highlighted is None
+ assert pilot.app.screen.query_one(CommandList).visible is True
+ assert pilot.app.screen.query_one(CommandList).highlighted is None
await pilot.press("enter")
- assert pilot.app.query_one(CommandList).highlighted is not None
+ assert pilot.app.screen.query_one(CommandList).highlighted is not None
async def test_selection_of_command_closes_command_palette() -> None:
"""Selecting a command from the list should close the list."""
async with CommandPaletteApp().run_test() as pilot:
- assert len(pilot.app.query(CommandPalette)) == 1
- assert pilot.app.query_one(CommandList).visible is False
+ assert CommandPalette.is_open(pilot.app)
+ assert pilot.app.screen.query_one(CommandList).visible is False
await pilot.press("a")
- assert pilot.app.query_one(CommandList).visible is True
- assert pilot.app.query_one(CommandList).highlighted is None
+ assert pilot.app.screen.query_one(CommandList).visible is True
+ assert pilot.app.screen.query_one(CommandList).highlighted is None
await pilot.press("enter")
- assert pilot.app.query_one(CommandList).highlighted is not None
+ assert pilot.app.screen.query_one(CommandList).highlighted is not None
await pilot.press("enter")
- assert len(pilot.app.query(CommandPalette)) == 0
+ assert not CommandPalette.is_open(pilot.app)
diff --git a/tests/command_palette/test_no_results.py b/tests/command_palette/test_no_results.py
index 400e69c28c..de4956262f 100644
--- a/tests/command_palette/test_no_results.py
+++ b/tests/command_palette/test_no_results.py
@@ -13,7 +13,7 @@ def on_mount(self) -> None:
async def test_no_results() -> None:
"""Receiving no results from a search for a command should not be a problem."""
async with CommandPaletteApp().run_test() as pilot:
- assert len(pilot.app.query(CommandPalette)) == 1
+ assert CommandPalette.is_open(pilot.app)
results = pilot.app.screen.query_one(OptionList)
assert results.visible is False
assert results.option_count == 0
diff --git a/tests/command_palette/test_run_on_select.py b/tests/command_palette/test_run_on_select.py
index a652096b56..31946a127b 100644
--- a/tests/command_palette/test_run_on_select.py
+++ b/tests/command_palette/test_run_on_select.py
@@ -37,7 +37,7 @@ async def test_with_run_on_select_on() -> None:
assert isinstance(pilot.app, CommandPaletteRunOnSelectApp)
pilot.app.action_command_palette()
await pilot.press("0")
- await pilot.app.query_one(CommandPalette).workers.wait_for_complete()
+ await pilot.app.screen.workers.wait_for_complete()
await pilot.press("down")
await pilot.press("enter")
assert pilot.app.selection is not None
@@ -57,11 +57,11 @@ async def test_with_run_on_select_off() -> None:
assert isinstance(pilot.app, CommandPaletteDoNotRunOnSelectApp)
pilot.app.action_command_palette()
await pilot.press("0")
- await pilot.app.query_one(CommandPalette).workers.wait_for_complete()
+ await pilot.app.screen.workers.wait_for_complete()
await pilot.press("down")
await pilot.press("enter")
assert pilot.app.selection is None
- assert pilot.app.query_one(Input).value != ""
+ assert pilot.app.screen.query_one(Input).value != ""
await pilot.press("enter")
assert pilot.app.selection is not None
CommandPalette.run_on_select = save
diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr
index 65901f8f26..5d649d2575 100644
--- a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr
+++ b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr
@@ -2831,136 +2831,137 @@
font-weight: 700;
}
- .terminal-3973201778-matrix {
+ .terminal-3683073661-matrix {
font-family: Fira Code, monospace;
font-size: 20px;
line-height: 24.4px;
font-variant-east-asian: full-width;
}
- .terminal-3973201778-title {
+ .terminal-3683073661-title {
font-size: 18px;
font-weight: bold;
font-family: arial;
}
- .terminal-3973201778-r1 { fill: #a2a2a2 }
- .terminal-3973201778-r2 { fill: #c5c8c6 }
- .terminal-3973201778-r3 { fill: #004578 }
- .terminal-3973201778-r4 { fill: #00ff00 }
- .terminal-3973201778-r5 { fill: #e2e3e3 }
- .terminal-3973201778-r6 { fill: #1e1e1e }
- .terminal-3973201778-r7 { fill: #fea62b;font-weight: bold }
+ .terminal-3683073661-r1 { fill: #a2a2a2 }
+ .terminal-3683073661-r2 { fill: #c5c8c6 }
+ .terminal-3683073661-r3 { fill: #004578 }
+ .terminal-3683073661-r4 { fill: #00ff00 }
+ .terminal-3683073661-r5 { fill: #24292f }
+ .terminal-3683073661-r6 { fill: #e2e3e3 }
+ .terminal-3683073661-r7 { fill: #1e1e1e }
+ .terminal-3683073661-r8 { fill: #fea62b;font-weight: bold }
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
- CommandPaletteApp
+ CommandPaletteApp
-
+
-
-
-
-
- ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
-
- 🔎A
-
-
- This is a test of this code 9
- This is a test of this code 8
- This is a test of this code 7
- This is a test of this code 6
- This is a test of this code 5
- This is a test of this code 4
- This is a test of this code 3
- This is a test of this code 2
- This is a test of this code 1
- This is a test of this code 0
- ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
-
-
-
-
+
+
+
+
+ ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
+
+ 🔎A
+
+
+ This is a test of this code 9
+ This is a test of this code 8
+ This is a test of this code 7
+ This is a test of this code 6
+ This is a test of this code 5
+ This is a test of this code 4
+ This is a test of this code 3
+ This is a test of this code 2
+ This is a test of this code 1
+ This is a test of this code 0
+ ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
+
+
+
+
diff --git a/tests/snapshot_tests/test_snapshots.py b/tests/snapshot_tests/test_snapshots.py
index 6856c89d74..d39e47b8f5 100644
--- a/tests/snapshot_tests/test_snapshots.py
+++ b/tests/snapshot_tests/test_snapshots.py
@@ -669,15 +669,12 @@ async def run_before(pilot) -> None:
def test_command_palette(snap_compare) -> None:
- from textual.command import CommandPalette
async def run_before(pilot) -> None:
- palette = pilot.app.query_one(CommandPalette)
- palette_input = palette.query_one(Input)
- palette_input.cursor_blink = False
- await pilot.press("ctrl+backslash")
+ #await pilot.press("ctrl+backslash")
+ pilot.app.screen.query_one(Input).cursor_blink = False
await pilot.press("A")
- await pilot.app.query_one(CommandPalette).workers.wait_for_complete()
+ await pilot.app.screen.workers.wait_for_complete()
assert snap_compare(SNAPSHOT_APPS_DIR / "command_palette.py", run_before=run_before)