GraphiteEditor / GraphiteEditor/Graphite
Resizing a text box by one edge handle incorrectly locks both Max Width and Max Height, silently clipping text
- 主要语言
- Rust
- 星标
- 27.2k
- 派生
- 1.3k
- 平均合并
- 20 小时 5 分钟
- 30 天内合并 PR
- 57
描述
Dragging a single edge handle to resize a text layer's bounding box incorrectly enables and locks both the Max Width and Max Height constraints together, even when only one axis was actually resized. Since Max Height causes any text beyond it to not be drawn, this can silently clip text that should still be auto-growing.
**Steps to reproduce:**
1. Select the Text tool and click (don't drag) to create point text, then type several lines — this creates auto-sized text with neither Max Width nor Max Height enabled
2. Switch to resizing and drag only the right-edge handle of the bounding box to set a width (so the text wraps)
3. Expected: only Max Width becomes active; height keeps auto-growing to fit the rewrapped text
4. Actual: Max Height also gets switched on and frozen to whatever the box's height happened to be before the rewrap — any lines that end up pushed past that frozen height are silently not drawn
**Cause:**
In `editor/src/messages/tool/tool_messages/text_tool.rs`, the `ResizingBounds` → `PointerMove` handler (around lines 851-920) unconditionally sets both `HasMaxWidthInput`/`MaxWidthInput` and `HasMaxHeightInput`/`MaxHeightInput`, regardless of which edge is being dragged. There's actually a TODO comment already sitting right above this code:
// TODO: Don't set both max_width and max_height to true at the same time, only do one based on which edge is being dragged (or both if a corner is being dragged)
The information needed to fix it is already available and just unused: `SelectedEdges { top, bottom, left, right }` in `transformation_cage.rs` records exactly which edge(s) are being dragged, and `new_size()` already leaves `size.y` untouched (equal to the pre-drag height) when only a left/right edge is dragged — that stale value is what's getting wrongly frozen into `MaxHeightInput`.
**Suggested fix:**
Gate the two pairs of `SetInput` calls on which axis was actually touched, per the existing TODO:
let (touches_width, touches_height) = (movement.left || movement.right, movement.top || movement.bottom);
if touches_width {
// set HasMaxWidthInput / MaxWidthInput
}
if touches_height {
// set HasMaxHeightInput / MaxHeightInput
}
A corner-handle drag naturally sets both pairs of edges, so both branches fire together there, matching the "(or both if a corner is being dragged)" note in the TODO.
贡献指南
这个仓库没有索引到贡献指南
调研方向
从 editor/src/messages/tool/tool_messages/text_tool.rs 中 851-920 行附近的 ResizingBounds → PointerMove 处理程序开始,并阅读附近的 TODO。然后检查 transformation_cage.rs 中的 SelectedEdges,以及 new_size() 如何处理单边拖动。完成的标准是:拖动左/右边缘时只启用宽度约束,拖动上/下边缘时只启用高度约束,拖动角点时同时启用两者,并且不会裁剪重新换行的文本。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- rust
- 领域
- computer-graphics
- Issue 类型
- 缺陷
- 难度
- 2/5
- 预计耗时
- 1-3 小时
- 活跃度
- 冷清
- 描述清晰度
- 描述清楚
- 新手友好度
- 78/100