Skip to content

Retain maximized group size when adding and removing groups or toggling side bar#137962

Merged
joaomoreno merged 12 commits intomicrosoft:mainfrom
ssigwart:maxGrpSize
Dec 22, 2022
Merged

Retain maximized group size when adding and removing groups or toggling side bar#137962
joaomoreno merged 12 commits intomicrosoft:mainfrom
ssigwart:maxGrpSize

Conversation

@ssigwart
Copy link
Contributor

This PR fixes #137865
This PR fixes #70083

When an editor group is maximized, the active group will remain maximized as you add and remove splits or toggle the side bar.

@joaomoreno
Copy link
Member

The SplitView already supports layout priorities. Could the EditorPart fix this by using layout priorities? Eg: when a view is maximized, set its priority to High.

@joaomoreno joaomoreno assigned bpasero and sbatten and unassigned joaomoreno Nov 29, 2021
@joaomoreno joaomoreno self-requested a review November 29, 2021 13:33
@bpasero bpasero added this to the On Deck milestone Nov 29, 2021
@ssigwart
Copy link
Contributor Author

Thanks for the quick review, @joaomoreno.

There is no setter for priority. I could add one and update GridView.maximizeViewSize to set the priority, but then I'd need to reset the priority on the other views here:

for (let i = 0; i < ancestors.length; i++) {
ancestors[i].resizeChild(location[i], Number.POSITIVE_INFINITY);
}

However, I don't think I can set it back to LayoutPriority.Normal because I don't know if that was the original setting. I can add another variable for the initial setting, but that's another variable to store. Even after that, I don't think setting the priority work because the priorities are used in the following flow, but in this case, we already have proportions:

if (!this.proportions) {
const indexes = range(this.viewItems.length);
const lowPriorityIndexes = indexes.filter(i => this.viewItems[i].priority === LayoutPriority.Low);
const highPriorityIndexes = indexes.filter(i => this.viewItems[i].priority === LayoutPriority.High);
this.resize(this.viewItems.length - 1, size - previousSize, undefined, lowPriorityIndexes, highPriorityIndexes);
} else {

So I think I'd still need to update the following anyway:

} else {
for (let i = 0; i < this.viewItems.length; i++) {
const item = this.viewItems[i];
item.size = clamp(Math.round(this.proportions[i] * size), item.minimumSize, item.maximumSize);
}
}

It's possible that I could revert adding the following code if I set the priority.

