From 42e9ddcc78710c101315a58b87c1c9db893fe3a7 Mon Sep 17 00:00:00 2001 From: James Pack Date: Thu, 20 Jul 2023 12:09:57 -0400 Subject: [PATCH] Add support for running profiles from Add tab menu as admin without a keyboard (#15679) ## Summary of the Pull Request Add support for running profiles in the Add Tab drop down as administrator without a keyboard. ## References and Relevant Issues #14517 ## Detailed Description of the Pull Request / Additional comments This pull request adds a FlyoutMenu to each Profile entry in the Add New tab drop down. When a profile is right clicked or held for 2 seconds in the case of no mouse input will present a MenuItem to allow the user to click and run the selected profile as administrator ## Validation Steps Performed - Responds to pointer input events (mouse, pointer, touchpad) - Adjusts to theme changes. - Only shows when a profile is selected. Will not show on settings or pallete entries ## PR Checklist - [x] Closes #14517 - [ ] Tests added/passed - [ ] Documentation updated - If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx - [ ] Schema updated (if necessary) --- .../Resources/en-US/Resources.resw | 8 +++- src/cascadia/TerminalApp/TerminalPage.cpp | 47 +++++++++++++++++++ src/cascadia/TerminalApp/TerminalPage.h | 2 +- 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw index 1a20db37695..80f0a9df574 100644 --- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw @@ -216,7 +216,7 @@ Web Search - + Color... @@ -836,4 +836,8 @@ Moves tab to a new window - + + Run as Administrator + This text is displayed on context menu for profile entries in add new tab button. + + \ No newline at end of file diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 15bc81c4004..8140af22b3e 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -1057,6 +1057,15 @@ namespace winrt::TerminalApp::implementation } }); + // Using the static method on the base class seems to do what we want in terms of placement. + WUX::Controls::Primitives::FlyoutBase::SetAttachedFlyout(profileMenuItem, _CreateRunAsAdminFlyout(profileIndex)); + + // Since we are not setting the ContextFlyout property of the item we have to handle the ContextRequested event + // and rely on the base class to show our menu. + profileMenuItem.ContextRequested([profileMenuItem](auto&&, auto&&) { + WUX::Controls::Primitives::FlyoutBase::ShowAttachedFlyout(profileMenuItem); + }); + return profileMenuItem; } @@ -4959,4 +4968,42 @@ namespace winrt::TerminalApp::implementation // _RemoveTab will make sure to null out the _stashed.draggedTab _RemoveTab(*_stashed.draggedTab); } + + /// + /// Creates a sub flyout menu for profile items in the split button menu that when clicked will show a menu item for + /// Run as Administrator + /// + /// The index for the profileMenuItem + /// MenuFlyout that will show when the context is request on a profileMenuItem + WUX::Controls::MenuFlyout TerminalPage::_CreateRunAsAdminFlyout(int profileIndex) + { + // Create the MenuFlyout and set its placement + WUX::Controls::MenuFlyout profileMenuItemFlyout{}; + profileMenuItemFlyout.Placement(WUX::Controls::Primitives::FlyoutPlacementMode::BottomEdgeAlignedRight); + + // Create the menu item and an icon to use in the menu + WUX::Controls::MenuFlyoutItem runAsAdminItem{}; + WUX::Controls::FontIcon adminShieldIcon{}; + + adminShieldIcon.Glyph(L"\xEA18"); + adminShieldIcon.FontFamily(Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" }); + + runAsAdminItem.Icon(adminShieldIcon); + runAsAdminItem.Text(RS_(L"RunAsAdminFlyout/Text")); + + // Click handler for the flyout item + runAsAdminItem.Click([profileIndex, weakThis{ get_weak() }](auto&&, auto&&) { + if (auto page{ weakThis.get() }) + { + NewTerminalArgs args{ profileIndex }; + args.Elevate(true); + page->_OpenNewTerminalViaDropdown(args); + } + }); + + profileMenuItemFlyout.Items().Append(runAsAdminItem); + + return profileMenuItemFlyout; + } + } diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 095647b17b2..7a6866e20ec 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -532,7 +532,7 @@ namespace winrt::TerminalApp::implementation void _ContextMenuOpened(const IInspectable& sender, const IInspectable& args); void _SelectionMenuOpened(const IInspectable& sender, const IInspectable& args); void _PopulateContextMenu(const IInspectable& sender, const bool withSelection); - + winrt::Windows::UI::Xaml::Controls::MenuFlyout _CreateRunAsAdminFlyout(int profileIndex); #pragma region ActionHandlers // These are all defined in AppActionHandlers.cpp #define ON_ALL_ACTIONS(action) DECLARE_ACTION_HANDLER(action);