mirror of
https://github.com/microsoft/terminal.git
synced 2026-02-03 18:17:40 -06:00
## Summary of the Pull Request Fixes a memory leak for `IHostedInWindow` in the TerminalSettingsEditor. The memory leak occurs from `MainPage` creating an object that stores reference to back to `MainPage` as `IHostedInWindow`. With `IconPicker` specifically, the cycle would look like `MainPage` --> `NewTabMenu` --> `IconPicker` --> `MainPage`. I've audited uses of `IHostedInWindow` in the TerminalSettingsEditor and replaced them as weak references. I also checked areas that `WindowRoot()` was called and added a null-check for safety. ## Validation Steps Performed Verified `MainPage` and `NewTabMenu` dtors are called when the settings UI closes from... ✅ Launch page (base case - it doesn't have an `IHostedInWindow`) ✅ New Tab Menu page
74 lines
4.5 KiB
C++
74 lines
4.5 KiB
C++
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT license.
|
|
|
|
#pragma once
|
|
|
|
#include "NewTabMenu.g.h"
|
|
#include "NewTabMenuEntryTemplateSelector.g.h"
|
|
#include "Utils.h"
|
|
|
|
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|
{
|
|
struct NewTabMenu : public HasScrollViewer<NewTabMenu>, NewTabMenuT<NewTabMenu>
|
|
{
|
|
public:
|
|
NewTabMenu();
|
|
|
|
void OnNavigatedTo(const winrt::Windows::UI::Xaml::Navigation::NavigationEventArgs& e);
|
|
|
|
// FolderPickerDialog handlers
|
|
void FolderPickerDialog_Opened(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::Controls::ContentDialogOpenedEventArgs& e);
|
|
void FolderPickerDialog_PrimaryButtonClick(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::Controls::ContentDialogButtonClickEventArgs& e);
|
|
|
|
// NTM Entry handlers
|
|
void EditEntry_Clicked(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& e);
|
|
void ReorderEntry_Clicked(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& e);
|
|
void DeleteEntry_Clicked(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& e);
|
|
|
|
// Multiple Entry handlers
|
|
safe_void_coroutine MoveMultiple_Click(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& e);
|
|
void DeleteMultiple_Click(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& e);
|
|
|
|
// New Entry handlers
|
|
void AddProfileButton_Clicked(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& e);
|
|
void AddSeparatorButton_Clicked(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& e);
|
|
void AddFolderButton_Clicked(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& e);
|
|
void AddMatchProfilesButton_Clicked(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& e);
|
|
void AddRemainingProfilesButton_Clicked(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& e);
|
|
void AddFolderNameTextBox_KeyDown(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::Input::KeyRoutedEventArgs& e);
|
|
void AddFolderNameTextBox_TextChanged(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::Controls::TextChangedEventArgs& e);
|
|
|
|
Editor::IHostedInWindow WindowRoot() const noexcept { return _weakWindowRoot.get(); }
|
|
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
|
|
WINRT_OBSERVABLE_PROPERTY(Editor::NewTabMenuViewModel, ViewModel, _PropertyChangedHandlers, nullptr);
|
|
|
|
private:
|
|
Editor::NewTabMenuEntryViewModel _draggedEntry{ nullptr };
|
|
winrt::weak_ref<Editor::IHostedInWindow> _weakWindowRoot;
|
|
|
|
void _ScrollToEntry(const Editor::NewTabMenuEntryViewModel& entry);
|
|
};
|
|
|
|
struct NewTabMenuEntryTemplateSelector : public NewTabMenuEntryTemplateSelectorT<NewTabMenuEntryTemplateSelector>
|
|
{
|
|
public:
|
|
NewTabMenuEntryTemplateSelector() = default;
|
|
|
|
Windows::UI::Xaml::DataTemplate SelectTemplateCore(const Windows::Foundation::IInspectable& item, const Windows::UI::Xaml::DependencyObject& container);
|
|
Windows::UI::Xaml::DataTemplate SelectTemplateCore(const Windows::Foundation::IInspectable& item);
|
|
|
|
WINRT_PROPERTY(Windows::UI::Xaml::DataTemplate, ProfileEntryTemplate, nullptr);
|
|
WINRT_PROPERTY(Windows::UI::Xaml::DataTemplate, ActionEntryTemplate, nullptr);
|
|
WINRT_PROPERTY(Windows::UI::Xaml::DataTemplate, SeparatorEntryTemplate, nullptr);
|
|
WINRT_PROPERTY(Windows::UI::Xaml::DataTemplate, FolderEntryTemplate, nullptr);
|
|
WINRT_PROPERTY(Windows::UI::Xaml::DataTemplate, MatchProfilesEntryTemplate, nullptr);
|
|
WINRT_PROPERTY(Windows::UI::Xaml::DataTemplate, RemainingProfilesEntryTemplate, nullptr);
|
|
};
|
|
}
|
|
|
|
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
|
|
{
|
|
BASIC_FACTORY(NewTabMenu);
|
|
BASIC_FACTORY(NewTabMenuEntryTemplateSelector);
|
|
}
|