Skip to content

Commit 5d8ed5e

Browse files
authored
Merge pull request #163 from unchihugo/taskbar
Added three new premium taskbar widget settings: TaskbarWidgetClickable, TaskbarWidgetBackgroundBlur, and TaskbarWidgetHideCompletely Upgraded System.Drawing.Common from v9.0.2 to v10.0.0 and WPF-UI from v4.0.3 to v4.1.0 Refactored settings initialization to use CompleteInitialization() method for proper state management
2 parents a8b7d0a + a7e2479 commit 5d8ed5e

12 files changed

Lines changed: 489 additions & 152 deletions

File tree

‎FluentFlyoutWPF/App.xaml.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace FluentFlyoutWPF;
88
/// </summary>
99
public partial class App : Application
1010
{
11-
protected override void OnStartup(StartupEventArgs e)
11+
protected override async void OnStartup(StartupEventArgs e)
1212
{
1313
// Apply localization before any windows are created
1414
LocalizationManager.ApplyLocalization();

‎FluentFlyoutWPF/Classes/LicenseManager.cs‎

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using FluentFlyout.Classes.Settings;
22
using System.Diagnostics;
3+
using System.Windows;
4+
using System.Windows.Interop;
35
using Windows.Services.Store;
46
using Wpf.Ui.Controls;
57

@@ -55,7 +57,6 @@ private LicenseManager()
5557
{
5658
_isInitialized = false;
5759
_isPremiumUnlocked = false;
58-
_isStoreVersion = false;
5960
}
6061

6162
/// <summary>
@@ -75,8 +76,9 @@ public async Task InitializeAsync()
7576
_appLicense = await _storeContext.GetAppLicenseAsync();
7677

7778
// if user ever ran a self-compiled or GitHub version, set store version to false
78-
if (SettingsManager.Current.LastKnownVersion != null && SettingsManager.Current.IsStoreVersion == false)
79+
if (!String.IsNullOrEmpty(SettingsManager.Current.LastKnownVersion) && SettingsManager.Current.IsStoreVersion == false)
7980
{
81+
Debug.WriteLine("LicenseManager: Previous non-Store version detected. Treating as non-Store version.");
8082
_isStoreVersion = false;
8183
}
8284
else
@@ -163,21 +165,9 @@ public async Task<bool> PurchasePremiumAsync()
163165
return true;
164166
}
165167

166-
// Get product info
167-
if (_productResult == null)
168-
{
169-
_productResult = await _storeContext.GetStoreProductForCurrentAppAsync();
170-
171-
if (_productResult.ExtendedError != null)
172-
{
173-
Debug.WriteLine($"LicenseManager: Error getting product - {_productResult.ExtendedError.Message}");
174-
return false;
175-
}
176-
}
177-
178168
// Get the add-on
179-
var addOnResult = await _storeContext.GetAssociatedStoreProductsAsync(new[] { "Durable" });
180-
169+
var addOnResult = await _storeContext.GetStoreProductsAsync(new[] { "Durable" }, new[] { PremiumAddOnId });
170+
181171
if (addOnResult.ExtendedError != null)
182172
{
183173
Debug.WriteLine($"LicenseManager: Error getting add-ons - {addOnResult.ExtendedError.Message}");
@@ -189,7 +179,11 @@ public async Task<bool> PurchasePremiumAsync()
189179
Debug.WriteLine("LicenseManager: Premium add-on not found in store");
190180
return false;
191181
}
192-
182+
183+
var interop = new WindowInteropHelper(Application.Current.MainWindow);
184+
IntPtr hwnd = interop.Handle;
185+
WinRT.Interop.InitializeWithWindow.Initialize(_storeContext, hwnd);
186+
193187
// Request purchase
194188
var purchaseResult = await _storeContext.RequestPurchaseAsync(PremiumAddOnId);
195189

‎FluentFlyoutWPF/Classes/Settings/SettingsManager.cs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ public UserSettings RestoreSettings()
7373
{
7474
XmlSerializer xmlSerializer = new XmlSerializer(typeof(UserSettings));
7575
_current = (UserSettings)xmlSerializer.Deserialize(reader);
76+
_current.CompleteInitialization();
7677
//File.AppendAllText(logFilePath, $"[{DateTime.Now}] Settings restored\n");
7778
//EventLog.WriteEntry("FluentFlyout", "Settings restored", EventLogEntryType.Information);
7879
return _current;
@@ -91,6 +92,7 @@ public UserSettings RestoreSettings()
9192
// if the settings file not found or cannot be read
9293
//File.AppendAllText(logFilePath, $"[{DateTime.Now}] Settings file not found or cannot be read\n");
9394
_current = new UserSettings();
95+
_current.CompleteInitialization();
9496
return _current;
9597
}
9698

‎FluentFlyoutWPF/FluentFlyout.csproj‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@
3030
<ItemGroup>
3131
<PackageReference Include="Dubya.WindowsMediaController" Version="2.5.5" />
3232
<PackageReference Include="MicaWPF" Version="6.3.0" />
33-
<PackageReference Include="System.Drawing.Common" Version="9.0.2" />
34-
<PackageReference Include="WPF-UI" Version="4.0.3" />
33+
<PackageReference Include="System.Drawing.Common" Version="10.0.0" />
34+
<PackageReference Include="WPF-UI" Version="4.1.0" />
3535
<PackageReference Include="WPF-UI.Tray" Version="4.0.3" />
3636
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0-preview3" />
3737
</ItemGroup>

‎FluentFlyoutWPF/MainWindow.xaml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@
171171
MenuOnRightClick="True"
172172
TooltipText="FluentFlyout"
173173
Icon="/Resources/FluentFlyout2.ico"
174-
Margin="0,127,0,114">
174+
Margin="0,127,0,114" Visibility="Collapsed">
175175
<tray:NotifyIcon.Menu>
176176
<ContextMenu>
177177
<ui:MenuItem x:Name="NotifyIconSettings" Header="{DynamicResource TrayIcon_SettingsOption}" Click="openSettings">

‎FluentFlyoutWPF/MainWindow.xaml.cs‎

Lines changed: 58 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -78,22 +78,63 @@ public MainWindow()
7878

7979
if (!singleton.WaitOne(TimeSpan.Zero, true)) // if another instance is already running, close this one
8080
{
81-
Application.Current.Shutdown();
81+
// Signal the existing instance to open settings
82+
Task.Run(() =>
83+
{
84+
try
85+
{
86+
using (EventWaitHandle settingsEvent = new EventWaitHandle(false, EventResetMode.AutoReset, "FluentFlyout_OpenSettings"))
87+
{
88+
settingsEvent.Set();
89+
}
90+
}
91+
catch (Exception ex)
92+
{
93+
Debug.WriteLine($"Failed to signal existing instance: {ex.Message}");
94+
}
95+
});
96+
97+
Environment.Exit(0);
8298
}
8399

100+
// in the existing instance, listen for the signal to open settings
101+
Task.Run(() =>
102+
{
103+
try
104+
{
105+
using (EventWaitHandle settingsEvent = new EventWaitHandle(false, EventResetMode.AutoReset, "FluentFlyout_OpenSettings"))
106+
{
107+
while (true)
108+
{
109+
settingsEvent.WaitOne();
110+
Application.Current.Dispatcher.Invoke(() => { SettingsWindow.ShowInstance(); });
111+
}
112+
}
113+
}
114+
catch (Exception ex)
115+
{
116+
Debug.WriteLine($"Settings event listener error: {ex.Message}");
117+
}
118+
});
119+
84120
SettingsManager settingsManager = new();
85121
try
86122
{
87123
settingsManager.RestoreSettings();
124+
LicenseManager.Instance.InitializeAsync();
125+
126+
// Sync license status from LicenseManager to SettingsManager
127+
SettingsManager.Current.IsPremiumUnlocked = LicenseManager.Instance.IsPremiumUnlocked;
128+
SettingsManager.Current.IsStoreVersion = LicenseManager.Instance.IsStoreVersion;
129+
SettingsManager.SaveSettings();
130+
131+
Debug.WriteLine($"License synced on startup - Store: {SettingsManager.Current.IsStoreVersion}, Premium: {SettingsManager.Current.IsPremiumUnlocked}");
88132
}
89133
catch (Exception ex)
90134
{
91135
MessageBox.Show($"Failed to restore settings: {ex.Message}");
92136
}
93137

94-
// Initialize license manager and check premium status
95-
InitializeLicenseAsync();
96-
97138
if (SettingsManager.Current.Startup == true) // add to startup programs if enabled, needs improvement
98139
{
99140
RegistryKey key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
@@ -148,27 +189,6 @@ public MainWindow()
148189
UpdateTaskbar();
149190
}
150191

151-
private async void InitializeLicenseAsync()
152-
{
153-
try
154-
{
155-
await LicenseManager.Instance.InitializeAsync();
156-
157-
// Update settings with license status
158-
SettingsManager.Current.IsPremiumUnlocked = LicenseManager.Instance.IsPremiumUnlocked;
159-
SettingsManager.Current.IsStoreVersion = LicenseManager.Instance.IsStoreVersion;
160-
161-
Debug.WriteLine($"License initialized - Store: {SettingsManager.Current.IsStoreVersion}, Premium: {SettingsManager.Current.IsPremiumUnlocked}");
162-
}
163-
catch (Exception ex)
164-
{
165-
Debug.WriteLine($"Error initializing license: {ex.Message}");
166-
// On error, default to unlocked (benefit of the doubt)
167-
SettingsManager.Current.IsPremiumUnlocked = true;
168-
SettingsManager.Current.IsStoreVersion = false;
169-
}
170-
}
171-
172192
private void openSettings(object? sender, EventArgs e)
173193
{
174194
SettingsWindow.ShowInstance();
@@ -1131,6 +1151,19 @@ private void MicaWindow_Loaded(object sender, RoutedEventArgs e)
11311151
Hide();
11321152
UpdateUILayout();
11331153
ThemeManager.ApplySavedTheme();
1154+
1155+
// add tray icon if not hidden
1156+
try
1157+
{
1158+
if (!SettingsManager.Current.NIconHide)
1159+
{
1160+
nIcon.Visibility = Visibility.Visible;
1161+
}
1162+
}
1163+
catch (Exception ex)
1164+
{
1165+
Debug.WriteLine(ex);
1166+
}
11341167
}
11351168

11361169
private void nIcon_LeftClick(Wpf.Ui.Tray.Controls.NotifyIcon sender, RoutedEventArgs e) // change the behavior of the tray icon

‎FluentFlyoutWPF/Resources/Localization/Dictionary-en-US.xaml‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,21 @@ hides repeat, shuffle and player info</System:String>
4040
<System:String x:Key="PauseOtherMediaDescription">When you play or focus on new media, other active sessions are automatically paused</System:String>
4141
<System:String x:Key="TaskbarWidgetCustomizationTitle">Taskbar Widget Customization</System:String>
4242
<System:String x:Key="TaskbarWidgetDescription">A compact, built-in widget that lives right on your Windows Taskbar for instant access to your media. Click the widget to expand the full Media Flyout (when enabled).</System:String>
43-
<System:String x:Key="TaskbarWidgetEnabledTitle">Enable Taskbar Widget (Premium)</System:String>
43+
<System:String x:Key="TaskbarWidgetEnabledTitle">Enable Taskbar Widget</System:String>
4444
<System:String x:Key="TaskbarWidgetEnabledDescription">Show a compact media widget on the taskbar</System:String>
4545
<System:String x:Key="TaskbarWidgetVisualIssuesWarning">Configure the options below if you experience visual issues.</System:String>
4646
<System:String x:Key="TaskbarWidgetPaddingTitle">Add Padding for Windows Widgets button</System:String>
4747
<System:String x:Key="TaskbarWidgetPaddingDescription">Turn this feature on if you have Windows Widgets enabled</System:String>
48+
<System:String x:Key="TaskbarWidgetClickableTitle">Click to open Media Flyout when media is Present</System:String>
49+
<System:String x:Key="TaskbarWidgetClickableDescription">If media flyout is enabled, it will open when you click the taskbar widget</System:String>
50+
<System:String x:Key="TaskbarWidgetBackgroundBlurTitle">Background Blur</System:String>
51+
<System:String x:Key="TaskbarWidgetBackgroundBlurDescription">Add background blur effect to the taskbar widget</System:String>
52+
<System:String x:Key="TaskbarWidgetHideCompletelyTitle">Hide Completely When No Media Is Present</System:String>
53+
<System:String x:Key="TaskbarWidgetHideCompletelyDescription">Hides the entire widget when no media is available, instead of displaying a media icon</System:String>
4854
<System:String x:Key="PremiumFeatureTitle">Premium Feature</System:String>
4955
<System:String x:Key="PremiumFeatureDescription" xml:space="preserve">Your one-time contribution helps me keep FluentFlyout alive and updated. It instantly unlocks all premium customization features, forever.
5056

51-
Note: As an open-source project, these features are also available for free via the manual installer on GitHub.</System:String>
57+
Note: As an open-source project, these features are also available for free via the manual installer on GitHub. The only trade-off is that updates and installation must be done manually.</System:String>
5258
<System:String x:Key="PremiumLockedMessage">This feature is part of the premium package</System:String>
5359
<System:String x:Key="PremiumUnlockedMessage">Premium features unlocked. Thank you for your support!</System:String>
5460
<System:String x:Key="PremiumGitHubMessage">Premium features are unlocked for GitHub/self-compiled versions</System:String>
@@ -87,6 +93,9 @@ Note: As an open-source project, these features are also available for free via
8793
<System:String x:Key="TrayIconLeftClickOption2"> Show Media Flyout</System:String>
8894
<System:String x:Key="Win11TrayIconTitle">Windows 11-like Tray Icon</System:String>
8995
<System:String x:Key="Win11TrayIconDescription">Use a tray icon that matches Windows 11 (toggle to refresh theme)</System:String>
96+
<System:String x:Key="TrayIconSectionTitle">Tray Icon</System:String>
97+
<System:String x:Key="HideTrayIconTitle">Hide Tray Icon Completely</System:String>
98+
<System:String x:Key="HideTrayIconDescription">Access settings from launching the program twice</System:String>
9099
<System:String x:Key="AnimationSettingsTitle">Animation Settings</System:String>
91100
<System:String x:Key="AnimationSettingsDescription">Tweak the animations to your liking</System:String>
92101
<System:String x:Key="AnimationDurationScaleTitle">Animation Duration Scale</System:String>
@@ -101,6 +110,7 @@ Note: As an open-source project, these features are also available for free via
101110
<System:String x:Key="NativeExperienceInfo">For the native Windows 11 experience, the settings should be kept at default.</System:String>
102111
<System:String x:Key="DisableOnFullscreenTitle">Disable Flyouts if DirectX fullscreen program is detected</System:String>
103112
<System:String x:Key="DisableOnFullscreenDescription">Prevents DirectX games in exclusive fullscreen from minimizing if a flyout pops up</System:String>
113+
<System:String x:Key="AboutPremiumTitle">About Premium</System:String>
104114
<System:String x:Key="EnjoyingAppText" xml:space="preserve">Enjoying the app? Star it on GitHub,
105115
or leave a review on Microsoft Store!</System:String>
106116
<System:String x:Key="GitHubRepoLink">GitHub Repository</System:String>

0 commit comments

Comments
 (0)