Skip to content

Commit 2150042

Browse files
authored
Merge pull request #758 from Sidekick-Poe/feature/revert-icon
Reverted previous changes to the tray icon
2 parents 4bf1951 + 9df964d commit 2150042

File tree

5 files changed

+80
-79
lines changed

5 files changed

+80
-79
lines changed

Directory.Packages.props

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1515
</PackageVersion>
1616
<PackageVersion Include="FuzzySharp" Version="2.0.2" />
17+
<PackageVersion Include="Hardcodet.NotifyIcon.Wpf" Version="2.0.1" />
1718
<PackageVersion Include="Microsoft.AspNetCore.Components.Web" Version="8.0.19" />
1819
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.19" />
1920
<PackageVersion Include="Microsoft.AspNetCore.Components.WebView.Wpf" Version="8.0.100" />
@@ -58,4 +59,4 @@
5859
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
5960
</PackageVersion>
6061
</ItemGroup>
61-
</Project>
62+
</Project>

src/Sidekick.Wpf/Helpers/CenterHelper.cs

Lines changed: 13 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,39 @@
1-
using System.Runtime.InteropServices;
21
using System.Windows;
2+
using System.Windows.Forms;
33
using System.Windows.Interop;
44
using System.Windows.Media;
55

66
namespace Sidekick.Wpf.Helpers;
77

