terminal icon indicating copy to clipboard operation
terminal copied to clipboard

Add support for OSC777 - send notification

Open zadjii-msft opened this issue 3 years ago • 14 comments

This adds support for the OSC 777 ; notify ; title ; body ST sequence. This allows client applications to send a notification to the Terminal. When this notification is clicked, it summons the terminal window that sent it.

This can be used in PowerShell as follows:


Write-Output "`e]777;notify;Hello From the Terminal;This is a notification sent by the client application`a"
 
# but do it with a sleep, because notifications while the Terminal is the FG window won't do anything
sleep 2; write-Output "`e]777;notify;Hello From the Terminal;This is a notification sent by the client </text><text>application`a"
  • closes #7718
  • gifs in that thread

other details

  • The notification is only sent if the tab is inactive, or the window is inactive.
  • When a user clicks on a notification, it launches a new windowsterminal.exe. So we've got to be able to send a notification to the existing window, WITHOUT registering as the monarch. That's what WindowManager::SummonForNotification is all about.
  • Future places we could use this:
    • #6372
    • #7955

todo

  • [x] Elevated?
    • see https://github.com/microsoft/terminal/pull/14425#issuecomment-1334149539
    • This plain-old isn't possible.
  • [x] Unpackaged?
  • [x] XML injection?
    • Looks like they handled this for us image
  • [ ] Doesn't work on Windows 10? https://github.com/microsoft/terminal/pull/14425#discussion_r1043340579

zadjii-msft avatar Nov 22 '22 14:11 zadjii-msft

Is there going to be an optional WinToast notification as well users can set in settings.json or Settings UI (Similar to BEL where we could have visual, audio or both) where here we have "only within the Terminal, only in the Action Center or both"?)

WSLUser avatar Nov 28 '22 14:11 WSLUser

Is there going to be an optional WinToast notification as well users can set in settings.json or Settings UI (Similar to BEL where we could have visual, audio or both) where here we have "only within the Terminal, only in the Action Center or both"?)

