fix search index + deep link navigation

This commit is contained in:
Carlos Zamora
2026-06-17 13:02:36 -07:00
parent 0229d31215
commit de71721154
4 changed files with 69 additions and 14 deletions

View File

@@ -1151,7 +1151,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
if (const auto& controlToFocus{ strongThis->FindName(elementToFocus).try_as<Controls::Control>() })
{
winrt::Microsoft::Terminal::Settings::ExpandAncestorsAndBringIntoView(strongThis.as<FrameworkElement>(), controlToFocus);
const auto& target{ winrt::Microsoft::Terminal::Settings::ResolveFocusTarget(controlToFocus) };
winrt::Microsoft::Terminal::Settings::ExpandAncestorsAndBringIntoView(strongThis.as<FrameworkElement>(), target);
}
strongThis->_loadedRevoker.revoke();
}

View File

@@ -101,6 +101,35 @@ namespace winrt::Microsoft::Terminal::Settings
return GetLibraryResourceString(fmtKey);
}
// Returns the control that should actually receive focus for a resolved
// search-navigation target.
Controls::Control ResolveFocusTarget(const Controls::Control& element)
{
if (!element)
{
return element;
}
winrt::Windows::Foundation::IInspectable content{ nullptr };
if (const auto expander = element.try_as<Editor::SettingsExpander>())
{
content = expander.Content();
}
else if (const auto card = element.try_as<Editor::SettingsCard>())
{
content = card.Content();
}
if (content)
{
if (const auto contentControl = content.try_as<Controls::Control>())
{
return contentControl;
}
}
return element;
}
void ExpandAncestorsAndBringIntoView(const FrameworkElement& root, const Controls::Control& control)
{
if (!control)

View File

@@ -79,6 +79,7 @@ namespace winrt::Microsoft::Terminal::Settings
winrt::hstring GetSelectedItemTag(const winrt::Windows::Foundation::IInspectable& comboBoxAsInspectable);
winrt::hstring LocalizedNameForEnumName(const std::wstring_view sectionAndType, const std::wstring_view enumValue, const std::wstring_view propertyType);
void ExpandAncestorsAndBringIntoView(const winrt::Windows::UI::Xaml::FrameworkElement& root, const winrt::Windows::UI::Xaml::Controls::Control& control);
winrt::Windows::UI::Xaml::Controls::Control ResolveFocusTarget(const winrt::Windows::UI::Xaml::Controls::Control& element);
}
// BODGY!
@@ -132,10 +133,14 @@ struct HasScrollViewer
{
if (const auto& controlToFocus{ page->FindName(elementName).try_as<winrt::Windows::UI::Xaml::Controls::Control>() })
{
// If the named element is a SettingsExpander/SettingsCard with an
// interactive control in its Content, focus that inner control instead.
const auto& target{ winrt::Microsoft::Terminal::Settings::ResolveFocusTarget(controlToFocus) };
// We need to wait for the page to be loaded
// or else the call to StartBringIntoView()
// will end up doing nothing.
winrt::Microsoft::Terminal::Settings::ExpandAncestorsAndBringIntoView(page.template as<winrt::Windows::UI::Xaml::FrameworkElement>(), controlToFocus);
winrt::Microsoft::Terminal::Settings::ExpandAncestorsAndBringIntoView(page.template as<winrt::Windows::UI::Xaml::FrameworkElement>(), target);
}
page->_loadedRevoker.revoke();
}

View File

@@ -193,20 +193,40 @@ foreach ($xamlFile in Get-ChildItem -Path $SourceDir -Filter *.xaml)
# Iterate over all local:SettingsCard and local:SettingsExpander nodes
foreach ($settingContainer in ($xml.SelectNodes("//local:SettingsCard", $xm) + $xml.SelectNodes("//local:SettingsExpander", $xm)))
{
# Extract Uid
if ($null -eq $settingContainer.Uid)
# Determine what to index for this container. A SettingContainer is indexable
# either via its own x:Uid (its label comes from the Header, resource suffix
# "/Header") OR, when it has none, via a content-labeled child control
# (CheckBox/ToggleSwitch/etc.) that carries its own x:Uid (its label comes from
# its Content, resource suffix "/Content"). The latter is wrapped in a SettingsCard
# that usually has no x:Uid of its own, so without this it would never be indexed.
$suffix = "Header"
$uid = $settingContainer.Uid
$name = $settingContainer.GetAttribute("x:Name")
if ([string]::IsNullOrEmpty($uid))
{
# SettingsCard/SettingsExpander without x:Uid are not indexable — skip silently
continue
# No x:Uid on the container itself, look for a child control.
$child = $settingContainer.SelectNodes("*") |
Where-Object { @("CheckBox", "ToggleSwitch", "RadioButton", "ToggleButton") -contains $_.LocalName -and -not [string]::IsNullOrEmpty($_.GetAttribute("x:Uid")) } |
Select-Object -First 1
if ($null -ne $child)
{
$suffix = "Content"
$uid = $child.GetAttribute("x:Uid")
# Prefer the control's own x:Name; otherwise fall back to the container's.
$childName = $child.GetAttribute("x:Name")
if (-not [string]::IsNullOrEmpty($childName))
{
$name = $childName
}
}
}
elseif ($ProhibitedUids -contains $settingContainer.Uid)
if ([string]::IsNullOrEmpty($uid) -or ($ProhibitedUids -contains $uid))
{
continue
}
# Extract Name via GetAttribute to avoid PowerShell's XML integration
# returning the element name (e.g. "local:SettingsCard") when x:Name is absent.
$name = $settingContainer.GetAttribute("x:Name")
if ([string]::IsNullOrEmpty($name))
{
$name = ""
@@ -227,7 +247,7 @@ foreach ($xamlFile in Get-ChildItem -Path $SourceDir -Filter *.xaml)
$subPage = $ClassMap[$pageClass].SubPage ?? "BreadcrumbSubPage::None"
if ($pageClass -match "Editor::NewTabMenu")
{
if ($settingContainer.Uid -match "NewTabMenu_CurrentFolder")
if ($uid -match "NewTabMenu_CurrentFolder")
{
$navigationParam = $null # VM param at runtime
$subPage = "BreadcrumbSubPage::NewTabMenu_Folder"
@@ -254,7 +274,7 @@ foreach ($xamlFile in Get-ChildItem -Path $SourceDir -Filter *.xaml)
if ($includeInBuildIndex)
{
$entries += [pscustomobject]@{
ResourceName = "$($settingContainer.Uid)/Header"
ResourceName = "$uid/$suffix"
ParentPage = $pageClass
NavigationParam = $navigationParam
SubPage = $subPage
@@ -266,7 +286,7 @@ foreach ($xamlFile in Get-ChildItem -Path $SourceDir -Filter *.xaml)
if ($includeInPartialIndex)
{
$entries += [pscustomobject]@{
ResourceName = "$($settingContainer.Uid)/Header"
ResourceName = "$uid/$suffix"
ParentPage = $pageClass
NavigationParam = $null # VM param at runtime
SubPage = $pageClass -match "Editor::NewTabMenu" ? "BreadcrumbSubPage::NewTabMenu_Folder" : $subPage
@@ -455,4 +475,4 @@ Set-Content -LiteralPath $cppPath -Value $cpp -NoNewline
Write-Host "Generated:"
Write-Host " $headerPath"
Write-Host " $cppPath"
Write-Host " $cppPath"