question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Bug] Snackbar opens a new app process on Windows

See original GitHub issue

Description

Snackbar opens a new window as shown here when you click the action button on Windows.

Stack Trace

Link to Reproduction Sample

Steps to Reproduce

  1. Place a snackbar inside the default template.
  2. Click on the toast action button
  3. See how a new window appears.

Expected Behavior

Action executes inside the current open app without opening a new app.

Actual Behavior

Action executes and a new app process is opened.

Basic Information

  • Version with issue: prev 8 (MAUI prev 14)
  • Last known good version: unknown
  • IDE: VS

Workaround

None without modifying the snackbar files, since the snackbar registers itself to the Activated event instead of using the solution below:

I just wanted to share a little what I’ve discovered after quite a bit of experimentation. I thought it might be useful for your nuget.

On Windows there’s two kind of activations for UWP apps: foreground and background. The former will use the current app but you need to modify the package.appxmanifext file if you want to use ToastNotificationManagerCompat.OnActivated. You must both modify the appxmanifest as indicated here in order to make this work without opening a new window. The background activation uses background tasks instead but they require the background tasks to be either registered as an In-Process background task or Out-of-Process background task as shown here.

For my use case the background task sounded ideal, but I was unable to make it work with MAUI (at least for the In-Process Background tasks). I kept getting argument out of range exception.

I might try the out-of-process background tasks later.

In any case, one way I found to solve this issue using the foreground activation (the one currently used here), you need to make this change to the package.appxmanifest:

in the Package element this needs to be added:

xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10" 
xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
IgnorableNamespaces="uap rescap com desktop"

Inside of the applications:

<Applications>
    <Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="$targetentrypoint$">
      <uap:VisualElements />
     <Extensions>

        <!-- Specify which CLSID to activate when toast clicked -->
        <desktop:Extension Category="windows.toastNotificationActivation">
          <desktop:ToastNotificationActivation ToastActivatorCLSID="guid-used-in-maui-csproj" /> 
        </desktop:Extension>

        <!--Register COM CLSID LocalServer32 registry key-->
        <com:Extension Category="windows.comServer">
          <com:ComServer>
            <com:ExeServer Executable="filename-used-for-the-exe-usually-the-assembly-name.exe" Arguments="-ToastActivated" DisplayName="Toast activator">
              <com:Class Id="guid-used-in-maui-csproj" DisplayName="Toast activator"/>
            </com:ExeServer>
          </com:ComServer>
        </com:Extension>

      </Extensions>
    </Application>
  </Applications>

Using $targetnametoken$.exe for the executable in com:ExeServer didn’t work. I had to manually enter the assembly name.

Finally I register in the MauiProgram.cs the event:

using Microsoft.Toolkit.Uwp.Notifications;
builder.
... (every other build action)
.ConfigureLifecycleEvents(configure =>
            {
				configure.AddWindows(c =>
				{
					c.OnLaunched((window, args) =>
					{
						ToastNotificationManagerCompat.OnActivated += WindowsNotificationService.OnActivated;
					});
                });
            });

I made this minimal repo that works: https://github.com/emorell96/MauiWithWindowsToasts

I guess to make the snackbar work you could do:

	/// <summary>
	/// Show Snackbar
	/// </summary>
	private partial async Task ShowNative(CancellationToken token)
	{
		await DismissNative(token);
		token.ThrowIfCancellationRequested();
		var toastContentBuilder = new ToastContentBuilder()
			.AddText(Text)
			.AddButton(
				new ToastButton { ActivationType = ToastActivationType.Foreground }.SetContent(ActionButtonText));

		var toastContent = toastContentBuilder.GetToastContent();
		toastContent.ActivationType = ToastActivationType.Background;

		dismissedTCS = new();

		var xmlDocument = new XmlDocument();
		xmlDocument.LoadXml(toastContent.GetContent());

		NativeSnackbar = new ToastNotification(xmlDocument);
		//NativeSnackbar.Activated += OnActivated; //this is not needed anymore
		NativeSnackbar.Dismissed += OnDismissed;
		NativeSnackbar.ExpirationTime = DateTimeOffset.Now.Add(Duration);

		ToastNotificationManager.CreateToastNotifier().Show(nativeSnackbar);

		OnShown();
	}

public static void OnActivated(ToastNotification sender, object args)
	{
		if (NativeSnackbar is not null && Action is not null)
		{
			MainThread.BeginInvokeOnMainThread(Action);
		}
	}

And you would register OnActivated in an extension method that the user would have to register if he wants to use snackbar on windows?

I’d be happy to contribute to it.

Hope it helps.

Reproduction imagery

gif

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:21

github_iconTop GitHub Comments

2reactions
brminnickcommented, Apr 19, 2022

Just a thought for a future feature - maybe we could add an extension to CommunityToolit.Maui.Core that adds the single-instance code for Windows easily into the Toolkit?

protected override void OnLaunched(LaunchActivatedEventArgs args)
{
    CommunityToolkit.Maui.Core.Windows.EnableSingleInstance();
    base.OnLaunched(args);
}
2reactions
VladislavAntonyukcommented, Apr 19, 2022

@emorell96 the docs PR is merged. I am closing the issue.

Read more comments on GitHub >

github_iconTop Results From Across the Web

App is only opening as a background process instead of an ...
1. On your search bar, type command prompt and select "run as administrator" · 2. On the command prompt window, type net user...
Read more >
Snackbar appears towards top of window · Issue #9875
Bug, hopefully not a duplicate. What is the expected behavior? Snackbar appears at bottom of browser window. What is the current behavior?
Read more >
Snackbars
Snackbars inform users of a process that an app has performed or will perform. They appear temporarily, towards the bottom of the screen....
Read more >
How to display a SnackBar in Flutter: A tutorial with examples
Start a new Flutter project; Select Flutter Application and name the project something like “snackbardemo”. NOTE: If you run into the “Null ...
Read more >
How to fix Windows apps won't on open on Windows 10/11
Apps aren't opening in Windows? If you're in Windows 10/11 and you're having problems with apps not opening, consider these fixes and updates....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found