Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resize tab view items only once the pointer has left the TabViewItem strip #2569

Merged
merged 10 commits into from
Jun 5, 2020

Conversation

marcelwgn
Copy link
Collaborator

@marcelwgn marcelwgn commented May 29, 2020

Description

Move the resizing of TabViewItems to a PointerExited event of the TabItemStrip container grid.. The scroll buttons are updated after every item to disable them once the number of items is low enough to make scrolling unecessary.

Motivation and Context

Closes #2417

How Has This Been Tested?

Add new interaction test and testpage.

Screenshots (if appropriate):

gif

@msft-github-bot msft-github-bot added the needs-triage Issue needs to be triaged by the area owners label May 29, 2020
@shaheedmalik
Copy link

Is that a glitch in the screen shot 4 clicks in? It seems like it isn't consistent.

@marcelwgn
Copy link
Collaborator Author

I am not entirely sure what you mean. The items jump after the 5th click because we hide the scroll buttons since for that number of items, we don't need scrolling anymore.

@shaheedmalik
Copy link

I am not entirely sure what you mean. The items jump after the 5th click because we hide the scroll buttons since for that number of items, we don't need scrolling anymore.

"Resize tab view items only once the pointer has left the TabViewItem strip"

The close button isn't underneath the the pointer and you didn't move it outside of the tab.

@marcelwgn
Copy link
Collaborator Author

Yes the items moved because the scroll buttons on the left and right have disappeared, the items did not resize.

The scroll buttons take up space and move the whole list of tabs (aka TabViewItems) a bit to the right so they are always visible and don't occlude the first and last item. When we remove enough items so that the items wouldn't need scrolling anymore, we hide those buttons, thus making space on the left side. Since we don't want to render an empty gap, the tabs list get's moved to the right.

@shaheedmalik
Copy link

Yes the items moved because the scroll buttons on the left and right have disappeared, the items did not resize.

The scroll buttons take up space and move the whole list of tabs (aka TabViewItems) a bit to the right so they are always visible and don't occlude the first and last item. When we remove enough items so that the items wouldn't need scrolling anymore, we hide those buttons, thus making space on the left side. Since we don't want to render an empty gap, the tabs list get's moved to the right.

This is different than how Edge handles it. The scroll bars should remain until the user moves the cursor outside the TabViewItem strip,

If I have 30 tabs open and want to close all of them, as soon as the scroll bars removes, I will have to move my mouse back to the correct tab. This behavior doesn't fix the original problem.

Proposal: Tab resizing should be differed in order to maintain the close button under the pointer
How Edge handles it.
https://camo.githubusercontent.com/65c1f251089fa08355549d2110db3d35a3888e09/68747470733a2f2f692e6779617a6f2e636f6d2f31633964326235366264356537393962376562376139666265646235303165392e676966

@StephenLPeters
Copy link
Contributor

Yes the items moved because the scroll buttons on the left and right have disappeared, the items did not resize.
The scroll buttons take up space and move the whole list of tabs (aka TabViewItems) a bit to the right so they are always visible and don't occlude the first and last item. When we remove enough items so that the items wouldn't need scrolling anymore, we hide those buttons, thus making space on the left side. Since we don't want to render an empty gap, the tabs list get's moved to the right.

This is different than how Edge handles it. The scroll bars should remain until the user moves the cursor outside the TabViewItem strip,

If I have 30 tabs open and want to close all of them, as soon as the scroll bars removes, I will have to move my mouse back to the correct tab. This behavior doesn't fix the original problem.

Proposal: Tab resizing should be differed in order to maintain the close button under the pointer
How Edge handles it.
https://camo.githubusercontent.com/65c1f251089fa08355549d2110db3d35a3888e09/68747470733a2f2f692e6779617a6f2e636f6d2f31633964326235366264356537393962376562376139666265646235303165392e676966

Edge and chrome do not scroll their tabs, the experience is actually pretty bad in both browsers if you open more tabs than can be displayed in the window. They both hide tabs off screen with no way to navigate to them with mouse. That being said, I think it would be better not to hide the scroll buttons until we relayout. A big benefit of this change is that you can close many tabs without moving your pointer. I think it would be better to disable the scrollbuttons rather than collapse them while the pointer remains in the tab well, and then collapse them when we adjust the tab size.

