Fix terminal text selection not auto-scrolling when dragging beyond bounds (#9448)

## Description

Fix terminal text selection no longer auto-scrolling downward when drag
exits the scroll container (block list).

**Root cause:** `LeftMouseDragged` events were subject to z-index
coverage checks in `DispatchedEvent::at_z_index()`. When the user
dragged downward past the block list, the cursor entered the area of
higher-z-index UI elements (input/footer), causing `is_covered()` to
return true and the drag events to be filtered out. This prevented the
block list element from receiving drag events, so its auto-scroll logic
(`mouse_dragged()`) never executed.

**Fix:** Bypass z-index filtering for `LeftMouseDragged` events in the
blocklist element specifically when selecting.

Fixes APP-3952

## Testing

Manual testing:
https://www.loom.com/share/0e81bc86229a4e0085b52253ca846346

## Agent Mode
- [x] Warp Agent Mode - This PR was created via Warp's AI Agent Mode

## Changelog Entries for Stable

CHANGELOG-BUG-FIX: Fixed terminal text selection not auto-scrolling when
dragging beyond bounds

---------

Co-authored-by: Oz <oz-agent@warp.dev>
Co-authored-by: oz-for-oss[bot] <277970191+oz-for-oss[bot]@users.noreply.github.com>
This commit is contained in:
Roland Huang
2026-05-05 13:27:23 -05:00
committed by GitHub
parent 3417e7d23a
commit b7dd0ef828

View File

@@ -4430,9 +4430,25 @@ impl Element for BlockListElement {
app: &AppContext,
) -> bool {
let z_index = self.child_max_z_index.expect("Z-index should exist.");
let Some(event_at_z_index) = event.at_z_index(z_index, ctx) else {
// Only proceed if there's a relevant event at this z-index.
return false;
// During an active text selection, bypass the z-index coverage check for
// drag events. The input/footer area below the block list is painted at a
// higher z-index, so `at_z_index` would filter out drags that cross into
// that region — breaking selection auto-scroll when dragging downward.
// This matches the pattern used by SelectableArea, Draggable, Resizable,
// and both Scrollable variants, which all use `raw_event()` for drags.
let event_at_z_index = if self.is_terminal_selecting
&& matches!(
event.raw_event(),
Event::LeftMouseDragged { .. } | Event::LeftMouseUp { .. }
) {
event.raw_event()
} else {
let Some(e) = event.at_z_index(z_index, ctx) else {
// Only proceed if there's a relevant event at this z-index.
return false;
};
e
};
let mut handled = false;