diff --git a/App/App.csproj b/App/App.csproj
index caa2c3b..f7e3c18 100644
--- a/App/App.csproj
+++ b/App/App.csproj
@@ -15,6 +15,12 @@
10.0.22000.0
PerMonitorV2
AnyCPU;x64;ARM64;x86
+ 2.1.1
+ https://github.com/soleon/Percentage
+ https://github.com/soleon/Percentage?tab=MIT-1-ov-file
+ Icon.png
+ https://github.com/soleon/Percentage
+ git
diff --git a/App/App.xaml b/App/App.xaml
index a51e39c..ee4042f 100644
--- a/App/App.xaml
+++ b/App/App.xaml
@@ -2,8 +2,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
- StartupUri="TrayIconWindow.xaml"
- ShutdownMode="OnExplicitShutdown">
+ StartupUri="TrayIconWindow.xaml">
diff --git a/App/App.xaml.cs b/App/App.xaml.cs
index 3e96b72..fc6e209 100644
--- a/App/App.xaml.cs
+++ b/App/App.xaml.cs
@@ -1,8 +1,12 @@
using System;
+using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
+using Microsoft.Toolkit.Uwp.Notifications;
+using Percentage.App.Extensions;
+using Percentage.App.Pages;
using Wpf.Ui;
using Wpf.Ui.Markup;
using static Percentage.App.Properties.Settings;
@@ -42,7 +46,13 @@ public App()
{
_appMutex = new Mutex(true, Id, out var isNewInstance);
- if (!isNewInstance) Shutdown(1);
+ if (!isNewInstance)
+ {
+ Shutdown(1);
+ return;
+ }
+
+ ShutdownMode = ShutdownMode.OnExplicitShutdown;
DispatcherUnhandledException += (_, e) => HandleException(e.Exception);
@@ -54,6 +64,28 @@ public App()
// User settings migration for backward compatibility.
MigrateUserSettings();
+
+ // Subscribe to toast notification activations.
+ ToastNotificationManagerCompat.OnActivated += async toastArgs =>
+ {
+ if (ToastArguments.Parse(toastArgs.Argument).GetActionArgument() ==
+ ToastNotificationExtensions.Action.ViewDetails)
+ await Dispatcher.InvokeAsync(() => ActivateMainWindow().NavigateToPage());
+ };
+ }
+
+ internal static MainWindow ActivateMainWindow()
+ {
+ var window = Current.Windows.OfType().FirstOrDefault();
+ if (window != null)
+ {
+ window.Activate();
+ return window;
+ }
+
+ window = new MainWindow();
+ window.Show();
+ return window;
}
internal static Exception GetTrayIconUpdateError()
diff --git a/App/Extensions/ToastNotificationExtensions.cs b/App/Extensions/ToastNotificationExtensions.cs
new file mode 100644
index 0000000..b572714
--- /dev/null
+++ b/App/Extensions/ToastNotificationExtensions.cs
@@ -0,0 +1,29 @@
+using Microsoft.Toolkit.Uwp.Notifications;
+
+namespace Percentage.App.Extensions;
+
+internal static class ToastNotificationExtensions
+{
+ private const string ActionArgumentKey = "action";
+
+ internal static Action GetActionArgument(this ToastArguments arguments)
+ {
+ return arguments.GetEnum(ActionArgumentKey);
+ }
+
+ internal static void ShowToastNotification(string header, string body)
+ {
+ new ToastContentBuilder()
+ .AddText(header)
+ .AddText(body)
+ .AddButton(new ToastButton().SetContent("See more details")
+ .AddArgument(ActionArgumentKey, Action.ViewDetails))
+ .AddButton(new ToastButtonDismiss())
+ .Show();
+ }
+
+ internal enum Action
+ {
+ ViewDetails = 0
+ }
+}
\ No newline at end of file
diff --git a/App/NotificationType.cs b/App/NotificationType.cs
deleted file mode 100644
index 1e1ce18..0000000
--- a/App/NotificationType.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace Percentage.App;
-
-internal enum NotificationType : byte
-{
- None = 0,
- Critical,
- Low,
- High,
- Full
-}
\ No newline at end of file
diff --git a/App/TrayIconWindow.xaml.cs b/App/TrayIconWindow.xaml.cs
index 5630ecc..8cae1df 100644
--- a/App/TrayIconWindow.xaml.cs
+++ b/App/TrayIconWindow.xaml.cs
@@ -1,6 +1,5 @@
using System;
using System.ComponentModel;
-using System.Linq;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Windows;
@@ -10,8 +9,8 @@
using System.Windows.Media.Imaging;
using System.Windows.Threading;
using Windows.Devices.Power;
-using Microsoft.Toolkit.Uwp.Notifications;
using Microsoft.Win32;
+using Percentage.App.Extensions;
using Percentage.App.Pages;
using Wpf.Ui.Appearance;
using Wpf.Ui.Markup;
@@ -44,20 +43,6 @@ public TrayIconWindow()
_refreshTimer.Tick += (_, _) => _batteryStatusUpdateSubject.OnNext(false);
}
- private static MainWindow ActivateMainWindow()
- {
- var window = Application.Current.Windows.OfType().FirstOrDefault();
- if (window != null)
- {
- window.Activate();
- return window;
- }
-
- window = new MainWindow();
- window.Show();
- return window;
- }
-
private static Brush GetBrushFromColourHexString(string hexString, Brush fallbackBrush)
{
object colour;
@@ -121,12 +106,12 @@ private Brush GetTargetBrush(bool isUsingAutoColour, string targetColour, Brush
private void OnAboutMenuItemClick(object sender, RoutedEventArgs e)
{
- ActivateMainWindow().NavigateToPage();
+ App.ActivateMainWindow().NavigateToPage();
}
private void OnDetailsMenuItemClick(object sender, RoutedEventArgs e)
{
- ActivateMainWindow().NavigateToPage();
+ App.ActivateMainWindow().NavigateToPage();
}
private void OnExitMenuItemClick(object sender, RoutedEventArgs e)
@@ -138,7 +123,7 @@ private void OnLoaded(object sender, RoutedEventArgs args)
{
Visibility = Visibility.Collapsed;
- if (!Default.HideAtStartup) ActivateMainWindow().NavigateToPage();
+ if (!Default.HideAtStartup) App.ActivateMainWindow().NavigateToPage();
// Debounce calls to update battery status.
// This should be the only place that calls the UpdateBatteryStatus method.
@@ -173,12 +158,12 @@ private void OnLoaded(object sender, RoutedEventArgs args)
private void OnNotifyIconLeftDoubleClick(NotifyIcon sender, RoutedEventArgs e)
{
- ActivateMainWindow().NavigateToPage();
+ App.ActivateMainWindow().NavigateToPage();
}
private void OnSettingsMenuItemClick(object sender, RoutedEventArgs e)
{
- ActivateMainWindow().NavigateToPage();
+ App.ActivateMainWindow().NavigateToPage();
}
private void OnUserSettingsPropertyChanged(string propertyName)
@@ -401,21 +386,22 @@ void CheckAndSendNotification()
return;
var utcNow = DateTime.UtcNow;
- if (_lastNotification.Type != notificationType)
- // Notification required, and battery status has changed from last notification, notify user.
- new ToastContentBuilder()
- .AddText(_notificationTitle)
- .AddText(_notificationText)
- .Show();
- else if (utcNow - _lastNotification.DateTime > TimeSpan.FromMinutes(5))
- // Notification required, but battery status is the same as last notification for more than 5 minutes,
- // notify user.
- new ToastContentBuilder()
- .AddText(_notificationTitle)
- .AddText(_notificationText)
- .Show();
+ if (_lastNotification.Type != notificationType ||
+ utcNow - _lastNotification.DateTime > TimeSpan.FromMinutes(5))
+ // Notification is required if the existing notification type is different from the previous one or
+ // battery status is the same, but it has been more than 5 minutes since the last notification was shown.
+ ToastNotificationExtensions.ShowToastNotification(_notificationTitle, _notificationText);
_lastNotification = (notificationType, utcNow);
}
}
+
+ private enum NotificationType : byte
+ {
+ None = 0,
+ Critical,
+ Low,
+ High,
+ Full
+ }
}
\ No newline at end of file
diff --git a/Pack/Package.appxmanifest b/Pack/Package.appxmanifest
index b1eed6c..9471b84 100644
--- a/Pack/Package.appxmanifest
+++ b/Pack/Package.appxmanifest
@@ -4,13 +4,15 @@
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:uap5="http://schemas.microsoft.com/appx/manifest/uap/windows10/5"
+ xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
+ xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
- IgnorableNamespaces="uap rescap">
+ IgnorableNamespaces="uap rescap com desktop">
+ Version="2.1.1.0" />
Battery Percentage Icon
@@ -47,6 +49,20 @@
Enabled="true"
DisplayName="Battery Percentage Icon" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+