Merge branch 'dev/migrie/f/non-terminal-content-elevation-warning' into dev/migrie/f/632-on-warning-dialog
This commit is contained in:
commit
88da035e8a
|
@ -6,7 +6,9 @@
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "AdminWarningPlaceholder.h"
|
#include "AdminWarningPlaceholder.h"
|
||||||
#include "AdminWarningPlaceholder.g.cpp"
|
#include "AdminWarningPlaceholder.g.cpp"
|
||||||
|
#include <LibraryResources.h>
|
||||||
using namespace winrt::Windows::UI::Xaml;
|
using namespace winrt::Windows::UI::Xaml;
|
||||||
|
using namespace winrt::Windows::UI::Xaml::Automation::Peers;
|
||||||
|
|
||||||
namespace winrt::TerminalApp::implementation
|
namespace winrt::TerminalApp::implementation
|
||||||
{
|
{
|
||||||
|
@ -37,4 +39,37 @@ namespace winrt::TerminalApp::implementation
|
||||||
{
|
{
|
||||||
return _control;
|
return _control;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Move the focus to the cancel button by default. This has the LOAD
|
||||||
|
// BEARING side effect of also triggering Narrator to read out the
|
||||||
|
// contents of the dialog. It's unclear why doing this works, but it does.
|
||||||
|
// - Using a LayoutUpdated event to trigger the focus change when we're
|
||||||
|
// added to the UI tree did not seem to work.
|
||||||
|
// - Whoever is adding us to the UI tree is responsible for calling this!
|
||||||
|
// Arguments:
|
||||||
|
// - <none>
|
||||||
|
// Return Value:
|
||||||
|
// - <none>
|
||||||
|
void AdminWarningPlaceholder::FocusOnLaunch()
|
||||||
|
{
|
||||||
|
CancelButton().Focus(FocusState::Programmatic);
|
||||||
|
}
|
||||||
|
|
||||||
|
winrt::hstring AdminWarningPlaceholder::ControlName()
|
||||||
|
{
|
||||||
|
return RS_(L"AdminWarningPlaceholderName");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdminWarningPlaceholder::_keyUpHandler(IInspectable const& /*sender*/,
|
||||||
|
Windows::UI::Xaml::Input::KeyRoutedEventArgs const& e)
|
||||||
|
{
|
||||||
|
// If the user presses escape, close the dialog (without confirming)
|
||||||
|
const auto key = e.OriginalKey();
|
||||||
|
if (key == winrt::Windows::System::VirtualKey::Escape)
|
||||||
|
{
|
||||||
|
_CancelButtonClickedHandlers(*this, e);
|
||||||
|
e.Handled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,22 @@
|
||||||
// Copyright (c) Microsoft Corporation.
|
/*++
|
||||||
// Licensed under the MIT license.
|
Copyright (c) Microsoft Corporation
|
||||||
|
Licensed under the MIT license.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
- AdminWarningPlaceholder
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
- The AdminaWarningPlaceholder is a control used to fill space in a pane and
|
||||||
|
present a warning to the user. It holds on to a real control that it should be
|
||||||
|
replaced with. It looks just like a ContentDialog, except it exists per-pane,
|
||||||
|
whereas a ContentDialog can only be added to take up the whole window.
|
||||||
|
- The caller should make sure to bind our PrimaryButtonClicked and
|
||||||
|
CancelButtonClicked events, to be informed as to which was pressed.
|
||||||
|
|
||||||
|
Author(s):
|
||||||
|
- Mike Griese - September 2021
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
@ -11,8 +28,9 @@ namespace winrt::TerminalApp::implementation
|
||||||
struct AdminWarningPlaceholder : AdminWarningPlaceholderT<AdminWarningPlaceholder>
|
struct AdminWarningPlaceholder : AdminWarningPlaceholderT<AdminWarningPlaceholder>
|
||||||
{
|
{
|
||||||
AdminWarningPlaceholder(const winrt::Microsoft::Terminal::Control::TermControl& control, const winrt::hstring& cmdline);
|
AdminWarningPlaceholder(const winrt::Microsoft::Terminal::Control::TermControl& control, const winrt::hstring& cmdline);
|
||||||
|
void FocusOnLaunch();
|
||||||
winrt::Windows::UI::Xaml::Controls::UserControl Control();
|
winrt::Windows::UI::Xaml::Controls::UserControl Control();
|
||||||
|
winrt::hstring ControlName();
|
||||||
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
|
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
|
||||||
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, Commandline, _PropertyChangedHandlers);
|
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, Commandline, _PropertyChangedHandlers);
|
||||||
TYPED_EVENT(PrimaryButtonClicked, TerminalApp::AdminWarningPlaceholder, winrt::Windows::UI::Xaml::RoutedEventArgs);
|
TYPED_EVENT(PrimaryButtonClicked, TerminalApp::AdminWarningPlaceholder, winrt::Windows::UI::Xaml::RoutedEventArgs);
|
||||||
|
@ -27,5 +45,7 @@ namespace winrt::TerminalApp::implementation
|
||||||
winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
|
winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
|
||||||
void _cancelButtonClick(winrt::Windows::Foundation::IInspectable const& sender,
|
void _cancelButtonClick(winrt::Windows::Foundation::IInspectable const& sender,
|
||||||
winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
|
winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
|
||||||
|
void _keyUpHandler(Windows::Foundation::IInspectable const& sender,
|
||||||
|
Windows::UI::Xaml::Input::KeyRoutedEventArgs const& e);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,5 +7,6 @@ namespace TerminalApp
|
||||||
Windows.UI.Xaml.Data.INotifyPropertyChanged
|
Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
String Commandline { get; };
|
String Commandline { get; };
|
||||||
|
String ControlName { get; };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,10 @@
|
||||||
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:mux="using:Microsoft.UI.Xaml.Controls"
|
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
|
||||||
|
AutomationProperties.AccessibilityView="Content"
|
||||||
|
AutomationProperties.IsDialog="True"
|
||||||
|
AutomationProperties.Name="{x:Bind ControlName, Mode=OneWay}"
|
||||||
|
PreviewKeyUp="_keyUpHandler"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
@ -27,44 +31,60 @@
|
||||||
VerticalAlignment="Center">
|
VerticalAlignment="Center">
|
||||||
<Border Margin="8,8,8,8"
|
<Border Margin="8,8,8,8"
|
||||||
Padding="16,8,16,8"
|
Padding="16,8,16,8"
|
||||||
|
AllowFocusOnInteraction="True"
|
||||||
|
AutomationProperties.AccessibilityView="Raw"
|
||||||
|
AutomationProperties.IsDialog="True"
|
||||||
Background="{ThemeResource SystemControlBackgroundAltHighBrush}"
|
Background="{ThemeResource SystemControlBackgroundAltHighBrush}"
|
||||||
BorderBrush="{ThemeResource SystemAccentColor}"
|
BorderBrush="{ThemeResource SystemAccentColor}"
|
||||||
BorderThickness="2,2,2,2"
|
BorderThickness="2,2,2,2"
|
||||||
CornerRadius="{ThemeResource OverlayCornerRadius}">
|
CornerRadius="{ThemeResource OverlayCornerRadius}">
|
||||||
<StackPanel Orientation="Vertical">
|
<StackPanel Orientation="Vertical">
|
||||||
<TextBlock x:Uid="ApproveCommandlineWarningTitle"
|
<TextBlock x:Name="ApproveCommandlineWarningTitle"
|
||||||
|
x:Uid="ApproveCommandlineWarningTitle"
|
||||||
Padding="0,0,0,16"
|
Padding="0,0,0,16"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
FontSize="20"
|
FontSize="20"
|
||||||
FontWeight="Normal"
|
FontWeight="Normal"
|
||||||
TextWrapping="WrapWholeWords" />
|
TextWrapping="WrapWholeWords" />
|
||||||
|
|
||||||
<TextBlock x:Uid="ApproveCommandlineWarningPrefixTextBlock"
|
<TextBlock x:Name="PrefixTextBlock"
|
||||||
|
x:Uid="ApproveCommandlineWarningPrefixTextBlock"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
TextWrapping="WrapWholeWords" />
|
TextWrapping="WrapWholeWords" />
|
||||||
|
|
||||||
<TextBlock Margin="0,8,0,8"
|
<TextBlock x:Name="CommandlineText"
|
||||||
HorizontalAlignment="Center"
|
Margin="0,16,0,16"
|
||||||
FontFamily="Cascadia Code"
|
HorizontalAlignment="Left"
|
||||||
|
FontFamily="Cascadia Mono"
|
||||||
Text="{x:Bind Commandline, Mode=OneWay}"
|
Text="{x:Bind Commandline, Mode=OneWay}"
|
||||||
TextWrapping="WrapWholeWords" />
|
TextWrapping="WrapWholeWords" />
|
||||||
|
|
||||||
<TextBlock x:Uid="ApproveCommandlineWarningSuffixTextBlock"
|
<TextBlock x:Name="SuffixTextBlock"
|
||||||
|
x:Uid="ApproveCommandlineWarningSuffixTextBlock"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
TextWrapping="WrapWholeWords" />
|
TextWrapping="WrapWholeWords" />
|
||||||
<StackPanel HorizontalAlignment="Right"
|
<Grid Margin="0,8,0,8"
|
||||||
Orientation="Horizontal">
|
HorizontalAlignment="Stretch"
|
||||||
|
XYFocusKeyboardNavigation="Enabled">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
<Button x:Name="PrimaryButton"
|
<Button x:Name="PrimaryButton"
|
||||||
x:Uid="ApproveCommandlineWarning_PrimaryButton"
|
x:Uid="ApproveCommandlineWarning_PrimaryButton"
|
||||||
Margin="8"
|
Grid.Column="0"
|
||||||
HorizontalAlignment="Right"
|
Margin="0,0,8,0"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
Click="_primaryButtonClick"
|
Click="_primaryButtonClick"
|
||||||
|
IsTabStop="True"
|
||||||
Style="{StaticResource AccentButtonStyle}" />
|
Style="{StaticResource AccentButtonStyle}" />
|
||||||
<Button x:Name="CancelButton"
|
<Button x:Name="CancelButton"
|
||||||
x:Uid="ApproveCommandlineWarning_CancelButton"
|
x:Uid="ApproveCommandlineWarning_CancelButton"
|
||||||
HorizontalAlignment="Right"
|
Grid.Column="1"
|
||||||
Click="_cancelButtonClick" />
|
HorizontalAlignment="Stretch"
|
||||||
</StackPanel>
|
Click="_cancelButtonClick"
|
||||||
|
IsTabStop="True" />
|
||||||
|
</Grid>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
|
@ -144,7 +144,7 @@ NewTerminalArgs Pane::GetTerminalArgsForPane() const
|
||||||
|
|
||||||
args.Profile(controlSettings.ProfileName());
|
args.Profile(controlSettings.ProfileName());
|
||||||
// If we know the user's working directory use it instead of the profile.
|
// If we know the user's working directory use it instead of the profile.
|
||||||
if (const auto dir = _control.WorkingDirectory(); !dir.empty())
|
if (const auto dir = termControl.WorkingDirectory(); !dir.empty())
|
||||||
{
|
{
|
||||||
args.StartingDirectory(dir);
|
args.StartingDirectory(dir);
|
||||||
}
|
}
|
||||||
|
|
|
@ -504,21 +504,24 @@
|
||||||
<data name="MultiLinePasteDialog.Title" xml:space="preserve">
|
<data name="MultiLinePasteDialog.Title" xml:space="preserve">
|
||||||
<value>Warning</value>
|
<value>Warning</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ApproveCommandlineWarning_CancelButton.Content" xml:space="preserve">
|
|
||||||
<value>Cancel</value>
|
|
||||||
</data>
|
|
||||||
<data name="ApproveCommandlineWarningPrefixTextBlock.Text" xml:space="preserve">
|
<data name="ApproveCommandlineWarningPrefixTextBlock.Text" xml:space="preserve">
|
||||||
<value>You are about to execute the following commandline:</value>
|
<value>You are about to execute the following command-line:</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ApproveCommandlineWarningSuffixTextBlock.Text" xml:space="preserve">
|
<data name="ApproveCommandlineWarningSuffixTextBlock.Text" xml:space="preserve">
|
||||||
<value>Do you wish to continue?</value>
|
<value>Do you wish to continue?</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ApproveCommandlineWarning_PrimaryButton.Content" xml:space="preserve">
|
<data name="ApproveCommandlineWarning_PrimaryButton.Content" xml:space="preserve">
|
||||||
<value>Allow Commandline</value>
|
<value>Allow command-line</value>
|
||||||
|
</data>
|
||||||
|
<data name="ApproveCommandlineWarning_CancelButton.Content" xml:space="preserve">
|
||||||
|
<value>Cancel</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ApproveCommandlineWarningTitle.Text" xml:space="preserve">
|
<data name="ApproveCommandlineWarningTitle.Text" xml:space="preserve">
|
||||||
<value>Warning</value>
|
<value>Warning</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="AdminWarningPlaceholderName" xml:space="preserve">
|
||||||
|
<value>Elevated command-line warning</value>
|
||||||
|
</data>
|
||||||
<data name="CommandPalette_SearchBox.PlaceholderText" xml:space="preserve">
|
<data name="CommandPalette_SearchBox.PlaceholderText" xml:space="preserve">
|
||||||
<value>Type a command name...</value>
|
<value>Type a command name...</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
@ -315,6 +315,17 @@ namespace winrt::TerminalApp::implementation
|
||||||
// Split (auto) with the debug tap.
|
// Split (auto) with the debug tap.
|
||||||
newTabImpl->SplitPane(SplitDirection::Automatic, 0.5f, profile, newControl);
|
newTabImpl->SplitPane(SplitDirection::Automatic, 0.5f, profile, newControl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (doAdminWarning)
|
||||||
|
{
|
||||||
|
// We know this is safe - we literally just added the
|
||||||
|
// AdminWarningPlaceholder as the controlToAdd like 20 lines up.
|
||||||
|
//
|
||||||
|
// Focus the warning here. The LayoutUpdated within the dialog
|
||||||
|
// itself isn't good enough. That, for some reason, fires _before_
|
||||||
|
// the dialog is in the UI tree, which is useless for us.
|
||||||
|
controlToAdd.try_as<implementation::AdminWarningPlaceholder>()->FocusOnLaunch();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
|
|
|
@ -1919,7 +1919,8 @@ namespace winrt::TerminalApp::implementation
|
||||||
WUX::Controls::UserControl controlToAdd{ newControl };
|
WUX::Controls::UserControl controlToAdd{ newControl };
|
||||||
|
|
||||||
const auto& cmdline{ controlSettings.DefaultSettings().Commandline() };
|
const auto& cmdline{ controlSettings.DefaultSettings().Commandline() };
|
||||||
if (_shouldPromptForCommandline(cmdline))
|
const auto doAdminWarning{ _shouldPromptForCommandline(cmdline) };
|
||||||
|
if (doAdminWarning)
|
||||||
{
|
{
|
||||||
auto warningControl{ winrt::make_self<implementation::AdminWarningPlaceholder>(newControl, cmdline) };
|
auto warningControl{ winrt::make_self<implementation::AdminWarningPlaceholder>(newControl, cmdline) };
|
||||||
warningControl->PrimaryButtonClicked({ get_weak(), &TerminalPage::_adminWarningPrimaryClicked });
|
warningControl->PrimaryButtonClicked({ get_weak(), &TerminalPage::_adminWarningPrimaryClicked });
|
||||||
|
@ -1944,6 +1945,17 @@ namespace winrt::TerminalApp::implementation
|
||||||
activeControl.Focus(FocusState::Programmatic);
|
activeControl.Focus(FocusState::Programmatic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (doAdminWarning)
|
||||||
|
{
|
||||||
|
// We know this is safe - we literally just added the
|
||||||
|
// AdminWarningPlaceholder as the controlToAdd like 20 lines up.
|
||||||
|
//
|
||||||
|
// Focus the warning here. The LayoutUpdated within the dialog
|
||||||
|
// itself isn't good enough. That, for some reason, fires _before_
|
||||||
|
// the dialog is in the UI tree, which is useless for us.
|
||||||
|
controlToAdd.try_as<implementation::AdminWarningPlaceholder>()->FocusOnLaunch();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
CATCH_LOG();
|
CATCH_LOG();
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,7 @@
|
||||||
<!-- Must be Stdcall on all platforms to resolve _ObjectStublessClient3 -->
|
<!-- Must be Stdcall on all platforms to resolve _ObjectStublessClient3 -->
|
||||||
<PreprocessorDefinitions>REGISTER_PROXY_DLL;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>REGISTER_PROXY_DLL;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
<SDLCheck>false</SDLCheck>
|
<SDLCheck>false</SDLCheck>
|
||||||
<ForcedIncludeFiles>nodefaultlib_shim.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
|
<ForcedIncludeFiles>nodefaultlib_shim.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
|
||||||
|
|
|
@ -1,18 +1,8 @@
|
||||||
// Copyright (c) Microsoft Corporation.
|
// Copyright (c) Microsoft Corporation.
|
||||||
// Licensed under the MIT license.
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include <guiddef.h>
|
#include <guiddef.h>
|
||||||
|
|
||||||
#if !defined(_M_IX86) && !defined(_M_X64)
|
#define memcmp(a, b, c) (!InlineIsEqualGUID(a, b))
|
||||||
|
|
||||||
// ARM64 doesn't define a (__builtin_)memcmp function without CRT,
|
|
||||||
// but we need one to compile IID_GENERIC_CHECK_IID.
|
|
||||||
// Luckily we only ever use memcmp for IIDs.
|
|
||||||
#pragma function(memcmp)
|
|
||||||
inline int memcmp(const IID* a, const IID* b, size_t count)
|
|
||||||
{
|
|
||||||
(void)(count);
|
|
||||||
return 1 - InlineIsEqualGUID(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
Loading…
Reference in a new issue