beeware / beeware/toga

Hint ScrollContainers properly in non-scrolling directions

Open
#4,503 4 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Python
Stars
5.4k
Forks
827
Avg merge
15h 39m
Merged PRs (30d)
40

Description

### Describe the bug

On all platforms, when the content of a ScrollContainer has a minimum size in a non-scrollable direction (e.g. a widget with minimum width as the content of a horizontally non-scrollable ScrollContainer), the ScrollContainer is still allowed to shrink in the nonscrollable axis beyond a size necessary to present the content.

### How to reproduce the bug

1. Run the example code
2. See how you can shrink the window beyond 500px which is the minimum size of the content.

### Minimum example code

```shell
import toga
from toga.style import Pack
from toga.style.pack import COLUMN

class ScrollTest(toga.App):
def startup(self):
content = toga.Box()
content.width = 500
content.background_color = "magenta"

scroll = toga.ScrollContainer(
horizontal=False, # disable horizontal scrolling
vertical=True,
content=content,
style=Pack(flex=1),
)

self.main_window = toga.MainWindow(title=self.formal_name)
self.main_window.content = scroll
self.main_window.show()
ScrollTest('1', '2.3').main_loop()
```

### Screenshots

Shrinked window:

Image

Actual minimum size of content:

Image

### Environment details

- Operating system and version: macOS 26.3.1
- Python version: Python 3.13.0
- Software versions:
- Toga: https://github.com/beeware/toga/commit/e9cdbdbb059226df062787f837706124156ab7b5

### Logs

_No response_

### Additional context

I believe that the fix will be in the rehint() of each backend.

The two different scrollbars will interact with the minimum sizing, so that must be handled properly.

On macOS, opaque scrollbars may be shown at all times through a setting, which can be changed at runtime; that must be handled appropriately, even though macOS usually uses a translucent scrollbar.

Contributor guide

Open the contributing guide

Research direction

Start by running the minimum example to reproduce the window shrinking below the content's 500px width. Then inspect rehint() in each backend; done means the non-scrollable axis respects content minimum sizing, including interactions between both scrollbars and runtime changes to macOS scrollbar visibility.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
desktop-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.