mirror of
https://github.com/microsoft/terminal.git
synced 2026-04-06 14:19:45 +00:00
jesus what
This commit is contained in:
@@ -76,6 +76,36 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"OutputNotificationStyle": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"taskbar",
|
||||
"audible",
|
||||
"tab",
|
||||
"notification"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"taskbar",
|
||||
"audible",
|
||||
"tab",
|
||||
"notification",
|
||||
"all",
|
||||
"none"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"BellSound": {
|
||||
"default": "",
|
||||
"description": "Sets the file location of the sound played when the application emits a BEL character. If the path is invalid no sound will be played. This property also accepts an array of sounds and the terminal will pick one at random.",
|
||||
@@ -94,6 +124,14 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"AutoDetectRunningCommand": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"disabled",
|
||||
"automatic",
|
||||
"progress"
|
||||
]
|
||||
},
|
||||
"BuiltinSuggestionSource": {
|
||||
"type": "string",
|
||||
"anyOf": [
|
||||
@@ -3174,6 +3212,21 @@
|
||||
"mingw"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"notifyOnInactiveOutput": {
|
||||
"default": "none",
|
||||
"description": "Controls how the terminal notifies you when a background pane produces output. Supported values include `taskbar`, `audible`, `tab`, and `notification`. Can be set to true (equivalent to `tab`), false/none (disabled), a single string, or an array of strings.",
|
||||
"$ref": "#/$defs/OutputNotificationStyle"
|
||||
},
|
||||
"notifyOnNextPrompt": {
|
||||
"default": "none",
|
||||
"description": "Controls how the terminal notifies you when a running command finishes and the shell returns to a prompt. Requires shell integration. Supported values include `taskbar`, `audible`, `tab`, and `notification`. Can be set to true (equivalent to `tab`), false/none (disabled), a single string, or an array of strings.",
|
||||
"$ref": "#/$defs/OutputNotificationStyle"
|
||||
},
|
||||
"autoDetectRunningCommand": {
|
||||
"default": "disabled",
|
||||
"description": "Controls automatic detection of running commands via shell integration marks. When set to `automatic`, an indeterminate progress indicator is shown on the tab while a command is executing. When set to `progress`, the terminal will also attempt to detect progress percentages from command output. Requires shell integration.",
|
||||
"$ref": "#/$defs/AutoDetectRunningCommand"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace winrt::TerminalApp::implementation
|
||||
til::typed_event<> ConnectionStateChanged;
|
||||
til::typed_event<IPaneContent> CloseRequested;
|
||||
til::typed_event<IPaneContent, winrt::TerminalApp::BellEventArgs> BellRequested;
|
||||
til::typed_event<IPaneContent, winrt::TerminalApp::NotificationEventArgs> NotificationRequested;
|
||||
til::typed_event<IPaneContent> TitleChanged;
|
||||
til::typed_event<IPaneContent> TabColorChanged;
|
||||
til::typed_event<IPaneContent> TaskbarProgressChanged;
|
||||
|
||||
99
src/cascadia/TerminalApp/DesktopNotification.cpp
Normal file
99
src/cascadia/TerminalApp/DesktopNotification.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "DesktopNotification.h"
|
||||
|
||||
using namespace winrt::Windows::UI::Notifications;
|
||||
using namespace winrt::Windows::Data::Xml::Dom;
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
std::atomic<int64_t> DesktopNotification::_lastNotificationTime{ 0 };
|
||||
|
||||
bool DesktopNotification::ShouldSendNotification()
|
||||
{
|
||||
FILETIME ft{};
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
const auto now = (static_cast<int64_t>(ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
|
||||
auto last = _lastNotificationTime.load(std::memory_order_relaxed);
|
||||
|
||||
if (now - last < MinNotificationIntervalTicks)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Attempt to update; if another thread beat us, that's fine — we'll skip this one.
|
||||
_lastNotificationTime.compare_exchange_strong(last, now, std::memory_order_relaxed);
|
||||
return true;
|
||||
}
|
||||
|
||||
void DesktopNotification::SendNotification(
|
||||
const DesktopNotificationArgs& args,
|
||||
std::function<void(uint32_t tabIndex)> activated)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!ShouldSendNotification())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Build the toast XML. We use a simple template with a title and body text.
|
||||
//
|
||||
// <toast launch="tabIndex=N">
|
||||
// <visual>
|
||||
// <binding template="ToastGeneric">
|
||||
// <text>Title</text>
|
||||
// <text>Message</text>
|
||||
// </binding>
|
||||
// </visual>
|
||||
// </toast>
|
||||
auto toastXml = ToastNotificationManager::GetTemplateContent(ToastTemplateType::ToastText02);
|
||||
auto textNodes = toastXml.GetElementsByTagName(L"text");
|
||||
|
||||
// First <text> is the title
|
||||
textNodes.Item(0).InnerText(args.Title);
|
||||
// Second <text> is the body
|
||||
textNodes.Item(1).InnerText(args.Message);
|
||||
|
||||
// Set launch args so we can identify which tab to activate.
|
||||
auto toastElement = toastXml.DocumentElement();
|
||||
toastElement.SetAttribute(L"launch", fmt::format(FMT_COMPILE(L"tabIndex={}"), args.TabIndex));
|
||||
|
||||
// Set the scenario to "reminder" to ensure the toast shows even in DND,
|
||||
// and the group/tag to allow replacement of repeated notifications.
|
||||
toastElement.SetAttribute(L"scenario", L"default");
|
||||
|
||||
auto toast = ToastNotification{ toastXml };
|
||||
|
||||
// Set the tag and group to enable notification replacement.
|
||||
// Using the tab index as a tag means repeated output from the same tab
|
||||
// replaces the previous notification rather than stacking.
|
||||
toast.Tag(fmt::format(FMT_COMPILE(L"wt-tab-{}"), args.TabIndex));
|
||||
toast.Group(L"WindowsTerminal");
|
||||
|
||||
// When the user activates (clicks) the toast, fire the callback.
|
||||
if (activated)
|
||||
{
|
||||
const auto tabIndex = args.TabIndex;
|
||||
toast.Activated([activated, tabIndex](const auto& /*sender*/, const auto& /*eventArgs*/) {
|
||||
activated(tabIndex);
|
||||
});
|
||||
}
|
||||
|
||||
// For packaged apps, CreateToastNotifier() uses the package identity automatically.
|
||||
// For unpackaged apps, we need to provide an AUMID, but that case is less common
|
||||
// and toast notifications may not be supported without additional setup.
|
||||
auto notifier = ToastNotificationManager::CreateToastNotifier();
|
||||
notifier.Show(toast);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// Toast notification is a best-effort feature. If it fails (e.g., notifications
|
||||
// are disabled, or the app is unpackaged without proper AUMID setup), we silently
|
||||
// ignore the error.
|
||||
LOG_CAUGHT_EXCEPTION();
|
||||
}
|
||||
}
|
||||
}
|
||||
52
src/cascadia/TerminalApp/DesktopNotification.h
Normal file
52
src/cascadia/TerminalApp/DesktopNotification.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
|
||||
Module Name:
|
||||
- DesktopNotification.h
|
||||
|
||||
Module Description:
|
||||
- Helper for sending Windows desktop toast notifications. Used by the
|
||||
`OutputNotificationStyle::Notification` flag to surface activity
|
||||
and prompt-return events to the user via the Windows notification center.
|
||||
|
||||
--*/
|
||||
|
||||
#pragma once
|
||||
#include "pch.h"
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct DesktopNotificationArgs
|
||||
{
|
||||
winrt::hstring Title;
|
||||
winrt::hstring Message;
|
||||
uint32_t TabIndex{ 0 };
|
||||
};
|
||||
|
||||
class DesktopNotification
|
||||
{
|
||||
public:
|
||||
// Sends a toast notification with the given title and message.
|
||||
// When the user clicks the toast, the `Activated` callback fires
|
||||
// with the tabIndex that was passed in, so the caller can switch
|
||||
// to the correct tab and summon the window.
|
||||
//
|
||||
// activated: A callback invoked on the background thread when the
|
||||
// toast is clicked. The uint32_t parameter is the tab index.
|
||||
static void SendNotification(
|
||||
const DesktopNotificationArgs& args,
|
||||
std::function<void(uint32_t tabIndex)> activated);
|
||||
|
||||
// Rate-limits toast notifications so we don't spam the user.
|
||||
// Returns true if a notification is allowed, false if too recent.
|
||||
static bool ShouldSendNotification();
|
||||
|
||||
private:
|
||||
static std::atomic<int64_t> _lastNotificationTime;
|
||||
|
||||
// Minimum interval between notifications, in 100ns ticks (FILETIME units).
|
||||
// 5 seconds = 5 * 10,000,000
|
||||
static constexpr int64_t MinNotificationIntervalTicks = 50'000'000LL;
|
||||
};
|
||||
}
|
||||
@@ -16,6 +16,11 @@ namespace TerminalApp
|
||||
Boolean FlashTaskbar { get; };
|
||||
};
|
||||
|
||||
runtimeclass NotificationEventArgs
|
||||
{
|
||||
Microsoft.Terminal.Control.OutputNotificationStyle Style { get; };
|
||||
};
|
||||
|
||||
interface IPaneContent
|
||||
{
|
||||
Windows.UI.Xaml.FrameworkElement GetRoot();
|
||||
@@ -41,6 +46,7 @@ namespace TerminalApp
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> ConnectionStateChanged;
|
||||
event Windows.Foundation.TypedEventHandler<IPaneContent, BellEventArgs> BellRequested;
|
||||
event Windows.Foundation.TypedEventHandler<IPaneContent, NotificationEventArgs> NotificationRequested;
|
||||
event Windows.Foundation.TypedEventHandler<IPaneContent, Object> TitleChanged;
|
||||
event Windows.Foundation.TypedEventHandler<IPaneContent, Object> TabColorChanged;
|
||||
event Windows.Foundation.TypedEventHandler<IPaneContent, Object> TaskbarProgressChanged;
|
||||
|
||||
@@ -923,4 +923,16 @@
|
||||
<data name="InvalidRegex" xml:space="preserve">
|
||||
<value>An invalid regular expression was found.</value>
|
||||
</data>
|
||||
<data name="NotificationTitle" xml:space="preserve">
|
||||
<value>Windows Terminal</value>
|
||||
<comment>Title shown in desktop toast notifications for tab activity.</comment>
|
||||
</data>
|
||||
<data name="NotificationMessage_TabActivity" xml:space="preserve">
|
||||
<value>Tab "{0}" has new activity</value>
|
||||
<comment>{Locked="{0}"}Message shown in a desktop toast notification when a tab produces output. {0} is the tab title.</comment>
|
||||
</data>
|
||||
<data name="NotificationMessage_TabActivityInWindow" xml:space="preserve">
|
||||
<value>Tab "{0}" in {1} has new activity</value>
|
||||
<comment>{Locked="{0}"}{Locked="{1}"}Message shown in a desktop toast notification when a tab produces output. {0} is the tab title. {1} is the window name.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -123,6 +123,15 @@ namespace winrt::TerminalApp::implementation
|
||||
_bellIndicatorTimer.Stop();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Called when the timer for the activity indicator in the tab header fires
|
||||
// - Removes the activity indicator from the tab header
|
||||
void Tab::_ActivityIndicatorTimerTick(const Windows::Foundation::IInspectable& /*sender*/, const Windows::Foundation::IInspectable& /*e*/)
|
||||
{
|
||||
ShowActivityIndicator(false);
|
||||
_activityIndicatorTimer.Stop();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Initializes a TabViewItem for this Tab instance.
|
||||
// Arguments:
|
||||
@@ -329,6 +338,11 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
ShowBellIndicator(false);
|
||||
}
|
||||
// When we gain focus, remove the activity indicator if it is active
|
||||
if (_tabStatus.ActivityIndicator())
|
||||
{
|
||||
ShowActivityIndicator(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -459,6 +473,29 @@ namespace winrt::TerminalApp::implementation
|
||||
_bellIndicatorTimer.Start();
|
||||
}
|
||||
|
||||
void Tab::ShowActivityIndicator(const bool show)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
_tabStatus.ActivityIndicator(show);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Activates the timer for the activity indicator in the tab
|
||||
// - Called if a notification was raised when the tab already has focus
|
||||
void Tab::ActivateActivityIndicatorTimer()
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
if (!_activityIndicatorTimer)
|
||||
{
|
||||
_activityIndicatorTimer.Interval(std::chrono::milliseconds(2000));
|
||||
_activityIndicatorTimer.Tick({ get_weak(), &Tab::_ActivityIndicatorTimerTick });
|
||||
}
|
||||
|
||||
_activityIndicatorTimer.Start();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Gets the title string of the last focused terminal control in our tree.
|
||||
// Returns the empty string if there is no such control.
|
||||
@@ -1161,6 +1198,54 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
});
|
||||
|
||||
events.NotificationRequested = content.NotificationRequested(
|
||||
winrt::auto_revoke,
|
||||
[dispatcher, weakThis](TerminalApp::IPaneContent sender, auto notifArgs) -> safe_void_coroutine {
|
||||
const auto weakThisCopy = weakThis;
|
||||
co_await wil::resume_foreground(dispatcher);
|
||||
if (const auto tab{ weakThisCopy.get() })
|
||||
{
|
||||
// For NotifyOnInactiveOutput, only show notifications if this sender
|
||||
// is NOT the currently active pane content. For NotifyOnNextPrompt,
|
||||
// the notification is always relevant.
|
||||
const auto activeContent = tab->GetActiveContent();
|
||||
const auto isActivePaneContent = activeContent && activeContent == sender;
|
||||
|
||||
const auto style = notifArgs.Style();
|
||||
|
||||
if (WI_IsFlagSet(style, winrt::Microsoft::Terminal::Control::OutputNotificationStyle::Taskbar))
|
||||
{
|
||||
// Flash the taskbar button
|
||||
tab->TabRaiseVisualBell.raise();
|
||||
}
|
||||
|
||||
// Audible notification is handled in TerminalPaneContent already
|
||||
|
||||
if (WI_IsFlagSet(style, winrt::Microsoft::Terminal::Control::OutputNotificationStyle::Tab))
|
||||
{
|
||||
// Show the activity indicator in the tab header (distinct from bell)
|
||||
// Only for inactive pane output, skip if this is the focused pane in a focused tab
|
||||
if (!isActivePaneContent || tab->_focusState == WUX::FocusState::Unfocused)
|
||||
{
|
||||
tab->ShowActivityIndicator(true);
|
||||
|
||||
if (tab->_focusState != WUX::FocusState::Unfocused)
|
||||
{
|
||||
tab->ActivateActivityIndicatorTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (WI_IsFlagSet(style, winrt::Microsoft::Terminal::Control::OutputNotificationStyle::Notification))
|
||||
{
|
||||
// Request a desktop toast notification.
|
||||
// TerminalPage subscribes to this event and handles sending the toast
|
||||
// and processing its activation (summoning the window + switching tabs).
|
||||
tab->TabToastNotificationRequested.raise(tab->Title(), tab->TabViewIndex());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (const auto& terminal{ content.try_as<TerminalApp::TerminalPaneContent>() })
|
||||
{
|
||||
events.RestartTerminalRequested = terminal.RestartTerminalRequested(winrt::auto_revoke, { get_weak(), &Tab::_bubbleRestartTerminalRequested });
|
||||
@@ -1393,6 +1478,11 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
tab->ShowBellIndicator(false);
|
||||
}
|
||||
// Also remove the activity indicator
|
||||
if (tab->_tabStatus.ActivityIndicator())
|
||||
{
|
||||
tab->ShowActivityIndicator(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -48,6 +48,9 @@ namespace winrt::TerminalApp::implementation
|
||||
void ShowBellIndicator(const bool show);
|
||||
void ActivateBellIndicatorTimer();
|
||||
|
||||
void ShowActivityIndicator(const bool show);
|
||||
void ActivateActivityIndicatorTimer();
|
||||
|
||||
float CalcSnappedDimension(const bool widthOrHeight, const float dimension) const;
|
||||
std::optional<winrt::Microsoft::Terminal::Settings::Model::SplitDirection> PreCalculateCanSplit(winrt::Microsoft::Terminal::Settings::Model::SplitDirection splitType,
|
||||
const float splitSize,
|
||||
@@ -121,6 +124,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
til::typed_event<TerminalApp::Tab, IInspectable> ActivePaneChanged;
|
||||
til::event<winrt::delegate<>> TabRaiseVisualBell;
|
||||
til::event<winrt::delegate<winrt::hstring /*title*/, uint32_t /*tabIndex*/>> TabToastNotificationRequested;
|
||||
til::typed_event<IInspectable, IInspectable> TaskbarProgressChanged;
|
||||
|
||||
// The TabViewIndex is the index this Tab object resides in TerminalPage's _tabs vector.
|
||||
@@ -176,6 +180,7 @@ namespace winrt::TerminalApp::implementation
|
||||
struct ContentEventTokens
|
||||
{
|
||||
winrt::TerminalApp::IPaneContent::BellRequested_revoker BellRequested;
|
||||
winrt::TerminalApp::IPaneContent::NotificationRequested_revoker NotificationRequested;
|
||||
winrt::TerminalApp::IPaneContent::TitleChanged_revoker TitleChanged;
|
||||
winrt::TerminalApp::IPaneContent::TabColorChanged_revoker TabColorChanged;
|
||||
winrt::TerminalApp::IPaneContent::TaskbarProgressChanged_revoker TaskbarProgressChanged;
|
||||
@@ -210,6 +215,9 @@ namespace winrt::TerminalApp::implementation
|
||||
SafeDispatcherTimer _bellIndicatorTimer;
|
||||
void _BellIndicatorTimerTick(const Windows::Foundation::IInspectable& sender, const Windows::Foundation::IInspectable& e);
|
||||
|
||||
SafeDispatcherTimer _activityIndicatorTimer;
|
||||
void _ActivityIndicatorTimerTick(const Windows::Foundation::IInspectable& sender, const Windows::Foundation::IInspectable& e);
|
||||
|
||||
void _UpdateHeaderControlMaxWidth();
|
||||
|
||||
void _CreateContextMenu();
|
||||
|
||||
@@ -32,6 +32,12 @@
|
||||
FontSize="12"
|
||||
Glyph=""
|
||||
Visibility="{x:Bind TabStatus.BellIndicator, Mode=OneWay}" />
|
||||
<FontIcon x:Name="HeaderActivityIndicator"
|
||||
Margin="0,0,8,0"
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
FontSize="8"
|
||||
Glyph=""
|
||||
Visibility="{x:Bind TabStatus.ActivityIndicator, Mode=OneWay}" />
|
||||
<FontIcon x:Name="HeaderZoomIcon"
|
||||
Margin="0,0,8,0"
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "DebugTapConnection.h"
|
||||
#include "..\TerminalSettingsModel\FileUtils.h"
|
||||
#include "../TerminalSettingsAppAdapterLib/TerminalSettings.h"
|
||||
#include "DesktopNotification.h"
|
||||
|
||||
#include <shlobj.h>
|
||||
|
||||
@@ -150,6 +151,15 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
});
|
||||
|
||||
// When a tab requests a desktop toast notification (OutputNotificationStyle::Notification),
|
||||
// send the toast and handle activation by summoning this window and switching to the tab.
|
||||
newTabImpl->TabToastNotificationRequested([weakThis{ get_weak() }](const winrt::hstring& title, uint32_t tabIndex) {
|
||||
if (const auto page{ weakThis.get() })
|
||||
{
|
||||
page->_SendDesktopNotification(title, tabIndex);
|
||||
}
|
||||
});
|
||||
|
||||
auto tabViewItem = newTabImpl->TabViewItem();
|
||||
_tabView.TabItems().InsertAt(insertPosition, tabViewItem);
|
||||
|
||||
@@ -1185,4 +1195,54 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
return _tabs.Size() > 1;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sends a Windows desktop toast notification for a tab. When the user clicks
|
||||
// the toast, summon this window and switch to the specified tab.
|
||||
// Arguments:
|
||||
// - tabTitle: The title of the tab to display in the notification.
|
||||
// - tabIndex: The index of the tab to switch to when the toast is activated.
|
||||
void TerminalPage::_SendDesktopNotification(const winrt::hstring& tabTitle, uint32_t tabIndex)
|
||||
{
|
||||
// Build the notification message.
|
||||
// Use the window name if available for context, otherwise just use the tab title.
|
||||
const auto windowName = _WindowProperties ? _WindowProperties.WindowNameForDisplay() : winrt::hstring{};
|
||||
winrt::hstring message;
|
||||
if (!windowName.empty())
|
||||
{
|
||||
message = RS_fmt(L"NotificationMessage_TabActivityInWindow", std::wstring_view{ tabTitle }, std::wstring_view{ windowName });
|
||||
}
|
||||
else
|
||||
{
|
||||
message = RS_fmt(L"NotificationMessage_TabActivity", std::wstring_view{ tabTitle });
|
||||
}
|
||||
|
||||
implementation::DesktopNotificationArgs args;
|
||||
args.Title = RS_(L"NotificationTitle");
|
||||
args.Message = message;
|
||||
args.TabIndex = tabIndex;
|
||||
|
||||
// Capture a weak ref and the dispatcher so we can marshal back to the UI thread
|
||||
// when the toast is activated.
|
||||
auto weakThis = get_weak();
|
||||
auto dispatcher = Dispatcher();
|
||||
|
||||
implementation::DesktopNotification::SendNotification(
|
||||
args,
|
||||
[weakThis, dispatcher, tabIndex](uint32_t /*activatedTabIndex*/) -> void {
|
||||
// The toast Activated callback fires on a background thread.
|
||||
// We need to dispatch to the UI thread to summon the window and switch tabs.
|
||||
[](auto weakThis, auto dispatcher, auto tabIndex) -> safe_void_coroutine {
|
||||
co_await wil::resume_foreground(dispatcher);
|
||||
if (const auto page{ weakThis.get() })
|
||||
{
|
||||
// Summon this window (bring to foreground)
|
||||
page->SummonWindowRequested.raise(nullptr, nullptr);
|
||||
|
||||
// Switch to the tab that triggered the notification
|
||||
page->_SelectTab(tabIndex);
|
||||
}
|
||||
}(weakThis, dispatcher, tabIndex);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,6 +173,7 @@
|
||||
<ClInclude Include="SettingsPaneContent.h">
|
||||
<DependentUpon>TerminalPaneContent.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DesktopNotification.h" />
|
||||
<ClInclude Include="Toast.h" />
|
||||
<ClInclude Include="TerminalSettingsCache.h" />
|
||||
<ClInclude Include="SuggestionsControl.h">
|
||||
@@ -286,6 +287,7 @@
|
||||
<DependentUpon>TerminalPaneContent.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
||||
<ClCompile Include="DesktopNotification.cpp" />
|
||||
<ClCompile Include="Toast.cpp" />
|
||||
<ClCompile Include="TerminalSettingsCache.cpp" />
|
||||
<ClCompile Include="SuggestionsControl.cpp">
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
<ClCompile Include="fzf/fzf.cpp">
|
||||
<Filter>fzf</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DesktopNotification.cpp" />
|
||||
<ClCompile Include="Toast.cpp" />
|
||||
<ClCompile Include="LanguageProfileNotifier.cpp" />
|
||||
<ClCompile Include="TerminalSettingsCache.cpp" />
|
||||
@@ -58,6 +59,7 @@
|
||||
<ClInclude Include="fzf/fzf.h">
|
||||
<Filter>fzf</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DesktopNotification.h" />
|
||||
<ClInclude Include="Toast.h" />
|
||||
<ClInclude Include="LanguageProfileNotifier.h" />
|
||||
<ClInclude Include="WindowsPackageManagerFactory.h" />
|
||||
|
||||
@@ -570,6 +570,8 @@ namespace winrt::TerminalApp::implementation
|
||||
void _activePaneChanged(winrt::TerminalApp::Tab tab, Windows::Foundation::IInspectable args);
|
||||
safe_void_coroutine _doHandleSuggestions(Microsoft::Terminal::Settings::Model::SuggestionsArgs realArgs);
|
||||
|
||||
void _SendDesktopNotification(const winrt::hstring& tabTitle, uint32_t tabIndex);
|
||||
|
||||
#pragma region ActionHandlers
|
||||
// These are all defined in AppActionHandlers.cpp
|
||||
#define ON_ALL_ACTIONS(action) DECLARE_ACTION_HANDLER(action);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "../../types/inc/utils.hpp"
|
||||
|
||||
#include "BellEventArgs.g.cpp"
|
||||
#include "NotificationEventArgs.g.cpp"
|
||||
#include "TerminalPaneContent.g.cpp"
|
||||
|
||||
using namespace winrt::Windows::Foundation;
|
||||
@@ -34,8 +35,11 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
_controlEvents._ConnectionStateChanged = _control.ConnectionStateChanged(winrt::auto_revoke, { this, &TerminalPaneContent::_controlConnectionStateChangedHandler });
|
||||
_controlEvents._WarningBell = _control.WarningBell(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlWarningBellHandler });
|
||||
_controlEvents._PromptReturned = _control.PromptReturned(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlPromptReturnedHandler });
|
||||
_controlEvents._CommandStarted = _control.CommandStarted(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlCommandStartedHandler });
|
||||
_controlEvents._CloseTerminalRequested = _control.CloseTerminalRequested(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_closeTerminalRequestedHandler });
|
||||
_controlEvents._RestartTerminalRequested = _control.RestartTerminalRequested(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_restartTerminalRequestedHandler });
|
||||
_controlEvents._OutputIdle = _control.OutputIdle(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlOutputIdleHandler });
|
||||
|
||||
_controlEvents._TitleChanged = _control.TitleChanged(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlTitleChanged });
|
||||
_controlEvents._TabColorChanged = _control.TabColorChanged(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlTabColorChanged });
|
||||
@@ -298,6 +302,119 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Returns the taskbar state, accounting for auto-detected running command progress.
|
||||
// VT-set progress (OSC 9;4) takes precedence over auto-detected progress.
|
||||
uint64_t TerminalPaneContent::TaskbarState()
|
||||
{
|
||||
const auto vtState = _control.TaskbarState();
|
||||
// VT-set progress takes precedence over auto-detected progress
|
||||
if (vtState != 0)
|
||||
{
|
||||
return vtState;
|
||||
}
|
||||
// Auto-detected indeterminate progress (between command start and prompt return)
|
||||
if (_autoDetectActive)
|
||||
{
|
||||
return 3; // TaskbarState::Indeterminate
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Returns the taskbar progress, accounting for auto-detected running command progress.
|
||||
uint64_t TerminalPaneContent::TaskbarProgress()
|
||||
{
|
||||
const auto vtState = _control.TaskbarState();
|
||||
// VT-set progress takes precedence
|
||||
if (vtState != 0)
|
||||
{
|
||||
return _control.TaskbarProgress();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Raised when a shell integration prompt mark (133;A) is received, indicating
|
||||
// the command has finished and we're back at a prompt.
|
||||
// - Checks NotifyOnNextPrompt setting and raises NotificationRequested.
|
||||
// - If autoDetectRunningCommand is enabled, clears the indeterminate progress ring.
|
||||
void TerminalPaneContent::_controlPromptReturnedHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
|
||||
const winrt::Windows::Foundation::IInspectable& /*eventArgs*/)
|
||||
{
|
||||
if (_profile)
|
||||
{
|
||||
// Check NotifyOnNextPrompt setting and raise a notification
|
||||
const auto notifyStyle = _profile.NotifyOnNextPrompt();
|
||||
if (static_cast<int>(notifyStyle) != 0)
|
||||
{
|
||||
// Play audible notification if requested (handle here like BellStyle::Audible)
|
||||
if (WI_IsFlagSet(notifyStyle, OutputNotificationStyle::Audible))
|
||||
{
|
||||
const auto soundAlias = reinterpret_cast<LPCTSTR>(SND_ALIAS_SYSTEMHAND);
|
||||
PlaySound(soundAlias, NULL, SND_ALIAS_ID | SND_ASYNC | SND_SENTRY);
|
||||
}
|
||||
|
||||
// Raise NotificationRequested so Tab can handle Taskbar/Tab/Notification flags
|
||||
NotificationRequested.raise(*this,
|
||||
*winrt::make_self<TerminalApp::implementation::NotificationEventArgs>(notifyStyle));
|
||||
}
|
||||
|
||||
// If autoDetectRunningCommand is enabled, clear the progress ring
|
||||
const auto autoDetect = _profile.AutoDetectRunningCommand();
|
||||
if (autoDetect != AutoDetectRunningCommand::Disabled && _autoDetectActive)
|
||||
{
|
||||
_autoDetectActive = false;
|
||||
TaskbarProgressChanged.raise(*this, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Raised when a shell integration command output mark (133;C) is received,
|
||||
// indicating a command has started executing.
|
||||
// - If autoDetectRunningCommand is enabled, shows an indeterminate progress ring.
|
||||
void TerminalPaneContent::_controlCommandStartedHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
|
||||
const winrt::Windows::Foundation::IInspectable& /*eventArgs*/)
|
||||
{
|
||||
if (_profile)
|
||||
{
|
||||
const auto autoDetect = _profile.AutoDetectRunningCommand();
|
||||
if (autoDetect != AutoDetectRunningCommand::Disabled && !_autoDetectActive)
|
||||
{
|
||||
_autoDetectActive = true;
|
||||
TaskbarProgressChanged.raise(*this, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Raised when output stops being produced for ~100ms (debounced).
|
||||
// Used to detect output in inactive panes for NotifyOnInactiveOutput.
|
||||
// - Raises NotificationRequested so Tab can show activity indicators.
|
||||
void TerminalPaneContent::_controlOutputIdleHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
|
||||
const winrt::Windows::Foundation::IInspectable& /*eventArgs*/)
|
||||
{
|
||||
if (_profile)
|
||||
{
|
||||
const auto notifyStyle = _profile.NotifyOnInactiveOutput();
|
||||
if (static_cast<int>(notifyStyle) != 0)
|
||||
{
|
||||
// Play audible notification if requested
|
||||
if (WI_IsFlagSet(notifyStyle, OutputNotificationStyle::Audible))
|
||||
{
|
||||
const auto soundAlias = reinterpret_cast<LPCTSTR>(SND_ALIAS_SYSTEMHAND);
|
||||
PlaySound(soundAlias, NULL, SND_ALIAS_ID | SND_ASYNC | SND_SENTRY);
|
||||
}
|
||||
|
||||
// Raise NotificationRequested so Tab can handle Taskbar/Tab flags.
|
||||
// Tab will check if this pane is the active pane and skip if so.
|
||||
NotificationRequested.raise(*this,
|
||||
*winrt::make_self<TerminalApp::implementation::NotificationEventArgs>(notifyStyle));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
safe_void_coroutine TerminalPaneContent::_playBellSound(winrt::Windows::Foundation::Uri uri)
|
||||
{
|
||||
auto weakThis{ get_weak() };
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#pragma once
|
||||
#include "TerminalPaneContent.g.h"
|
||||
#include "BellEventArgs.g.h"
|
||||
#include "NotificationEventArgs.g.h"
|
||||
#include "BasicPaneEvents.h"
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
@@ -19,6 +20,15 @@ namespace winrt::TerminalApp::implementation
|
||||
til::property<bool> FlashTaskbar;
|
||||
};
|
||||
|
||||
struct NotificationEventArgs : public NotificationEventArgsT<NotificationEventArgs>
|
||||
{
|
||||
public:
|
||||
NotificationEventArgs(winrt::Microsoft::Terminal::Control::OutputNotificationStyle style) :
|
||||
Style(style) {}
|
||||
|
||||
til::property<winrt::Microsoft::Terminal::Control::OutputNotificationStyle> Style;
|
||||
};
|
||||
|
||||
struct TerminalPaneContent : TerminalPaneContentT<TerminalPaneContent>, BasicPaneEvents
|
||||
{
|
||||
TerminalPaneContent(const winrt::Microsoft::Terminal::Settings::Model::Profile& profile,
|
||||
@@ -43,8 +53,8 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
winrt::hstring Title() { return _control.Title(); }
|
||||
uint64_t TaskbarState() { return _control.TaskbarState(); }
|
||||
uint64_t TaskbarProgress() { return _control.TaskbarProgress(); }
|
||||
uint64_t TaskbarState();
|
||||
uint64_t TaskbarProgress();
|
||||
bool ReadOnly() { return _control.ReadOnly(); }
|
||||
winrt::hstring Icon() const;
|
||||
Windows::Foundation::IReference<winrt::Windows::UI::Color> TabColor() const noexcept;
|
||||
@@ -66,11 +76,15 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
winrt::Windows::Media::Playback::MediaPlayer _bellPlayer{ nullptr };
|
||||
bool _bellPlayerCreated{ false };
|
||||
bool _autoDetectActive{ false };
|
||||
|
||||
struct ControlEventTokens
|
||||
{
|
||||
winrt::Microsoft::Terminal::Control::TermControl::ConnectionStateChanged_revoker _ConnectionStateChanged;
|
||||
winrt::Microsoft::Terminal::Control::TermControl::WarningBell_revoker _WarningBell;
|
||||
winrt::Microsoft::Terminal::Control::TermControl::PromptReturned_revoker _PromptReturned;
|
||||
winrt::Microsoft::Terminal::Control::TermControl::CommandStarted_revoker _CommandStarted;
|
||||
winrt::Microsoft::Terminal::Control::TermControl::OutputIdle_revoker _OutputIdle;
|
||||
winrt::Microsoft::Terminal::Control::TermControl::CloseTerminalRequested_revoker _CloseTerminalRequested;
|
||||
winrt::Microsoft::Terminal::Control::TermControl::RestartTerminalRequested_revoker _RestartTerminalRequested;
|
||||
|
||||
@@ -89,6 +103,12 @@ namespace winrt::TerminalApp::implementation
|
||||
safe_void_coroutine _controlConnectionStateChangedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& /*args*/);
|
||||
void _controlWarningBellHandler(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
const winrt::Windows::Foundation::IInspectable& e);
|
||||
void _controlPromptReturnedHandler(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
const winrt::Windows::Foundation::IInspectable& e);
|
||||
void _controlCommandStartedHandler(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
const winrt::Windows::Foundation::IInspectable& e);
|
||||
void _controlOutputIdleHandler(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
const winrt::Windows::Foundation::IInspectable& e);
|
||||
void _controlReadOnlyChangedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& e);
|
||||
|
||||
void _controlTitleChanged(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args);
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace winrt::TerminalApp::implementation
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, IsProgressRingActive, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, IsProgressRingIndeterminate, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, BellIndicator, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, ActivityIndicator, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, IsReadOnlyActive, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(uint32_t, ProgressValue, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, IsInputBroadcastActive, PropertyChanged.raise);
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace TerminalApp
|
||||
Boolean IsProgressRingActive { get; set; };
|
||||
Boolean IsProgressRingIndeterminate { get; set; };
|
||||
Boolean BellIndicator { get; set; };
|
||||
Boolean ActivityIndicator { get; set; };
|
||||
UInt32 ProgressValue { get; set; };
|
||||
Boolean IsReadOnlyActive { get; set; };
|
||||
Boolean IsInputBroadcastActive { get; set; };
|
||||
|
||||
@@ -54,6 +54,9 @@
|
||||
#include <winrt/Windows.Media.Playback.h>
|
||||
#include <winrt/Windows.Management.Deployment.h>
|
||||
|
||||
#include <winrt/Windows.UI.Notifications.h>
|
||||
#include <winrt/Windows.Data.Xml.Dom.h>
|
||||
|
||||
#include <winrt/Microsoft.UI.Xaml.Controls.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.Controls.Primitives.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.XamlTypeInfo.h>
|
||||
|
||||
@@ -118,6 +118,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
auto pfnWarningBell = [this] { _terminalWarningBell(); };
|
||||
_terminal->SetWarningBellCallback(pfnWarningBell);
|
||||
|
||||
auto pfnPromptReturned = [this] { _terminalPromptReturned(); };
|
||||
_terminal->SetPromptReturnedCallback(pfnPromptReturned);
|
||||
|
||||
auto pfnCommandStarted = [this] { _terminalCommandStarted(); };
|
||||
_terminal->SetCommandStartedCallback(pfnCommandStarted);
|
||||
|
||||
auto pfnTitleChanged = [this](auto&& PH1) { _terminalTitleChanged(std::forward<decltype(PH1)>(PH1)); };
|
||||
_terminal->SetTitleChangedCallback(pfnTitleChanged);
|
||||
|
||||
@@ -1593,6 +1599,22 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
WarningBell.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
void ControlCore::_terminalPromptReturned()
|
||||
{
|
||||
// Since this can only ever be triggered by output from the connection,
|
||||
// then the Terminal already has the write lock when calling this
|
||||
// callback.
|
||||
PromptReturned.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
void ControlCore::_terminalCommandStarted()
|
||||
{
|
||||
// Since this can only ever be triggered by output from the connection,
|
||||
// then the Terminal already has the write lock when calling this
|
||||
// callback.
|
||||
CommandStarted.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Called for the Terminal's TitleChanged callback. This will re-raise
|
||||
// a new winrt TypedEvent that can be listened to.
|
||||
|
||||
@@ -276,6 +276,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
til::typed_event<IInspectable, Control::TitleChangedEventArgs> TitleChanged;
|
||||
til::typed_event<IInspectable, Control::WriteToClipboardEventArgs> WriteToClipboard;
|
||||
til::typed_event<> WarningBell;
|
||||
til::typed_event<> PromptReturned;
|
||||
til::typed_event<> CommandStarted;
|
||||
til::typed_event<> TabColorChanged;
|
||||
til::typed_event<> BackgroundColorChanged;
|
||||
til::typed_event<IInspectable, Control::ScrollPositionChangedArgs> ScrollPositionChanged;
|
||||
@@ -324,6 +326,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
#pragma region TerminalCoreCallbacks
|
||||
void _terminalWarningBell();
|
||||
void _terminalPromptReturned();
|
||||
void _terminalCommandStarted();
|
||||
void _terminalTitleChanged(std::wstring_view wstr);
|
||||
void _terminalScrollPositionChanged(const int viewTop,
|
||||
const int viewHeight,
|
||||
|
||||
@@ -191,6 +191,8 @@ namespace Microsoft.Terminal.Control
|
||||
event Windows.Foundation.TypedEventHandler<Object, TitleChangedEventArgs> TitleChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, WriteToClipboardEventArgs> WriteToClipboard;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> WarningBell;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> PromptReturned;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> CommandStarted;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> TabColorChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> BackgroundColorChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> TaskbarProgressChanged;
|
||||
|
||||
@@ -29,6 +29,23 @@ namespace Microsoft.Terminal.Control
|
||||
MinGW,
|
||||
};
|
||||
|
||||
[flags]
|
||||
enum OutputNotificationStyle
|
||||
{
|
||||
Taskbar = 0x1,
|
||||
Audible = 0x2,
|
||||
Tab = 0x4,
|
||||
Notification = 0x8,
|
||||
All = 0xffffffff
|
||||
};
|
||||
|
||||
enum AutoDetectRunningCommand
|
||||
{
|
||||
Disabled,
|
||||
Automatic,
|
||||
Progress
|
||||
};
|
||||
|
||||
// Class Description:
|
||||
// TerminalSettings encapsulates all settings that control the
|
||||
// TermControl's behavior. In these settings there is both the entirety
|
||||
@@ -77,6 +94,10 @@ namespace Microsoft.Terminal.Control
|
||||
|
||||
PathTranslationStyle PathTranslationStyle { get; };
|
||||
|
||||
OutputNotificationStyle NotifyOnInactiveOutput { get; };
|
||||
OutputNotificationStyle NotifyOnNextPrompt { get; };
|
||||
AutoDetectRunningCommand AutoDetectRunningCommand { get; };
|
||||
|
||||
// NOTE! When adding something here, make sure to update ControlProperties.h too!
|
||||
};
|
||||
}
|
||||
|
||||
@@ -393,6 +393,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// attached content before we set up the throttled func, and that'll A/V
|
||||
_revokers.coreScrollPositionChanged = _core.ScrollPositionChanged(winrt::auto_revoke, { get_weak(), &TermControl::_ScrollPositionChanged });
|
||||
_revokers.WarningBell = _core.WarningBell(winrt::auto_revoke, { get_weak(), &TermControl::_coreWarningBell });
|
||||
_revokers.PromptReturned = _core.PromptReturned(winrt::auto_revoke, { get_weak(), &TermControl::_corePromptReturned });
|
||||
_revokers.CommandStarted = _core.CommandStarted(winrt::auto_revoke, { get_weak(), &TermControl::_coreCommandStarted });
|
||||
|
||||
static constexpr auto AutoScrollUpdateInterval = std::chrono::microseconds(static_cast<int>(1.0 / 30.0 * 1000000));
|
||||
_autoScrollTimer.Interval(AutoScrollUpdateInterval);
|
||||
@@ -3699,6 +3701,16 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_playWarningBell->Run();
|
||||
}
|
||||
|
||||
void TermControl::_corePromptReturned(const IInspectable& /*sender*/, const IInspectable& /*args*/)
|
||||
{
|
||||
PromptReturned.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
void TermControl::_coreCommandStarted(const IInspectable& /*sender*/, const IInspectable& /*args*/)
|
||||
{
|
||||
CommandStarted.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
hstring TermControl::ReadEntireBuffer() const
|
||||
{
|
||||
return _core.ReadEntireBuffer();
|
||||
@@ -3820,6 +3832,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void TermControl::_coreOutputIdle(const IInspectable& /*sender*/, const IInspectable& /*args*/)
|
||||
{
|
||||
_refreshSearch();
|
||||
OutputIdle.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
void TermControl::OwningHwnd(uint64_t owner)
|
||||
|
||||
@@ -212,6 +212,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
til::typed_event<IInspectable, IInspectable> FocusFollowMouseRequested;
|
||||
til::typed_event<Control::TermControl, Windows::UI::Xaml::RoutedEventArgs> Initialized;
|
||||
til::typed_event<> WarningBell;
|
||||
til::typed_event<> PromptReturned;
|
||||
til::typed_event<> CommandStarted;
|
||||
til::typed_event<> OutputIdle;
|
||||
til::typed_event<IInspectable, Control::KeySentEventArgs> KeySent;
|
||||
til::typed_event<IInspectable, Control::CharSentEventArgs> CharSent;
|
||||
til::typed_event<IInspectable, Control::StringSentEventArgs> StringSent;
|
||||
@@ -425,6 +428,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void _coreTransparencyChanged(IInspectable sender, Control::TransparencyChangedEventArgs args);
|
||||
void _coreRaisedNotice(const IInspectable& s, const Control::NoticeEventArgs& args);
|
||||
void _coreWarningBell(const IInspectable& sender, const IInspectable& args);
|
||||
void _corePromptReturned(const IInspectable& sender, const IInspectable& args);
|
||||
void _coreCommandStarted(const IInspectable& sender, const IInspectable& args);
|
||||
void _coreOutputIdle(const IInspectable& sender, const IInspectable& args);
|
||||
|
||||
winrt::Windows::Foundation::Point _toPosInDips(const Core::Point terminalCellPos);
|
||||
@@ -450,6 +455,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
Control::ControlCore::ScrollPositionChanged_revoker coreScrollPositionChanged;
|
||||
Control::ControlCore::WarningBell_revoker WarningBell;
|
||||
Control::ControlCore::PromptReturned_revoker PromptReturned;
|
||||
Control::ControlCore::CommandStarted_revoker CommandStarted;
|
||||
Control::ControlCore::RendererEnteredErrorState_revoker RendererEnteredErrorState;
|
||||
Control::ControlCore::BackgroundColorChanged_revoker BackgroundColorChanged;
|
||||
Control::ControlCore::FontSizeChanged_revoker FontSizeChanged;
|
||||
|
||||
@@ -68,6 +68,9 @@ namespace Microsoft.Terminal.Control
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> SetTaskbarProgress;
|
||||
event Windows.Foundation.TypedEventHandler<Object, NoticeEventArgs> RaiseNotice;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> WarningBell;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> PromptReturned;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> CommandStarted;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> OutputIdle;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> HidePointerCursor;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> RestorePointerCursor;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> TabColorChanged;
|
||||
|
||||
@@ -1265,6 +1265,16 @@ void Microsoft::Terminal::Core::Terminal::SetClearQuickFixCallback(std::function
|
||||
_pfnClearQuickFix.swap(pfn);
|
||||
}
|
||||
|
||||
void Terminal::SetPromptReturnedCallback(std::function<void()> pfn) noexcept
|
||||
{
|
||||
_pfnPromptReturned.swap(pfn);
|
||||
}
|
||||
|
||||
void Terminal::SetCommandStartedCallback(std::function<void()> pfn) noexcept
|
||||
{
|
||||
_pfnCommandStarted.swap(pfn);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Stores the search highlighted regions in the terminal
|
||||
void Terminal::SetSearchHighlights(const std::vector<til::point_span>& highlights) noexcept
|
||||
|
||||
@@ -156,7 +156,7 @@ public:
|
||||
|
||||
bool IsVtInputEnabled() const noexcept override;
|
||||
void NotifyBufferRotation(const int delta) override;
|
||||
void NotifyShellIntegrationMark() override;
|
||||
void NotifyShellIntegrationMark(ShellIntegrationMark mark) override;
|
||||
|
||||
void InvokeCompletions(std::wstring_view menuJson, unsigned int replaceLength) override;
|
||||
|
||||
@@ -232,6 +232,8 @@ public:
|
||||
void SetSearchMissingCommandCallback(std::function<void(std::wstring_view, const til::CoordType)> pfn) noexcept;
|
||||
void SetClearQuickFixCallback(std::function<void()> pfn) noexcept;
|
||||
void SetWindowSizeChangedCallback(std::function<void(int32_t, int32_t)> pfn) noexcept;
|
||||
void SetPromptReturnedCallback(std::function<void()> pfn) noexcept;
|
||||
void SetCommandStartedCallback(std::function<void()> pfn) noexcept;
|
||||
void SetSearchHighlights(const std::vector<til::point_span>& highlights) noexcept;
|
||||
void SetSearchHighlightFocused(size_t focusedIdx) noexcept;
|
||||
void ScrollToSearchHighlight(til::CoordType searchScrollOffset);
|
||||
@@ -340,6 +342,8 @@ private:
|
||||
std::function<void(std::wstring_view, const til::CoordType)> _pfnSearchMissingCommand;
|
||||
std::function<void()> _pfnClearQuickFix;
|
||||
std::function<void(int32_t, int32_t)> _pfnWindowSizeChanged;
|
||||
std::function<void()> _pfnPromptReturned;
|
||||
std::function<void()> _pfnCommandStarted;
|
||||
|
||||
RenderSettings _renderSettings;
|
||||
std::unique_ptr<::Microsoft::Console::VirtualTerminal::StateMachine> _stateMachine;
|
||||
|
||||
@@ -400,8 +400,26 @@ void Terminal::NotifyBufferRotation(const int delta)
|
||||
}
|
||||
}
|
||||
|
||||
void Terminal::NotifyShellIntegrationMark()
|
||||
void Terminal::NotifyShellIntegrationMark(ShellIntegrationMark mark)
|
||||
{
|
||||
// Notify the scrollbar that marks have been added so it can refresh the mark indicators
|
||||
_NotifyScrollEvent();
|
||||
|
||||
switch (mark)
|
||||
{
|
||||
case ShellIntegrationMark::Prompt:
|
||||
if (_pfnPromptReturned)
|
||||
{
|
||||
_pfnPromptReturned();
|
||||
}
|
||||
break;
|
||||
case ShellIntegrationMark::Output:
|
||||
if (_pfnCommandStarted)
|
||||
{
|
||||
_pfnCommandStarted();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,6 +353,10 @@ namespace winrt::Microsoft::Terminal::Settings
|
||||
_AllowVtChecksumReport = profile.AllowVtChecksumReport();
|
||||
_AllowVtClipboardWrite = profile.AllowVtClipboardWrite();
|
||||
_PathTranslationStyle = profile.PathTranslationStyle();
|
||||
|
||||
_NotifyOnInactiveOutput = profile.NotifyOnInactiveOutput();
|
||||
_NotifyOnNextPrompt = profile.NotifyOnNextPrompt();
|
||||
_AutoDetectRunningCommand = profile.AutoDetectRunningCommand();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
||||
@@ -40,6 +40,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING_REVERSE_ORDER(CloseOnExitMode, CloseOnExitMode, winrt::Microsoft::Terminal::Settings::Model::CloseOnExitMode, L"Profile_CloseOnExit", L"Content");
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING(ScrollState, ScrollbarState, winrt::Microsoft::Terminal::Control::ScrollbarState, L"Profile_ScrollbarVisibility", L"Content");
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING(PathTranslationStyle, PathTranslationStyle, winrt::Microsoft::Terminal::Control::PathTranslationStyle, L"Profile_PathTranslationStyle", L"Content");
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING(AutoDetectRunningCommand, AutoDetectRunningCommand, winrt::Microsoft::Terminal::Control::AutoDetectRunningCommand, L"Profile_AutoDetectRunningCommand", L"Content");
|
||||
|
||||
_InitializeCurrentBellSounds();
|
||||
|
||||
@@ -640,6 +641,170 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
BellStyle(currentStyle);
|
||||
}
|
||||
|
||||
// ===================== NotifyOnInactiveOutput =====================
|
||||
|
||||
hstring ProfileViewModel::NotifyOnInactiveOutputPreview() const
|
||||
{
|
||||
using Ons = Control::OutputNotificationStyle;
|
||||
const auto style = NotifyOnInactiveOutput();
|
||||
if (WI_AreAllFlagsSet(style, Ons::Taskbar | Ons::Audible | Ons::Tab | Ons::Notification))
|
||||
{
|
||||
return RS_(L"Profile_OutputNotificationStyleAll/Content");
|
||||
}
|
||||
else if (style == static_cast<Ons>(0))
|
||||
{
|
||||
return RS_(L"Profile_OutputNotificationStyleNone/Content");
|
||||
}
|
||||
|
||||
std::vector<hstring> resultList;
|
||||
resultList.reserve(4);
|
||||
if (WI_IsFlagSet(style, Ons::Taskbar))
|
||||
{
|
||||
resultList.emplace_back(RS_(L"Profile_OutputNotificationStyleTaskbar/Content"));
|
||||
}
|
||||
if (WI_IsFlagSet(style, Ons::Audible))
|
||||
{
|
||||
resultList.emplace_back(RS_(L"Profile_OutputNotificationStyleAudible/Content"));
|
||||
}
|
||||
if (WI_IsFlagSet(style, Ons::Tab))
|
||||
{
|
||||
resultList.emplace_back(RS_(L"Profile_OutputNotificationStyleTab/Content"));
|
||||
}
|
||||
if (WI_IsFlagSet(style, Ons::Notification))
|
||||
{
|
||||
resultList.emplace_back(RS_(L"Profile_OutputNotificationStyleNotification/Content"));
|
||||
}
|
||||
|
||||
hstring result{};
|
||||
for (auto&& entry : resultList)
|
||||
{
|
||||
if (result.empty())
|
||||
{
|
||||
result = entry;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = result + L", " + entry;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ProfileViewModel::IsNotifyOnInactiveOutputFlagSet(const uint32_t flag)
|
||||
{
|
||||
return (WI_EnumValue(NotifyOnInactiveOutput()) & flag) == flag;
|
||||
}
|
||||
|
||||
void ProfileViewModel::SetNotifyOnInactiveOutputTaskbar(winrt::Windows::Foundation::IReference<bool> on)
|
||||
{
|
||||
auto currentStyle = NotifyOnInactiveOutput();
|
||||
WI_UpdateFlag(currentStyle, Control::OutputNotificationStyle::Taskbar, winrt::unbox_value<bool>(on));
|
||||
NotifyOnInactiveOutput(currentStyle);
|
||||
}
|
||||
|
||||
void ProfileViewModel::SetNotifyOnInactiveOutputAudible(winrt::Windows::Foundation::IReference<bool> on)
|
||||
{
|
||||
auto currentStyle = NotifyOnInactiveOutput();
|
||||
WI_UpdateFlag(currentStyle, Control::OutputNotificationStyle::Audible, winrt::unbox_value<bool>(on));
|
||||
NotifyOnInactiveOutput(currentStyle);
|
||||
}
|
||||
|
||||
void ProfileViewModel::SetNotifyOnInactiveOutputTab(winrt::Windows::Foundation::IReference<bool> on)
|
||||
{
|
||||
auto currentStyle = NotifyOnInactiveOutput();
|
||||
WI_UpdateFlag(currentStyle, Control::OutputNotificationStyle::Tab, winrt::unbox_value<bool>(on));
|
||||
NotifyOnInactiveOutput(currentStyle);
|
||||
}
|
||||
|
||||
void ProfileViewModel::SetNotifyOnInactiveOutputNotification(winrt::Windows::Foundation::IReference<bool> on)
|
||||
{
|
||||
auto currentStyle = NotifyOnInactiveOutput();
|
||||
WI_UpdateFlag(currentStyle, Control::OutputNotificationStyle::Notification, winrt::unbox_value<bool>(on));
|
||||
NotifyOnInactiveOutput(currentStyle);
|
||||
}
|
||||
|
||||
// ===================== NotifyOnNextPrompt =====================
|
||||
|
||||
hstring ProfileViewModel::NotifyOnNextPromptPreview() const
|
||||
{
|
||||
using Ons = Control::OutputNotificationStyle;
|
||||
const auto style = NotifyOnNextPrompt();
|
||||
if (WI_AreAllFlagsSet(style, Ons::Taskbar | Ons::Audible | Ons::Tab | Ons::Notification))
|
||||
{
|
||||
return RS_(L"Profile_OutputNotificationStyleAll/Content");
|
||||
}
|
||||
else if (style == static_cast<Ons>(0))
|
||||
{
|
||||
return RS_(L"Profile_OutputNotificationStyleNone/Content");
|
||||
}
|
||||
|
||||
std::vector<hstring> resultList;
|
||||
resultList.reserve(4);
|
||||
if (WI_IsFlagSet(style, Ons::Taskbar))
|
||||
{
|
||||
resultList.emplace_back(RS_(L"Profile_OutputNotificationStyleTaskbar/Content"));
|
||||
}
|
||||
if (WI_IsFlagSet(style, Ons::Audible))
|
||||
{
|
||||
resultList.emplace_back(RS_(L"Profile_OutputNotificationStyleAudible/Content"));
|
||||
}
|
||||
if (WI_IsFlagSet(style, Ons::Tab))
|
||||
{
|
||||
resultList.emplace_back(RS_(L"Profile_OutputNotificationStyleTab/Content"));
|
||||
}
|
||||
if (WI_IsFlagSet(style, Ons::Notification))
|
||||
{
|
||||
resultList.emplace_back(RS_(L"Profile_OutputNotificationStyleNotification/Content"));
|
||||
}
|
||||
|
||||
hstring result{};
|
||||
for (auto&& entry : resultList)
|
||||
{
|
||||
if (result.empty())
|
||||
{
|
||||
result = entry;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = result + L", " + entry;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ProfileViewModel::IsNotifyOnNextPromptFlagSet(const uint32_t flag)
|
||||
{
|
||||
return (WI_EnumValue(NotifyOnNextPrompt()) & flag) == flag;
|
||||
}
|
||||
|
||||
void ProfileViewModel::SetNotifyOnNextPromptTaskbar(winrt::Windows::Foundation::IReference<bool> on)
|
||||
{
|
||||
auto currentStyle = NotifyOnNextPrompt();
|
||||
WI_UpdateFlag(currentStyle, Control::OutputNotificationStyle::Taskbar, winrt::unbox_value<bool>(on));
|
||||
NotifyOnNextPrompt(currentStyle);
|
||||
}
|
||||
|
||||
void ProfileViewModel::SetNotifyOnNextPromptAudible(winrt::Windows::Foundation::IReference<bool> on)
|
||||
{
|
||||
auto currentStyle = NotifyOnNextPrompt();
|
||||
WI_UpdateFlag(currentStyle, Control::OutputNotificationStyle::Audible, winrt::unbox_value<bool>(on));
|
||||
NotifyOnNextPrompt(currentStyle);
|
||||
}
|
||||
|
||||
void ProfileViewModel::SetNotifyOnNextPromptTab(winrt::Windows::Foundation::IReference<bool> on)
|
||||
{
|
||||
auto currentStyle = NotifyOnNextPrompt();
|
||||
WI_UpdateFlag(currentStyle, Control::OutputNotificationStyle::Tab, winrt::unbox_value<bool>(on));
|
||||
NotifyOnNextPrompt(currentStyle);
|
||||
}
|
||||
|
||||
void ProfileViewModel::SetNotifyOnNextPromptNotification(winrt::Windows::Foundation::IReference<bool> on)
|
||||
{
|
||||
auto currentStyle = NotifyOnNextPrompt();
|
||||
WI_UpdateFlag(currentStyle, Control::OutputNotificationStyle::Notification, winrt::unbox_value<bool>(on));
|
||||
NotifyOnNextPrompt(currentStyle);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Construct _CurrentBellSounds by importing the _inherited_ value from the model
|
||||
// - Adds a PropertyChanged handler to each BellSoundViewModel to propagate changes to the model
|
||||
|
||||
@@ -47,6 +47,22 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
void SetBellStyleWindow(winrt::Windows::Foundation::IReference<bool> on);
|
||||
void SetBellStyleTaskbar(winrt::Windows::Foundation::IReference<bool> on);
|
||||
|
||||
// notify on inactive output bits
|
||||
hstring NotifyOnInactiveOutputPreview() const;
|
||||
bool IsNotifyOnInactiveOutputFlagSet(const uint32_t flag);
|
||||
void SetNotifyOnInactiveOutputTaskbar(winrt::Windows::Foundation::IReference<bool> on);
|
||||
void SetNotifyOnInactiveOutputAudible(winrt::Windows::Foundation::IReference<bool> on);
|
||||
void SetNotifyOnInactiveOutputTab(winrt::Windows::Foundation::IReference<bool> on);
|
||||
void SetNotifyOnInactiveOutputNotification(winrt::Windows::Foundation::IReference<bool> on);
|
||||
|
||||
// notify on next prompt bits
|
||||
hstring NotifyOnNextPromptPreview() const;
|
||||
bool IsNotifyOnNextPromptFlagSet(const uint32_t flag);
|
||||
void SetNotifyOnNextPromptTaskbar(winrt::Windows::Foundation::IReference<bool> on);
|
||||
void SetNotifyOnNextPromptAudible(winrt::Windows::Foundation::IReference<bool> on);
|
||||
void SetNotifyOnNextPromptTab(winrt::Windows::Foundation::IReference<bool> on);
|
||||
void SetNotifyOnNextPromptNotification(winrt::Windows::Foundation::IReference<bool> on);
|
||||
|
||||
hstring BellSoundPreview();
|
||||
void RequestAddBellSound(hstring path);
|
||||
void RequestDeleteBellSound(const Editor::BellSoundViewModel& vm);
|
||||
@@ -146,12 +162,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, RainbowSuggestions);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, PathTranslationStyle);
|
||||
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, NotifyOnInactiveOutput);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, NotifyOnNextPrompt);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, AutoDetectRunningCommand);
|
||||
|
||||
WINRT_PROPERTY(bool, IsBaseLayer, false);
|
||||
WINRT_PROPERTY(bool, FocusDeleteButton, false);
|
||||
GETSET_BINDABLE_ENUM_SETTING(AntiAliasingMode, Microsoft::Terminal::Control::TextAntialiasingMode, AntialiasingMode);
|
||||
GETSET_BINDABLE_ENUM_SETTING(CloseOnExitMode, Microsoft::Terminal::Settings::Model::CloseOnExitMode, CloseOnExit);
|
||||
GETSET_BINDABLE_ENUM_SETTING(ScrollState, Microsoft::Terminal::Control::ScrollbarState, ScrollState);
|
||||
GETSET_BINDABLE_ENUM_SETTING(PathTranslationStyle, Microsoft::Terminal::Control::PathTranslationStyle, PathTranslationStyle);
|
||||
GETSET_BINDABLE_ENUM_SETTING(AutoDetectRunningCommand, Microsoft::Terminal::Control::AutoDetectRunningCommand, AutoDetectRunningCommand);
|
||||
|
||||
private:
|
||||
Model::Profile _profile;
|
||||
|
||||
@@ -50,6 +50,23 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
void SetBellStyleWindow(Windows.Foundation.IReference<Boolean> on);
|
||||
void SetBellStyleTaskbar(Windows.Foundation.IReference<Boolean> on);
|
||||
|
||||
String NotifyOnInactiveOutputPreview { get; };
|
||||
Boolean IsNotifyOnInactiveOutputFlagSet(UInt32 flag);
|
||||
void SetNotifyOnInactiveOutputTaskbar(Windows.Foundation.IReference<Boolean> on);
|
||||
void SetNotifyOnInactiveOutputAudible(Windows.Foundation.IReference<Boolean> on);
|
||||
void SetNotifyOnInactiveOutputTab(Windows.Foundation.IReference<Boolean> on);
|
||||
void SetNotifyOnInactiveOutputNotification(Windows.Foundation.IReference<Boolean> on);
|
||||
|
||||
String NotifyOnNextPromptPreview { get; };
|
||||
Boolean IsNotifyOnNextPromptFlagSet(UInt32 flag);
|
||||
void SetNotifyOnNextPromptTaskbar(Windows.Foundation.IReference<Boolean> on);
|
||||
void SetNotifyOnNextPromptAudible(Windows.Foundation.IReference<Boolean> on);
|
||||
void SetNotifyOnNextPromptTab(Windows.Foundation.IReference<Boolean> on);
|
||||
void SetNotifyOnNextPromptNotification(Windows.Foundation.IReference<Boolean> on);
|
||||
|
||||
IInspectable CurrentAutoDetectRunningCommand;
|
||||
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> AutoDetectRunningCommandList { get; };
|
||||
|
||||
String BellSoundPreview { get; };
|
||||
Windows.Foundation.Collections.IObservableVector<BellSoundViewModel> CurrentBellSounds { get; };
|
||||
void RequestAddBellSound(String path);
|
||||
@@ -140,5 +157,8 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, RainbowSuggestions);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Control.PathTranslationStyle, PathTranslationStyle);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, AllowVtClipboardWrite);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Control.OutputNotificationStyle, NotifyOnInactiveOutput);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Control.OutputNotificationStyle, NotifyOnNextPrompt);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Control.AutoDetectRunningCommand, AutoDetectRunningCommand);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,6 +196,59 @@
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Notify On Inactive Output -->
|
||||
<local:SettingContainer x:Name="NotifyOnInactiveOutput"
|
||||
x:Uid="Profile_NotifyOnInactiveOutput"
|
||||
ClearSettingValue="{x:Bind Profile.ClearNotifyOnInactiveOutput}"
|
||||
CurrentValue="{x:Bind Profile.NotifyOnInactiveOutputPreview, Mode=OneWay}"
|
||||
HasSettingValue="{x:Bind Profile.HasNotifyOnInactiveOutput, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.NotifyOnInactiveOutputOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<StackPanel>
|
||||
<CheckBox x:Uid="Profile_OutputNotificationStyleTaskbar"
|
||||
IsChecked="{x:Bind Profile.IsNotifyOnInactiveOutputFlagSet(1), BindBack=Profile.SetNotifyOnInactiveOutputTaskbar, Mode=TwoWay}" />
|
||||
<CheckBox x:Uid="Profile_OutputNotificationStyleAudible"
|
||||
IsChecked="{x:Bind Profile.IsNotifyOnInactiveOutputFlagSet(2), BindBack=Profile.SetNotifyOnInactiveOutputAudible, Mode=TwoWay}" />
|
||||
<CheckBox x:Uid="Profile_OutputNotificationStyleTab"
|
||||
IsChecked="{x:Bind Profile.IsNotifyOnInactiveOutputFlagSet(4), BindBack=Profile.SetNotifyOnInactiveOutputTab, Mode=TwoWay}" />
|
||||
<CheckBox x:Uid="Profile_OutputNotificationStyleNotification"
|
||||
IsChecked="{x:Bind Profile.IsNotifyOnInactiveOutputFlagSet(8), BindBack=Profile.SetNotifyOnInactiveOutputNotification, Mode=TwoWay}" />
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Notify On Next Prompt -->
|
||||
<local:SettingContainer x:Name="NotifyOnNextPrompt"
|
||||
x:Uid="Profile_NotifyOnNextPrompt"
|
||||
ClearSettingValue="{x:Bind Profile.ClearNotifyOnNextPrompt}"
|
||||
CurrentValue="{x:Bind Profile.NotifyOnNextPromptPreview, Mode=OneWay}"
|
||||
HasSettingValue="{x:Bind Profile.HasNotifyOnNextPrompt, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.NotifyOnNextPromptOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<StackPanel>
|
||||
<CheckBox x:Uid="Profile_OutputNotificationStyleTaskbar"
|
||||
IsChecked="{x:Bind Profile.IsNotifyOnNextPromptFlagSet(1), BindBack=Profile.SetNotifyOnNextPromptTaskbar, Mode=TwoWay}" />
|
||||
<CheckBox x:Uid="Profile_OutputNotificationStyleAudible"
|
||||
IsChecked="{x:Bind Profile.IsNotifyOnNextPromptFlagSet(2), BindBack=Profile.SetNotifyOnNextPromptAudible, Mode=TwoWay}" />
|
||||
<CheckBox x:Uid="Profile_OutputNotificationStyleTab"
|
||||
IsChecked="{x:Bind Profile.IsNotifyOnNextPromptFlagSet(4), BindBack=Profile.SetNotifyOnNextPromptTab, Mode=TwoWay}" />
|
||||
<CheckBox x:Uid="Profile_OutputNotificationStyleNotification"
|
||||
IsChecked="{x:Bind Profile.IsNotifyOnNextPromptFlagSet(8), BindBack=Profile.SetNotifyOnNextPromptNotification, Mode=TwoWay}" />
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Auto Detect Running Command -->
|
||||
<local:SettingContainer x:Name="AutoDetectRunningCommand"
|
||||
x:Uid="Profile_AutoDetectRunningCommand"
|
||||
ClearSettingValue="{x:Bind Profile.ClearAutoDetectRunningCommand}"
|
||||
HasSettingValue="{x:Bind Profile.HasAutoDetectRunningCommand, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.AutoDetectRunningCommandOverrideSource, Mode=OneWay}">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind Profile.AutoDetectRunningCommandList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind Profile.CurrentAutoDetectRunningCommand, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- RightClickContextMenu -->
|
||||
<local:SettingContainer x:Name="RightClickContextMenu"
|
||||
x:Uid="Profile_RightClickContextMenu"
|
||||
|
||||
@@ -2748,4 +2748,92 @@
|
||||
<value>Type to filter icons</value>
|
||||
<comment>Placeholder text for a text box to filter and select an icon.</comment>
|
||||
</data>
|
||||
<!-- OutputNotificationStyle shared checkbox labels -->
|
||||
<data name="Profile_OutputNotificationStyleTaskbar.Content" xml:space="preserve">
|
||||
<value>Flash taskbar</value>
|
||||
<comment>An option to choose from for a notification style setting. When selected, the taskbar is flashed.</comment>
|
||||
</data>
|
||||
<data name="Profile_OutputNotificationStyleAudible.Content" xml:space="preserve">
|
||||
<value>Audible</value>
|
||||
<comment>An option to choose from for a notification style setting. When selected, an audible cue is played.</comment>
|
||||
</data>
|
||||
<data name="Profile_OutputNotificationStyleTab.Content" xml:space="preserve">
|
||||
<value>Tab indicator</value>
|
||||
<comment>An option to choose from for a notification style setting. When selected, an activity indicator is shown on the tab.</comment>
|
||||
</data>
|
||||
<data name="Profile_OutputNotificationStyleNotification.Content" xml:space="preserve">
|
||||
<value>Desktop notification</value>
|
||||
<comment>An option to choose from for a notification style setting. When selected, a desktop toast notification is sent.</comment>
|
||||
</data>
|
||||
<data name="Profile_OutputNotificationStyleAll/Content" xml:space="preserve">
|
||||
<value>All</value>
|
||||
<comment>An option label for notification style. Shown when all notification styles are enabled.</comment>
|
||||
</data>
|
||||
<data name="Profile_OutputNotificationStyleNone/Content" xml:space="preserve">
|
||||
<value>None</value>
|
||||
<comment>An option label for notification style. Shown when no notification styles are enabled.</comment>
|
||||
</data>
|
||||
<!-- NotifyOnInactiveOutput -->
|
||||
<data name="Profile_NotifyOnInactiveOutput.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Notify on inactive output</value>
|
||||
<comment>Name for a control to select how the app notifies the user when an inactive pane produces output.</comment>
|
||||
</data>
|
||||
<data name="Profile_NotifyOnInactiveOutput.Header" xml:space="preserve">
|
||||
<value>Notify on inactive output</value>
|
||||
<comment>Header for a control to select how the app notifies the user when an inactive pane produces output.</comment>
|
||||
</data>
|
||||
<data name="Profile_NotifyOnInactiveOutput.HelpText" xml:space="preserve">
|
||||
<value>Controls how you are notified when a background pane produces new output.</value>
|
||||
<comment>A description for what the "notify on inactive output" setting does.</comment>
|
||||
</data>
|
||||
<!-- NotifyOnNextPrompt -->
|
||||
<data name="Profile_NotifyOnNextPrompt.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Notify on next prompt</value>
|
||||
<comment>Name for a control to select how the app notifies the user when a command finishes and the shell returns to a prompt.</comment>
|
||||
</data>
|
||||
<data name="Profile_NotifyOnNextPrompt.Header" xml:space="preserve">
|
||||
<value>Notify on next prompt</value>
|
||||
<comment>Header for a control to select how the app notifies the user when a command finishes and the shell returns to a prompt.</comment>
|
||||
</data>
|
||||
<data name="Profile_NotifyOnNextPrompt.HelpText" xml:space="preserve">
|
||||
<value>Controls how you are notified when a running command finishes and the shell returns to a prompt. Requires shell integration.</value>
|
||||
<comment>A description for what the "notify on next prompt" setting does.</comment>
|
||||
</data>
|
||||
<!-- AutoDetectRunningCommand -->
|
||||
<data name="Profile_AutoDetectRunningCommand.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Auto-detect running command</value>
|
||||
<comment>Name for a control to select how the app detects and indicates a running command.</comment>
|
||||
</data>
|
||||
<data name="Profile_AutoDetectRunningCommand.Header" xml:space="preserve">
|
||||
<value>Auto-detect running command</value>
|
||||
<comment>Header for a control to select how the app detects and indicates a running command.</comment>
|
||||
</data>
|
||||
<data name="Profile_AutoDetectRunningCommand.HelpText" xml:space="preserve">
|
||||
<value>Controls whether and how the terminal automatically shows progress while a command is running. Requires shell integration.</value>
|
||||
<comment>A description for what the "auto-detect running command" setting does.</comment>
|
||||
</data>
|
||||
<data name="Profile_AutoDetectRunningCommand_Disabled.Content" xml:space="preserve">
|
||||
<value>Disabled</value>
|
||||
<comment>An option to choose from for the "auto-detect running command" setting. When selected, no auto-detection occurs.</comment>
|
||||
</data>
|
||||
<data name="Profile_AutoDetectRunningCommand_Automatic.Content" xml:space="preserve">
|
||||
<value>Automatic</value>
|
||||
<comment>An option to choose from for the "auto-detect running command" setting. When selected, an indeterminate progress ring is shown while a command is running.</comment>
|
||||
</data>
|
||||
<data name="Profile_AutoDetectRunningCommand_Progress.Content" xml:space="preserve">
|
||||
<value>Progress</value>
|
||||
<comment>An option to choose from for the "auto-detect running command" setting. When selected, the terminal attempts to detect progress percentage from command output.</comment>
|
||||
</data>
|
||||
<data name="Profile_AutoDetectRunningCommandDisabled.Content" xml:space="preserve">
|
||||
<value>Disabled</value>
|
||||
<comment>An option to choose from for the "auto-detect running command" setting. When selected, no auto-detection occurs.</comment>
|
||||
</data>
|
||||
<data name="Profile_AutoDetectRunningCommandAutomatic.Content" xml:space="preserve">
|
||||
<value>Automatic</value>
|
||||
<comment>An option to choose from for the "auto-detect running command" setting. When selected, an indeterminate progress ring is shown while a command is running.</comment>
|
||||
</data>
|
||||
<data name="Profile_AutoDetectRunningCommandProgress.Content" xml:space="preserve">
|
||||
<value>Progress</value>
|
||||
<comment>An option to choose from for the "auto-detect running command" setting. When selected, the terminal attempts to detect progress percentage from command output.</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -53,6 +53,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
DEFINE_ENUM_MAP(Microsoft::Terminal::Settings::Model::IntenseStyle, IntenseTextStyle);
|
||||
DEFINE_ENUM_MAP(Microsoft::Terminal::Core::AdjustTextMode, AdjustIndistinguishableColors);
|
||||
DEFINE_ENUM_MAP(Microsoft::Terminal::Control::PathTranslationStyle, PathTranslationStyle);
|
||||
DEFINE_ENUM_MAP(Microsoft::Terminal::Control::AutoDetectRunningCommand, AutoDetectRunningCommand);
|
||||
|
||||
// Actions
|
||||
DEFINE_ENUM_MAP(Microsoft::Terminal::Settings::Model::ResizeDirection, ResizeDirection);
|
||||
|
||||
@@ -51,6 +51,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
static winrt::Windows::Foundation::Collections::IMap<winrt::hstring, winrt::Microsoft::Terminal::Settings::Model::IntenseStyle> IntenseTextStyle();
|
||||
static winrt::Windows::Foundation::Collections::IMap<winrt::hstring, winrt::Microsoft::Terminal::Core::AdjustTextMode> AdjustIndistinguishableColors();
|
||||
static winrt::Windows::Foundation::Collections::IMap<winrt::hstring, winrt::Microsoft::Terminal::Control::PathTranslationStyle> PathTranslationStyle();
|
||||
static winrt::Windows::Foundation::Collections::IMap<winrt::hstring, winrt::Microsoft::Terminal::Control::AutoDetectRunningCommand> AutoDetectRunningCommand();
|
||||
|
||||
// Actions
|
||||
static winrt::Windows::Foundation::Collections::IMap<winrt::hstring, winrt::Microsoft::Terminal::Settings::Model::ResizeDirection> ResizeDirection();
|
||||
|
||||
@@ -33,6 +33,7 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
static Windows.Foundation.Collections.IMap<String, UInt16> FontWeight { get; };
|
||||
static Windows.Foundation.Collections.IMap<String, Microsoft.Terminal.Settings.Model.IntenseStyle> IntenseTextStyle { get; };
|
||||
static Windows.Foundation.Collections.IMap<String, Microsoft.Terminal.Control.PathTranslationStyle> PathTranslationStyle { get; };
|
||||
static Windows.Foundation.Collections.IMap<String, Microsoft.Terminal.Control.AutoDetectRunningCommand> AutoDetectRunningCommand { get; };
|
||||
|
||||
// Actions
|
||||
static Windows.Foundation.Collections.IMap<String, Microsoft.Terminal.Settings.Model.ResizeDirection> ResizeDirection { get; };
|
||||
|
||||
@@ -108,7 +108,10 @@ Author(s):
|
||||
X(bool, AllowVtChecksumReport, "compatibility.allowDECRQCRA", false) \
|
||||
X(bool, AllowVtClipboardWrite, "compatibility.allowOSC52", true) \
|
||||
X(bool, AllowKeypadMode, "compatibility.allowDECNKM", false) \
|
||||
X(Microsoft::Terminal::Control::PathTranslationStyle, PathTranslationStyle, "pathTranslationStyle", Microsoft::Terminal::Control::PathTranslationStyle::None)
|
||||
X(Microsoft::Terminal::Control::PathTranslationStyle, PathTranslationStyle, "pathTranslationStyle", Microsoft::Terminal::Control::PathTranslationStyle::None) \
|
||||
X(Microsoft::Terminal::Control::OutputNotificationStyle, NotifyOnInactiveOutput, "notifyOnInactiveOutput", Microsoft::Terminal::Control::OutputNotificationStyle{0}) \
|
||||
X(Microsoft::Terminal::Control::OutputNotificationStyle, NotifyOnNextPrompt, "notifyOnNextPrompt", Microsoft::Terminal::Control::OutputNotificationStyle{0}) \
|
||||
X(Microsoft::Terminal::Control::AutoDetectRunningCommand, AutoDetectRunningCommand, "autoDetectRunningCommand", Microsoft::Terminal::Control::AutoDetectRunningCommand::Disabled)
|
||||
|
||||
// Intentionally omitted Profile settings:
|
||||
// * Name
|
||||
|
||||
@@ -94,5 +94,9 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
INHERITABLE_PROFILE_SETTING(Boolean, AllowVtClipboardWrite);
|
||||
|
||||
INHERITABLE_PROFILE_SETTING(Microsoft.Terminal.Control.PathTranslationStyle, PathTranslationStyle);
|
||||
|
||||
INHERITABLE_PROFILE_SETTING(Microsoft.Terminal.Control.OutputNotificationStyle, NotifyOnInactiveOutput);
|
||||
INHERITABLE_PROFILE_SETTING(Microsoft.Terminal.Control.OutputNotificationStyle, NotifyOnNextPrompt);
|
||||
INHERITABLE_PROFILE_SETTING(Microsoft.Terminal.Control.AutoDetectRunningCommand, AutoDetectRunningCommand);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,6 +119,46 @@ JSON_FLAG_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::BellStyle)
|
||||
}
|
||||
};
|
||||
|
||||
JSON_FLAG_MAPPER(::winrt::Microsoft::Terminal::Control::OutputNotificationStyle)
|
||||
{
|
||||
static constexpr std::array<pair_type, 6> mappings = {
|
||||
pair_type{ "none", AllClear },
|
||||
pair_type{ "taskbar", ValueType::Taskbar },
|
||||
pair_type{ "audible", ValueType::Audible },
|
||||
pair_type{ "tab", ValueType::Tab },
|
||||
pair_type{ "notification", ValueType::Notification },
|
||||
pair_type{ "all", AllSet },
|
||||
};
|
||||
|
||||
auto FromJson(const Json::Value& json)
|
||||
{
|
||||
if (json.isBool())
|
||||
{
|
||||
return json.asBool() ? ValueType::Tab : AllClear;
|
||||
}
|
||||
return BaseFlagMapper::FromJson(json);
|
||||
}
|
||||
|
||||
bool CanConvert(const Json::Value& json)
|
||||
{
|
||||
return BaseFlagMapper::CanConvert(json) || json.isBool();
|
||||
}
|
||||
|
||||
Json::Value ToJson(const ::winrt::Microsoft::Terminal::Control::OutputNotificationStyle& style)
|
||||
{
|
||||
return BaseFlagMapper::ToJson(style);
|
||||
}
|
||||
};
|
||||
|
||||
JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Control::AutoDetectRunningCommand)
|
||||
{
|
||||
JSON_MAPPINGS(3) = {
|
||||
pair_type{ "disabled", ValueType::Disabled },
|
||||
pair_type{ "automatic", ValueType::Automatic },
|
||||
pair_type{ "progress", ValueType::Progress },
|
||||
};
|
||||
};
|
||||
|
||||
JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::ConvergedAlignment)
|
||||
{
|
||||
// reduce repetition
|
||||
|
||||
@@ -87,4 +87,7 @@
|
||||
X(bool, ShowMarks, false) \
|
||||
X(winrt::Microsoft::Terminal::Control::CopyFormat, CopyFormatting, 0) \
|
||||
X(bool, RightClickContextMenu, false) \
|
||||
X(winrt::Microsoft::Terminal::Control::PathTranslationStyle, PathTranslationStyle, winrt::Microsoft::Terminal::Control::PathTranslationStyle::None)
|
||||
X(winrt::Microsoft::Terminal::Control::PathTranslationStyle, PathTranslationStyle, winrt::Microsoft::Terminal::Control::PathTranslationStyle::None) \
|
||||
X(winrt::Microsoft::Terminal::Control::OutputNotificationStyle, NotifyOnInactiveOutput, winrt::Microsoft::Terminal::Control::OutputNotificationStyle{0}) \
|
||||
X(winrt::Microsoft::Terminal::Control::OutputNotificationStyle, NotifyOnNextPrompt, winrt::Microsoft::Terminal::Control::OutputNotificationStyle{0}) \
|
||||
X(winrt::Microsoft::Terminal::Control::AutoDetectRunningCommand, AutoDetectRunningCommand, winrt::Microsoft::Terminal::Control::AutoDetectRunningCommand::Disabled)
|
||||
|
||||
@@ -424,7 +424,7 @@ void ConhostInternalGetSet::NotifyBufferRotation(const int)
|
||||
{
|
||||
}
|
||||
|
||||
void ConhostInternalGetSet::NotifyShellIntegrationMark()
|
||||
void ConhostInternalGetSet::NotifyShellIntegrationMark(ShellIntegrationMark /*mark*/)
|
||||
{
|
||||
// Not implemented for conhost - shell integration marks are a Terminal app feature.
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ public:
|
||||
bool IsVtInputEnabled() const override;
|
||||
|
||||
void NotifyBufferRotation(const int delta) override;
|
||||
void NotifyShellIntegrationMark() override;
|
||||
void NotifyShellIntegrationMark(ShellIntegrationMark mark) override;
|
||||
|
||||
void InvokeCompletions(std::wstring_view menuJson, unsigned int replaceLength) override;
|
||||
|
||||
|
||||
@@ -85,7 +85,16 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
virtual bool ResizeWindow(const til::CoordType width, const til::CoordType height) = 0;
|
||||
|
||||
virtual void NotifyBufferRotation(const int delta) = 0;
|
||||
virtual void NotifyShellIntegrationMark() = 0;
|
||||
|
||||
enum class ShellIntegrationMark
|
||||
{
|
||||
Prompt,
|
||||
Command,
|
||||
Output,
|
||||
CommandFinished,
|
||||
Other
|
||||
};
|
||||
virtual void NotifyShellIntegrationMark(ShellIntegrationMark mark) = 0;
|
||||
|
||||
virtual void InvokeCompletions(std::wstring_view menuJson, unsigned int replaceLength) = 0;
|
||||
|
||||
|
||||
@@ -3583,7 +3583,7 @@ void AdaptDispatch::DoConEmuAction(const std::wstring_view string)
|
||||
else if (subParam == 12)
|
||||
{
|
||||
_pages.ActivePage().Buffer().StartCommand();
|
||||
_api.NotifyShellIntegrationMark();
|
||||
_api.NotifyShellIntegrationMark(ITerminalApi::ShellIntegrationMark::Command);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3614,7 +3614,7 @@ void AdaptDispatch::DoITerm2Action(const std::wstring_view string)
|
||||
if (action == L"SetMark")
|
||||
{
|
||||
_pages.ActivePage().Buffer().StartPrompt();
|
||||
_api.NotifyShellIntegrationMark();
|
||||
_api.NotifyShellIntegrationMark(ITerminalApi::ShellIntegrationMark::Prompt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3648,19 +3648,19 @@ void AdaptDispatch::DoFinalTermAction(const std::wstring_view string)
|
||||
case L'A': // FTCS_PROMPT
|
||||
{
|
||||
_pages.ActivePage().Buffer().StartPrompt();
|
||||
_api.NotifyShellIntegrationMark();
|
||||
_api.NotifyShellIntegrationMark(ITerminalApi::ShellIntegrationMark::Prompt);
|
||||
break;
|
||||
}
|
||||
case L'B': // FTCS_COMMAND_START
|
||||
{
|
||||
_pages.ActivePage().Buffer().StartCommand();
|
||||
_api.NotifyShellIntegrationMark();
|
||||
_api.NotifyShellIntegrationMark(ITerminalApi::ShellIntegrationMark::Command);
|
||||
break;
|
||||
}
|
||||
case L'C': // FTCS_COMMAND_EXECUTED
|
||||
{
|
||||
_pages.ActivePage().Buffer().StartOutput();
|
||||
_api.NotifyShellIntegrationMark();
|
||||
_api.NotifyShellIntegrationMark(ITerminalApi::ShellIntegrationMark::Output);
|
||||
break;
|
||||
}
|
||||
case L'D': // FTCS_COMMAND_FINISHED
|
||||
@@ -3681,7 +3681,7 @@ void AdaptDispatch::DoFinalTermAction(const std::wstring_view string)
|
||||
}
|
||||
|
||||
_pages.ActivePage().Buffer().EndCurrentCommand(error);
|
||||
_api.NotifyShellIntegrationMark();
|
||||
_api.NotifyShellIntegrationMark(ITerminalApi::ShellIntegrationMark::CommandFinished);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ public:
|
||||
Log::Comment(L"NotifyBufferRotation MOCK called...");
|
||||
}
|
||||
|
||||
void NotifyShellIntegrationMark() override
|
||||
void NotifyShellIntegrationMark(ShellIntegrationMark /*mark*/) override
|
||||
{
|
||||
Log::Comment(L"NotifyShellIntegrationMark MOCK called...");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user