Skip to content

Commit d173c26

Browse files
authored
Merge pull request #4951 from Textualize/escape-minimize
Add classvar ESCAPE_TO_MINIMIZE
2 parents 58d25fb + 3c50b0d commit d173c26

File tree

6 files changed

+432
-3
lines changed

6 files changed

+432
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1010
### Added
1111

1212
- Added `DOMNode.check_consume_key` https://github.com/Textualize/textual/pull/4940
13+
- Added `App.ESCAPE_TO_MINIMIZE`, `App.screen_to_minimize`, and `Screen.ESCAPE_TO_MINIMIZE` https://github.com/Textualize/textual/pull/4951
1314
- Added `DOMNode.query_exactly_one` https://github.com/Textualize/textual/pull/4950
1415
- Added `SelectorSet.is_simple` https://github.com/Textualize/textual/pull/4950
1516

src/textual/app.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,9 +410,18 @@ class MyApp(App[None]):
410410
"""The time in seconds after which a tooltip gets displayed."""
411411

412412
BINDING_GROUP_TITLE = "App"
413+
"""Shown in the key panel."""
414+
415+
ESCAPE_TO_MINIMIZE: ClassVar[bool] = True
416+
"""Use escape key to minimize widgets (potentially overriding bindings).
417+
418+
This is the default value, used if the active screen's `ESCAPE_TO_MINIMIZE` is not changed from `None`.
419+
"""
413420

414421
title: Reactive[str] = Reactive("", compute=False)
422+
"""The title of the app, displayed in the header."""
415423
sub_title: Reactive[str] = Reactive("", compute=False)
424+
"""The app's sub-title, combined with [`title`][textual.app.App.title] in the header."""
416425

417426
dark: Reactive[bool] = Reactive(True, compute=False)
418427
"""Use a dark theme if `True`, otherwise use a light theme.
@@ -3278,7 +3287,11 @@ async def on_event(self, event: events.Event) -> None:
32783287
elif isinstance(event, events.Key):
32793288
# Special case for maximized widgets
32803289
# If something is maximized, then escape should minimize
3281-
if self.screen.maximized is not None and event.key == "escape":
3290+
if (
3291+
self.screen.maximized is not None
3292+
and event.key == "escape"
3293+
and self.escape_to_minimize
3294+
):
32823295
self.screen.minimize()
32833296
return
32843297
if self.focused:
@@ -3300,6 +3313,23 @@ async def on_event(self, event: events.Event) -> None:
33003313
else:
33013314
await super().on_event(event)
33023315

3316+
@property
3317+
def escape_to_minimize(self) -> bool:
3318+
"""Use the escape key to minimize?
3319+
3320+
When a widget is [maximized][textual.screen.Screen.maximize], this boolean determines if the `escape` key will
3321+
minimize the widget (potentially overriding any bindings).
3322+
3323+
The default logic is to use the screen's `ESCAPE_TO_MINIMIZE` classvar if it is set to `True` or `False`.
3324+
If the classvar on the screen is *not* set (and left as `None`), then the app's `ESCAPE_TO_MINIMIZE` is used.
3325+
3326+
"""
3327+
return bool(
3328+
self.ESCAPE_TO_MINIMIZE
3329+
if self.screen.ESCAPE_TO_MINIMIZE is None
3330+
else self.screen.ESCAPE_TO_MINIMIZE
3331+
)
3332+
33033333
def _parse_action(
33043334
self, action: str | ActionParseResult, default_namespace: DOMNode
33053335
) -> tuple[DOMNode, str, tuple[object, ...]]:
@@ -3336,7 +3366,6 @@ def _check_action_state(
33363366
self, action: str, default_namespace: DOMNode
33373367
) -> bool | None:
33383368
"""Check if an action is enabled.
3339-
33403369
Args:
33413370
action: An action string.
33423371

src/textual/screen.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,9 @@ class Screen(Generic[ScreenResultType], Widget):
191191
ALLOW_IN_MAXIMIZED_VIEW: ClassVar[str] = ".-textual-system,Footer"
192192
"""A selector for the widgets (direct children of Screen) that are allowed in the maximized view (in addition to maximized widget)."""
193193

194+
ESCAPE_TO_MINIMIZE: ClassVar[bool | None] = None
195+
"""Use escape key to minimize (potentially overriding bindings) or `None` to defer to [`App.ESCAPE_TO_MINIMIZE`][textual.app.App.ESCAPE_TO_MINIMIZE]."""
196+
194197
maximized: Reactive[Widget | None] = Reactive(None, layout=True)
195198
"""The currently maximized widget, or `None` for no maximized widget."""
196199

0 commit comments

Comments
 (0)