Add settings for "notifying" on "activity"#20014
Conversation
4357c17 to
aeb531f
Compare
## Summary of the Pull Request Targets #20010 Manually assign an AUMID to our process when we're running unpackaged. Main difference from #19937 is what AUMID we use. Before, it was per branding, but the `WindowEmperor` already appends an exe path hash for unpackaged instances to prevent crosstalk. Here, we're just using the same pattern: `Microsoft.WindowsTerminal.<hash>`. Heavily based on #19937 Co-authored by @zadjii-msft
47c0ae7 to
09c47c6
Compare
09c47c6 to
98a4ccb
Compare
|
Tested this out, it's pretty cool. The only thing I can think of is the possibility of adding the So yeah, marked this as ready for review. Enjoy y'all! 😊 |
90fdd9b to
fbb886e
Compare
| "description": "Sets the sound played when the application emits a BEL. When set to an array, the terminal will pick one of those sounds at random.", | ||
| "$ref": "#/$defs/BellSound" | ||
| }, | ||
| "notifyOnInactiveOutput": { |
There was a problem hiding this comment.
What about a setting for duration? Ghostty has this as well. I may only want to see this after, say, 10s and not a command that maybe takes a second and I quickly flip away intending to come back in a few seconds. A longer job is more likely something we'll "walk away from" for a longer period instead of just flipping windows back and forth a bit.
If someone really wanted to be alerted for every command when the window is inactive, they can set this to 0 (or maybe that's the default).
There was a problem hiding this comment.
Hmm... ghostty calls these settings activity-monitor and activity-monitor-threshold. So, we could name this notifyOnInactiveOutputThreshold and also have it take an int representing seconds (default of 0). Then just place them next to each other in the settings UI.
There was a problem hiding this comment.
Having a higher default (IIRC, Ghostty's is 30s when enabled) might solve the other issue you mentioned, but you could also debounce notifications. If they come in within Xs (maybe also configurable), don't notify. Frankly, given the goal is to notify you some task is done - and this would seem to be a long-running task, IMO, since any quick task you're probably coming back to frequently - the "threshold" having a higher default like 30s would probably be sufficient - at least as a start.
There was a problem hiding this comment.
"notifyOnInactiveOutput" sounds a bit weird to me and I think I'd prefer something like "notifyOnActivity". It not sending a notification when focused seems implicitly natural to me, so it probably doesn't need to be in the name.
|
I was just using this feature with Copilot, and it was sending a ton of notifications as it was thinking. Thoughts? CC @DHowett @zadjii-msft |
|
IMO: I think we need to send one notification when the tab gets activity and then no more until that pane is focused. Like, consider how the in-tab indicator would work. It's like the bell icon. "this tab did a thing" stays until the user activates it to dismiss that state. |
| } | ||
| }, | ||
| { | ||
| "type": "string", |
There was a problem hiding this comment.
If the setting always used an array, I think that'd be fine too. That's just [two] extra characters after all.
There was a problem hiding this comment.
Keeping as is. You'd be surprised how many people forgot the [] back with keyChords haha.
| page->Dispatcher().RunAsync(winrt::Windows::UI::Core::CoreDispatcherPriority::Normal, [weakPage{ page->get_weak() }, weakTab, weakContent]() { | ||
| if (const auto p{ weakPage.get() }) | ||
| page->Dispatcher().RunAsync(winrt::Windows::UI::Core::CoreDispatcherPriority::Normal, [weakThis, weakTab, weakContent]() { | ||
| if (const auto p{ weakThis.get() }) |
There was a problem hiding this comment.
personally i'd revert it, since it's unrelated - what makes it neat?
fbb886e to
6c2b796
Compare
lhecker
left a comment
There was a problem hiding this comment.
Love it! The only minor qualm I have is the naming of "notifyOnInactiveOutput".
This comment was marked as resolved.
This comment was marked as resolved.
DHowett
left a comment
There was a problem hiding this comment.
5/51 blocking for discussion...
| page->Dispatcher().RunAsync(winrt::Windows::UI::Core::CoreDispatcherPriority::Normal, [weakPage{ page->get_weak() }, weakTab, weakContent]() { | ||
| if (const auto p{ weakPage.get() }) | ||
| page->Dispatcher().RunAsync(winrt::Windows::UI::Core::CoreDispatcherPriority::Normal, [weakThis, weakTab, weakContent]() { | ||
| if (const auto p{ weakThis.get() }) |
There was a problem hiding this comment.
personally i'd revert it, since it's unrelated - what makes it neat?
| 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 }, |
There was a problem hiding this comment.
does this differ from the other notification styles we have? if so, why? if not, why have a separate type for it?
There was a problem hiding this comment.
Good eye. The overlap is a bit weird here:
< investigation notes>
OutputNotificationStyle |
BellStyle |
|
|---|---|---|
taskbar |
✅ | ✅ |
audible |
✅ | ✅ |
tab |
✅ | ❌ |
notification |
✅ | ✅ |
window |
❌ | ✅ |
visual = window + taskbar |
❌ | ✅ |
Note: OutputNotificationStyle is used by notifyOnActivity and notifyOnNextPrompt.
The question kinda becomes:
- should
notifyOnActivity/notifyOnNextPromptsupportwindow?- I can see this being useful. It would be a more aggressive flash whenever the terminal session/control is visible. If it's a background tab, it shouldn't flash.
- my opinion: ✅
- should
bellStylesupporttab?BELseems critical enough to deserve a tab indicator. I don't think that should be configurable. My concern is specifically that someone accidentally omitstaband effectively silencesBEL's visual indicator.- my opinion: ❌
- Then, should
tabbe removed fromnotifyOnActivity/notifyOnNextPrompt?- No? A tab indicator seems valuable. It's an easy way to visually identify which tabs are requesting attention. It's a sensible way to opt-in for this setting/behavior, especially since it's disabled by default.
- my opinion: ❌
Implementation-wise, we could consolidate these to be a single NotificationStyle enum in the backend. Then just omit the ones that aren't used in TerminalSettingsSerializationHelpers.h. The fix in the TerminalSettingsEditor side would be a bit more troublesome due to the EnumMappings, but doable.
</ investigation notes>
Though I like the idea of adding window for consistency, I don't think it's worth merging the enums.
Let me know what you think
CC @zadjii-msft (you may have opinions on https://github.com/microsoft/terminal/pull/20014/changes/BASE..b044fd661d730a70fdb11c0c0c5ee4b1e2ba20b6#r3185470645 too)
|
|
||
| auto FromJson(const Json::Value& json) | ||
| { | ||
| if (json.isBool()) |
There was a problem hiding this comment.
this is a NEW SETTING, I do not believe it needs a fallback boolean mapper... right?
There was a problem hiding this comment.
Need? No.
That said, something like "notifyOnActivity": true and "notifyOnNextPrompt": true feels like a good QOL improvement. Much easier to read/write.
That said, true is pretty ambiguous here. IMO. There's a lot of flags, so on first glance, it's a bit overwhelming. I'd probably default to "all" and call it a day. Really this is indicative of a larger issue on how to simplify these settings, but I'll leave that for another day.
tldr: removing boolean support for now. I think there's value to having a simple boolean toggle, but I think that's a part of a broader discussion of how to simplify these settings more.
This comment was marked as resolved.
This comment was marked as resolved.
|
Weird interaction to note. When A "toggle notifying on activity" action could be useful here. Currently, I have to go into the settings and enable/disable notifications at a profile-level. But I'm finding that I don't like that level of customization that much. I generally only use one PowerShell profile, so I'm finding that I prefer session-level customization over profile-level ones. |
|
Similarly, for For both of these, Heath's suggestion of a minimum threshold are relevant. Should be easy to add too, so that's probably the next step of work to do in this PR. |
This PR implements the proposal in this comment. It adds 3 settings:
notifyOnActivity: send a "notification"(below) of some kind when an inactive tab has new output.notifyOnNextPrompt: Similarly, but when we get a new prompt start (requires shell integration)autoDetectRunningCommand: attempt to automatically detect the progress state of this profileFor the
notifyOn*settings, they take any combination of the following flags:tab: flash the taskbaraudible: emit an audible bell (This will use the sounds from bellSounds, if specified)taskbar: display an icon in the tab (ala terminal activity indicator/alert when in background #7955 (comment) ) (basically, similar to the bell icon)notification: send a desktop "toast" (read: notification). Clicking that notification will focus the tab that sent itFor the
autoDetectRunningCommandsetting, we support:false: don't do thistrue: (requires shell integration) if we got a FTCS_COMMAND_EXECUTED (133;C), then any output, set our progress state to indeterminateValidated using this config:
notifyOnActivity)notifyOnNextPrompt)autoDetectRunningCommand)Heavily based on #19935
Co-authored by @zadjii-msft