diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
index 2200421..f76bdb5 100644
--- a/.github/workflows/dotnet.yml
+++ b/.github/workflows/dotnet.yml
@@ -21,5 +21,6 @@ jobs:
/target:libs\H_NotifyIcon_Uno_WinUI
/target:libs\H_NotifyIcon_WinUI
/target:libs\H_NotifyIcon_Wpf
+ /target:libs\H_NotifyIcon_Maui
secrets:
nuget-key: ${{ secrets.NUGET_KEY }}
diff --git a/H.NotifyIcon.sln b/H.NotifyIcon.sln
index 194200d..e171c55 100644
--- a/H.NotifyIcon.sln
+++ b/H.NotifyIcon.sln
@@ -61,6 +61,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "H.GeneratedIcons.System.Dra
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "H.GeneratedIcons.SkiaSharp", "src\libs\H.GeneratedIcons.SkiaSharp\H.GeneratedIcons.SkiaSharp.csproj", "{EECF393D-0F55-4BFE-AEA8-7FD90383C05D}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "H.NotifyIcon.Maui", "src\libs\H.NotifyIcon.Maui\H.NotifyIcon.Maui.csproj", "{84E993AA-5343-4502-9612-B9A416AF243F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "H.NotifyIcon.Apps.Maui", "src\apps\H.NotifyIcon.Apps.Maui\H.NotifyIcon.Apps.Maui.csproj", "{6C5EA367-5663-420E-B10C-8E5543EBF8DD}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -329,6 +333,38 @@ Global
{EECF393D-0F55-4BFE-AEA8-7FD90383C05D}.Release|x64.Build.0 = Release|Any CPU
{EECF393D-0F55-4BFE-AEA8-7FD90383C05D}.Release|x86.ActiveCfg = Release|Any CPU
{EECF393D-0F55-4BFE-AEA8-7FD90383C05D}.Release|x86.Build.0 = Release|Any CPU
+ {84E993AA-5343-4502-9612-B9A416AF243F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {84E993AA-5343-4502-9612-B9A416AF243F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {84E993AA-5343-4502-9612-B9A416AF243F}.Debug|arm64.ActiveCfg = Debug|Any CPU
+ {84E993AA-5343-4502-9612-B9A416AF243F}.Debug|arm64.Build.0 = Debug|Any CPU
+ {84E993AA-5343-4502-9612-B9A416AF243F}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {84E993AA-5343-4502-9612-B9A416AF243F}.Debug|x64.Build.0 = Debug|Any CPU
+ {84E993AA-5343-4502-9612-B9A416AF243F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {84E993AA-5343-4502-9612-B9A416AF243F}.Debug|x86.Build.0 = Debug|Any CPU
+ {84E993AA-5343-4502-9612-B9A416AF243F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {84E993AA-5343-4502-9612-B9A416AF243F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {84E993AA-5343-4502-9612-B9A416AF243F}.Release|arm64.ActiveCfg = Release|Any CPU
+ {84E993AA-5343-4502-9612-B9A416AF243F}.Release|arm64.Build.0 = Release|Any CPU
+ {84E993AA-5343-4502-9612-B9A416AF243F}.Release|x64.ActiveCfg = Release|Any CPU
+ {84E993AA-5343-4502-9612-B9A416AF243F}.Release|x64.Build.0 = Release|Any CPU
+ {84E993AA-5343-4502-9612-B9A416AF243F}.Release|x86.ActiveCfg = Release|Any CPU
+ {84E993AA-5343-4502-9612-B9A416AF243F}.Release|x86.Build.0 = Release|Any CPU
+ {6C5EA367-5663-420E-B10C-8E5543EBF8DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6C5EA367-5663-420E-B10C-8E5543EBF8DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6C5EA367-5663-420E-B10C-8E5543EBF8DD}.Debug|arm64.ActiveCfg = Debug|Any CPU
+ {6C5EA367-5663-420E-B10C-8E5543EBF8DD}.Debug|arm64.Build.0 = Debug|Any CPU
+ {6C5EA367-5663-420E-B10C-8E5543EBF8DD}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {6C5EA367-5663-420E-B10C-8E5543EBF8DD}.Debug|x64.Build.0 = Debug|Any CPU
+ {6C5EA367-5663-420E-B10C-8E5543EBF8DD}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {6C5EA367-5663-420E-B10C-8E5543EBF8DD}.Debug|x86.Build.0 = Debug|Any CPU
+ {6C5EA367-5663-420E-B10C-8E5543EBF8DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6C5EA367-5663-420E-B10C-8E5543EBF8DD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6C5EA367-5663-420E-B10C-8E5543EBF8DD}.Release|arm64.ActiveCfg = Release|Any CPU
+ {6C5EA367-5663-420E-B10C-8E5543EBF8DD}.Release|arm64.Build.0 = Release|Any CPU
+ {6C5EA367-5663-420E-B10C-8E5543EBF8DD}.Release|x64.ActiveCfg = Release|Any CPU
+ {6C5EA367-5663-420E-B10C-8E5543EBF8DD}.Release|x64.Build.0 = Release|Any CPU
+ {6C5EA367-5663-420E-B10C-8E5543EBF8DD}.Release|x86.ActiveCfg = Release|Any CPU
+ {6C5EA367-5663-420E-B10C-8E5543EBF8DD}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -350,6 +386,8 @@ Global
{A04E983D-5631-4C68-B34A-796970E060C0} = {52FA15AF-CAE7-4822-9975-F5E812EDEF33}
{A4A97F4E-71C1-42FA-84DC-7D4A41079A13} = {FCF55611-6E25-4F1E-8E88-705896171E71}
{EECF393D-0F55-4BFE-AEA8-7FD90383C05D} = {FCF55611-6E25-4F1E-8E88-705896171E71}
+ {84E993AA-5343-4502-9612-B9A416AF243F} = {FCF55611-6E25-4F1E-8E88-705896171E71}
+ {6C5EA367-5663-420E-B10C-8E5543EBF8DD} = {52FA15AF-CAE7-4822-9975-F5E812EDEF33}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C139BD97-A4F7-411B-99B1-824CE1ABA403}
diff --git a/src/apps/H.NotifyIcon.Apps.Maui/H.NotifyIcon.Apps.Maui.csproj b/src/apps/H.NotifyIcon.Apps.Maui/H.NotifyIcon.Apps.Maui.csproj
index bdc8484..70b5fee 100644
--- a/src/apps/H.NotifyIcon.Apps.Maui/H.NotifyIcon.Apps.Maui.csproj
+++ b/src/apps/H.NotifyIcon.Apps.Maui/H.NotifyIcon.Apps.Maui.csproj
@@ -10,6 +10,7 @@
true
true
enable
+ $(NoWarn);MT0182
H.NotifyIcon.Apps.Maui
@@ -30,6 +31,13 @@
6.5
+
+
+
+
+
+
+
@@ -54,6 +62,7 @@
+
diff --git a/src/apps/H.NotifyIcon.Apps.Maui/MainPage.xaml b/src/apps/H.NotifyIcon.Apps.Maui/MainPage.xaml
index 4f9c270..d90f043 100644
--- a/src/apps/H.NotifyIcon.Apps.Maui/MainPage.xaml
+++ b/src/apps/H.NotifyIcon.Apps.Maui/MainPage.xaml
@@ -1,13 +1,19 @@
-
-
-
+
+
+
+
+
+
diff --git a/src/apps/H.NotifyIcon.Apps.Maui/MainPage.xaml.cs b/src/apps/H.NotifyIcon.Apps.Maui/MainPage.xaml.cs
index d3b1867..66bcdc7 100644
--- a/src/apps/H.NotifyIcon.Apps.Maui/MainPage.xaml.cs
+++ b/src/apps/H.NotifyIcon.Apps.Maui/MainPage.xaml.cs
@@ -1,7 +1,4 @@
-using SkiaSharp;
-using SkiaSharp.Views.Maui;
-
-namespace H.NotifyIcon.Apps.Maui;
+namespace H.NotifyIcon.Apps.Maui;
public partial class MainPage
{
@@ -9,41 +6,41 @@ public MainPage()
{
InitializeComponent();
- CanvasView.PaintSurface += CanvasViewOnPaintSurface;
+ //CanvasView.PaintSurface += CanvasViewOnPaintSurface;
}
-
- private static void CanvasViewOnPaintSurface(object? sender, SKPaintSurfaceEventArgs args)
- {
- SKImageInfo info = args.Info;
- SKSurface surface = args.Surface;
- SKCanvas canvas = surface.Canvas;
-
- canvas.Clear();
-
- using var backgroundBrush = new SKPaint();
- backgroundBrush.Style = SKPaintStyle.Stroke;
- backgroundBrush.Color = SKColors.Black;
- backgroundBrush.StrokeWidth = 24;
- backgroundBrush.StrokeCap = SKStrokeCap.Round;
-
- using var foregroundBrush = new SKPaint();
- foregroundBrush.Style = SKPaintStyle.Stroke;
- foregroundBrush.Color = SKColors.White;
- foregroundBrush.StrokeWidth = 1;
- foregroundBrush.StrokeCap = SKStrokeCap.Round;
- foregroundBrush.TextSize = 48;
-
- canvas.DrawBitmap(SkiaSharpIconGenerator.Generate(
- backgroundBrush: backgroundBrush,
- foregroundBrush: foregroundBrush,
- text: "H",
- font: new SKFont(SKTypeface.Default, size: 48F),
- pen: new SKPaint
- {
- Style = SKPaintStyle.Stroke,
- StrokeWidth = 5,
- Color = SKColors.Aqua,
- }), info.Rect);
- }
+ //
+ // private static void CanvasViewOnPaintSurface(object? sender, SKPaintSurfaceEventArgs args)
+ // {
+ // SKImageInfo info = args.Info;
+ // SKSurface surface = args.Surface;
+ // SKCanvas canvas = surface.Canvas;
+ //
+ // canvas.Clear();
+ //
+ // using var backgroundBrush = new SKPaint();
+ // backgroundBrush.Style = SKPaintStyle.Stroke;
+ // backgroundBrush.Color = SKColors.Black;
+ // backgroundBrush.StrokeWidth = 24;
+ // backgroundBrush.StrokeCap = SKStrokeCap.Round;
+ //
+ // using var foregroundBrush = new SKPaint();
+ // foregroundBrush.Style = SKPaintStyle.Stroke;
+ // foregroundBrush.Color = SKColors.White;
+ // foregroundBrush.StrokeWidth = 1;
+ // foregroundBrush.StrokeCap = SKStrokeCap.Round;
+ // foregroundBrush.TextSize = 48;
+ //
+ // canvas.DrawBitmap(SkiaSharpIconGenerator.Generate(
+ // backgroundBrush: backgroundBrush,
+ // foregroundBrush: foregroundBrush,
+ // text: "H",
+ // font: new SKFont(SKTypeface.Default, size: 48F),
+ // pen: new SKPaint
+ // {
+ // Style = SKPaintStyle.Stroke,
+ // StrokeWidth = 5,
+ // Color = SKColors.Aqua,
+ // }), info.Rect);
+ // }
}
diff --git a/src/apps/H.NotifyIcon.Apps.Maui/MauiProgram.cs b/src/apps/H.NotifyIcon.Apps.Maui/MauiProgram.cs
index c106787..f752e11 100644
--- a/src/apps/H.NotifyIcon.Apps.Maui/MauiProgram.cs
+++ b/src/apps/H.NotifyIcon.Apps.Maui/MauiProgram.cs
@@ -11,6 +11,7 @@ public static MauiApp CreateMauiApp()
builder
.UseMauiApp()
.UseSkiaSharp()
+ .UseNotifyIcon()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
diff --git a/src/apps/H.NotifyIcon.Apps.Maui/Platforms/MacCatalyst/Program.cs b/src/apps/H.NotifyIcon.Apps.Maui/Platforms/MacCatalyst/Program.cs
index affb33b..25f0831 100644
--- a/src/apps/H.NotifyIcon.Apps.Maui/Platforms/MacCatalyst/Program.cs
+++ b/src/apps/H.NotifyIcon.Apps.Maui/Platforms/MacCatalyst/Program.cs
@@ -1,15 +1,11 @@
-using ObjCRuntime;
+using H.NotifyIcon.Apps.Maui;
using UIKit;
-namespace H.NotifyIcon.Apps.Maui;
-
-public class Program
+#if DEBUG
+if (System.Diagnostics.Debugger.IsAttached)
{
- // This is the main entry point of the application.
- static void Main(string[] args)
- {
- // if you want to use a different Application Delegate class from "AppDelegate"
- // you can specify it here.
- UIApplication.Main(args, null, typeof(AppDelegate));
- }
+ Thread.Sleep(TimeSpan.FromSeconds(5));
}
+#endif
+
+UIApplication.Main(args, null, typeof(AppDelegate));
diff --git a/src/apps/H.NotifyIcon.Apps.Maui/Platforms/iOS/Program.cs b/src/apps/H.NotifyIcon.Apps.Maui/Platforms/iOS/Program.cs
index affb33b..25f0831 100644
--- a/src/apps/H.NotifyIcon.Apps.Maui/Platforms/iOS/Program.cs
+++ b/src/apps/H.NotifyIcon.Apps.Maui/Platforms/iOS/Program.cs
@@ -1,15 +1,11 @@
-using ObjCRuntime;
+using H.NotifyIcon.Apps.Maui;
using UIKit;
-namespace H.NotifyIcon.Apps.Maui;
-
-public class Program
+#if DEBUG
+if (System.Diagnostics.Debugger.IsAttached)
{
- // This is the main entry point of the application.
- static void Main(string[] args)
- {
- // if you want to use a different Application Delegate class from "AppDelegate"
- // you can specify it here.
- UIApplication.Main(args, null, typeof(AppDelegate));
- }
+ Thread.Sleep(TimeSpan.FromSeconds(5));
}
+#endif
+
+UIApplication.Main(args, null, typeof(AppDelegate));
diff --git a/src/apps/H.NotifyIcon.Apps.Maui/Resources/Images/red.ico b/src/apps/H.NotifyIcon.Apps.Maui/Resources/Images/red.ico
new file mode 100644
index 0000000..8a8bbaf
Binary files /dev/null and b/src/apps/H.NotifyIcon.Apps.Maui/Resources/Images/red.ico differ
diff --git a/src/libs/Directory.Build.targets b/src/libs/Directory.Build.targets
index 85a9414..3df63b6 100644
--- a/src/libs/Directory.Build.targets
+++ b/src/libs/Directory.Build.targets
@@ -30,5 +30,9 @@
+
+
+
+
diff --git a/src/libs/H.NotifyIcon.Maui/H.NotifyIcon.Maui.csproj b/src/libs/H.NotifyIcon.Maui/H.NotifyIcon.Maui.csproj
new file mode 100644
index 0000000..6d4949b
--- /dev/null
+++ b/src/libs/H.NotifyIcon.Maui/H.NotifyIcon.Maui.csproj
@@ -0,0 +1,48 @@
+
+
+
+ net7.0;net7.0-windows10.0.19041.0
+ true
+ $(DefineConstants);HAS_PLATFORM_CODE;HAS_MAUI
+ $(NoWarn);CA1031;CS8002;CS0108;CA1501
+ true
+
+
+
+ This is an implementation of a NotifyIcon (aka system tray icon or taskbar icon) for the MAUI platform.
+It does not just rely on the Windows Forms NotifyIcon component,
+but is a purely independent control which leverages several features of the WinUI framework in order to display rich tooltips,
+popups, context menus, and balloon messages. It can be used directly in code or embedded in any XAML file.
+
+ notifyicon;maui;tray
+
+
+
+
+ <_Parameter1>https://notifyicon.com/
+ <_Parameter2>tb
+
+
+ <_Parameter1>https://notifyicon.com/
+ <_Parameter2>H.NotifyIcon
+
+
+
+
+
+ all
+ compile; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ compile; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/libs/H.NotifyIcon.Maui/MauiAppBuilderExtensions.cs b/src/libs/H.NotifyIcon.Maui/MauiAppBuilderExtensions.cs
new file mode 100644
index 0000000..925a06a
--- /dev/null
+++ b/src/libs/H.NotifyIcon.Maui/MauiAppBuilderExtensions.cs
@@ -0,0 +1,18 @@
+namespace H.NotifyIcon;
+
+///
+///
+///
+[CLSCompliant(false)]
+public static class MauiAppBuilderExtensions
+{
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static MauiAppBuilder UseNotifyIcon(this MauiAppBuilder builder)
+ {
+ return builder;
+ }
+}
diff --git a/src/libs/H.NotifyIcon.Shared/GlobalUsings.cs b/src/libs/H.NotifyIcon.Shared/GlobalUsings.cs
index ccf9d2f..d2648eb 100644
--- a/src/libs/H.NotifyIcon.Shared/GlobalUsings.cs
+++ b/src/libs/H.NotifyIcon.Shared/GlobalUsings.cs
@@ -4,6 +4,7 @@
global using DependencyPropertyGenerator;
global using EventGenerator;
global using H.NotifyIcon.Core;
+global using System.Runtime.Versioning;
#if HAS_AVALONIA
global using Avalonia;
global using Avalonia.Data;
@@ -42,7 +43,7 @@
#if HAS_UNO
global using WindowActivationState = Windows.UI.Core.CoreWindowActivationState;
#endif
-#else
+#elif HAS_UNO
global using Windows.UI.Core;
global using Windows.System;
global using Windows.UI;
@@ -57,6 +58,18 @@
global using Windows.Storage;
global using Windows.Foundation;
global using FontStyles = Windows.UI.Text.FontStyle;
+#else
+global using System.Windows.Input;
+global using Microsoft.Maui;
+global using Microsoft.Maui.Controls;
+global using Microsoft.Maui.Media;
+global using Microsoft.Maui.Graphics;
+global using Microsoft.Maui.Primitives;
+global using FontStyle = Microsoft.Maui.Controls.FontAttributes;
+global using FontStyles = Microsoft.Maui.Controls.FontAttributes;
+global using FontWeights = Microsoft.Maui.FontWeight;
+global using FontFamily = System.String;
+global using FrameworkElement = Microsoft.Maui.Controls.TemplatedView;
#endif
#if HAS_SYSTEM_DRAWING
global using Icon = System.Drawing.Icon;
diff --git a/src/libs/H.NotifyIcon.Shared/TaskbarIcon.IconSource.cs b/src/libs/H.NotifyIcon.Shared/TaskbarIcon.IconSource.cs
index 9d015a2..049c9cc 100644
--- a/src/libs/H.NotifyIcon.Shared/TaskbarIcon.IconSource.cs
+++ b/src/libs/H.NotifyIcon.Shared/TaskbarIcon.IconSource.cs
@@ -4,6 +4,7 @@
Description = "Resolves an image source and updates the Icon property accordingly.", Category = CategoryName)]
public partial class TaskbarIcon
{
+ [SupportedOSPlatform("windows5.0")]
async partial void OnIconSourceChanged(ImageSource? oldValue, ImageSource? newValue)
{
if (newValue == null)
diff --git a/src/libs/H.NotifyIcon.Shared/TaskbarIcon.KeyboardEvents.cs b/src/libs/H.NotifyIcon.Shared/TaskbarIcon.KeyboardEvents.cs
index 16a3c5f..50d03ae 100644
--- a/src/libs/H.NotifyIcon.Shared/TaskbarIcon.KeyboardEvents.cs
+++ b/src/libs/H.NotifyIcon.Shared/TaskbarIcon.KeyboardEvents.cs
@@ -10,6 +10,7 @@ public partial class TaskbarIcon
{
#region Event handlers
+#if !HAS_MAUI
///
/// Processes keyboard events, which are bubbled
/// through the class' routed events, trigger
@@ -45,6 +46,7 @@ private void OnKeyboardEvent(object? sender, MessageWindow.KeyboardEventReceived
$"Missing handler for keyboard event flag: {args.KeyboardEvent}");
}
}
-
+#endif
+
#endregion
}
diff --git a/src/libs/H.NotifyIcon.Shared/TaskbarIcon.MouseEvents.cs b/src/libs/H.NotifyIcon.Shared/TaskbarIcon.MouseEvents.cs
index cd3038c..62fa0be 100644
--- a/src/libs/H.NotifyIcon.Shared/TaskbarIcon.MouseEvents.cs
+++ b/src/libs/H.NotifyIcon.Shared/TaskbarIcon.MouseEvents.cs
@@ -41,12 +41,14 @@ public partial class TaskbarIcon
///
/// The time we should wait for a double click.
///
+ [SupportedOSPlatform("windows5.0")]
private int DoubleClickWaitTime => NoLeftClickDelay ? 0 : CursorUtilities.GetDoubleClickTime();
#endregion
#region Event handlers
+#if !HAS_MAUI
///
/// Processes mouse events, which are bubbled
/// through the class' routed events, trigger
@@ -198,7 +200,8 @@ private void OnMouseEvent(object? sender, MessageWindow.MouseEventReceivedEventA
SingleClickTimer.Change(DoubleClickWaitTime, Timeout.Infinite);
}
}
-
+#endif
+
///
/// Performs a delayed action if the user requested an action
/// based on a single click of the left mouse.
@@ -223,6 +226,8 @@ private void DoSingleClickAction(object? state)
this.GetDispatcher().Invoke(action);
#elif HAS_UNO && (!HAS_WINUI && !HAS_UNO_WINUI)
_ = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => action());
+#elif HAS_MAUI
+ MainThread.BeginInvokeOnMainThread(action);
#else
DispatcherQueue.TryEnqueue(() => action());
#endif
diff --git a/src/libs/H.NotifyIcon.Shared/TaskbarIcon.Notifications.cs b/src/libs/H.NotifyIcon.Shared/TaskbarIcon.Notifications.cs
index c79fe6e..06cfc3a 100644
--- a/src/libs/H.NotifyIcon.Shared/TaskbarIcon.Notifications.cs
+++ b/src/libs/H.NotifyIcon.Shared/TaskbarIcon.Notifications.cs
@@ -56,6 +56,7 @@ public partial class TaskbarIcon
#if !HAS_WPF
[CLSCompliant(false)]
#endif
+ [SupportedOSPlatform("windows5.1.2600")]
public void ShowNotification(
string title,
string message,
@@ -88,6 +89,7 @@ public void ShowNotification(
/// but I haven't been able to get it to work.
///
///
+ [SupportedOSPlatform("windows5.1.2600")]
public void ClearNotifications()
{
EnsureNotDisposed();
@@ -99,6 +101,7 @@ public void ClearNotifications()
#region Event handlers
+#if !HAS_MAUI
///
/// Bubbles events if a balloon ToolTip was displayed
/// or removed.
@@ -117,6 +120,7 @@ private void OnBalloonToolTipChanged(object? sender, MessageWindow.BalloonToolTi
_ = OnTrayBalloonTipClosed();
}
}
+#endif
#endregion
}
diff --git a/src/libs/H.NotifyIcon.Shared/TaskbarIcon.Popups.cs b/src/libs/H.NotifyIcon.Shared/TaskbarIcon.Popups.cs
index cc2fe2a..293265a 100644
--- a/src/libs/H.NotifyIcon.Shared/TaskbarIcon.Popups.cs
+++ b/src/libs/H.NotifyIcon.Shared/TaskbarIcon.Popups.cs
@@ -1,5 +1,6 @@
namespace H.NotifyIcon;
+#if !HAS_MAUI
[DependencyProperty("PopupActivation", DefaultValue = PopupActivationMode.LeftClick,
Description = "Defines what mouse events display the TaskbarIconPopup.", Category = CategoryName, ClsCompliant = false)]
[DependencyProperty("TrayPopup",
@@ -236,3 +237,4 @@ private void PlacePopup(System.Drawing.Point cursorPosition)
#endregion
}
+#endif
diff --git a/src/libs/H.NotifyIcon.Shared/TaskbarIcon.Properties.cs b/src/libs/H.NotifyIcon.Shared/TaskbarIcon.Properties.cs
index 905b047..1380b51 100644
--- a/src/libs/H.NotifyIcon.Shared/TaskbarIcon.Properties.cs
+++ b/src/libs/H.NotifyIcon.Shared/TaskbarIcon.Properties.cs
@@ -22,11 +22,13 @@ public partial class TaskbarIcon
#region Id
#if !MACOS
+ [SupportedOSPlatform("windows5.1.2600")]
partial void OnIdChanged(Guid newValue)
{
TrayIcon.UpdateId(newValue);
}
+ [SupportedOSPlatform("windows5.1.2600")]
partial void OnCustomNameChanged(string? newValue)
{
TrayIcon.UpdateName(newValue ?? string.Empty);
@@ -37,6 +39,7 @@ partial void OnCustomNameChanged(string? newValue)
#region Icon/IconSource
+ [SupportedOSPlatform("windows5.1.2600")]
partial void OnIconChanged(Icon? oldValue, Icon? newValue)
{
oldValue?.Dispose();
@@ -48,6 +51,7 @@ partial void OnIconChanged(Icon? oldValue, Icon? newValue)
///
///
[CLSCompliant(false)]
+ [SupportedOSPlatform("windows5.1.2600")]
public void UpdateIcon(Icon? value)
{
#if !MACOS
@@ -57,8 +61,11 @@ public void UpdateIcon(Icon? value)
#endregion
+#if !HAS_MAUI
+
#region Visibility
+ [SupportedOSPlatform("windows5.1.2600")]
partial void OnVisibilityChanged(Visibility newValue)
{
var state = newValue == Visibility.Visible
@@ -114,4 +121,6 @@ partial void OnDataContextChanged(object? newValue)
}
#endregion
+
+#endif
}
diff --git a/src/libs/H.NotifyIcon.Shared/TaskbarIcon.ToolTips.cs b/src/libs/H.NotifyIcon.Shared/TaskbarIcon.ToolTips.cs
index 67c0b90..ce52677 100644
--- a/src/libs/H.NotifyIcon.Shared/TaskbarIcon.ToolTips.cs
+++ b/src/libs/H.NotifyIcon.Shared/TaskbarIcon.ToolTips.cs
@@ -1,5 +1,6 @@
namespace H.NotifyIcon;
+#if !HAS_MAUI
[DependencyProperty("ToolTipText", DefaultValue = "",
Description = "A tooltip text that is being displayed if no custom ToolTip was set or if custom tooltips are not supported.", Category = CategoryName)]
[DependencyProperty("TrayToolTip",
@@ -278,3 +279,4 @@ private void OnToolTipChange(object? sender, MessageWindow.ChangeToolTipStateReq
#endregion
}
+#endif
diff --git a/src/libs/H.NotifyIcon.Shared/TaskbarIcon.cs b/src/libs/H.NotifyIcon.Shared/TaskbarIcon.cs
index 9667385..7d74808 100644
--- a/src/libs/H.NotifyIcon.Shared/TaskbarIcon.cs
+++ b/src/libs/H.NotifyIcon.Shared/TaskbarIcon.cs
@@ -13,16 +13,14 @@ namespace H.NotifyIcon;
#else
[OverrideMetadata("ContextFlyout")]
#endif
-#if HAS_WINUI || HAS_UNO
+#if HAS_WINUI || HAS_UNO || HAS_MAUI
[CLSCompliant(false)]
#endif
-#if NET5_0_OR_GREATER
#if MACOS || MACCATALYST
[Advice("Starting with macos10.10 Soft-deprecation, forwards message to button, but will be gone in the future.")]
-[System.Runtime.Versioning.UnsupportedOSPlatform("macos10.10")]
-[System.Runtime.Versioning.UnsupportedOSPlatform("maccatalyst")]
-[System.Runtime.Versioning.SupportedOSPlatform("macos")]
-#endif
+[UnsupportedOSPlatform("macos10.10")]
+[UnsupportedOSPlatform("maccatalyst")]
+[SupportedOSPlatform("macos")]
#endif
public partial class TaskbarIcon : FrameworkElement, IDisposable
{
@@ -36,6 +34,7 @@ public partial class TaskbarIcon : FrameworkElement, IDisposable
///
/// Indicates whether the taskbar icon has been created or not.
///
+ [SupportedOSPlatform("windows5.1.2600")]
public bool IsCreated => TrayIcon.IsCreated;
#endregion
@@ -46,9 +45,10 @@ public partial class TaskbarIcon : FrameworkElement, IDisposable
/// Initializes the taskbar icon and registers a message listener
/// in order to receive events from the taskbar area.
///
+ [SupportedOSPlatform("windows5.1.2600")]
public TaskbarIcon()
{
-#if !HAS_WPF
+#if !HAS_WPF && !HAS_MAUI
RegisterPropertyChangedCallbacks();
#endif
@@ -64,7 +64,7 @@ public TaskbarIcon()
Debugger.Break();
}
};
-#if !MACOS
+#if !MACOS && !HAS_MAUI
// https://github.com/HavenDV/H.NotifyIcon/issues/34
//Unloaded += (_, _) => Dispose();
TrayIcon.MessageWindow.DpiChanged += static (_, _) => DpiUtilities.UpdateDpiFactors();
@@ -101,6 +101,7 @@ public TaskbarIcon()
/// Recreates the taskbar icon if the whole taskbar was
/// recreated (e.g. because Explorer was shut down).
///
+ [SupportedOSPlatform("windows5.1.2600")]
private void OnTaskbarCreated(object? sender, EventArgs args)
{
try
@@ -122,6 +123,7 @@ private void OnTaskbarCreated(object? sender, EventArgs args)
/// Use it to force create icon if it placed in resources.
/// This also turns on Efficiency Mode by default, meaning you run the app in a hidden state.
///
+ [SupportedOSPlatform("windows5.1.2600")]
public void ForceCreate(bool enablesEfficiencyMode = true)
{
TrayIcon.Create();
@@ -160,7 +162,11 @@ private void EnsureNotDisposed()
{
if (IsDisposed)
{
- throw new ObjectDisposedException(Name ?? GetType().FullName);
+#if HAS_MAUI
+ throw new ObjectDisposedException(GetType().FullName);
+#else
+ throw new ObjectDisposedException(Name ?? nameof(TaskbarIcon));
+#endif
}
}
@@ -168,6 +174,7 @@ private void EnsureNotDisposed()
///
/// Disposes the class if the application exits.
///
+ [SupportedOSPlatform("windows5.1.2600")]
private void OnExit(object sender, EventArgs e)
{
Dispose();
@@ -182,6 +189,7 @@ private void OnExit(object sender, EventArgs e)
/// Important: Do not provide destructor in types derived from this class.
///
///
+ [SupportedOSPlatform("windows5.1.2600")]
~TaskbarIcon()
{
Dispose(false);
@@ -194,6 +202,7 @@ private void OnExit(object sender, EventArgs e)
/// This method is not virtual by design. Derived classes
/// should override .
///
+ [SupportedOSPlatform("windows5.1.2600")]
#if HAS_UNO
public new void Dispose()
#else
@@ -226,6 +235,7 @@ public void Dispose()
/// be disposed.
/// Check the property to determine whether
/// the method has already been called.
+ [SupportedOSPlatform("windows5.1.2600")]
protected virtual void Dispose(bool disposing)
{
if (IsDisposed || !disposing)
@@ -251,7 +261,7 @@ protected virtual void Dispose(bool disposing)
balloonCloseTimer.Dispose();
#endif
-#if !HAS_WPF && !HAS_UNO
+#if !HAS_WPF && !HAS_UNO && !HAS_MAUI
ContextMenuWindow?.Close();
ContextMenuWindow = null;
ContextMenuWindowHandle = null;
diff --git a/src/libs/H.NotifyIcon.Shared/Utilities/ImageExtensions.Maui.cs b/src/libs/H.NotifyIcon.Shared/Utilities/ImageExtensions.Maui.cs
new file mode 100644
index 0000000..5564958
--- /dev/null
+++ b/src/libs/H.NotifyIcon.Shared/Utilities/ImageExtensions.Maui.cs
@@ -0,0 +1,32 @@
+namespace H.NotifyIcon;
+
+internal static partial class ImageExtensions
+{
+ public static Stream ToStream(this ImageSource imageSource)
+ {
+ switch (imageSource)
+ {
+ case FileImageSource bitmapImage:
+ {
+ return File.OpenRead(bitmapImage.File);
+ }
+
+ default:
+ throw new NotImplementedException($"ImageSource type: {imageSource.GetType()} is not supported");
+ }
+ }
+
+ public static Task ToStreamAsync(this ImageSource imageSource, CancellationToken cancellationToken = default)
+ {
+ switch(imageSource)
+ {
+ case FileImageSource bitmapImage:
+ {
+ return Task.FromResult(File.OpenRead(bitmapImage.File));
+ }
+
+ default:
+ return Task.FromException(new NotImplementedException($"ImageSource type: {imageSource.GetType()} is not supported"));
+ }
+ }
+}
diff --git a/src/libs/H.NotifyIcon.Shared/Utilities/System.Drawing/StreamExtensions.cs b/src/libs/H.NotifyIcon.Shared/Utilities/System.Drawing/StreamExtensions.cs
index de64b7c..e9fca1f 100644
--- a/src/libs/H.NotifyIcon.Shared/Utilities/System.Drawing/StreamExtensions.cs
+++ b/src/libs/H.NotifyIcon.Shared/Utilities/System.Drawing/StreamExtensions.cs
@@ -4,7 +4,7 @@ namespace H.NotifyIcon;
internal static class StreamExtensions
{
- [SupportedOSPlatform("windows")]
+ [SupportedOSPlatform("windows5.0")]
internal static Icon ToSmallIcon(this Stream stream)
{
var iconSize = IconUtilities.GetRequiredCustomIconSize(largeIcon: false).ScaleWithDpi();
diff --git a/src/libs/H.NotifyIcon.Shared/WindowExtensions.cs b/src/libs/H.NotifyIcon.Shared/WindowExtensions.cs
index 2cc5e02..93567b0 100644
--- a/src/libs/H.NotifyIcon.Shared/WindowExtensions.cs
+++ b/src/libs/H.NotifyIcon.Shared/WindowExtensions.cs
@@ -20,7 +20,7 @@ public static void Hide(
#if HAS_WPF
window.Hide();
-#elif !HAS_UNO
+#elif !HAS_UNO && !HAS_MAUI
WindowUtilities.HideWindow(WindowNative.GetWindowHandle(window));
#endif
@@ -49,7 +49,7 @@ public static void Show(
#if HAS_WPF
window.Show();
-#elif !HAS_UNO
+#elif !HAS_UNO && !HAS_MAUI
WindowUtilities.ShowWindow(WindowNative.GetWindowHandle(window));
#endif