Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix missing new widgets #5048

Merged
merged 5 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

- Tree will no longer scroll the X axis when moving the cursor https://github.com/Textualize/textual/pull/5047

### Fixed

- Fixed widgets occasionally not getting Resize events https://github.com/Textualize/textual/pull/5048

## [0.80.1] - 2024-09-24

### Fixed
Expand Down
10 changes: 8 additions & 2 deletions src/textual/_compositor.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,9 @@ def __init__(self) -> None:
# Mapping of line numbers on to lists of widget and regions
self._layers_visible: list[list[tuple[Widget, Region, Region]]] | None = None

# New widgets added between updates
self._new_widgets: set[Widget] = set()

def clear(self) -> None:
"""Remove all references to widgets (used when the screen closes)."""
self._full_map.clear()
Expand Down Expand Up @@ -387,7 +390,9 @@ def reflow(self, parent: Widget, size: Size) -> ReflowResult:
new_widgets = map.keys()

# Newly visible widgets
shown_widgets = new_widgets - old_widgets
shown_widgets = (new_widgets - old_widgets) | self._new_widgets
self._new_widgets.clear()

# Newly hidden widgets
hidden_widgets = self.widgets - widgets

Expand Down Expand Up @@ -419,7 +424,6 @@ def reflow(self, parent: Widget, size: Size) -> ReflowResult:
for widget, (region, *_) in changes
if (widget in common_widgets and old_map[widget].region[2:] != region[2:])
}

return ReflowResult(
hidden=hidden_widgets,
shown=shown_widgets,
Expand Down Expand Up @@ -483,6 +487,8 @@ def full_map(self) -> CompositorMap:
if self._full_map_invalidated:
self._full_map_invalidated = False
map, _widgets = self._arrange_root(self.root, self.size, visible_only=False)
# Update any widgets which became visible in the interim
self._new_widgets.update(map.keys() - self._full_map.keys())
self._full_map = map
self._visible_widgets = None
self._visible_map = None
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
33 changes: 30 additions & 3 deletions tests/snapshot_tests/test_snapshots.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from textual import events
from textual.app import App, ComposeResult
from textual.binding import Binding
from textual.containers import Vertical
from textual.containers import Vertical, VerticalScroll
from textual.pilot import Pilot
from textual.screen import Screen
from textual.widgets import (
Expand All @@ -24,8 +24,7 @@
OptionList,
SelectionList,
)
from textual.widgets import Switch
from textual.widgets import Label
from textual.widgets import ProgressBar, Label, Switch
from textual.widgets.text_area import BUILTIN_LANGUAGES, Selection, TextAreaTheme

# These paths should be relative to THIS directory.
Expand Down Expand Up @@ -1992,3 +1991,31 @@ def on_mount(self) -> None:

app = DisabledApp()
assert snap_compare(app)


def test_missing_new_widgets(snap_compare):
"""Regression test for https://github.com/Textualize/textual/issues/5024"""

class MRE(App):
BINDINGS = [("z", "toggle_console", "Console")]
CSS = """
RichLog { border-top: dashed blue; height: 6; }
.hidden { display: none; }
"""

def compose(self):
yield VerticalScroll()
yield ProgressBar(
classes="hidden"
) # removing or displaying this widget prevents the bug
yield Footer() # clicking "Console" in the footer prevents the bug
yield RichLog(classes="hidden")

def on_ready(self) -> None:
self.query_one(RichLog).write("\n".join(f"line #{i}" for i in range(5)))

def action_toggle_console(self) -> None:
self.query_one(RichLog).toggle_class("hidden")

app = MRE()
assert snap_compare(app, press=["space", "space", "z"])
Loading