Skip to content

Commit

Permalink
Explicitly stop taskbar flashing after 4 seconds
Browse files Browse the repository at this point in the history
  • Loading branch information
ScrubN committed Dec 1, 2023
1 parent cf35e4c commit a2280bb
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 15 deletions.
50 changes: 36 additions & 14 deletions TwitchDownloaderWPF/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.IO;
using System.Net;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows;
using System.Windows.Interop;
using TwitchDownloaderWPF.Properties;
Expand Down Expand Up @@ -103,20 +104,7 @@ private async void Window_Loaded(object sender, RoutedEventArgs e)

// Flash the window taskbar icon if it is not in the foreground. This is to mitigate a problem where
// it will sometimes start behind other windows, usually (but not always) due to the user's actions.
var currentWindow = new WindowInteropHelper(this).Handle;
var foregroundWindow = NativeFunctions.GetForegroundWindow();
if (currentWindow != foregroundWindow)
{
var flashInfo = new NativeFunctions.FlashWInfo
{
StructSize = (uint)Marshal.SizeOf<NativeFunctions.FlashWInfo>(),
WindowHandle = new WindowInteropHelper(this).Handle,
Flags = NativeFunctions.FlashWInfo.FLASHW_TRAY,
FlashCount = uint.MaxValue,
Timeout = 0
};
NativeFunctions.FlashWindowEx(flashInfo);
}
FlashWindowIfNotForeground(TimeSpan.FromSeconds(4));

AutoUpdater.InstalledVersion = currentVersion;
#if !DEBUG
Expand All @@ -129,6 +117,40 @@ private async void Window_Loaded(object sender, RoutedEventArgs e)
#endif
}

private void FlashWindowIfNotForeground(TimeSpan flashDuration)
{
var currentWindow = new WindowInteropHelper(this).Handle;
var foregroundWindow = NativeFunctions.GetForegroundWindow();
if (currentWindow == foregroundWindow)
return;

var flashWInfo = new NativeFunctions.FlashWInfo
{
StructSize = (uint)Marshal.SizeOf<NativeFunctions.FlashWInfo>(),
WindowHandle = currentWindow,
Flags = NativeFunctions.FlashWInfo.FLASHW_TRAY,
FlashCount = uint.MaxValue,
Timeout = 0
};
_ = NativeFunctions.FlashWindowEx(flashWInfo);

_ = new Timer(static state =>
{
if (state is not IntPtr windowHandle)
return;

var flashWInfo = new NativeFunctions.FlashWInfo
{
StructSize = (uint)Marshal.SizeOf<NativeFunctions.FlashWInfo>(),
WindowHandle = windowHandle,
Flags = NativeFunctions.FlashWInfo.FLASHW_STOP,
FlashCount = 0,
Timeout = 0
};
_ = NativeFunctions.FlashWindowEx(flashWInfo);
}, currentWindow, flashDuration, Timeout.InfiniteTimeSpan);
}

private class FfmpegDownloadProgress : IProgress<ProgressInfo>
{
private int _lastPercent = -1;
Expand Down
1 change: 1 addition & 0 deletions TwitchDownloaderWPF/Services/NativeFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public static unsafe class NativeFunctions
public static extern IntPtr GetForegroundWindow();

[DllImport("user32.dll", EntryPoint = "FlashWindowEx", PreserveSig = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool FlashWindowEx(FlashWInfo info);

// https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-flashwinfo
Expand Down
3 changes: 2 additions & 1 deletion TwitchDownloaderWPF/Services/ThemeService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ public void SetTitleBarTheme(WindowCollection windows)
{
SizeToContent = SizeToContent.WidthAndHeight,
Top = int.MinValue + 1,
WindowStyle = WindowStyle.None
WindowStyle = WindowStyle.None,
ShowInTaskbar = false
};
wnd.Show();
wnd.Close();
Expand Down

0 comments on commit a2280bb

Please sign in to comment.