mirror of
https://github.com/microsoft/terminal.git
synced 2025-12-19 18:11:39 -05:00
Implement custom text context menus to fix crashes (#18854)
This works around a bug in WinUI where it creates a single context menu/flyout for text elements per thread, not per `XamlRoot`, similar to many other areas. Since the `XamlRoot` cannot change after creation, this means that once you've opened the flyout, you're locked into that window (= XAML root) forever. You can't open the flyout in another window and once you've closed that window, you can't open it anywhere at all. Closes #18599 ## Validation Steps Performed * Flies out right click in the * About dialog ✅ * Search dialog ✅ * Word delimiters setting ✅ * Launch size setting ✅ * Across two windows ✅
This commit is contained in:
3
.github/actions/spelling/expect/expect.txt
vendored
3
.github/actions/spelling/expect/expect.txt
vendored
@@ -128,6 +128,7 @@ Blt
|
|||||||
blu
|
blu
|
||||||
BLUESCROLL
|
BLUESCROLL
|
||||||
bmi
|
bmi
|
||||||
|
bodgy
|
||||||
BODGY
|
BODGY
|
||||||
BOLDFONT
|
BOLDFONT
|
||||||
Borland
|
Borland
|
||||||
@@ -371,8 +372,8 @@ Dcd
|
|||||||
DColor
|
DColor
|
||||||
dcommon
|
dcommon
|
||||||
DComposition
|
DComposition
|
||||||
dde
|
|
||||||
DDDCCC
|
DDDCCC
|
||||||
|
dde
|
||||||
DDESHARE
|
DDESHARE
|
||||||
DDevice
|
DDevice
|
||||||
DEADCHAR
|
DEADCHAR
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:local="using:TerminalApp"
|
xmlns:local="using:TerminalApp"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:mtu="using:Microsoft.Terminal.UI"
|
||||||
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
|
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
|
||||||
x:Uid="AboutDialog"
|
x:Uid="AboutDialog"
|
||||||
DefaultButton="Close"
|
DefaultButton="Close"
|
||||||
@@ -17,6 +18,9 @@
|
|||||||
|
|
||||||
<StackPanel Orientation="Vertical">
|
<StackPanel Orientation="Vertical">
|
||||||
<TextBlock IsTextSelectionEnabled="True">
|
<TextBlock IsTextSelectionEnabled="True">
|
||||||
|
<TextBlock.ContextFlyout>
|
||||||
|
<mtu:TextMenuFlyout />
|
||||||
|
</TextBlock.ContextFlyout>
|
||||||
<Run AutomationProperties.HeadingLevel="1"
|
<Run AutomationProperties.HeadingLevel="1"
|
||||||
Text="{x:Bind ApplicationDisplayName}" /> <LineBreak />
|
Text="{x:Bind ApplicationDisplayName}" /> <LineBreak />
|
||||||
<Run x:Uid="AboutDialog_VersionLabel" />
|
<Run x:Uid="AboutDialog_VersionLabel" />
|
||||||
@@ -39,7 +43,7 @@
|
|||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Orientation="Vertical"
|
Orientation="Vertical"
|
||||||
Visibility="{x:Bind UpdatesAvailable, Mode=OneWay}">
|
Visibility="{x:Bind UpdatesAvailable, Mode=OneWay}">
|
||||||
<TextBlock IsTextSelectionEnabled="False">
|
<TextBlock>
|
||||||
<Run x:Uid="AboutDialog_UpdateAvailableLabel" />
|
<Run x:Uid="AboutDialog_UpdateAvailableLabel" />
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
<!-- <Button x:Uid="AboutDialog_InstallUpdateButton"
|
<!-- <Button x:Uid="AboutDialog_InstallUpdateButton"
|
||||||
@@ -59,4 +63,3 @@
|
|||||||
Click="_ThirdPartyNoticesOnClick" />
|
Click="_ThirdPartyNoticesOnClick" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</ContentDialog>
|
</ContentDialog>
|
||||||
|
|
||||||
|
|||||||
@@ -284,7 +284,11 @@
|
|||||||
IsSpellCheckEnabled="False"
|
IsSpellCheckEnabled="False"
|
||||||
PlaceholderText="{x:Bind SearchBoxPlaceholderText, Mode=OneWay}"
|
PlaceholderText="{x:Bind SearchBoxPlaceholderText, Mode=OneWay}"
|
||||||
Text=""
|
Text=""
|
||||||
TextChanged="_filterTextChanged" />
|
TextChanged="_filterTextChanged">
|
||||||
|
<TextBox.ContextFlyout>
|
||||||
|
<mtu:TextMenuFlyout />
|
||||||
|
</TextBox.ContextFlyout>
|
||||||
|
</TextBox>
|
||||||
|
|
||||||
<TextBlock x:Name="_prefixCharacter"
|
<TextBlock x:Name="_prefixCharacter"
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ namespace winrt::TerminalApp::implementation
|
|||||||
void MarkdownPaneContent::_loadText()
|
void MarkdownPaneContent::_loadText()
|
||||||
{
|
{
|
||||||
auto block = WUX::Controls::TextBlock();
|
auto block = WUX::Controls::TextBlock();
|
||||||
|
block.ContextFlyout(winrt::Microsoft::Terminal::UI::TextMenuFlyout{});
|
||||||
block.IsTextSelectionEnabled(true);
|
block.IsTextSelectionEnabled(true);
|
||||||
block.FontFamily(WUX::Media::FontFamily{ L"Cascadia Code" });
|
block.FontFamily(WUX::Media::FontFamily{ L"Cascadia Code" });
|
||||||
block.Text(FileContents());
|
block.Text(FileContents());
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:local="using:TerminalApp"
|
xmlns:local="using:TerminalApp"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:mtu="using:Microsoft.Terminal.UI"
|
||||||
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
|
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
|
|
||||||
@@ -51,7 +52,11 @@
|
|||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
Margin="4"
|
Margin="4"
|
||||||
PlaceholderText="Enter a path to a markdown file..."
|
PlaceholderText="Enter a path to a markdown file..."
|
||||||
Text="Z:\dev\simple-test.md" />
|
Text="Z:\dev\simple-test.md">
|
||||||
|
<TextBox.ContextFlyout>
|
||||||
|
<mtu:TextMenuFlyout />
|
||||||
|
</TextBox.ContextFlyout>
|
||||||
|
</TextBox>
|
||||||
<StackPanel Grid.Column="1"
|
<StackPanel Grid.Column="1"
|
||||||
Orientation="Horizontal">
|
Orientation="Horizontal">
|
||||||
<Button Margin="4"
|
<Button Margin="4"
|
||||||
@@ -105,7 +110,11 @@
|
|||||||
FontFamily="Cascadia Code"
|
FontFamily="Cascadia Code"
|
||||||
IsSpellCheckEnabled="False"
|
IsSpellCheckEnabled="False"
|
||||||
Text="{x:Bind FileContents, Mode=TwoWay}"
|
Text="{x:Bind FileContents, Mode=TwoWay}"
|
||||||
Visibility="{x:Bind Editing}" />
|
Visibility="{x:Bind Editing}">
|
||||||
|
<TextBox.ContextFlyout>
|
||||||
|
<mtu:TextMenuFlyout />
|
||||||
|
</TextBox.ContextFlyout>
|
||||||
|
</TextBox>
|
||||||
|
|
||||||
<ScrollViewer x:Name="_scrollViewer"
|
<ScrollViewer x:Name="_scrollViewer"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ namespace winrt::TerminalApp::implementation
|
|||||||
_root.Background(bg.try_as<Media::Brush>());
|
_root.Background(bg.try_as<Media::Brush>());
|
||||||
|
|
||||||
_box = winrt::Windows::UI::Xaml::Controls::TextBox{};
|
_box = winrt::Windows::UI::Xaml::Controls::TextBox{};
|
||||||
|
_box.ContextFlyout(winrt::Microsoft::Terminal::UI::TextMenuFlyout{});
|
||||||
_box.Margin({ 10, 10, 10, 10 });
|
_box.Margin({ 10, 10, 10, 10 });
|
||||||
_box.AcceptsReturn(true);
|
_box.AcceptsReturn(true);
|
||||||
_box.TextWrapping(TextWrapping::Wrap);
|
_box.TextWrapping(TextWrapping::Wrap);
|
||||||
|
|||||||
@@ -182,7 +182,6 @@
|
|||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Margin="12,0,12,6"
|
Margin="12,0,12,6"
|
||||||
FontFamily="Cascadia Mono, Consolas"
|
FontFamily="Cascadia Mono, Consolas"
|
||||||
IsTextSelectionEnabled="False"
|
|
||||||
Style="{ThemeResource BodyTextBlockStyle}"
|
Style="{ThemeResource BodyTextBlockStyle}"
|
||||||
Text="{x:Bind Input}"
|
Text="{x:Bind Input}"
|
||||||
Visibility="{Binding ElementName=rootItem, Path=IsSelected}" />
|
Visibility="{Binding ElementName=rootItem, Path=IsSelected}" />
|
||||||
@@ -263,7 +262,11 @@
|
|||||||
Margin="8,0,8,8"
|
Margin="8,0,8,8"
|
||||||
AllowFocusOnInteraction="True"
|
AllowFocusOnInteraction="True"
|
||||||
TextChanged="_filterTextChanged"
|
TextChanged="_filterTextChanged"
|
||||||
Visibility="{x:Bind HasSnippets, Mode=OneWay}" />
|
Visibility="{x:Bind HasSnippets, Mode=OneWay}">
|
||||||
|
<TextBox.ContextFlyout>
|
||||||
|
<mtu:TextMenuFlyout />
|
||||||
|
</TextBox.ContextFlyout>
|
||||||
|
</TextBox>
|
||||||
|
|
||||||
<mux:TreeView x:Name="_treeView"
|
<mux:TreeView x:Name="_treeView"
|
||||||
Grid.Row="2"
|
Grid.Row="2"
|
||||||
|
|||||||
@@ -141,7 +141,11 @@
|
|||||||
PlaceholderText="{x:Bind SearchBoxPlaceholderText, Mode=OneWay}"
|
PlaceholderText="{x:Bind SearchBoxPlaceholderText, Mode=OneWay}"
|
||||||
Text=""
|
Text=""
|
||||||
TextChanged="_filterTextChanged"
|
TextChanged="_filterTextChanged"
|
||||||
Visibility="Collapsed" />
|
Visibility="Collapsed">
|
||||||
|
<TextBox.ContextFlyout>
|
||||||
|
<mtu:TextMenuFlyout />
|
||||||
|
</TextBox.ContextFlyout>
|
||||||
|
</TextBox>
|
||||||
|
|
||||||
<StackPanel Grid.Row="1"
|
<StackPanel Grid.Row="1"
|
||||||
Margin="8,0,8,8"
|
Margin="8,0,8,8"
|
||||||
@@ -224,7 +228,11 @@
|
|||||||
FontSize="14"
|
FontSize="14"
|
||||||
FontWeight="Bold"
|
FontWeight="Bold"
|
||||||
IsTextSelectionEnabled="True"
|
IsTextSelectionEnabled="True"
|
||||||
TextWrapping="WrapWholeWords" />
|
TextWrapping="WrapWholeWords">
|
||||||
|
<TextBlock.ContextFlyout>
|
||||||
|
<mtu:TextMenuFlyout />
|
||||||
|
</TextBlock.ContextFlyout>
|
||||||
|
</TextBlock>
|
||||||
<ScrollViewer MaxHeight="64"
|
<ScrollViewer MaxHeight="64"
|
||||||
VerticalScrollBarVisibility="Visible"
|
VerticalScrollBarVisibility="Visible"
|
||||||
VerticalScrollMode="Enabled"
|
VerticalScrollMode="Enabled"
|
||||||
@@ -232,7 +240,11 @@
|
|||||||
<TextBlock x:Name="_descriptionComment"
|
<TextBlock x:Name="_descriptionComment"
|
||||||
Margin="0,0,20,0"
|
Margin="0,0,20,0"
|
||||||
IsTextSelectionEnabled="True"
|
IsTextSelectionEnabled="True"
|
||||||
TextWrapping="WrapWholeWords" />
|
TextWrapping="WrapWholeWords">
|
||||||
|
<TextBlock.ContextFlyout>
|
||||||
|
<mtu:TextMenuFlyout />
|
||||||
|
</TextBlock.ContextFlyout>
|
||||||
|
</TextBlock>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:local="using:TerminalApp"
|
xmlns:local="using:TerminalApp"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:mtu="using:Microsoft.Terminal.UI"
|
||||||
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
|
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
|
||||||
MinHeight="16"
|
MinHeight="16"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
@@ -67,6 +68,10 @@
|
|||||||
IsSpellCheckEnabled="False"
|
IsSpellCheckEnabled="False"
|
||||||
LostFocus="RenameBoxLostFocusHandler"
|
LostFocus="RenameBoxLostFocusHandler"
|
||||||
MaxLength="1024"
|
MaxLength="1024"
|
||||||
Visibility="Collapsed" />
|
Visibility="Collapsed">
|
||||||
|
<TextBox.ContextFlyout>
|
||||||
|
<mtu:TextMenuFlyout />
|
||||||
|
</TextBox.ContextFlyout>
|
||||||
|
</TextBox>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|||||||
@@ -70,8 +70,7 @@
|
|||||||
FontSize="12">
|
FontSize="12">
|
||||||
<ToolTipService.ToolTip>
|
<ToolTipService.ToolTip>
|
||||||
<ToolTip Placement="Mouse">
|
<ToolTip Placement="Mouse">
|
||||||
<TextBlock IsTextSelectionEnabled="False"
|
<TextBlock TextWrapping="Wrap">
|
||||||
TextWrapping="Wrap">
|
|
||||||
<Run x:Uid="NewTabRun" /> <LineBreak />
|
<Run x:Uid="NewTabRun" /> <LineBreak />
|
||||||
<Run x:Uid="NewPaneRun"
|
<Run x:Uid="NewPaneRun"
|
||||||
FontStyle="Italic" /> <LineBreak />
|
FontStyle="Italic" /> <LineBreak />
|
||||||
|
|||||||
@@ -137,6 +137,9 @@
|
|||||||
DefaultButton="Primary">
|
DefaultButton="Primary">
|
||||||
<TextBlock IsTextSelectionEnabled="True"
|
<TextBlock IsTextSelectionEnabled="True"
|
||||||
TextWrapping="WrapWholeWords">
|
TextWrapping="WrapWholeWords">
|
||||||
|
<TextBlock.ContextFlyout>
|
||||||
|
<mtu:TextMenuFlyout />
|
||||||
|
</TextBlock.ContextFlyout>
|
||||||
<Run x:Name="NoticeMessage" />
|
<Run x:Name="NoticeMessage" />
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
</ContentDialog>
|
</ContentDialog>
|
||||||
@@ -148,6 +151,9 @@
|
|||||||
DefaultButton="Primary">
|
DefaultButton="Primary">
|
||||||
<TextBlock IsTextSelectionEnabled="True"
|
<TextBlock IsTextSelectionEnabled="True"
|
||||||
TextWrapping="WrapWholeWords">
|
TextWrapping="WrapWholeWords">
|
||||||
|
<TextBlock.ContextFlyout>
|
||||||
|
<mtu:TextMenuFlyout />
|
||||||
|
</TextBlock.ContextFlyout>
|
||||||
<Run x:Name="CouldNotOpenUriReason" /> <LineBreak />
|
<Run x:Name="CouldNotOpenUriReason" /> <LineBreak />
|
||||||
<Run x:Name="UnopenedUri"
|
<Run x:Name="UnopenedUri"
|
||||||
FontFamily="Cascadia Mono" />
|
FontFamily="Cascadia Mono" />
|
||||||
@@ -191,7 +197,11 @@
|
|||||||
<TextBox x:Name="WindowRenamerTextBox"
|
<TextBox x:Name="WindowRenamerTextBox"
|
||||||
KeyDown="_WindowRenamerKeyDown"
|
KeyDown="_WindowRenamerKeyDown"
|
||||||
KeyUp="_WindowRenamerKeyUp"
|
KeyUp="_WindowRenamerKeyUp"
|
||||||
Text="{x:Bind WindowProperties.WindowName, Mode=OneWay}" />
|
Text="{x:Bind WindowProperties.WindowName, Mode=OneWay}">
|
||||||
|
<TextBox.ContextFlyout>
|
||||||
|
<mtu:TextMenuFlyout />
|
||||||
|
</TextBox.ContextFlyout>
|
||||||
|
</TextBox>
|
||||||
</mux:TeachingTip.Content>
|
</mux:TeachingTip.Content>
|
||||||
</mux:TeachingTip>
|
</mux:TeachingTip>
|
||||||
|
|
||||||
|
|||||||
@@ -434,6 +434,7 @@ namespace winrt::TerminalApp::implementation
|
|||||||
auto buttonText = RS_(L"Ok");
|
auto buttonText = RS_(L"Ok");
|
||||||
|
|
||||||
Controls::TextBlock warningsTextBlock;
|
Controls::TextBlock warningsTextBlock;
|
||||||
|
warningsTextBlock.ContextFlyout(winrt::Microsoft::Terminal::UI::TextMenuFlyout{});
|
||||||
// Make sure you can copy-paste
|
// Make sure you can copy-paste
|
||||||
warningsTextBlock.IsTextSelectionEnabled(true);
|
warningsTextBlock.IsTextSelectionEnabled(true);
|
||||||
// Make sure the lines of text wrap
|
// Make sure the lines of text wrap
|
||||||
@@ -483,6 +484,7 @@ namespace winrt::TerminalApp::implementation
|
|||||||
auto buttonText = RS_(L"Ok");
|
auto buttonText = RS_(L"Ok");
|
||||||
|
|
||||||
Controls::TextBlock warningsTextBlock;
|
Controls::TextBlock warningsTextBlock;
|
||||||
|
warningsTextBlock.ContextFlyout(winrt::Microsoft::Terminal::UI::TextMenuFlyout{});
|
||||||
// Make sure you can copy-paste
|
// Make sure you can copy-paste
|
||||||
warningsTextBlock.IsTextSelectionEnabled(true);
|
warningsTextBlock.IsTextSelectionEnabled(true);
|
||||||
// Make sure the lines of text wrap
|
// Make sure the lines of text wrap
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:local="using:Microsoft.Terminal.Control"
|
xmlns:local="using:Microsoft.Terminal.Control"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:mtu="using:Microsoft.Terminal.UI"
|
||||||
x:Name="Root"
|
x:Name="Root"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Top"
|
||||||
@@ -197,7 +198,11 @@
|
|||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
IsSpellCheckEnabled="False"
|
IsSpellCheckEnabled="False"
|
||||||
KeyDown="TextBoxKeyDown"
|
KeyDown="TextBoxKeyDown"
|
||||||
TextChanged="TextBoxTextChanged" />
|
TextChanged="TextBoxTextChanged">
|
||||||
|
<TextBox.ContextFlyout>
|
||||||
|
<mtu:TextMenuFlyout />
|
||||||
|
</TextBox.ContextFlyout>
|
||||||
|
</TextBox>
|
||||||
|
|
||||||
<TextBlock x:Name="StatusBox"
|
<TextBlock x:Name="StatusBox"
|
||||||
x:Uid="SearchBox_StatusBox"
|
x:Uid="SearchBox_StatusBox"
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:local="using:Microsoft.Terminal.Control"
|
xmlns:local="using:Microsoft.Terminal.Control"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:mtu="using:Microsoft.Terminal.UI"
|
||||||
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
|
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
@@ -1272,6 +1273,9 @@
|
|||||||
Placement="Mouse">
|
Placement="Mouse">
|
||||||
<TextBlock IsTextSelectionEnabled="True"
|
<TextBlock IsTextSelectionEnabled="True"
|
||||||
TextWrapping="Wrap">
|
TextWrapping="Wrap">
|
||||||
|
<TextBlock.ContextFlyout>
|
||||||
|
<mtu:TextMenuFlyout />
|
||||||
|
</TextBlock.ContextFlyout>
|
||||||
<Run x:Name="HoveredUri" /> <LineBreak />
|
<Run x:Name="HoveredUri" /> <LineBreak />
|
||||||
<Run x:Uid="HowToOpenRun"
|
<Run x:Uid="HowToOpenRun"
|
||||||
FontStyle="Italic" />
|
FontStyle="Italic" />
|
||||||
|
|||||||
@@ -132,6 +132,11 @@
|
|||||||
<Style x:Key="TextBoxSettingStyle"
|
<Style x:Key="TextBoxSettingStyle"
|
||||||
BasedOn="{StaticResource DefaultTextBoxStyle}"
|
BasedOn="{StaticResource DefaultTextBoxStyle}"
|
||||||
TargetType="TextBox">
|
TargetType="TextBox">
|
||||||
|
<Setter Property="ContextFlyout">
|
||||||
|
<Setter.Value>
|
||||||
|
<mtu:TextMenuFlyout />
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
<Setter Property="MinWidth" Value="{StaticResource StandardBoxMinWidth}" />
|
<Setter Property="MinWidth" Value="{StaticResource StandardBoxMinWidth}" />
|
||||||
<Setter Property="MaxWidth" Value="400" />
|
<Setter Property="MaxWidth" Value="400" />
|
||||||
<Setter Property="HorizontalAlignment" Value="Left" />
|
<Setter Property="HorizontalAlignment" Value="Left" />
|
||||||
|
|||||||
136
src/cascadia/UIHelpers/Resources/en-US/Resources.resw
Normal file
136
src/cascadia/UIHelpers/Resources/en-US/Resources.resw
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="Cut" xml:space="preserve">
|
||||||
|
<value>Cut</value>
|
||||||
|
<comment>"Cut" as contained in a Cut/Copy/Paste menu</comment>
|
||||||
|
</data>
|
||||||
|
<data name="Copy" xml:space="preserve">
|
||||||
|
<value>Copy</value>
|
||||||
|
<comment>"Copy" as contained in a Cut/Copy/Paste menu</comment>
|
||||||
|
</data>
|
||||||
|
<data name="Paste" xml:space="preserve">
|
||||||
|
<value>Paste</value>
|
||||||
|
<comment>"Paste" as contained in a Cut/Copy/Paste menu</comment>
|
||||||
|
</data>
|
||||||
|
<data name="SelectAll" xml:space="preserve">
|
||||||
|
<value>Select All</value>
|
||||||
|
<comment>"Select All" as contained in a Cut/Copy/Paste menu</comment>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
204
src/cascadia/UIHelpers/TextMenuFlyout.cpp
Normal file
204
src/cascadia/UIHelpers/TextMenuFlyout.cpp
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
#include "pch.h"
|
||||||
|
#include "TextMenuFlyout.h"
|
||||||
|
|
||||||
|
#include <LibraryResources.h>
|
||||||
|
|
||||||
|
#include "TextMenuFlyout.g.cpp"
|
||||||
|
|
||||||
|
using namespace ::winrt::Windows::UI::Xaml;
|
||||||
|
using namespace ::winrt::Windows::UI::Xaml::Controls;
|
||||||
|
using namespace ::winrt::Windows::ApplicationModel::Resources::Core;
|
||||||
|
using namespace ::winrt::Microsoft::UI::Xaml::Controls;
|
||||||
|
using namespace ::winrt::Windows::System;
|
||||||
|
using namespace ::winrt::Windows::UI::Xaml::Input;
|
||||||
|
|
||||||
|
using MenuFlyoutItemClick = void (*)(IInspectable const&, RoutedEventArgs const&);
|
||||||
|
|
||||||
|
constexpr auto NullSymbol = static_cast<Symbol>(0);
|
||||||
|
|
||||||
|
namespace winrt::Microsoft::Terminal::UI::implementation
|
||||||
|
{
|
||||||
|
#pragma warning(suppress : 26455) // Default constructor should not throw. Declare it 'noexcept' (f.6).
|
||||||
|
TextMenuFlyout::TextMenuFlyout()
|
||||||
|
{
|
||||||
|
// Most of the initialization is delayed until the first call to MenuFlyout_Opening.
|
||||||
|
Opening({ this, &TextMenuFlyout::MenuFlyout_Opening });
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextMenuFlyout::MenuFlyout_Opening(IInspectable const&, IInspectable const&)
|
||||||
|
{
|
||||||
|
auto target = Target();
|
||||||
|
if (!target)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hstring selection;
|
||||||
|
bool writable = false;
|
||||||
|
|
||||||
|
// > Common group of selectable controls with common actions
|
||||||
|
// > The I in MIDL stands for...
|
||||||
|
// No common interface.
|
||||||
|
if (const auto box = target.try_as<NumberBox>())
|
||||||
|
{
|
||||||
|
target = box.GetTemplateChild(L"InputBox").as<TextBox>();
|
||||||
|
}
|
||||||
|
if (const auto control = target.try_as<TextBlock>())
|
||||||
|
{
|
||||||
|
selection = control.SelectedText();
|
||||||
|
}
|
||||||
|
else if (const auto control = target.try_as<TextBox>())
|
||||||
|
{
|
||||||
|
selection = control.SelectedText();
|
||||||
|
writable = true;
|
||||||
|
}
|
||||||
|
else if (const auto control = target.try_as<RichTextBlock>())
|
||||||
|
{
|
||||||
|
selection = control.SelectedText();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_copy)
|
||||||
|
{
|
||||||
|
til::small_vector<MenuFlyoutItemBase, 4> items;
|
||||||
|
|
||||||
|
if (writable)
|
||||||
|
{
|
||||||
|
_cut = items.emplace_back(_createMenuItem(Symbol::Cut, RS_(L"Cut"), { this, &TextMenuFlyout::Cut_Click }, VirtualKeyModifiers::Control, VirtualKey::X));
|
||||||
|
}
|
||||||
|
_copy = items.emplace_back(_createMenuItem(Symbol::Copy, RS_(L"Copy"), { this, &TextMenuFlyout::Copy_Click }, VirtualKeyModifiers::Control, VirtualKey::C));
|
||||||
|
if (writable)
|
||||||
|
{
|
||||||
|
items.emplace_back(_createMenuItem(Symbol::Paste, RS_(L"Paste"), { this, &TextMenuFlyout::Paste_Click }, VirtualKeyModifiers::Control, VirtualKey::V));
|
||||||
|
}
|
||||||
|
items.emplace_back(_createMenuItem(NullSymbol, RS_(L"SelectAll"), { this, &TextMenuFlyout::SelectAll_Click }, VirtualKeyModifiers::Control, VirtualKey::A));
|
||||||
|
|
||||||
|
Items().ReplaceAll({ items.data(), gsl::narrow_cast<uint32_t>(items.size()) });
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto visibilityOfItemsRequiringSelection = selection.empty() ? Visibility::Collapsed : Visibility::Visible;
|
||||||
|
if (_cut)
|
||||||
|
{
|
||||||
|
_cut.Visibility(visibilityOfItemsRequiringSelection);
|
||||||
|
}
|
||||||
|
_copy.Visibility(visibilityOfItemsRequiringSelection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextMenuFlyout::Cut_Click(IInspectable const&, RoutedEventArgs const&)
|
||||||
|
{
|
||||||
|
// NOTE: When the flyout closes, WinUI doesn't disconnect the accelerator keys.
|
||||||
|
// Since that means we'll get Ctrl+X/C/V callbacks forever, just ignore them.
|
||||||
|
// The TextBox will still handle those events...
|
||||||
|
auto target = Target();
|
||||||
|
if (!target)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const auto box = target.try_as<NumberBox>())
|
||||||
|
{
|
||||||
|
target = box.GetTemplateChild(L"InputBox").as<TextBox>();
|
||||||
|
}
|
||||||
|
if (const auto control = target.try_as<TextBox>())
|
||||||
|
{
|
||||||
|
control.CutSelectionToClipboard();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextMenuFlyout::Copy_Click(IInspectable const&, RoutedEventArgs const&)
|
||||||
|
{
|
||||||
|
auto target = Target();
|
||||||
|
if (!target)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const auto box = target.try_as<NumberBox>())
|
||||||
|
{
|
||||||
|
target = box.GetTemplateChild(L"InputBox").as<TextBox>();
|
||||||
|
}
|
||||||
|
if (const auto control = target.try_as<TextBlock>())
|
||||||
|
{
|
||||||
|
control.CopySelectionToClipboard();
|
||||||
|
}
|
||||||
|
else if (const auto control = target.try_as<TextBox>())
|
||||||
|
{
|
||||||
|
control.CopySelectionToClipboard();
|
||||||
|
}
|
||||||
|
else if (const auto control = target.try_as<RichTextBlock>())
|
||||||
|
{
|
||||||
|
control.CopySelectionToClipboard();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextMenuFlyout::Paste_Click(IInspectable const&, RoutedEventArgs const&)
|
||||||
|
{
|
||||||
|
auto target = Target();
|
||||||
|
if (!target)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const auto box = target.try_as<NumberBox>())
|
||||||
|
{
|
||||||
|
target = box.GetTemplateChild(L"InputBox").as<TextBox>();
|
||||||
|
}
|
||||||
|
if (const auto control = target.try_as<TextBox>())
|
||||||
|
{
|
||||||
|
control.PasteFromClipboard();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextMenuFlyout::SelectAll_Click(IInspectable const&, RoutedEventArgs const&)
|
||||||
|
{
|
||||||
|
// BODGY:
|
||||||
|
// Once the flyout was open once, we'll get Ctrl+A events and the TextBox will
|
||||||
|
// ignore them. As such, we have to dig out the focused element as a fallback,
|
||||||
|
// because otherwise Ctrl+A will be permanently broken. Put differently,
|
||||||
|
// this is bodgy because WinUI 2.8 is buggy. There's no other solution here.
|
||||||
|
IInspectable target = Target();
|
||||||
|
if (!target)
|
||||||
|
{
|
||||||
|
target = FocusManager::GetFocusedElement(XamlRoot());
|
||||||
|
if (!target)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const auto box = target.try_as<NumberBox>())
|
||||||
|
{
|
||||||
|
target = box.GetTemplateChild(L"InputBox").as<TextBox>();
|
||||||
|
}
|
||||||
|
if (const auto control = target.try_as<TextBlock>())
|
||||||
|
{
|
||||||
|
control.SelectAll();
|
||||||
|
}
|
||||||
|
else if (const auto control = target.try_as<TextBox>())
|
||||||
|
{
|
||||||
|
control.SelectAll();
|
||||||
|
}
|
||||||
|
else if (const auto control = target.try_as<RichTextBlock>())
|
||||||
|
{
|
||||||
|
control.SelectAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuFlyoutItemBase TextMenuFlyout::_createMenuItem(Symbol symbol, hstring text, RoutedEventHandler click, VirtualKeyModifiers modifiers, VirtualKey key)
|
||||||
|
{
|
||||||
|
KeyboardAccelerator accel;
|
||||||
|
accel.Modifiers(modifiers);
|
||||||
|
accel.Key(key);
|
||||||
|
|
||||||
|
MenuFlyoutItem item;
|
||||||
|
if (symbol != NullSymbol)
|
||||||
|
{
|
||||||
|
item.Icon(SymbolIcon{ std::move(symbol) });
|
||||||
|
}
|
||||||
|
item.Text(std::move(text));
|
||||||
|
item.Click(std::move(click));
|
||||||
|
item.KeyboardAccelerators().Append(std::move(accel));
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
43
src/cascadia/UIHelpers/TextMenuFlyout.h
Normal file
43
src/cascadia/UIHelpers/TextMenuFlyout.h
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "TextMenuFlyout.g.h"
|
||||||
|
|
||||||
|
namespace winrt::Microsoft::Terminal::UI::implementation
|
||||||
|
{
|
||||||
|
// This custom flyout exists because WinUI 2 only supports 1 text block flyout
|
||||||
|
// *per thread* not per window. If you have >1 window per 1 thread, as we do,
|
||||||
|
// the focus will just be delegated to the window the flyout was first opened in.
|
||||||
|
// Once the first window is gone, WinUI will either do nothing or crash.
|
||||||
|
// See: GH#18599
|
||||||
|
struct TextMenuFlyout : TextMenuFlyoutT<TextMenuFlyout>
|
||||||
|
{
|
||||||
|
TextMenuFlyout();
|
||||||
|
|
||||||
|
void MenuFlyout_Opening(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::Foundation::IInspectable const& e);
|
||||||
|
void Cut_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
|
||||||
|
void Copy_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
|
||||||
|
void Paste_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
|
||||||
|
void SelectAll_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
|
||||||
|
|
||||||
|
private:
|
||||||
|
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItemBase _createMenuItem(
|
||||||
|
winrt::Windows::UI::Xaml::Controls::Symbol symbol,
|
||||||
|
winrt::hstring text,
|
||||||
|
winrt::Windows::UI::Xaml::RoutedEventHandler click,
|
||||||
|
winrt::Windows::System::VirtualKeyModifiers modifiers,
|
||||||
|
winrt::Windows::System::VirtualKey key);
|
||||||
|
|
||||||
|
// These are always present.
|
||||||
|
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItemBase _copy{ nullptr };
|
||||||
|
// These are only set for writable controls.
|
||||||
|
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItemBase _cut{ nullptr };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace winrt::Microsoft::Terminal::UI::factory_implementation
|
||||||
|
{
|
||||||
|
BASIC_FACTORY(TextMenuFlyout);
|
||||||
|
}
|
||||||
7
src/cascadia/UIHelpers/TextMenuFlyout.idl
Normal file
7
src/cascadia/UIHelpers/TextMenuFlyout.idl
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
namespace Microsoft.Terminal.UI
|
||||||
|
{
|
||||||
|
[default_interface] runtimeclass TextMenuFlyout : Windows.UI.Xaml.Controls.MenuFlyout
|
||||||
|
{
|
||||||
|
TextMenuFlyout();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,6 +26,9 @@
|
|||||||
<ClInclude Include="ResourceString.h">
|
<ClInclude Include="ResourceString.h">
|
||||||
<DependentUpon>ResourceString.idl</DependentUpon>
|
<DependentUpon>ResourceString.idl</DependentUpon>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="TextMenuFlyout.h">
|
||||||
|
<DependentUpon>TextMenuFlyout.idl</DependentUpon>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="init.cpp" />
|
<ClCompile Include="init.cpp" />
|
||||||
@@ -41,6 +44,9 @@
|
|||||||
<ClCompile Include="ResourceString.cpp">
|
<ClCompile Include="ResourceString.cpp">
|
||||||
<DependentUpon>ResourceString.idl</DependentUpon>
|
<DependentUpon>ResourceString.idl</DependentUpon>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="TextMenuFlyout.cpp">
|
||||||
|
<DependentUpon>TextMenuFlyout.idl</DependentUpon>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -48,6 +54,13 @@
|
|||||||
<Midl Include="IconPathConverter.idl" />
|
<Midl Include="IconPathConverter.idl" />
|
||||||
<Midl Include="IDirectKeyListener.idl" />
|
<Midl Include="IDirectKeyListener.idl" />
|
||||||
<Midl Include="ResourceString.idl" />
|
<Midl Include="ResourceString.idl" />
|
||||||
|
<Midl Include="TextMenuFlyout.idl" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PRIResource Include="Resources\en-US\Resources.resw">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</PRIResource>
|
||||||
|
<OCResourceDirectory Include="Resources" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- ========================= Project References ======================== -->
|
<!-- ========================= Project References ======================== -->
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -64,15 +77,12 @@
|
|||||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemDefinitionGroup>
|
<ItemDefinitionGroup>
|
||||||
<Link>
|
<Link>
|
||||||
<AdditionalDependencies>%(AdditionalDependencies);user32.lib;shell32.lib</AdditionalDependencies>
|
<AdditionalDependencies>%(AdditionalDependencies);user32.lib;shell32.lib</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
|
||||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
||||||
|
|
||||||
<!-- This -must- go after cppwinrt.build.post.props because that includes many VS-provided props including appcontainer.common.props, which stomps on what cppwinrt.targets did. -->
|
<!-- This -must- go after cppwinrt.build.post.props because that includes many VS-provided props including appcontainer.common.props, which stomps on what cppwinrt.targets did. -->
|
||||||
<Import Project="$(OpenConsoleDir)src\common.nugetversions.targets" />
|
<Import Project="$(OpenConsoleDir)src\common.nugetversions.targets" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -31,8 +31,18 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Midl Include="ResourceString.idl" />
|
<Midl Include="ResourceString.idl" />
|
||||||
|
<Midl Include="Converters.idl" />
|
||||||
|
<Midl Include="IconPathConverter.idl" />
|
||||||
|
<Midl Include="IDirectKeyListener.idl" />
|
||||||
|
<Midl Include="TextMenuFlyout.idl" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Natvis Include="$(SolutionDir)tools\ConsoleTypes.natvis" />
|
<Natvis Include="$(SolutionDir)tools\ConsoleTypes.natvis" />
|
||||||
|
<Natvis Include="$(MSBuildThisFileDirectory)..\..\natvis\wil.natvis" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PRIResource Include="Resources\en-US\Resources.resw">
|
||||||
|
<Filter>Resources\en-US</Filter>
|
||||||
|
</PRIResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
|
|
||||||
|
#include <LibraryResources.h>
|
||||||
|
|
||||||
#pragma warning(suppress : 26440) // Not interested in changing the specification of DllMain to make it noexcept given it's an interface to the OS.
|
#pragma warning(suppress : 26440) // Not interested in changing the specification of DllMain to make it noexcept given it's an interface to the OS.
|
||||||
BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD reason, LPVOID /*reserved*/)
|
BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD reason, LPVOID /*reserved*/)
|
||||||
{
|
{
|
||||||
@@ -11,11 +13,11 @@ BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD reason, LPVOID /*reserved*/)
|
|||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
DisableThreadLibraryCalls(hInstDll);
|
DisableThreadLibraryCalls(hInstDll);
|
||||||
break;
|
break;
|
||||||
case DLL_PROCESS_DETACH:
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UTILS_DEFINE_LIBRARY_RESOURCE_SCOPE(L"Microsoft.Terminal.UI/Resources")
|
||||||
|
|||||||
@@ -25,16 +25,15 @@
|
|||||||
|
|
||||||
#include <wil/cppwinrt.h>
|
#include <wil/cppwinrt.h>
|
||||||
|
|
||||||
#include <winrt/Windows.ApplicationModel.Resources.h>
|
#include <winrt/Windows.ApplicationModel.Resources.Core.h>
|
||||||
#include <winrt/Windows.Foundation.h>
|
#include <winrt/Windows.Foundation.Collections.h>
|
||||||
|
|
||||||
#include <winrt/Windows.Graphics.Imaging.h>
|
#include <winrt/Windows.Graphics.Imaging.h>
|
||||||
#include <Windows.Graphics.Imaging.Interop.h>
|
#include <Windows.Graphics.Imaging.Interop.h>
|
||||||
|
|
||||||
#include <winrt/Windows.UI.Text.h>
|
|
||||||
#include <winrt/Windows.UI.Xaml.Controls.h>
|
#include <winrt/Windows.UI.Xaml.Controls.h>
|
||||||
#include <winrt/Windows.UI.Xaml.Markup.h>
|
#include <winrt/Windows.UI.Xaml.Markup.h>
|
||||||
#include <winrt/Windows.UI.Xaml.Media.h>
|
#include <winrt/Windows.UI.Xaml.Input.h>
|
||||||
#include <winrt/Windows.UI.Xaml.Media.Imaging.h>
|
#include <winrt/Windows.UI.Xaml.Media.Imaging.h>
|
||||||
|
|
||||||
#include <winrt/Microsoft.UI.Xaml.Controls.h>
|
#include <winrt/Microsoft.UI.Xaml.Controls.h>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:local="using:Microsoft.Terminal.UI.Markdown"
|
xmlns:local="using:Microsoft.Terminal.UI.Markdown"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:mtu="using:Microsoft.Terminal.UI"
|
||||||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
|
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
@@ -201,7 +202,11 @@
|
|||||||
VerticalAlignment="Stretch">
|
VerticalAlignment="Stretch">
|
||||||
<TextBlock FontFamily="Cascadia Mono, Consolas"
|
<TextBlock FontFamily="Cascadia Mono, Consolas"
|
||||||
IsTextSelectionEnabled="True"
|
IsTextSelectionEnabled="True"
|
||||||
Text="{x:Bind Commandlines}" />
|
Text="{x:Bind Commandlines}">
|
||||||
|
<TextBlock.ContextFlyout>
|
||||||
|
<mtu:TextMenuFlyout />
|
||||||
|
</TextBlock.ContextFlyout>
|
||||||
|
</TextBlock>
|
||||||
</Grid>
|
</Grid>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</Border>
|
</Border>
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ WUX::Controls::RichTextBlock MarkdownToXaml::Convert(std::string_view markdownTe
|
|||||||
MarkdownToXaml::MarkdownToXaml(const winrt::hstring& baseUrl) :
|
MarkdownToXaml::MarkdownToXaml(const winrt::hstring& baseUrl) :
|
||||||
_baseUri{ baseUrl }
|
_baseUri{ baseUrl }
|
||||||
{
|
{
|
||||||
|
_root.ContextFlyout(winrt::Microsoft::Terminal::UI::TextMenuFlyout{});
|
||||||
_root.IsTextSelectionEnabled(true);
|
_root.IsTextSelectionEnabled(true);
|
||||||
_root.TextWrapping(WUX::TextWrapping::WrapWholeWords);
|
_root.TextWrapping(WUX::TextWrapping::WrapWholeWords);
|
||||||
}
|
}
|
||||||
@@ -155,6 +156,7 @@ void MarkdownToXaml::_EndParagraph() noexcept
|
|||||||
WUX::Controls::TextBlock MarkdownToXaml::_makeDefaultTextBlock()
|
WUX::Controls::TextBlock MarkdownToXaml::_makeDefaultTextBlock()
|
||||||
{
|
{
|
||||||
WUX::Controls::TextBlock b{};
|
WUX::Controls::TextBlock b{};
|
||||||
|
b.ContextFlyout(winrt::Microsoft::Terminal::UI::TextMenuFlyout{});
|
||||||
b.IsTextSelectionEnabled(true);
|
b.IsTextSelectionEnabled(true);
|
||||||
b.TextWrapping(WUX::TextWrapping::WrapWholeWords);
|
b.TextWrapping(WUX::TextWrapping::WrapWholeWords);
|
||||||
return b;
|
return b;
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<OpenConsoleUniversalApp>true</OpenConsoleUniversalApp>
|
<OpenConsoleUniversalApp>true</OpenConsoleUniversalApp>
|
||||||
|
|
||||||
<!-- C++/WinRT sets the depth to 1 if there is a XAML file in the project
|
<!-- C++/WinRT sets the depth to 1 if there is a XAML file in the project
|
||||||
Unfortunately for us, we need it to be 4. When the namespace merging
|
Unfortunately for us, we need it to be 4. When the namespace merging
|
||||||
depth is 1, Microsoft.Terminal.UI.Markdown becomes "Microsoft",
|
depth is 1, Microsoft.Terminal.UI.Markdown becomes "Microsoft",
|
||||||
@@ -18,7 +17,6 @@
|
|||||||
-->
|
-->
|
||||||
<CppWinRTNamespaceMergeDepth>4</CppWinRTNamespaceMergeDepth>
|
<CppWinRTNamespaceMergeDepth>4</CppWinRTNamespaceMergeDepth>
|
||||||
<XamlComponentResourceLocation>nested</XamlComponentResourceLocation>
|
<XamlComponentResourceLocation>nested</XamlComponentResourceLocation>
|
||||||
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Label="NuGet Dependencies">
|
<PropertyGroup Label="NuGet Dependencies">
|
||||||
<TerminalCppWinrt>true</TerminalCppWinrt>
|
<TerminalCppWinrt>true</TerminalCppWinrt>
|
||||||
@@ -78,10 +76,11 @@
|
|||||||
<Project>{CA5CAD1A-039A-4929-BA2A-8BEB2E4106FE}</Project>
|
<Project>{CA5CAD1A-039A-4929-BA2A-8BEB2E4106FE}</Project>
|
||||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\UIHelpers\UIHelpers.vcxproj">
|
||||||
|
<Project>{6515f03f-e56d-4db4-b23d-ac4fb80db36f}</Project>
|
||||||
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
||||||
|
|
||||||
<!-- This -must- go after cppwinrt.build.post.props because that includes many VS-provided props including appcontainer.common.props, which stomps on what cppwinrt.targets did. -->
|
<!-- This -must- go after cppwinrt.build.post.props because that includes many VS-provided props including appcontainer.common.props, which stomps on what cppwinrt.targets did. -->
|
||||||
<Import Project="$(OpenConsoleDir)src\common.nugetversions.targets" />
|
<Import Project="$(OpenConsoleDir)src\common.nugetversions.targets" />
|
||||||
</Project>
|
</Project>
|
||||||
@@ -25,14 +25,20 @@
|
|||||||
<ClCompile Include="pch.cpp">
|
<ClCompile Include="pch.cpp">
|
||||||
<Filter>Module</Filter>
|
<Filter>Module</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="MarkdownToXaml.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="pch.h" />
|
<ClInclude Include="pch.h" />
|
||||||
|
<ClInclude Include="MarkdownToXaml.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Midl Include="Builder.idl" />
|
<Midl Include="Builder.idl" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Natvis Include="$(SolutionDir)tools\ConsoleTypes.natvis" />
|
<Natvis Include="$(SolutionDir)tools\ConsoleTypes.natvis" />
|
||||||
|
<Natvis Include="$(MSBuildThisFileDirectory)..\..\natvis\wil.natvis" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
<ItemGroup>
|
||||||
|
<Page Include="CodeBlock.xaml" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
@@ -25,21 +25,19 @@
|
|||||||
|
|
||||||
#include <wil/cppwinrt.h>
|
#include <wil/cppwinrt.h>
|
||||||
|
|
||||||
#include <winrt/Windows.Foundation.h>
|
|
||||||
#include <winrt/Windows.Foundation.Collections.h>
|
#include <winrt/Windows.Foundation.Collections.h>
|
||||||
|
|
||||||
#include <winrt/Windows.UI.Text.h>
|
#include <winrt/Windows.UI.Text.h>
|
||||||
#include <winrt/Windows.UI.Xaml.Controls.h>
|
#include <winrt/Windows.UI.Xaml.Controls.h>
|
||||||
#include <winrt/Windows.UI.Xaml.Markup.h>
|
|
||||||
#include <winrt/Windows.UI.Xaml.Media.h>
|
|
||||||
#include <winrt/Windows.UI.Xaml.Media.Imaging.h>
|
#include <winrt/Windows.UI.Xaml.Media.Imaging.h>
|
||||||
#include <winrt/Windows.UI.Xaml.Documents.h>
|
#include <winrt/Windows.UI.Xaml.Documents.h>
|
||||||
#include <winrt/Windows.UI.Xaml.Input.h>
|
#include <winrt/Windows.UI.Xaml.Input.h>
|
||||||
|
|
||||||
#include <winrt/Microsoft.UI.Xaml.Controls.h>
|
#include <winrt/Microsoft.UI.Xaml.Controls.h>
|
||||||
#include <winrt/Microsoft.UI.Xaml.Controls.Primitives.h>
|
|
||||||
#include <winrt/Microsoft.UI.Xaml.XamlTypeInfo.h>
|
#include <winrt/Microsoft.UI.Xaml.XamlTypeInfo.h>
|
||||||
|
|
||||||
|
#include <winrt/Microsoft.Terminal.UI.h>
|
||||||
|
|
||||||
// Manually include til after we include Windows.Foundation to give it winrt superpowers
|
// Manually include til after we include Windows.Foundation to give it winrt superpowers
|
||||||
#include "til.h"
|
#include "til.h"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user