m_tabContainerGrid.set(GetTemplateChildT<winrt::Grid>(L"TabContainerGrid", controlProtected));
if (const auto& containerGrid = GetTemplateChildT<winrt::Grid>(L"TabContainerGrid", controlProtected))
{
m_tabContainerGrid.set(containerGrid);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

m_tabContainerGrid [](start = 8, length = 18)

a downside to this approach is that you will never set m_tabContainerGrid to null, even if a second template is later applied which doesn't have a TabContainerGrid. Seems unlikely in this case.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the code to set it to null if we get a nullptr.

auto scopeGuard = gsl::finally([this]()
{
updateTabWidthOnPointerLeave = false;
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scope guarded flag should be declared before UpdateTabWidths() is called. This is so that if UpdateTabWidths() throws but that exception is later handled we will still update this flag.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, moved the UpdateTabWidths call behind the scopeguard.

@stmoy
Copy link
Contributor

stmoy commented May 29, 2020

I think it would be better to disable the scrollbuttons rather than collapse them while the pointer remains in the tab well, and then collapse them when we adjust the tab size.

Agreed, this would be a reasonable way to do it. We could also just hide them. The end-user scenario is to keep the x-to-close button in the same location.

@marcelwgn
Copy link
Collaborator Author

I've updated the code now to disable the scroll buttons instead of hiding them completely:

gif

Note that when we close the TabViewItems, the items get resized to ensure that leaving the pointer on the last item allows you to close multiple tabs without moving the pointer.

@shaheedmalik
Copy link

I've updated the code now to disable the scroll buttons instead of hiding them completely:

gif

Note that when we close the TabViewItems, the items get resized to ensure that leaving the pointer on the last item allows you to close multiple tabs without moving the pointer.

This is better but it still shouldn't resize until the mouse leaves the TabItem strip.

@marcelwgn
Copy link
Collaborator Author

If we close the last item, items should be resized, which is the same behavior as edge and chrome have according to the proposal.

The question is should we expand the other items so that the items fill the space that the items took up before, or should all the sizes stay the same? @stmoy @StephenLPeters your thoughts?

@shaheedmalik
Copy link

shaheedmalik commented May 29, 2020

If we close the last item, items should be resized, which is the same behavior as edge and chrome have according to the proposal.

The question is should we expand the other items so that the items fill the space that the items took up before, or should all the sizes stay the same? @stmoy @StephenLPeters your thoughts?

When this is done in Edge the tabs next to it will slide over with the Close X under the pointer until approx 2 tabs or so are left.

This is how Edge does it.
New-tab-and-16-more-pages-Person

@StephenLPeters
Copy link
Contributor

Is the space to the right of the + button owned by the tabview? If so I think we should move the pointer exited handler up the visual tree to the point where that portion of the control is included so the user doesn't get a pointer exited event unintentionally

@stmoy
Copy link
Contributor

stmoy commented May 29, 2020

Is the space to the right of the + button owned by the tabview? If so I think we should move the pointer exited handler up the visual tree to the point where that portion of the control is included so the user doesn't get a pointer exited event unintentionally

+1, makes sense. The space to the right of the + button is also owned by the TabView, yes. It's the TabStripFooter area. However, it is outside of the tab strip area, and could be custom content, so I'm not sure where the handler would go. I imagine the Header, Strip, and Footer are all contained within some container - so maybe there?

@marcelwgn
Copy link
Collaborator Author

So I've updated the behavior again. Now it should be completely aligned with edge and chrome:

gif

gif

@marcelwgn
Copy link
Collaborator Author

Is the space to the right of the + button owned by the tabview? If so I think we should move the pointer exited handler up the visual tree to the point where that portion of the control is included so the user doesn't get a pointer exited event unintentionally

+1, makes sense. The space to the right of the + button is also owned by the TabView, yes. It's the TabStripFooter area. However, it is outside of the tab strip area, and could be custom content, so I'm not sure where the handler would go. I imagine the Header, Strip, and Footer are all contained within some container - so maybe there?

The current implementation already subscribes to the correct element for that use case. Moving the cursor to the right side (aka PaneFooter), the items do not get resized, only when the pointer moves out of that area:

gif

Copy link
Contributor

@StephenLPeters StephenLPeters left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@StephenLPeters
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@StephenLPeters
Copy link
Contributor

Eventuallly we should add an animation for the change in size when the pointer exits the well.. I don't think we need to block this change on that though. @chingucoding could you possibly open an issue for that and include one of the gifs here for reference.

@marcelwgn
Copy link
Collaborator Author

Eventuallly we should add an animation for the change in size when the pointer exits the well.. I don't think we need to block this change on that though. @chingucoding could you possibly open an issue for that and include one of the gifs here for reference.

Sure thing, created #2588 for tracking.

@ranjeshj ranjeshj added area-TabView team-Controls Issue for the Controls team and removed needs-triage Issue needs to be triaged by the area owners labels Jun 3, 2020
@StephenLPeters
Copy link
Contributor

@chingucoding the TabSizeAndScrollButtonsTest is failing with [Error]: IsFalse - Scroll buttons should disappear [File d:\a\1\s\dev\TabView\InteractionTests\TabViewTests.cs Line: 168]

I think there is an issue with the ADO site that will prevent you from seeing the tests page. We'll look into it.

@marcelwgn
Copy link
Collaborator Author

Thanks for the ping @StephenLPeters taking a look now. Also, yes the tests tab is missing, thanks for listing the failing tests here!

@marcelwgn
Copy link
Collaborator Author

The test should run successfully now, the issue was the we a) didn't handle non equal mode correctly and b) we did not leave the TabItemStrip to update the scrollbuttons.

@StephenLPeters
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@marcelwgn
Copy link
Collaborator Author

Seems like we still have test failures, however I can't repro that test failure on my machine. @StephenLPeters Did the test fail on a specific Windows 10 Build?

@StephenLPeters
Copy link
Contributor

Seems like we still have test failures, however I can't repro that test failure on my machine. @StephenLPeters Did the test fail on a specific Windows 10 Build?

Yes, consistently failing on RS3 and RS4 with this error: [Error]: IsFalse - Scroll buttons should disappear [File d:\a\1\s\dev\TabView\InteractionTests\TabViewTests.cs Line: 172]

@marcelwgn
Copy link
Collaborator Author

Could it be that the pointer moving is not reliable enough on those windows version? I highly doubt that, however I don't think that there are features that we are using in those areas that differ on RS3/4 compared to the other Windows 10 versions which would create that test failures.

@StephenLPeters
Copy link
Contributor

000002_Screenshot (1)
Looking at a screenshot from the test failure the mouse hasn't been moved from the tab's close button. I think that this is because the element you've chosen to move the mouse cursor to is not on screen. Maybe if you change the test to move cursor to something like the ISClosable on first tab check box it would resolve the issue.

@marcelwgn
Copy link
Collaborator Author

Oh right, good idea. I've updated the test now.

Maybe we should have some form of indication in the MUXControlsTestApp that shows what will get rendered inside the CI test run. That way we know how the test page will look like in CI while writing the tests and avoid those errors more easily. Thoughts @ranjeshj @StephenLPeters @kmahone ?

@kmahone
Copy link
Member

kmahone commented Jun 4, 2020

We could add a button to the app somewhere that resizes the root Frame to be 1024x768 (or whatever the correct size is once you account for taskbar, titlebar, etc.). That way the app content will be the same size as what it is in the CI pipeline.

@marcelwgn
Copy link
Collaborator Author

I think a button is the best idea for that. I've created a tracking issue for that #2604.

@StephenLPeters
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@StephenLPeters StephenLPeters merged commit 637b380 into microsoft:master Jun 5, 2020
@marcelwgn marcelwgn deleted the tabview-sizing-delay branch June 6, 2020 11:33
ghost pushed a commit to microsoft/terminal that referenced this pull request Jul 7, 2020
See: https://github.com/microsoft/microsoft-ui-xaml/releases/tag/v2.5.0-prerelease.200609001

> ### Notable Changes:
> 
>     Resize tab view items only once the pointer has left the TabViewItem strip (microsoft/microsoft-ui-xaml#2569)
>     Align TabView visuals with Edge (microsoft/microsoft-ui-xaml#2201)
>     Fix background of MenuFlyout in white high contrast (microsoft/microsoft-ui-xaml#2446)
>     TabView: Make TabViewItem consume the TabViewItemHeaderForeground theme resource (microsoft/microsoft-ui-xaml#2348)
>     TabView: Add tooltips to its scrolling buttons. (microsoft/microsoft-ui-xaml#2369)


* [x] Related to #5360 (@jtippet confirms that this alone does not close it.)
* [x] I work here
donno2048 added a commit to donno2048/terminal that referenced this pull request Sep 28, 2020
See: https://github.com/microsoft/microsoft-ui-xaml/releases/tag/v2.5.0-prerelease.200609001

> ### Notable Changes:
> 
>     Resize tab view items only once the pointer has left the TabViewItem strip (microsoft/microsoft-ui-xaml#2569)
>     Align TabView visuals with Edge (microsoft/microsoft-ui-xaml#2201)
>     Fix background of MenuFlyout in white high contrast (microsoft/microsoft-ui-xaml#2446)
>     TabView: Make TabViewItem consume the TabViewItemHeaderForeground theme resource (microsoft/microsoft-ui-xaml#2348)
>     TabView: Add tooltips to its scrolling buttons. (microsoft/microsoft-ui-xaml#2369)


* [x] Related to #5360 (@jtippet confirms that this alone does not close it.)
* [x] I work here
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-TabView team-Controls Issue for the Controls team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Proposal: Defer tab resizing in order to maintain the close button under the pointer
7 participants