2025-02-13 10:55:06 +00:00
from __future__ import annotations
2025-02-13 10:44:04 +00:00
from typing import Iterable
from textual . app import App , ComposeResult , SystemCommand
from textual . containers import Grid
from textual . screen import ModalScreen , Screen
from textual . widgets import Button , Label
class QuitScreen ( ModalScreen [ bool ] ) :
""" Screen with a dialog to quit. """
def compose ( self ) - > ComposeResult :
yield Grid (
Label ( " Are you sure you want to quit? " , id = " question " ) ,
Button ( " Quit " , variant = " error " , id = " quit " ) ,
Button ( " Cancel " , variant = " primary " , id = " cancel " ) ,
id = " dialog " ,
)
def on_button_pressed ( self , event : Button . Pressed ) - > None :
if event . button . id == " quit " :
self . dismiss ( True )
else :
self . dismiss ( False )
class ModalApp ( App ) :
""" An app with a modal dialog. """
BINDINGS = [ ( " q " , " request_quit " , " Quit " ) ]
def __init__ ( self ) - > None :
self . check_quit_called = False
super ( ) . __init__ ( )
def get_system_commands ( self , screen : Screen ) - > Iterable [ SystemCommand ] :
yield from super ( ) . get_system_commands ( screen )
yield SystemCommand (
" try a modal quit dialog " , " this should work " , self . action_request_quit
)
def action_request_quit ( self ) - > None :
""" Action to display the quit dialog. """
def check_quit ( quit : bool | None ) - > None :
""" Called when QuitScreen is dismissed. """
self . check_quit_called = True
self . push_screen ( QuitScreen ( ) , check_quit )
async def test_command_dismiss ( ) :
""" Regression test for https://github.com/Textualize/textual/issues/5512 """
app = ModalApp ( )
async with app . run_test ( ) as pilot :
await pilot . press ( " ctrl+p " , * " modal quit " , " enter " )
await pilot . pause ( )
await pilot . press ( " enter " )
assert app . check_quit_called