SidePanel resize direction reverses when pointer crosses anchor edge
- Dominant language
- Rust
- Stars
- 30.6k
- Forks
- 2.1k
- Avg merge
- 1d 9h
- Merged PRs (30d)
- 72
Description
## Description
When dragging a `SidePanel::left` resize separator leftward past x=0 (or a `SidePanel::right` separator past the right window edge), the resize direction **reverses**: further leftward mouse movement causes the panel to grow rightward instead of continuing to shrink.
## Root Cause
`panel.rs` line 268 (egui 0.31.1):
```rust
width = (pointer.x - side.side_x(panel_rect)).abs();
```
The `.abs()` mirrors the signed distance around zero. When `pointer.x` crosses the panel's anchor edge (left edge for a left panel), the expression goes negative — but `.abs()` flips it positive, making the panel grow instead of collapse.
## Steps to Reproduce
1. Create a `SidePanel::left` with `resizable(true)` and a `min_width` of e.g. 96px
2. Drag the resize separator leftward
3. Continue dragging past the left edge of the panel (pointer x < panel left edge)
4. Observe: the panel starts growing again instead of staying at min_width
## Suggested Fix
Remove `.abs()` and let `clamp_to_range` enforce the lower bound:
```rust
// Current (buggy):
width = (pointer.x - side.side_x(panel_rect)).abs();
// Option A — use sign() to get a correctly-signed width:
width = side.sign() * (side.side_x(panel_rect) - pointer.x);
// Then clamp_to_range(width, width_range) naturally handles width < min_width
```
The same pattern affects right panels symmetrically (dragging past the right anchor edge).
## Version
egui 0.31.1
Contributor guide
Research direction
Read panel.rs around line 268 and trace how the side and pointer positions produce the resize width. Reproduce the drag behavior for both left and right SidePanel separators, then verify that dragging past the anchor edge keeps the panel at its minimum width instead of reversing direction.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 38/100