[PR #4068] [CLOSED] Split Pane class into LeafPane and ParentPane + small fixes #25621

Open
opened 2026-01-31 09:10:39 +00:00 by claunia · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/microsoft/terminal/pull/4068
Author: @mcpiroman
Created: 12/27/2019
Status: Closed

Base: mainHead: refactor-pane


📝 Commits (10+)

  • c2d8e27 Now it works
  • 424485f Establish interfaces and majority of implementation, order things in files
  • 816228e Make compile and const qualify
  • 9a26040 Comments, comments and small but important changes and comments
  • 205b395 Fix build
  • b5a04b1 Initial PR fixes that won't tear things apart
  • f9aaed6 Support SplitState::Automatic
  • 58ee87f Small fixes
  • a9b3056 Remove debug crap
  • e02fd89 Explicit format, so there is enough small commits to mess with in rebase

📊 Changes

14 files changed (+1782 additions, -1676 deletions)

View changed files

📝 src/cascadia/LocalTests_TerminalApp/KeyBindingsTests.cpp (+7 -17)
📝 src/cascadia/TerminalApp/ActionArgs.h (+2 -2)
📝 src/cascadia/TerminalApp/ActionArgs.idl (+5 -6)
src/cascadia/TerminalApp/LeafPane.cpp (+511 -0)
src/cascadia/TerminalApp/LeafPane.h (+91 -0)
📝 src/cascadia/TerminalApp/Pane.cpp (+3 -1466)
📝 src/cascadia/TerminalApp/Pane.h (+115 -133)
src/cascadia/TerminalApp/ParentPane.cpp (+788 -0)
src/cascadia/TerminalApp/ParentPane.h (+95 -0)
📝 src/cascadia/TerminalApp/Tab.cpp (+124 -38)
📝 src/cascadia/TerminalApp/Tab.h (+11 -3)
📝 src/cascadia/TerminalApp/TerminalPage.cpp (+13 -11)
📝 src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj (+5 -0)
📝 src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj.filters (+12 -0)

📄 Description

Summary of the Pull Request

Splits implementation of Pane class into LeafPane and ParentPane, both inheriting from, now abstract, Pane. Additionally applies some small fixes along the way. No behavior visible to user (other than one bug) has been changed.

Benefits of this change:

  • Eliminates possibilities of performing operations invalid for given state (e.g. accessing terminal control when the pane is leaf).
  • Makes clear what fields and methods are used in what state (e.g. that border is only used on leafs, which wasn't that obvious).
  • Makes the state immutable (leaf cannot directly become parent and v.v.), which reduces possibilities of broken invariants etc.
  • Makes me sleep better.

PR Checklist

Detailed Description of the Pull Request / Additional comments

About events:

All events that I introduced in LeafPane, ParentPane and Tab are being unsubscribed from in destructors of listener classes, therefore they can safely capture raw this pointer. But there may be other patterns: to always unsubscribe from events (which I've chosen), always capture strong/weak reference, or both (just for the feel of safety). Additionally, weak/strong capturing could also wait for #3999 and #3922. (Btw, if the event handler isn't removed, the listener object is destroyed and the listenee object is alive, then it's a leak, isn't it?)

Off-topic changes:

  • Removed Pane::_createCloseLock mutex - the only source of operations on pane from non-UI thread is ConnectionStateChanged event, which now switches to UI thread by itself.
  • Some event handlers, like TitleChanged, were sometimes registered twice. Now all event handling code is (hopefully) more consolidated.
  • Now all events are properly unsubscribed from.
  • Closed #4057, by setting the value of border that touches the just closed pane to the value from that pane.
  • Removed value None from SplitState as it is no longer needed.
  • Removed Tab::_activePane as it had duplicated state with Pane::_lastActive. It was replaced with calls to Pane::FindActivePane, which is based only on _lastActive.
  • Reviewed and corrected some comments that were still referring to separator after #3060

Other, possible improvement ways:

  • Code in ParentPane::_SetupChildEventHandlers and Tab::_SetupRootPaneEventHandlers is quite similar, esp. in purpose. Maybe try to merge it into some sort of static, template function? Or define small helper class that would hold the pane and handle its replacement, along with its event handlers.
  • Maybe create another class, PaneTree, which would handle the operations on whole tree and the replacement of root pane (which is now the job of tab)., It could also keep track of active pane, instead of holding _lastActive on each pane. Panes would then have a pointer to the tree object they belong to and would be able to query the active pane, or e.g. relayout whole tree.

I've made this draft as to alert everyone on what's going on. I based this PR on #3181 which went furthest into modifications of pane code and I'm going to rebase it when it gets merged.

Validation Steps Performed

Manually tested if all operations on panes work as they did and run Invoke-OpenConsoleTests -AllTests.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/microsoft/terminal/pull/4068 **Author:** [@mcpiroman](https://github.com/mcpiroman) **Created:** 12/27/2019 **Status:** ❌ Closed **Base:** `main` ← **Head:** `refactor-pane` --- ### 📝 Commits (10+) - [`c2d8e27`](https://github.com/microsoft/terminal/commit/c2d8e274afa462af79af13ed10693a079d9c3784) Now it works - [`424485f`](https://github.com/microsoft/terminal/commit/424485f7b28c770e1a04a9ce2ef41132e744403a) Establish interfaces and majority of implementation, order things in files - [`816228e`](https://github.com/microsoft/terminal/commit/816228e447f58d53b54e97db5db2de54711fbb92) Make compile and const qualify - [`9a26040`](https://github.com/microsoft/terminal/commit/9a26040992089f28161322a9a7425408783a392c) Comments, comments and small but important changes and comments - [`205b395`](https://github.com/microsoft/terminal/commit/205b39576cb9970d3d1393998364c9817be1e0ba) Fix build - [`b5a04b1`](https://github.com/microsoft/terminal/commit/b5a04b1e594bb18f9fffdb46647702d9f4b0996d) Initial PR fixes that won't tear things apart - [`f9aaed6`](https://github.com/microsoft/terminal/commit/f9aaed675526a4663b7024e36f334086409c6ebc) Support SplitState::Automatic - [`58ee87f`](https://github.com/microsoft/terminal/commit/58ee87f1c1c1bbeb721dc660fb37a9c41489e0e4) Small fixes - [`a9b3056`](https://github.com/microsoft/terminal/commit/a9b3056136cf5be6416e97932c2d9efbad757763) Remove debug crap - [`e02fd89`](https://github.com/microsoft/terminal/commit/e02fd898c4893cdec5acef15434128a735afb81b) Explicit format, so there is enough small commits to mess with in rebase ### 📊 Changes **14 files changed** (+1782 additions, -1676 deletions) <details> <summary>View changed files</summary> 📝 `src/cascadia/LocalTests_TerminalApp/KeyBindingsTests.cpp` (+7 -17) 📝 `src/cascadia/TerminalApp/ActionArgs.h` (+2 -2) 📝 `src/cascadia/TerminalApp/ActionArgs.idl` (+5 -6) ➕ `src/cascadia/TerminalApp/LeafPane.cpp` (+511 -0) ➕ `src/cascadia/TerminalApp/LeafPane.h` (+91 -0) 📝 `src/cascadia/TerminalApp/Pane.cpp` (+3 -1466) 📝 `src/cascadia/TerminalApp/Pane.h` (+115 -133) ➕ `src/cascadia/TerminalApp/ParentPane.cpp` (+788 -0) ➕ `src/cascadia/TerminalApp/ParentPane.h` (+95 -0) 📝 `src/cascadia/TerminalApp/Tab.cpp` (+124 -38) 📝 `src/cascadia/TerminalApp/Tab.h` (+11 -3) 📝 `src/cascadia/TerminalApp/TerminalPage.cpp` (+13 -11) 📝 `src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj` (+5 -0) 📝 `src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj.filters` (+12 -0) </details> ### 📄 Description ## Summary of the Pull Request Splits implementation of `Pane` class into `LeafPane` and `ParentPane`, both inheriting from, now abstract, `Pane`. Additionally applies some small fixes along the way. No behavior visible to user (other than one bug) has been changed. #### Benefits of this change: - Eliminates possibilities of performing operations invalid for given state (e.g. accessing terminal control when the pane is leaf). - Makes clear what fields and methods are used in what state (e.g. that border is only used on leafs, which wasn't that obvious). - Makes the state immutable (leaf cannot directly become parent and v.v.), which reduces possibilities of broken invariants etc. - Makes me sleep better. ## PR Checklist * [X] Closes #3248 Closes #4057 * [X] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [X] Tests added/passed * [ ] Requires documentation to be updated * [X] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #3248 ## Detailed Description of the Pull Request / Additional comments #### About events: All events that I introduced in `LeafPane`, `ParentPane` and `Tab` are being unsubscribed from in destructors of listener classes, therefore they can safely capture raw this pointer. But there may be other patterns: to always unsubscribe from events (which I've chosen), always capture strong/weak reference, or both (just for the feel of safety). Additionally, weak/strong capturing could also wait for #3999 and #3922. (Btw, if the event handler isn't removed, the listener object is destroyed and the listenee object is alive, then it's a leak, isn't it?) #### Off-topic changes: - Removed `Pane::_createCloseLock` mutex - the only source of operations on pane from non-UI thread is `ConnectionStateChanged` event, which now switches to UI thread by itself. - Some event handlers, like `TitleChanged`, were sometimes registered twice. Now all event handling code is (hopefully) more consolidated. - Now all events are properly unsubscribed from. - Closed #4057, by setting the value of border that touches the just closed pane to the value from that pane. - Removed value `None` from `SplitState` as it is no longer needed. - Removed `Tab::_activePane` as it had duplicated state with `Pane::_lastActive`. It was replaced with calls to `Pane::FindActivePane`, which is based only on `_lastActive`. - Reviewed and corrected some comments that were still referring to separator after #3060 #### Other, possible improvement ways: - Code in `ParentPane::_SetupChildEventHandlers` and `Tab::_SetupRootPaneEventHandlers` is quite similar, esp. in purpose. Maybe try to merge it into some sort of static, template function? Or define small helper class that would hold the pane and handle its replacement, along with its event handlers. - Maybe create another class, `PaneTree`, which would handle the operations on whole tree and the replacement of root pane (which is now the job of tab)., It could also keep track of active pane, instead of holding `_lastActive` on each pane. Panes would then have a pointer to the tree object they belong to and would be able to query the active pane, or e.g. relayout whole tree. I've made this draft as to alert everyone on what's going on. I based this PR on #3181 which went furthest into modifications of pane code and I'm going to rebase it when it gets merged. ## Validation Steps Performed Manually tested if all operations on panes work as they did and run `Invoke-OpenConsoleTests -AllTests`. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
claunia added the pull-request label 2026-01-31 09:10:39 +00:00
Sign in to join this conversation.
No Label pull-request
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#25621