Skip to content

Commit

Permalink
Merge pull request #4979 from Textualize/app-focus-style
Browse files Browse the repository at this point in the history
  • Loading branch information
willmcgugan authored Sep 12, 2024
2 parents 05fe60d + ef2281c commit d11ff24
Show file tree
Hide file tree
Showing 4 changed files with 213 additions and 3 deletions.
18 changes: 18 additions & 0 deletions src/textual/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,8 @@ class App(Generic[ReturnType], DOMNode):
App {
background: $background;
color: $text;
/* When a widget is maximized */
Screen.-maximized-view {
layout: vertical !important;
hatch: right $panel;
Expand All @@ -321,6 +323,10 @@ class App(Generic[ReturnType], DOMNode):
dock: initial !important;
}
}
/* Fade the header title when app is blurred */
&:blur HeaderTitle {
text-opacity: 50%;
}
}
*:disabled:can-focus {
opacity: 0.7;
Expand Down Expand Up @@ -820,6 +826,17 @@ def _context(self) -> Generator[None, None, None]:
active_message_pump.reset(message_pump_reset_token)
active_app.reset(app_reset_token)

def get_pseudo_classes(self) -> Iterable[str]:
"""Pseudo classes for a widget.
Returns:
Names of the pseudo classes.
"""
yield "focus" if self.app_focus else "blur"
yield "dark" if self.dark else "light"
if self.is_inline:
yield "inline"

def animate(
self,
attribute: str,
Expand Down Expand Up @@ -3617,6 +3634,7 @@ def post_mount() -> None:

def _watch_app_focus(self, focus: bool) -> None:
"""Respond to changes in app focus."""
self.screen._update_styles()
if focus:
# If we've got a last-focused widget, if it still has a screen,
# and if the screen is still the current screen and if nothing
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 40 additions & 1 deletion tests/snapshot_tests/test_snapshots.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from rich.text import Text

from tests.snapshot_tests.language_snippets import SNIPPETS
from textual import events
from textual.app import App, ComposeResult
from textual.binding import Binding
from textual.containers import Vertical
Expand Down Expand Up @@ -124,7 +125,9 @@ async def run_before(pilot):
pilot.app.query(Input).first().cursor_blink = False

assert snap_compare(
SNAPSHOT_APPS_DIR / "masked_input.py", press=["A","B","C","0","1","-","D","E"], run_before=run_before
SNAPSHOT_APPS_DIR / "masked_input.py",
press=["A", "B", "C", "0", "1", "-", "D", "E"],
run_before=run_before,
)


Expand Down Expand Up @@ -1820,3 +1823,39 @@ def on_mount(self) -> None:

# ctrl+m to maximize, escape *should* minimize
assert snap_compare(TextAreaExample(), press=["ctrl+m", "escape"])


def test_app_focus_style(snap_compare):
"""Test that app blur style can be selected."""

class FocusApp(App):
CSS = """
Label {
padding: 1 2;
margin: 1 2;
background: $panel;
border: $primary;
}
App:focus {
.blurred {
visibility: hidden;
}
}
App:blur {
.focussed {
visibility: hidden;
}
}
"""

def compose(self) -> ComposeResult:
yield Label("BLURRED", classes="blurred")
yield Label("FOCUSED", classes="focussed")

async def run_before(pilot: Pilot) -> None:
pilot.app.post_message(events.AppBlur())
await pilot.pause()

assert snap_compare(FocusApp(), run_before=run_before)
5 changes: 3 additions & 2 deletions tests/test_test_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ def on_key(self, event: events.Key) -> None:

app = TestApp()
async with app.run_test() as pilot:
assert (
str(pilot) == "<Pilot app=TestApp(title='TestApp', classes={'-dark-mode'})>"
assert str(pilot) in (
"<Pilot app=TestApp(title='TestApp', classes={'-dark-mode'}, pseudo_classes={'dark', 'focus'})>",
"<Pilot app=TestApp(title='TestApp', classes={'-dark-mode'}, pseudo_classes={'focus', 'dark'})>",
)
await pilot.press("tab", *"foo")
await pilot.exit("bar")
Expand Down

0 comments on commit d11ff24

Please sign in to comment.