// Only resize non-minimized items
if (item.size !== item.minimumSize) {

However, I'm not sure if it's worth having to add a getter and save the original priority. What do you think?

@joaomoreno
Copy link
Member

joaomoreno commented Nov 30, 2021

The grid/splitview can't modify priority, they only read the value. The views themselves set it. The user of the grid (EditorPart) would coordinate across its views and set their priorities accordingly.


But on second thought maybe that's too crazy. Let's tackle both issues individually and start with #70083 first.

The maximized state isn't preserved across layout calls. If we fix it, we don't want to change the default spltiview behavior, but add/modify an option. What if we have a different type for proportionalLayout? Like:

export enum ProportionalLayout {
    Enabled,
    DisabledWhenViewMaximized,
    Disabled
}

export interface ISplitViewOptions<TLayoutContext = undefined> {
	/**
	 * Resize each view proportionally when resizing the SplitView.
	 *
	 * @defaultValue `true`
	 */
	readonly proportionalLayout?: boolean | ProportionalLayout;
}

That way, we can preserve a maximized view's state across layout() calls. We can even have tests for this. The problem is what happens when the user resizes the splitview until it reaches the sum of all minimum sizes: at that point no view will be maximized any more. So, growing the splitview from then on would make it grow all views proportionally. This is why using layout priorities would be benefitial here. But we can also live with that behavior.


As for #137865, the grid/splitview already supports sizing options when adding views. The EditorPart just mostly uses Sizing.Distribute, which causes today's behavior. I would first try to fix the issue by using a different sizing option here.

@ssigwart
Copy link
Contributor Author

ssigwart commented Dec 1, 2021

Thanks for all the details, @joaomoreno. I tried looking into it, but I'm not all the familiar with the code, so I didn't make it too far. I'll try to work on in over the next week. For both issues, I probably still need to add a function to determine if there is a maximized view first, right? For #70083, I'd need to check that if DisabledWhenViewMaximized is set. For #137865, I'd need to know that to know if I should set Sizing.Distribute or not.

For #70083, essentially, I would keep the following code, but only use it if DisabledWhenViewMaximized is set, right?

// See if there's a maximized size
let maximizedIndex: number = -1;
for (let i = 0; i < this.viewItems.length; i++) {
const item = this.viewItems[i];
if (item.size !== item.minimumSize) {
if (maximizedIndex !== -1) {
maximizedIndex = -1;
break;
}
maximizedIndex = i;
}
}
if (maximizedIndex !== -1) {
const item = this.viewItems[maximizedIndex];
item.size -= (previousSize - item.size);
}

For #137865, what do you think of adding Sizing.Maximize and then adding code in doAddView to update the sizes?

private doAddView(view: IView<TLayoutContext>, size: number | Sizing, index = this.viewItems.length, skipLayout?: boolean): void {

@joaomoreno
Copy link
Member

joaomoreno commented Dec 1, 2021

Hm... After sleeping on it, I'm not entirely sure of my suggestions any more. Your initial PR might actually be a good option moving forward. 🙈

Let's do this: let's add test cases for the new splitview behavior you introduced in this PR. That will help us understand what it introduces and other bugs it might cause, such as unintentional resizing when a view is maximized. Remember that the splitview is used across the workbench in many cases, not just editor grids.

@joaomoreno joaomoreno assigned joaomoreno and unassigned bpasero and sbatten Dec 1, 2021
@ssigwart
Copy link
Contributor Author

ssigwart commented Dec 2, 2021

I added test for this. Noting mainly for myself that I can run them with these commands:

./scripts/test.sh --glob **/editorService.test.js
./scripts/test.sh --glob **/splitview.test.js

I wasn't positive if I put the test for #137865 in the right spot, so please let me know if I should move it.

I'm pretty new to VS Code and have gotten a grasp of some things enough to fix some things, but don't have a full understanding of the VS Code internal code structure. Is there any documentation I can read on that? In particular, I'm not really sure what the "workbench" vs "editor grid" vs "splitview" terms all mean?

@ssigwart
Copy link
Contributor Author

ssigwart commented Jan 8, 2022

@joaomoreno, do you need me to do anything else on this?

@joaomoreno
Copy link
Member

No need for anything else... just need to time to properly look into it. Sorry about that.

@joaomoreno joaomoreno added the splitview-widget Splitview UI system issues label Feb 2, 2022
@ssigwart
Copy link
Contributor Author

ssigwart commented Feb 3, 2022

No problem. Thanks. Just wanted to be sure I didn't miss something.

@joaomoreno joaomoreno modified the milestones: On Deck, Backlog Feb 17, 2022
@ssigwart
Copy link
Contributor Author

ssigwart commented Jul 7, 2022

I merged main and cleaned up the failing tests after that.

@joaomoreno joaomoreno modified the milestones: Backlog, March 2023 Dec 22, 2022
This reverts commit 61f90de.
This reverts commit 87faa0e.
This reverts commit 1195fdb.
also: keep maximized editor groups, if previously maximized

fixes microsoft#70083
fixes microsoft#137865
joaomoreno
joaomoreno previously approved these changes Dec 22, 2022
@joaomoreno
Copy link
Member

I'm very very sorry to only pick this up right now.

I've found the following issues:

  • When a single group is open, opening a file on the side will now make that group maximized.
  • When three views are open, one is minimzed and the rest of space split between the other two, the proportional resize will still stretch the minimized view.

While these issues could be fixed with the proposed approach, I went a different direction. I made proportionalLayout a property of each view. That way, the editor group views can claim not to be a part of the proportional layout algorithm, whenever they are minimized. This is simpler to maintain and understand than the original proposed change of this PR. This fixes #70083.

Additionally, I also made sure to maximize new groups if the reference group was maximized. This fixes #137865.

I'll push my changes on top of this PR so we still have you as a contributor, thanks so much for your patience and passion @ssigwart. 🍻

Tyriar
Tyriar previously approved these changes Dec 22, 2022
@joaomoreno joaomoreno dismissed stale reviews from Tyriar and themself via ce17144 December 22, 2022 15:59
@joaomoreno joaomoreno merged commit 6615806 into microsoft:main Dec 22, 2022
@ssigwart ssigwart deleted the maxGrpSize branch December 23, 2022 02:09
@ssigwart
Copy link
Contributor Author

Thank you, @joaomoreno!

@github-actions github-actions bot locked and limited conversation to collaborators Feb 5, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

splitview-widget Splitview UI system issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Preserve maximized state when opening new groups Maximize editor group auto sizing stops working after closing the sidebar

5 participants