I'd reckon probably not. Toasts have been harder to do right in the Terminal than it's been worth (see #8592).

zadjii-msft avatar Nov 28 '22 15:11 zadjii-msft

The issue you linked sounds a bit different than the guide I provided within 7718 (which this PR would close) but maybe they're the same thing.

WSLUser avatar Nov 28 '22 17:11 WSLUser

@WSLUser You linked to https://learn.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/scheduled-toast in #7718, which looks like a guide around using a C# wrapper around the same toast notification APIs I'm using here. Windows apparently just calls all these notifications "toast notifications", which kinda muddies the water when comparing to something like Android (where Toasts and Notifications are two very different concepts).

zadjii-msft avatar Nov 28 '22 19:11 zadjii-msft

Elevated?

Oh hey, this is a problem. We might have to disable this entirely for elevated instances.

The notification is obviously running unelevated. When it calls back to our app, you guessed it, it calls into the unelevated instance. We can't trivially have a notification call back to an elevated instance. We'd need to have the unelevated ActivatedEventArgs handler take the args, then use them to invoke an elevated wt.exe with some commandline to try and summon the window. Something like wt summon -w {id} ala #13276. That's obviously a long way off - I'm just gonna disable this when elevated for now.

zadjii-msft avatar Dec 01 '22 18:12 zadjii-msft

@check-spelling-bot Report

:red_circle: Please review

See the :open_file_folder: files view or the :scroll:action log for details.

Unrecognized words (2)

notif Urxvt

To accept :heavy_check_mark: these unrecognized words as correct, run the following commands

... in a clone of the [email protected]:microsoft/terminal.git repository on the dev/migrie/fhl/7718-notifications branch (:information_source: how do I use this?):

curl -s -S -L 'https://raw.githubusercontent.com/check-spelling/check-spelling/v0.0.21/apply.pl' |
perl - 'https://github.com/microsoft/terminal/actions/runs/3595571410/attempts/1'
:pencil2: Contributor please read this

By default the command suggestion will generate a file named based on your commit. That's generally ok as long as you add the file to your commit. Someone can reorganize it later.

:warning: The command is written for posix shells. If it doesn't work for you, you can manually add (one word per line) / remove items to expect.txt and the excludes.txt files.

If the listed items are:

  • ... misspelled, then please correct them instead of using the command.
  • ... names, please add them to .github/actions/spelling/allow/names.txt.
  • ... APIs, you can add them to a file in .github/actions/spelling/allow/.
  • ... just things you're using, please add them to an appropriate file in .github/actions/spelling/expect/.
  • ... tokens you only need in one place and shouldn't generally be used, you can add an item in an appropriate file in .github/actions/spelling/patterns/.

See the README.md in each directory for more information.

:microscope: You can test your commits without appending to a PR by creating a new branch with that extra change and pushing it to your fork. The check-spelling action will run in response to your push -- it doesn't require an open pull request. By using such a branch, you can limit the number of typos your peers see you make. :wink:

If the flagged items are :exploding_head: false positives

If items relate to a ...

  • binary file (or some other file you wouldn't want to check at all).

    Please add a file path to the excludes.txt file matching the containing file.

    File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

    ^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

  • well-formed pattern.

    If you can write a pattern that would match it, try adding it to the patterns.txt file.

    Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

    Note that patterns can't match multiline strings.

github-actions[bot] avatar Dec 01 '22 18:12 github-actions[bot]

@check-spelling-bot Report

:red_circle: Please review

See the :open_file_folder: files view or the :scroll:action log for details.

Unrecognized words (2)

notif Urxvt

Previously acknowledged words that are now absent CLA demoable DUMMYUNIONNAME everytime Hirots inthread ntsubauth NTWIN OPENIF OPENLINK PCLIENT PCOBJECT PCUNICODE PNTSTATUS PPROCESS PUNICODE reingest unmark :arrow_right:
To accept :heavy_check_mark: these unrecognized words as correct and remove the previously acknowledged and now absent words, run the following commands

... in a clone of the [email protected]:microsoft/terminal.git repository on the dev/migrie/fhl/7718-notifications branch (:information_source: how do I use this?):

curl -s -S -L 'https://raw.githubusercontent.com/check-spelling/check-spelling/v0.0.21/apply.pl' |
perl - 'https://github.com/microsoft/terminal/actions/runs/4326081813/attempts/1'
:pencil2: Contributor please read this

By default the command suggestion will generate a file named based on your commit. That's generally ok as long as you add the file to your commit. Someone can reorganize it later.

:warning: The command is written for posix shells. If it doesn't work for you, you can manually add (one word per line) / remove items to expect.txt and the excludes.txt files.

If the listed items are:

  • ... misspelled, then please correct them instead of using the command.
  • ... names, please add them to .github/actions/spelling/allow/names.txt.
  • ... APIs, you can add them to a file in .github/actions/spelling/allow/.
  • ... just things you're using, please add them to an appropriate file in .github/actions/spelling/expect/.
  • ... tokens you only need in one place and shouldn't generally be used, you can add an item in an appropriate file in .github/actions/spelling/patterns/.

See the README.md in each directory for more information.

:microscope: You can test your commits without appending to a PR by creating a new branch with that extra change and pushing it to your fork. The check-spelling action will run in response to your push -- it doesn't require an open pull request. By using such a branch, you can limit the number of typos your peers see you make. :wink:

If the flagged items are :exploding_head: false positives

If items relate to a ...

  • binary file (or some other file you wouldn't want to check at all).

    Please add a file path to the excludes.txt file matching the containing file.

    File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

    ^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

  • well-formed pattern.

    If you can write a pattern that would match it, try adding it to the patterns.txt file.

    Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

    Note that patterns can't match multiline strings.

github-actions[bot] avatar Mar 03 '23 18:03 github-actions[bot]

sequenceDiagram
    participant OS
    participant WT.exe[1]
    participant WT.exe[2]
    activate WT.exe[1]
    WT.exe[1]->>-OS: Sends toast notification 
    note left of OS: some time later
    OS->>+WT.exe[2]: User clicks notification 
    WT.exe[2]->>-WT.exe[1]: Tell [1] to restore
    activate WT.exe[1]
    note left of WT.exe[1]: restores to bottom<br> of z-order?
    deactivate WT.exe[1]  

zadjii-msft avatar Mar 08 '23 12:03 zadjii-msft

Note to self - pushed a merge of this with main to dev/migrie/fhl/7718-notifications-reboot. Still need to re-plumb the notification actually activating the window, but we're close. I'll merge that into here after I do that.

zadjii-msft avatar Aug 28 '23 13:08 zadjii-msft

@check-spelling-bot Report

:red_circle: Please review

See the :open_file_folder: files view, the :scroll:action log, or :memo: job summary for details.

Unrecognized words (2)

notif Urxvt

Previously acknowledged words that are now absent chcbpat DESTINATIONNAME inputrc kcub kcud kcuf kcuu khome Mbxy QUESTIONMARK reallocs reamapping RTFTo xff 🫥
To accept these unrecognized words as correct and remove the previously acknowledged and now absent words, you could run the following commands

... in a clone of the [email protected]:microsoft/terminal.git repository on the dev/migrie/fhl/7718-notifications branch (:information_source: how do I use this?):

curl -s -S -L 'https://raw.githubusercontent.com/check-spelling/check-spelling/v0.0.22/apply.pl' |
perl - 'https://github.com/microsoft/terminal/actions/runs/7819925556/attempts/1'
Available :books: dictionaries could cover words (expected and unrecognized) not in the :blue_book: dictionary

This includes both expected items (2245) from .github/actions/spelling/expect/04cdb9b77d6827c0202f51acd4205b017015bfff.txt .github/actions/spelling/expect/alphabet.txt .github/actions/spelling/expect/expect.txt .github/actions/spelling/expect/web.txt and unrecognized words (2)

Dictionary Entries Covers Uniquely
cspell:k8s/dict/k8s.txt 153 2 2
cspell:swift/src/swift.txt 53 1 1
cspell:gaming-terms/dict/gaming-terms.txt 59 1 1
cspell:monkeyc/src/monkeyc_keywords.txt 123 1 1
cspell:cryptocurrencies/cryptocurrencies.txt 125 1 1

Consider adding them (in .github/workflows/spelling2.yml) for uses: check-spelling/[email protected] in its with:

      with:
        extra_dictionaries:
          cspell:k8s/dict/k8s.txt
          cspell:swift/src/swift.txt
          cspell:gaming-terms/dict/gaming-terms.txt
          cspell:monkeyc/src/monkeyc_keywords.txt
          cspell:cryptocurrencies/cryptocurrencies.txt

To stop checking additional dictionaries, add (in .github/workflows/spelling2.yml) for uses: check-spelling/[email protected] in its with:

check_extra_dictionaries: ''
Errors (1)

See the :open_file_folder: files view, the :scroll:action log, or :memo: job summary for details.

:x: Errors Count
:x: ignored-expect-variant 3

See :x: Event descriptions for more information.

:pencil2: Contributor please read this

By default the command suggestion will generate a file named based on your commit. That's generally ok as long as you add the file to your commit. Someone can reorganize it later.

If the listed items are:

  • ... misspelled, then please correct them instead of using the command.
  • ... names, please add them to .github/actions/spelling/allow/names.txt.
  • ... APIs, you can add them to a file in .github/actions/spelling/allow/.
  • ... just things you're using, please add them to an appropriate file in .github/actions/spelling/expect/.
  • ... tokens you only need in one place and shouldn't generally be used, you can add an item in an appropriate file in .github/actions/spelling/patterns/.

See the README.md in each directory for more information.

:microscope: You can test your commits without appending to a PR by creating a new branch with that extra change and pushing it to your fork. The check-spelling action will run in response to your push -- it doesn't require an open pull request. By using such a branch, you can limit the number of typos your peers see you make. :wink:

If the flagged items are :exploding_head: false positives

If items relate to a ...

  • binary file (or some other file you wouldn't want to check at all).

    Please add a file path to the excludes.txt file matching the containing file.

    File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

    ^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

  • well-formed pattern.

    If you can write a pattern that would match it, try adding it to the patterns.txt file.

    Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

    Note that patterns can't match multiline strings.

github-actions[bot] avatar Feb 07 '24 19:02 github-actions[bot]

Further notes from 4ab628d62f9958ecd1eb433d51967a316c9b51df:

  • Testing this while debugging will not work. If you have a debugger attached to a process, Windows DNGAF about the FG rules and lets the terminal come to the FG. Without the debugger, this pretty much never works. At least, not on 26051.1000.amd64fre.ge_release_we_adept.240201-1823
  • Test case: sleep 2; write-Output "`e]777..., then minimize, then click another app, then click the notification
    • Terminal gets restored, and activated, but not brought to FG or the top
    • When I ask what the FG window is, it's a "New notification" window from ShellExperienceHost. NOT the Terminal
    • I tried AllowSetForeground(monarch.GetPID()) but that did nothing, and the HR was E_ACCESSDENIED
    • I tried to create a message window in the emperor of the toast wt.exe, but that didn't give us FG

Does this just... not work ever?

zadjii-msft avatar Feb 07 '24 19:02 zadjii-msft

At this point, I'm very tempted to stick this behind velocity and only enable for Dev & Canary builds, while we sort out the foreground issues

zadjii-msft avatar Feb 07 '24 19:02 zadjii-msft

I'm very on the fence about this, even checked in behind velocity.

  • It doesn't work for unpackaged builds (it requires package identity)
  • It's broken if Terminal isn't the foreground application, since it can't activate us
    • Much of the utility of notifications is that they bring you to the thing that notified you
  • It doesn't work on Windows 10 ??
  • It doesn't work when you're elevated?
  • In the limited cases where it actually does work, it allows a text-mode application to spam users with system-wide toasts
    • However, there's no possible "action" response, so they can't gate actual complicated and meaningful features behind notifications (e.g. to perform a thing on click, or to receive a text response)

Frankly, I still don't see the value in offering this support! 😄

DHowett avatar Feb 07 '24 21:02 DHowett

  • lemme look into this more. There's surely got to be other ways of doing this unpackaged, or this would be a good thing to send to our WASDK friends
  • LMAO we have just discovered that this is a platform issue. We'll get that fixed internally. I don't think that's a reason to prevent it from merging.
  • Almost certainly the same as the above
  • I have an i d e a here which I'll be excited to talk about tomorrow
  • Yep. That's... kinda the whole point. I believe semantically, the idea is to be used for after a long-running command completes. I wouldn't be opposed to a per-profile disableNotifications setting or something, for more granular control than just Windows Settings
    • The original spec doesn't support actions, it literally just sends a message. There's no existing spec for "send a notification with buttons", this was just supposed to implement the existing osc777.

fite-me.emoji

zadjii-msft avatar Feb 07 '24 22:02 zadjii-msft