diff --git a/Bloxstrap/App.xaml.cs b/Bloxstrap/App.xaml.cs
index 01253807..17b9d508 100644
--- a/Bloxstrap/App.xaml.cs
+++ b/Bloxstrap/App.xaml.cs
@@ -293,6 +293,9 @@ protected override void OnStartup(StartupEventArgs e)
{
Logger.WriteLine("[App::OnStartup] Bootstrapper task has finished");
+ // notifyicon is blocking main thread, must be disposed here
+ NotifyIcon?.Dispose();
+
if (t.IsFaulted)
Logger.WriteLine("[App::OnStartup] An exception occurred when running the bootstrapper");
diff --git a/Bloxstrap/UI/Elements/NotifyIconMenu.xaml b/Bloxstrap/UI/Elements/NotifyIconMenu.xaml
new file mode 100644
index 00000000..373a2b86
--- /dev/null
+++ b/Bloxstrap/UI/Elements/NotifyIconMenu.xaml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Bloxstrap/UI/Elements/NotifyIconMenu.xaml.cs b/Bloxstrap/UI/Elements/NotifyIconMenu.xaml.cs
new file mode 100644
index 00000000..d8e14d03
--- /dev/null
+++ b/Bloxstrap/UI/Elements/NotifyIconMenu.xaml.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Interop;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+
+using Bloxstrap.UI.ViewModels;
+
+namespace Bloxstrap.UI.Elements
+{
+ ///
+ /// Interaction logic for NotifyIconMenu.xaml
+ ///
+ public partial class NotifyIconMenu
+ {
+ public NotifyIconMenu()
+ {
+ InitializeComponent();
+ }
+
+ private void Window_Loaded(object? sender, RoutedEventArgs e)
+ {
+ // this is an awful hack lmao im so sorry to anyone who reads this
+ // https://stackoverflow.com/questions/357076/best-way-to-hide-a-window-from-the-alt-tab-program-switcher#:~:text=ShowInTaskbar%20%3D%20false%3B%20Owner%20%3D%20form1,form%27s%20ShowInTaskbar%20property%20to%20false.
+ var wndHelper = new WindowInteropHelper(this);
+ long exStyle = NativeMethods.GetWindowLongPtr(wndHelper.Handle, NativeMethods.GWL_EXSTYLE).ToInt64();
+ exStyle |= NativeMethods.WS_EX_TOOLWINDOW;
+ NativeMethods.SetWindowLongPtr(wndHelper.Handle, NativeMethods.GWL_EXSTYLE, (IntPtr)exStyle);
+ }
+
+ // i tried to use a viewmodel but uhhhhhhh it just didnt work idk
+ private void TestMenuItem_Click(object sender, RoutedEventArgs e)
+ {
+ Controls.ShowMessageBox($"hi how u doing i am {TestMenuItem.IsChecked}", MessageBoxImage.Warning);
+ }
+ }
+}
diff --git a/Bloxstrap/UI/NotifyIconWrapper.cs b/Bloxstrap/UI/NotifyIconWrapper.cs
index ceda58e2..14fcbdcc 100644
--- a/Bloxstrap/UI/NotifyIconWrapper.cs
+++ b/Bloxstrap/UI/NotifyIconWrapper.cs
@@ -1,5 +1,7 @@
using System.Windows.Forms;
+using Bloxstrap.UI.Elements;
+
namespace Bloxstrap.UI
{
public class NotifyIconWrapper : IDisposable
@@ -7,9 +9,12 @@ public class NotifyIconWrapper : IDisposable
bool _disposed = false;
private readonly NotifyIcon _notifyIcon;
+ private readonly NotifyIconMenu _contextMenuWrapper = new();
+
EventHandler? _alertClickHandler;
- public NotifyIconWrapper()
+
+ public NotifyIconWrapper()
{
App.Logger.WriteLine("[NotifyIconWrapper::NotifyIconWrapper] Initializing notification area icon");
@@ -19,6 +24,21 @@ public NotifyIconWrapper()
Text = App.ProjectName,
Visible = true
};
+
+ _notifyIcon.MouseClick += MouseClickEventHandler;
+
+ _contextMenuWrapper.Dispatcher.BeginInvoke(_contextMenuWrapper.ShowDialog);
+
+ _contextMenuWrapper.Closing += (_, _) => App.Logger.WriteLine("[NotifyIconWrapper::NotifyIconWrapper] Context menu wrapper closing");
+ }
+
+ public void MouseClickEventHandler(object? sender, MouseEventArgs e)
+ {
+ if (e.Button != MouseButtons.Right)
+ return;
+
+ _contextMenuWrapper.Activate();
+ _contextMenuWrapper.ContextMenu.IsOpen = true;
}
public void ShowAlert(string caption, string message, int duration, EventHandler? clickHandler)
@@ -62,8 +82,11 @@ public void Dispose()
if (_disposed)
return;
+ App.Logger.WriteLine($"[NotifyIconWrapper::Dispose] Disposing NotifyIcon");
+
+ _contextMenuWrapper.Dispatcher.Invoke(_contextMenuWrapper.Close);
_notifyIcon.Dispose();
-
+
_disposed = true;
GC.SuppressFinalize(this);
diff --git a/Bloxstrap/Utility/NativeMethods.cs b/Bloxstrap/Utility/NativeMethods.cs
index 321fbcfd..b869f071 100644
--- a/Bloxstrap/Utility/NativeMethods.cs
+++ b/Bloxstrap/Utility/NativeMethods.cs
@@ -9,5 +9,17 @@ static class NativeMethods
[DllImport("user32.dll")]
public static extern bool FlashWindow(IntPtr hWnd, bool bInvert);
+
+ [DllImport("user32.dll")]
+ public static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex);
+
+ [DllImport("user32.dll")]
+ public static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
+
+ // i only bothered to add the constants that im using lol
+
+ public const int GWL_EXSTYLE = -20;
+
+ public const int WS_EX_TOOLWINDOW = 0x00000080;
}
}