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

Make ITab an unsealed runtimeclass #8053

Merged
7 commits merged into from
Oct 29, 2020
Merged

Conversation

carlos-zamora
Copy link
Member

@carlos-zamora carlos-zamora commented Oct 27, 2020

TerminalTab and SettingsTab share some implementation details. The
close submenu introduced in #7728 is a good example of functionality
that is consistent across all tabs. This PR transforms ITab from an
interface, into an unsealed runtime class to de-duplicate some
functionality. Most of the logic from SettingsTab was moved there
because I expect the default behavior of a tab to resemble the
SettingsTab over a TerminalTab.

References

Verified that Close submenu work was transferred over (#7728, #7961, #8010).

Validation Steps Performed

Check close submenu on first/last tab when multiple tabs are open.

Closes #7969

@ghost ghost added Area-UserInterface Issues pertaining to the user interface of the Console or Terminal Issue-Bug It either shouldn't be doing this or needs an investigation. Priority-1 A description (P1) Product-Terminal The new Windows Terminal. labels Oct 27, 2020
@DHowett
Copy link
Member

DHowett commented Oct 27, 2020

inheritance isn't really a thing people do in winrt...

@DHowett
Copy link
Member

DHowett commented Oct 27, 2020

If you're going to make it a base class, don't name it IAnything. I has a very specific meaning.

Is it possible to achieve what you're trying to do with a CRTP mix-in like IINheritable?

@zadjii-msft
Copy link
Member

I haven't really reviewed this, but I'm doing something silly and similar over here

In that branch, both the Monarch and Peasant projected types implement the IPeasant interface. On the implementation side, they both are derived from PeasantBase, which actually implements the entire IPeasant interface

@carlos-zamora carlos-zamora force-pushed the dev/cazamor/split-tab-impl branch from fae2826 to 824c957 Compare October 27, 2020 21:42
@carlos-zamora carlos-zamora marked this pull request as ready for review October 27, 2020 21:45
@carlos-zamora
Copy link
Member Author

carlos-zamora commented Oct 28, 2020

For whatever reason, the following crash only occurs with a settings tab:

error message

Call Stack
>	Windows.UI.Xaml.dll!GetProgrammaticHitTestingParams(CCoreServices * coreServices, CUIElement * uiElement, ITransformer * * transformer, CUIElement * * ppThisNoRef, CPopupRoot * * popupRootNoRef, CUIElement * * popupHitTestSubtreeRootNoRef, bool * isRootNull) Line 5392	C++
 	Windows.UI.Xaml.dll!UIElement_HitTestPoint(CUIElement * uiElement, CCoreServices * coreServices, XPOINTF ptHit, bool canHitDisabledElements, bool canHitInvisibleElements, int * pnCount, CUIElement * * * ppElements) Line 5510	C++
 	Windows.UI.Xaml.dll!DirectUI::VisualTreeHelper::FindElementsInHostCoordinatesPointStatic(Windows::Foundation::Point intersectingPoint, Windows::UI::Xaml::IUIElement * pSubTree, unsigned char ppElements, unsigned char) Line 250	C++
 	Windows.UI.Xaml.dll!DirectUI::VisualTreeHelper::FindAllElementsInHostCoordinatesPointStatic(Windows::Foundation::Point intersectingPoint, Windows::UI::Xaml::IUIElement * pSubTree, unsigned char includeAllElements, Windows::Foundation::Collections::IIterable<Windows::UI::Xaml::UIElement *> * * ppElements) Line 329	C++
 	Windows.UI.Xaml.dll!DirectUI::CascadingMenuHelper::OnPointerExited(Windows::UI::Xaml::Input::IPointerRoutedEventArgs * args, bool parentIsSubMenu) Line 285	C++
 	Windows.UI.Xaml.dll!DirectUI::MenuFlyoutSubItem::OnPointerExited(Windows::UI::Xaml::Input::IPointerRoutedEventArgs * args) Line 141	C++
 	Windows.UI.Xaml.dll!DirectUI::ControlGenerated::OnPointerExitedProtected(Windows::UI::Xaml::Input::IPointerRoutedEventArgs * pE) Line 1404	C++
 	Windows.UI.Xaml.dll!DirectUI::Control::FireEvent(KnownEventIndex nDelegate, DirectUI::DependencyObject * pSender, IInspectable * pArgs) Line 267	C++
 	[Inline Frame] Windows.UI.Xaml.dll!DirectUI::DXamlCore::FireEvent(CDependencyObject *) Line 1985	C++
 	[Inline Frame] Windows.UI.Xaml.dll!AgCoreCallbacks::FireEvent(CDependencyObject *) Line 92	C++
 	[Inline Frame] Windows.UI.Xaml.dll!CFxCallbacks::JoltHelper_FireEvent(CDependencyObject *) Line 1015	C++
 	Windows.UI.Xaml.dll!CCoreServices::CLR_FireEvent(CDependencyObject * pListener, EventHandle hEvent, CDependencyObject * pSender, CEventArgs * pArgs, unsigned int flags) Line 3229	C++
 	Windows.UI.Xaml.dll!CommonBrowserHost::CLR_FireEvent(CDependencyObject * pListener, EventHandle hEvent, CDependencyObject * pSender, CEventArgs * pArgs, unsigned int flags) Line 771	C++
 	Windows.UI.Xaml.dll!CControlBase::ScriptCallback(void * pControl, CDependencyObject * pListener, EventHandle hEvent, CDependencyObject * pSender, CEventArgs * pArgs, int flags, IScriptObject * pScriptObject, HRESULT(*)(CDependencyObject *, CEventArgs *) pInternalHandler) Line 267	C++
 	Windows.UI.Xaml.dll!CXcpDispatcher::OnScriptCallback(CEventInfo * pEventInfo) Line 1347	C++
 	Windows.UI.Xaml.dll!CXcpDispatcher::OnWindowMessage(HWND__ * msg, unsigned int wParam, unsigned __int64 lParam, __int64) Line 1189	C++
 	Windows.UI.Xaml.dll!CXcpDispatcher::ProcessMessage(HWND__ * msg, unsigned int wParam, unsigned __int64 lParam, __int64 plRet, __int64 * pbDoDefault, unsigned int *) Line 925	C++
 	Windows.UI.Xaml.dll!CXcpDispatcher::WindowProc(HWND__ * hwnd, unsigned int msg, unsigned __int64 wParam, __int64 lParam) Line 839	C++
 	user32.dll!UserCallWinProcCheckWow(_ACTIVATION_CONTEXT * pActCtx, __int64(*)(tagWND *, unsigned int, unsigned __int64, __int64) pfn, HWND__ * hwnd, _WM_VALUE msg, unsigned __int64 wParam, __int64 lParam, void * fEnableLiteHooks, int) Line 280	C++
 	user32.dll!DispatchClientMessage(tagWND * pwnd, unsigned int message, unsigned __int64 wParam, __int64 lParam, unsigned __int64 pfn) Line 3446	C++
 	user32.dll!__fnDWORD(_FNDWORDMSG * pmsg) Line 1214	C++
 	ntdll.dll!KiUserCallbackDispatch() Line 603	Unknown
 	win32u.dll!ZwUserMessageCall() Line 213	Unknown
 	user32.dll!SendMessageWorker(tagWND * pwnd, unsigned int message, unsigned __int64 wParam, __int64 lParam, int fAnsi) Line 663	C++
 	user32.dll!SendMessageW(HWND__ * hwnd, unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 905	C++
 	[Inline Frame] Windows.UI.Xaml.dll!CXcpDispatcher::SendMessageW(unsigned int) Line 809	C++
 	Windows.UI.Xaml.dll!CXcpBrowserHost::SyncScriptCallbackRequest(void * pVoidBH, CDependencyObject * pListener, EventHandle hEvent, CDependencyObject * pSender, CEventArgs * pArgs, int flags, IScriptObject * pScriptObject, HRESULT(*)(CDependencyObject *, CEventArgs *) pHandler) Line 1048	C++
 	[Inline Frame] Windows.UI.Xaml.dll!CEventManager::RaiseControlEvents(EventHandle) Line 1133	C++
 	Windows.UI.Xaml.dll!CEventManager::Raise(EventHandle hEvent, int bRefire, CDependencyObject * pSender, CEventArgs * pArgs, bool fRaiseSync, bool fInputEvent, bool bAllowErrorFallback, CDependencyObject * pSenderOverride) Line 887	C++
 	Windows.UI.Xaml.dll!ContentRootInput::PointerInputProcessor::ProcessPointerEnterLeave(CDependencyObject * pContactElement, CDependencyObject * pPointerEnterDO, unsigned int pointerId, CPointerEventArgs * pArgs, int bSkipLeave, unsigned int bForceRaisePointerEntered, unsigned int bIgnoreHitTestVisibleForPointerExited, unsigned int bAsyncEvent, unsigned int bAddEventRequest, bool * enterLeaveFound) Line 1446	C++
 	Windows.UI.Xaml.dll!ContentRootInput::PointerInputProcessor::ProcessPointerInput(InputMessage * pMsg, int * handled) Line 558	C++
 	Windows.UI.Xaml.dll!CInputServices::ProcessInput(InputMessage * pMsg, CContentRoot * contentRoot, int * handled) Line 888	C++
 	Windows.UI.Xaml.dll!CCoreServices::ProcessInput(InputMessage * pMessage, CContentRoot * contentRoot, int * fHandled) Line 992	C++
 	Windows.UI.Xaml.dll!CXcpBrowserHost::HandleInputMessage(unsigned int uMsg, MsgPacket * pMsgPack, CContentRoot * contentRoot, bool & fHandled) Line 1411	C++
 	Windows.UI.Xaml.dll!CJupiterControl::HandlePointerMessage(unsigned int uMsg, unsigned __int64 wParam, __int64 lParam, CContentRoot * contentRoot, Windows::UI::Input::IPointerPoint * pointerPoint, Windows::UI::Core::IPointerEventArgs * pointerArgs) Line 750	C++
 	Windows.UI.Xaml.dll!CJupiterControl::ForwardWindowedPopupMessageToJupiterWindow(HWND__ * window, unsigned int message, unsigned __int64 wParam, __int64 lParam, CContentRoot * contentRoot) Line 1191	C++
 	[Inline Frame] Windows.UI.Xaml.dll!DirectUI::DXamlCore::ForwardWindowedPopupMessageToJupiterWindow(HWND__ *) Line 4515	C++
 	Windows.UI.Xaml.dll!DirectUI::DXamlCore::ForwardWindowedPopupMessageToJupiterWindow(HWND__ * window, unsigned int message, unsigned __int64 wParam, __int64 lParam, CContentRoot * contentRoot, __int64 * pResult) Line 4482	C++
 	[Inline Frame] Windows.UI.Xaml.dll!CFxCallbacks::Core_ForwardWindowedPopupMessageToJupiterWindow(HWND__ * contentRoot, unsigned int) Line 1132	C++
 	Windows.UI.Xaml.dll!CPopup::HandleWindowedPopupMessage(HWND__ * hwnd, unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 1652	C++
 	Windows.UI.Xaml.dll!CPopup::WindowedPopupWindowProc(HWND__ * hwnd, unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 1625	C++
 	user32.dll!UserCallWinProcCheckWow(_ACTIVATION_CONTEXT * pActCtx, __int64(*)(tagWND *, unsigned int, unsigned __int64, __int64) pfn, HWND__ * hwnd, _WM_VALUE msg, unsigned __int64 wParam, __int64 lParam, void * fEnableLiteHooks, int) Line 280	C++
 	user32.dll!DispatchMessageWorker(tagMSG * pmsg, int fAnsi) Line 3157	C++
 	WindowsTerminal.exe!wWinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, wchar_t * __formal, int __formal) Line 134	C++
 	[Inline Frame] WindowsTerminal.exe!invoke_main() Line 118	C++
 	WindowsTerminal.exe!__scrt_common_main_seh() Line 288	C++
 	kernel32.dll!BaseThreadInitThunk(unsigned long RunProcessInit, long(*)(void *) StartAddress, void * Argument) Line 70	C
 	ntdll.dll!RtlUserThreadStart(long(*)(void *) StartAddress, void * Argument) Line 1152	C

I get this by doing the following:

  1. Open Settings UI tab
  2. Open Close... submenu
  3. Select "Close other tabs"
  4. After the tabs close, right-click on the Settings UI tab again
  5. Hover over Close... option

What's bizarre is that this only happens with a Settings UI tab, not a Terminal Tab. But all of the submenu logic is in TabBase. Could I get some guidance here?

@carlos-zamora carlos-zamora force-pushed the dev/cazamor/split-tab-impl branch from 824c957 to c91623c Compare October 28, 2020 05:37
@zadjii-msft zadjii-msft self-assigned this Oct 28, 2020
@carlos-zamora
Copy link
Member Author

Good and bad news: the above bug seems to be a XAML Islands bug. It actually repros on the feature branch before this change even goes in effect. So we're just gonna push forward here.

Copy link
Member

@DHowett DHowett left a comment

Choose a reason for hiding this comment

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

While you're here, can you delete the old Tab.idl?

@zadjii-msft Composition is bad for various reasons, and I don't fully understand it (it requires the creation of a wrapper class, and there's this inner/outer class divide, where the outer class (TabBase) actually delegates to the inner class or something?)... but... doing the ConnectionStateHolder<T> or IInheritable<T> thing is even worse because we'd need to template it (again) so that we could dispatch the events with the right type[1].

[1]: we can't dispatch typed events off a TabBase, because the typed event's first argument is an IInspectable. TabBase would be outside the hierarchy, and not convertible to IInspectable. It's a whole ordeal to get it wired up, and it would require even more new macros like OBSERVABLE_GETSET_MACRO_BUT_WITH_EVENT_TYPE_T.

@zadjii-msft
Copy link
Member

It actually repros on the feature branch before this change even goes in effect.

That raises even MORE questions❗ We should probably consider that a blocking bug for the SUI, right? Since it's pretty trivially reproable, and the severity is the whole app crashes

Copy link
Member

@zadjii-msft zadjii-msft left a comment

Choose a reason for hiding this comment

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

I'm very concerned about the crash in feature/settings-ui, but this is okay

@zadjii-msft zadjii-msft removed their assignment Oct 29, 2020
@carlos-zamora carlos-zamora added the AutoMerge Marked for automatic merge by the bot when requirements are met label Oct 29, 2020
@ghost
Copy link

ghost commented Oct 29, 2020

Hello @carlos-zamora!

Because this pull request has the AutoMerge label, I will be glad to assist with helping to merge this pull request once all check-in policies pass.

p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (@msftbot) and give me an instruction to get started! Learn more here.

@ghost ghost merged commit 81ca24b into feature/settings-ui Oct 29, 2020
@ghost ghost deleted the dev/cazamor/split-tab-impl branch October 29, 2020 23:38
DHowett pushed a commit that referenced this pull request Nov 3, 2020
In preparation for the Settings UI, we needed to make some changes to
Tab to abstract out shared, common functionality between different types
of tab. This is the result of that work. All code references to the
settings have been removed or reverted.

Contains changes from #8053, #7802.

The messages below only make sense in the context of the Settings UI,
which this pull request does not bring in. They do, however, provide
valuable information.

From #7802 (@leonMSFT):

> This PR's goal was to add an option to the `OpenSettings` keybinding to
> open the Settings UI in a tab. In order to implement that, a couple of
> changes had to be made to `Tab`, specifically:
>
> - Introduce a tab interface named `ITab`
> - Create/Rename two new Tab classes that implement `ITab` called
>   `SettingsTab` and `TerminalTab`
>

From #8053:

> `TerminalTab` and `SettingsTab` share some implementation details. The
> close submenu introduced in #7728 is a good example of functionality
> that is consistent across all tabs. This PR transforms `ITab` from an
> interface, into an [unsealed runtime class] to de-duplicate some
> functionality. Most of the logic from `SettingsTab` was moved there
> because I expect the default behavior of a tab to resemble the
> `SettingsTab` over a `TerminalTab`.
>
> ## References
> Verified that Close submenu work was transferred over (#7728, #7961, #8010).
>
> ## Validation Steps Performed
> Check close submenu on first/last tab when multiple tabs are open.
>
> Closes #7969
>
> [unsealed runtime class]: https://docs.microsoft.com/en-us/uwp/midl-3/intro#base-classes

Co-authored-by: Carlos Zamora <[email protected]>
DHowett pushed a commit that referenced this pull request Nov 3, 2020
In preparation for the Settings UI, we needed to make some changes to
Tab to abstract out shared, common functionality between different types
of tab. This is the result of that work. All code references to the
settings have been removed or reverted.

Contains changes from #8053, #7802.

The messages below only make sense in the context of the Settings UI,
which this pull request does not bring in. They do, however, provide
valuable information.

From #7802 (@leonMSFT):

> This PR's goal was to add an option to the `OpenSettings` keybinding to
> open the Settings UI in a tab. In order to implement that, a couple of
> changes had to be made to `Tab`, specifically:
>
> - Introduce a tab interface named `ITab`
> - Create/Rename two new Tab classes that implement `ITab` called
>   `SettingsTab` and `TerminalTab`
>

From #8053:

> `TerminalTab` and `SettingsTab` share some implementation details. The
> close submenu introduced in #7728 is a good example of functionality
> that is consistent across all tabs. This PR transforms `ITab` from an
> interface, into an [unsealed runtime class] to de-duplicate some
> functionality. Most of the logic from `SettingsTab` was moved there
> because I expect the default behavior of a tab to resemble the
> `SettingsTab` over a `TerminalTab`.
>
> ## References
> Verified that Close submenu work was transferred over (#7728, #7961, #8010).
>
> ## Validation Steps Performed
> Check close submenu on first/last tab when multiple tabs are open.
>
> Closes #7969
>
> [unsealed runtime class]: https://docs.microsoft.com/en-us/uwp/midl-3/intro#base-classes

Co-authored-by: Carlos Zamora <[email protected]>
DHowett pushed a commit that referenced this pull request Nov 3, 2020
In preparation for the Settings UI, we needed to make some changes to
Tab to abstract out shared, common functionality between different types
of tab. This is the result of that work. All code references to the
settings have been removed or reverted.

Contains changes from #8053, #7802.

The messages below only make sense in the context of the Settings UI,
which this pull request does not bring in. They do, however, provide
valuable information.

From #7802 (@leonMSFT):

> This PR's goal was to add an option to the `OpenSettings` keybinding to
> open the Settings UI in a tab. In order to implement that, a couple of
> changes had to be made to `Tab`, specifically:
>
> - Introduce a tab interface named `ITab`
> - Create/Rename two new Tab classes that implement `ITab` called
>   `SettingsTab` and `TerminalTab`
>

From #8053:

> `TerminalTab` and `SettingsTab` share some implementation details. The
> close submenu introduced in #7728 is a good example of functionality
> that is consistent across all tabs. This PR transforms `ITab` from an
> interface, into an [unsealed runtime class] to de-duplicate some
> functionality. Most of the logic from `SettingsTab` was moved there
> because I expect the default behavior of a tab to resemble the
> `SettingsTab` over a `TerminalTab`.
>
> ## References
> Verified that Close submenu work was transferred over (#7728, #7961, #8010).
>
> ## Validation Steps Performed
> Check close submenu on first/last tab when multiple tabs are open.
>
> Closes #7969
>
> [unsealed runtime class]: https://docs.microsoft.com/en-us/uwp/midl-3/intro#base-classes

Co-authored-by: Carlos Zamora <[email protected]>
DHowett added a commit that referenced this pull request Nov 4, 2020
In preparation for the Settings UI, we needed to make some changes to
Tab to abstract out shared, common functionality between different types
of tab. This is the result of that work. All code references to the
settings have been removed or reverted.

Contains changes from #8053, #7802.

The messages below only make sense in the context of the Settings UI,
which this pull request does not bring in. They do, however, provide
valuable information.

From #7802 (@leonMSFT):

> This PR's goal was to add an option to the `OpenSettings` keybinding to
> open the Settings UI in a tab. In order to implement that, a couple of
> changes had to be made to `Tab`, specifically:
>
> - Introduce a tab interface named `ITab`
> - Create/Rename two new Tab classes that implement `ITab` called
>   `SettingsTab` and `TerminalTab`
>

From #8053:

> `TerminalTab` and `SettingsTab` share some implementation details. The
> close submenu introduced in #7728 is a good example of functionality
> that is consistent across all tabs. This PR transforms `ITab` from an
> interface, into an [unsealed runtime class] to de-duplicate some
> functionality. Most of the logic from `SettingsTab` was moved there
> because I expect the default behavior of a tab to resemble the
> `SettingsTab` over a `TerminalTab`.
>
> ## References
> Verified that Close submenu work was transferred over (#7728, #7961, #8010).
>
> ## Validation Steps Performed
> Check close submenu on first/last tab when multiple tabs are open.
>
> Closes #7969
>
> [unsealed runtime class]: https://docs.microsoft.com/en-us/uwp/midl-3/intro#base-classes

Co-authored-by: Carlos Zamora <[email protected]>

Co-authored-by: Leon Liang <[email protected]>
Co-authored-by: Carlos Zamora <[email protected]>
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-UserInterface Issues pertaining to the user interface of the Console or Terminal AutoMerge Marked for automatic merge by the bot when requirements are met Issue-Bug It either shouldn't be doing this or needs an investigation. Priority-1 A description (P1) Product-Terminal The new Windows Terminal.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants