Parent visibility not respected on add
- Dominant language
- Python
- Stars
- 5.4k
- Forks
- 827
- Avg merge
- 9h 45m
- Merged PRs (30d)
- 58
Description
### Describe the bug
#2950 fixed inherited visibility in descendant widgets... but not entirely, it turns out. That test verifies that everything behaves as expected when the `visibility` property is set after the widget hierarchy is already established. However, the mechanism that looks up the chain for a hidden ancestor isn't done when *adding* a child.
The simplest fix for this is to put `child.style.apply("visibility", child.style.visibility)` in `Widget.add`, but that seems like mixing concerns — Widget probably shouldn't be special-casing a specific Pack property like that, and it can't be tested in the current `test_apply.py` setup which uses dummy example nodes instead of actual widgets.
Perhaps Pack — or even BaseStyle? – could gain a hook to be called once its node has been added to a new parent. So `child.style.apply("visibility", child.style.visibility)` would become something like `child.style._added_to_new_parent()`, so the style engine can perform whatever inheritance-related checks it needs to do. This could potentially go in `Node.add`. Thoughts?
### Steps to reproduce
```python
def test_set_visibility_inherited_on_add():
"""Nodes should be hidden when added to an already-hidden parent."""
parent = ExampleParentNode("parent", style=Pack(visibility=HIDDEN))
child = ExampleNode("child", style=Pack())
parent.add(child)
child._impl.set_hidden.assert_called_once_with(True)
```
### Expected behavior
A child's on-screen visibility should respect an ancestor's hidden status upon being added as its child.
### Screenshots
_No response_
### Environment
- Toga: Main branch
### Logs
### Additional context
_No response_
Contributor guide
Research direction
Start with Widget.add and Node.add, then read the Pack and BaseStyle behavior involved in inherited visibility. Review test_apply.py and the provided test_set_visibility_inherited_on_add reproduction, noting its use of actual widgets rather than dummy nodes. Done means a child added to an already-hidden parent calls set_hidden(True) without special-casing visibility in Widget.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100