terminal
terminal copied to clipboard
Add support for resizing panes with mouse
Summary of the Pull Request
Adds support for resizing panes by dragging with the mouse.
ManipulationDelta is the WinUI event we're using to determine if a pane border was dragged. ManipulationDelta is kinda a wacky event in WinUI, but so is the entire Pane structure we've built. The important things to know about this PR are:
- Leaf panes are the only panes that actually have a
Border. - We only handle
ManipulationDeltaevents directly on leaf panes. - Parent panes, however, are the only ones that actually control the position of a split. So we use a special
ManipulationRequestedevent to bubble the request from the leaf pane that was clicked on, to the ancestor pane that actually owns the border on the side of the pane. - We can't just add a
ManipulationDeltaevent handler on the border itself - the event covers all drags in the entire bounding rect of the border. So we've got to use additional logic to make sure that drags originated on a border, not just on content within the border.
Closes #992
other PRs
- #16170
- #16171
- #16172
- #16895 <-- you are here
- #16914
- #16172
- #16171
todo from 06-04 bugbash
- [ ] Pane resize does not snap to cell
- [ ] Pane resize causes a crash(? not sure if this is from that build in general, or specific to this PR)
Demo:
Can we get the mouse cursor to change to ↔️ or ↕️ depending on what border is hovered? How about the omnidirectional arrow in case of an intersection of 4? (Will panes move that way? Can I grab the middle of a + and resize all 4 panes?) Can we get a hover color effect to indicate that there is something actionable here? This is pretty hidden at the minute 🙂
Can we get the mouse cursor to change to ↔️ or ↕️ depending on what border is hovered
maybe but you know first hand how hard that is
maybe but you know first hand how hard that is
Random thought: Make the specific border bolder when the mouse is hovering and the border can be dragged to resize.
Need a visual cue so user is confident that dragging will initiate a resize.
I'm still interested in the QoL/discoverability improvements above - are you going to look into those before this merges?
I'm not sure whether this is the best way to go about it, in particular the bubbling of events to figure out which divider gets dragged seems somewhat... off? I feel like iterating through the tree should accomplish the same thing but be much faster
Would it though? With bubbling, we start at the leaf that is at least adjacent to the border being resized, and only have to iterate O(log(n)) times upwards till at worst, the root, to find the pane that owns the border. Going top down, we'd have to check basically every pane till we found two on opposite sides of the click (right?)
I believe if we go top-down we can similarly decide whether descending in a sub-tree is necessary by checking if the pointer position falls into the current node's rect.
However, I estimate that a single WinRT object instantiation is roughly equivalent to iterating something in the order of dozens of Pane instances, so I believe we could just check all panes if that makes it easier to implement. The position checks are likely to be very cheap. After a divider has initially been grabbed I would suggest saving a weak reference to it so that dragging it doesn't need to walk through the tree at all. This may also double as a "is currently being dragged" state which I imagine may be useful to change the cursor, or the color of the divider, etc., in the future.
Sorry we didn't land this for 1.21 - I was looking over Leonard's concerns and I'm wondering if there's a nice middle ground we can strike!
Just sticking this in here because I'm sure I'll lose it in this notebook after the next couple weeks:
I had tried to mock out what Leonard's approach would be. I was pretty sure there wasn't a middle approach between the two, but doing it top-down would be entirely different.
I'll probably come back to try this after Build
discussion notes:
- skip the top down implementation for now
- add resize handles ala https://github.com/microsoft/terminal/pull/5028