Skip to content

Commit

Permalink
Flash the main window taskbar icon if it is not in the foreground on …
Browse files Browse the repository at this point in the history
…startup
  • Loading branch information
ScrubN committed Nov 30, 2023
1 parent c406baf commit cf35e4c
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
20 changes: 20 additions & 0 deletions TwitchDownloaderWPF/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using TwitchDownloaderWPF.Properties;
using TwitchDownloaderWPF.Services;
using Xabe.FFmpeg;
using Xabe.FFmpeg.Downloader;

Expand Down Expand Up @@ -98,6 +101,23 @@ private async void Window_Loaded(object sender, RoutedEventArgs e)
Title = oldTitle;
}

// 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);
}

AutoUpdater.InstalledVersion = currentVersion;
#if !DEBUG
if (AppContext.BaseDirectory.StartsWith(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)))
Expand Down
24 changes: 24 additions & 0 deletions TwitchDownloaderWPF/Services/NativeFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,29 @@ public static unsafe class NativeFunctions
{
[DllImport("dwmapi.dll", EntryPoint = "DwmSetWindowAttribute", PreserveSig = true)]
public static extern int SetWindowAttribute(IntPtr handle, int attribute, void* attributeValue, uint attributeSize);

[DllImport("user32.dll", EntryPoint = "GetForegroundWindow", PreserveSig = true)]
public static extern IntPtr GetForegroundWindow();

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

// https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-flashwinfo
[StructLayout(LayoutKind.Sequential)]
public record struct FlashWInfo
{
public uint StructSize;
public IntPtr WindowHandle;
public uint Flags;
public uint FlashCount;
public uint Timeout;

public const uint FLASHW_STOP = 0;
public const uint FLASHW_CAPTION = 1;
public const uint FLASHW_TRAY = 2;
public const uint FLASHW_ALL = 3;
public const uint FLASHW_TIMER = 4;
public const uint FLASHW_TIMERNOFG = 12;
}
}
}

0 comments on commit cf35e4c

Please sign in to comment.