88
public static class CenterHelper
99
{
10-
[DllImport("user32.dll")]
11-
private static extern IntPtr MonitorFromWindow(IntPtr hwnd, uint dwFlags);
12-
13-
[DllImport("user32.dll", SetLastError = true)]
14-
private static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi);
15-
16-
private const uint MONITOR_DEFAULTTONEAREST = 2;
17-
18-
[StructLayout(LayoutKind.Sequential)]
19-
private struct RECT
20-
{
21-
public int Left, Top, Right, Bottom;
22-
}
23-
24-
[StructLayout(LayoutKind.Sequential)]
25-
private struct MONITORINFO
26-
{
27-
public int cbSize;
28-
public RECT rcMonitor;
29-
public RECT rcWork;
30-
public uint dwFlags;
31-
}
32-
3310
public static void Center(Window window)
3411
{
3512
// Get the window's handle
3613
var windowHandle = new WindowInteropHelper(window).Handle;
37-
var monitor = MonitorFromWindow(windowHandle, MONITOR_DEFAULTTONEAREST);
3814

39-
var monitorInfo = new MONITORINFO();
40-
monitorInfo.cbSize = Marshal.SizeOf(typeof(MONITORINFO));
41-
GetMonitorInfo(monitor, ref monitorInfo);
15+
// Get the screen containing the window
16+
var currentScreen = Screen.FromHandle(windowHandle);
4217

43-
// Get the working area in physical pixels
44-
var workingArea = monitorInfo.rcWork;
18+
// Get the working area of the screen (excluding taskbar, DPI-aware)
19+
var workingArea = currentScreen.WorkingArea;
4520

4621
// Get the DPI scaling factor for the monitor
4722
var dpi = VisualTreeHelper.GetDpi(window);
4823

4924
// Convert physical pixels (from working area) to WPF device-independent units (DIPs)
50-
var workingAreaWidthInDips = (workingArea.Right - workingArea.Left) / (dpi.PixelsPerInchX / 96.0);
51-
var workingAreaHeightInDips = (workingArea.Bottom - workingArea.Top) / (dpi.PixelsPerInchY / 96.0);
25+
var workingAreaWidthInDips = workingArea.Width / (dpi.PixelsPerInchX / 96.0);
26+
var workingAreaHeightInDips = workingArea.Height / (dpi.PixelsPerInchY / 96.0);
5227
var workingAreaLeftInDips = workingArea.Left / (dpi.PixelsPerInchX / 96.0);
5328
var workingAreaTopInDips = workingArea.Top / (dpi.PixelsPerInchY / 96.0);
5429

30+
// Get the actual size of the window in DIPs
31+
var actualWidth = window.Width;
32+
var actualHeight = window.Height;
33+
5534
// Calculate centered position within the working area
56-
var left = workingAreaLeftInDips + (workingAreaWidthInDips - window.Width) / 2;
57-
var top = workingAreaTopInDips + (workingAreaHeightInDips - window.Height) / 2;
35+
var left = workingAreaLeftInDips + (workingAreaWidthInDips - actualWidth) / 2;
36+
var top = workingAreaTopInDips + (workingAreaHeightInDips - actualHeight) / 2;
5837

5938
// Set the window's position
6039
window.Left = left;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System.Windows.Input;
2+
3+
namespace Sidekick.Wpf.Services;
4+
5+
public class SimpleCommand(Action execute) : ICommand
6+
{
7+
public bool CanExecute(object? parameter) => true;
8+
9+
public void Execute(object? parameter) => execute.Invoke();
10+
11+
public event EventHandler? CanExecuteChanged
12+
{
13+
add { CommandManager.RequerySuggested += value; }
14+
remove { CommandManager.RequerySuggested -= value; }
15+
}
16+
}

src/Sidekick.Wpf/Services/WpfApplicationService.cs

Lines changed: 48 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
using System.Globalization;
2-
using System.IO;
2+
using System.Windows.Controls;
3+
using Hardcodet.Wpf.TaskbarNotification;
34
using Microsoft.Extensions.Localization;
4-
using Microsoft.Extensions.Logging;
5-
using NotificationIcon.NET;
65
using Sidekick.Common.Blazor.Home;
76
using Sidekick.Common.Browser;
87
using Sidekick.Common.Localization;
@@ -14,7 +13,6 @@ namespace Sidekick.Wpf.Services;
1413
public class WpfApplicationService
1514
(
1615
IViewLocator viewLocator,
17-
ILogger<WpfApplicationService> logger,
1816
IStringLocalizer<HomeResources> resources,
1917
IUiLanguageProvider uiLanguageProvider,
2018
IBrowserProvider browserProvider
@@ -24,7 +22,7 @@ IBrowserProvider browserProvider
2422

2523
private bool Initialized { get; set; }
2624

27-
private NotifyIcon? Icon { get; set; }
25+
private TaskbarIcon? Icon { get; set; }
2826

2927
public int Priority => 9000;
3028

@@ -45,53 +43,60 @@ public Task Initialize()
4543

4644
private void OnLanguageChanged(CultureInfo cultureInfo)
4745
{
48-
if (Icon is null)
46+
InitializeTray();
47+
}
48+
49+
private void InitializeTray()
50+
{
51+
Icon?.Dispose();
52+
53+
Icon = new TaskbarIcon();
54+
Icon.Icon = new System.Drawing.Icon(System.IO.Path.Combine(AppContext.BaseDirectory, "wwwroot/favicon.ico"));
55+
Icon.ToolTipText = "Sidekick";
56+
Icon.ContextMenu = new ContextMenu();
57+
Icon.DoubleClickCommand = new SimpleCommand(() => viewLocator.Open(SidekickViewType.Standard, "/home"));
58+
59+
AddTrayItem("Sidekick - " + ((IApplicationService)this).GetVersion(), null, true);
60+
AddTrayItem(resources["Home"], () =>
4961
{
50-
return;
51-
}
62+
viewLocator.Open(SidekickViewType.Standard, "/home");
63+
return Task.CompletedTask;
64+
});
65+
AddTrayItem(resources["Open_Website"],
66+
() =>
67+
{
68+
browserProvider.OpenUri(browserProvider.SidekickWebsite);
69+
return Task.CompletedTask;
70+
});
71+
AddTrayItem(resources["Exit"],
72+
() =>
73+
{
74+
Shutdown();
75+
return Task.CompletedTask;
76+
});
5277

53-
Icon.MenuItems[0].Text = resources["Sidekick"] + " - " + ((IApplicationService)this).GetVersion();
54-
Icon.MenuItems[1].Text = resources["Home"];
55-
Icon.MenuItems[2].Text = resources["Open_Website"];
56-
Icon.MenuItems[3].Text = resources["Exit"];
78+
Initialized = true;
5779
}
5880

59-
private void InitializeTray()
81+
private void AddTrayItem(string label, Func<Task>? onClick, bool disabled = false)
6082
{
61-
var iconImage = Path.Combine(AppContext.BaseDirectory, "wwwroot/favicon.ico");
83+
if (Icon?.ContextMenu == null) return;
6284

63-
Icon = NotifyIcon.Create(iconImage,
64-
[
65-
new("Sidekick - " + ((IApplicationService)this).GetVersion())
66-
{
67-
IsDisabled = true
68-
},
69-
new(resources["Home"])
70-
{
71-
Click = (s, e) => viewLocator.Open(SidekickViewType.Standard, "/home")
72-
},
73-
new(resources["Open_Website"])
74-
{
75-
Click = (s, e) => browserProvider.OpenUri(browserProvider.SidekickWebsite)
76-
},
77-
new(resources["Exit"])
78-
{
79-
Click = (s, e) => Shutdown()
80-
},
81-
]);
85+
var menuItem = new MenuItem
86+
{
87+
Header = label,
88+
IsEnabled = !disabled,
89+
};
8290

83-
// Runs its own message loop.
84-
_ = Task.Run(() =>
91+
if (onClick != null)
8592
{
86-
try
87-
{
88-
Icon.Show();
89-
}
90-
catch (Exception e)
93+
menuItem.Click += async (_, _) =>
9194
{
92-
logger.LogError(e, "[ApplicationService] Error while trying to create the notification icon in the taskbar.");
93-
}
94-
});
95+
await onClick();
96+
};
97+
}
98+
99+
Icon.ContextMenu.Items.Add(menuItem);
95100
}
96101

97102
public void Shutdown()

src/Sidekick.Wpf/Sidekick.Wpf.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@
5252
</ItemGroup>
5353

5454
<ItemGroup>
55+
<PackageReference Include="Hardcodet.NotifyIcon.Wpf" />
5556
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.Wpf" />
56-
<PackageReference Include="NotificationIcon.NET" />
5757
</ItemGroup>
5858

5959
<ItemGroup>

0 commit comments

Comments
 (0)