From 6be31dd630ab4945a266370c55300c505e3a8154 Mon Sep 17 00:00:00 2001 From: HeyItsJono Date: Sat, 15 Jul 2023 17:13:09 +1000 Subject: [PATCH] Merge Pull Requests with my own minor tweaks. Adds bottomleft (@vortex1942), topmiddle (@Farenheith), taskbar icon and exit option as well as github build workflow (@GabeDuarteM). --- .github/workflows/build-and-release.yml | 38 +++++ .gitignore | 4 + build.cmd | 2 + topnotify.cs | 206 +++++++++++++++++------- 4 files changed, 192 insertions(+), 58 deletions(-) create mode 100644 .github/workflows/build-and-release.yml create mode 100644 .gitignore diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml new file mode 100644 index 0000000..f0be33e --- /dev/null +++ b/.github/workflows/build-and-release.yml @@ -0,0 +1,38 @@ +name: Build and Release + +on: + release: + types: [published] + +jobs: + build: + runs-on: windows-latest + + permissions: + contents: write + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Build executables + run: ${{ github.workspace }}/build.cmd + + - name: Upload build artifacts + uses: actions/upload-artifact@v3 + with: + name: notifications-at-top + path: | + ${{ github.workspace }}/topleft.exe + ${{ github.workspace }}/topright.exe + ${{ github.workspace }}/topmiddle.exe + ${{ github.workspace }}/bottomleft.exe + + - name: Create release + uses: softprops/action-gh-release@v1 + with: + files: | + topleft.exe + topright.exe + topmiddle.exe + bottomleft.exe \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..63ca060 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +topleft.exe +topright.exe +topmiddle.exe +bottomleft.exe \ No newline at end of file diff --git a/build.cmd b/build.cmd index 64d392c..709b387 100644 --- a/build.cmd +++ b/build.cmd @@ -1,4 +1,6 @@ C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe -lib:"C:\Windows\Microsoft.NET\Framework64\v4.0.30319" -r:"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.VisualBasic.dll" -target:winexe -out:"topleft.exe" "topnotify.cs" C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe -lib:"C:\Windows\Microsoft.NET\Framework64\v4.0.30319" -r:"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.VisualBasic.dll" -target:winexe -out:"topright.exe" "topnotify.cs" +C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe -lib:"C:\Windows\Microsoft.NET\Framework64\v4.0.30319" -r:"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.VisualBasic.dll" -target:winexe -out:"topmiddle.exe" "topnotify.cs" +C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe -lib:"C:\Windows\Microsoft.NET\Framework64\v4.0.30319" -r:"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.VisualBasic.dll" -target:winexe -out:"bottomleft.exe" "topnotify.cs" PAUSE \ No newline at end of file diff --git a/topnotify.cs b/topnotify.cs index 3e29cfb..19d375f 100644 --- a/topnotify.cs +++ b/topnotify.cs @@ -3,6 +3,7 @@ using System.Runtime.InteropServices; using System.Drawing; using System.Threading; +using System.Threading.Tasks; public class Program { @@ -32,74 +33,163 @@ public class Program { public static int Cooldown; // Since The Teams Notification Stutters, Add A Cooldown To Dismiss public static void Main(string[] args) { + NotifyIcon notifyIcon = new NotifyIcon(); + notifyIcon.Icon = SystemIcons.Application; + notifyIcon.Visible = true; + + // Create the context menu for the taskbar icon + ContextMenu contextMenu = new ContextMenu(); + MenuItem exitMenuItem = new MenuItem("Exit"); + exitMenuItem.Click += new EventHandler(ExitMenuItem_Click); + contextMenu.MenuItems.Add(exitMenuItem); + notifyIcon.ContextMenu = contextMenu; + + // Run the main logic in another task to avoid blocking the main one with the while loop. + Task.Run(() => { + while (true) { + + //MS Teams Notifications + try{ + var teamsHwnd = FindWindow("Chrome_WidgetWin_1", "Microsoft Teams Notification"); + var chromeHwnd = FindWindowEx(teamsHwnd, IntPtr.Zero, "Chrome_RenderWidgetHostHWND", "Chrome Legacy Window"); // I Think MS Is Using Chrome Webview For Notifications + + //If A Notification Is Showing Up + if (chromeHwnd != IntPtr.Zero){ + Cooldown = 0; + + if (System.AppDomain.CurrentDomain.FriendlyName == "topleft.exe"){ + //Sets to top left + SetWindowPos(teamsHwnd, 0, 15, 15, 100, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); + } + else if (System.AppDomain.CurrentDomain.FriendlyName == "topright.exe"){ + //Sets to top right + + //Get the current position of the notification window + Rectangle NotifyRect = new Rectangle(); + GetWindowRect(teamsHwnd, ref NotifyRect); + + NotifyRect.Width = NotifyRect.Width - NotifyRect.X; + NotifyRect.Height = NotifyRect.Height - NotifyRect.Y; + + // Change the X and Y values to change the offset. + NotifyRect.X = Screen.PrimaryScreen.Bounds.Width - NotifyRect.Width; + NotifyRect.Y = 0; + + SetWindowPos(teamsHwnd, 0, NotifyRect.X - 15, 15, 100, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); + } + else if (System.AppDomain.CurrentDomain.FriendlyName == "topmiddle.exe"){ + //Sets to top middle + + //Get the current position of the notification window + Rectangle NotifyRect = new Rectangle(); + GetWindowRect(teamsHwnd, ref NotifyRect); + + NotifyRect.Width = NotifyRect.Width - NotifyRect.X; + NotifyRect.Height = NotifyRect.Height - NotifyRect.Y; + + // Change the X and Y values to change the offset. + NotifyRect.X = Screen.PrimaryScreen.Bounds.Width - NotifyRect.Width; + NotifyRect.X /= 2; + NotifyRect.Y = 0; - while (true) { + SetWindowPos(teamsHwnd, 0, NotifyRect.X - 15, 15, 100, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); + } + else if (System.AppDomain.CurrentDomain.FriendlyName == "bottomleft.exe"){ + //Sets to top middle - //MS Teams Notifications - try{ - var teamsHwnd = FindWindow("Chrome_WidgetWin_1", "Microsoft Teams Notification"); - var chromeHwnd = FindWindowEx(teamsHwnd, IntPtr.Zero, "Chrome_RenderWidgetHostHWND", "Chrome Legacy Window"); // I Think MS Is Using Chrome Webview For Notifications + //Get the current position of the notification window + Rectangle NotifyRect = new Rectangle(); + GetWindowRect(teamsHwnd, ref NotifyRect); - //If A Notification Is Showing Up - if (chromeHwnd != IntPtr.Zero){ - Cooldown = 0; + NotifyRect.Width = NotifyRect.Width - NotifyRect.X; + NotifyRect.Height = NotifyRect.Height - NotifyRect.Y; - if (System.AppDomain.CurrentDomain.FriendlyName == "topleft.exe"){ - //Sets to top left - SetWindowPos(teamsHwnd, 0, 15, 15, 100, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); + // Change the X and Y values to change the offset. + // 50PX Y Offset to match the default notification area being above taskbar + NotifyRect.X = 0; + NotifyRect.Y = Screen.PrimaryScreen.Bounds.Height - NotifyRect.Height - 25; + + SetWindowPos(teamsHwnd, 0, NotifyRect.X, NotifyRect.Y, 100, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); + } } - else if (System.AppDomain.CurrentDomain.FriendlyName == "topright.exe"){ - //Sets to top right - - - //Get the current position of the notification window - Rectangle NotifyRect = new Rectangle(); - GetWindowRect(teamsHwnd, ref NotifyRect); - - NotifyRect.Width = NotifyRect.Width - NotifyRect.X; - NotifyRect.Height = NotifyRect.Height - NotifyRect.Y; - - SetWindowPos(teamsHwnd, 0, Screen.PrimaryScreen.Bounds.Width - NotifyRect.Width - 15, 15, 100, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); + else { + if (Cooldown >= 30){ + SetWindowPos(teamsHwnd, 0, 0, -9999, -9999, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); // Move To Off Screen + Cooldown = 0; + } + Cooldown += 1; // Don't Dismiss Until 30 Frames After Signal, Prevents Stutters } } - else { - if (Cooldown >= 30){ - SetWindowPos(teamsHwnd, 0, 0, -9999, -9999, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); // Move To Off Screen - Cooldown = 0; - } - Cooldown += 1; // Don't Dismiss Until 30 Frames After Signal, Prevents Stutters + catch{ + //User Doesn't Have Teams } - } - catch{ - //User Doesn't Have Teams - } - //Windows System Notifications - var hwnd = FindWindow("Windows.UI.Core.CoreWindow", "New notification"); - if (System.AppDomain.CurrentDomain.FriendlyName == "topleft.exe"){ - //Sets to top left (easy peasy) - //50PX Y offset to make the spacing even - SetWindowPos(hwnd, 0, 0, -50, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); - } - else if (System.AppDomain.CurrentDomain.FriendlyName == "topright.exe"){ - //Sets to top right (not as easy) - - //Get the current position of the notification window - Rectangle NotifyRect = new Rectangle(); - GetWindowRect(hwnd, ref NotifyRect); - - NotifyRect.Width = NotifyRect.Width - NotifyRect.X; - NotifyRect.Height = NotifyRect.Height - NotifyRect.Y; - - //50PX Y offset to make the spacing even - SetWindowPos(hwnd, 0, Screen.PrimaryScreen.Bounds.Width - NotifyRect.Width, -50, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); - } + //Windows System Notifications + var hwnd = FindWindow("Windows.UI.Core.CoreWindow", "New notification"); + if (System.AppDomain.CurrentDomain.FriendlyName == "topleft.exe"){ + //Sets to top left (easy peasy) + //Third argument (2nd number after hwnd) is X offset, fourth argument (3rd number after hwnd) is Y offset. Negative Y offset raises position of notifcation up. + SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); + } + else if (System.AppDomain.CurrentDomain.FriendlyName == "topright.exe"){ + //Sets to top right (not as easy) - Thread.Sleep(10); - } + //Get the current position of the notification window + Rectangle NotifyRect = new Rectangle(); + GetWindowRect(hwnd, ref NotifyRect); - - Console.ReadLine(); + NotifyRect.Width = NotifyRect.Width - NotifyRect.X; + NotifyRect.Height = NotifyRect.Height - NotifyRect.Y; + + // Change the X and Y values to change the offset. + NotifyRect.X = Screen.PrimaryScreen.Bounds.Width - NotifyRect.Width; + NotifyRect.Y = 0; + + SetWindowPos(hwnd, 0, NotifyRect.X, NotifyRect.Y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); + } + else if (System.AppDomain.CurrentDomain.FriendlyName == "topmiddle.exe"){ + //Sets to top middle; same logic as top right but divide the NotifyRect.X by 2. + + //Get the current position of the notification window + Rectangle NotifyRect = new Rectangle(); + GetWindowRect(hwnd, ref NotifyRect); + + NotifyRect.Width = NotifyRect.Width - NotifyRect.X; + NotifyRect.Height = NotifyRect.Height - NotifyRect.Y; + + // Change the X and Y values to change the offset. + NotifyRect.X = Screen.PrimaryScreen.Bounds.Width - NotifyRect.Width; + NotifyRect.X /= 2; + NotifyRect.Y = 0; + + SetWindowPos(hwnd, 0, NotifyRect.X, NotifyRect.Y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); + } + else if (System.AppDomain.CurrentDomain.FriendlyName == "bottomleft.exe"){ + //Sets to bottom left + + //Get the current position of the notification window + Rectangle NotifyRect = new Rectangle(); + GetWindowRect(hwnd, ref NotifyRect); + + NotifyRect.Width = NotifyRect.Width - NotifyRect.X; + NotifyRect.Height = NotifyRect.Height - NotifyRect.Y; + + // Change the X and Y values to change the offset. + // 50PX Y Offset to match the default notification area being above taskbar + NotifyRect.X = 0; + NotifyRect.Y = Screen.PrimaryScreen.Bounds.Height - NotifyRect.Height - 50; + + SetWindowPos(hwnd, 0, NotifyRect.X, NotifyRect.Y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); + } + + Thread.Sleep(10); + } + }); + + Application.Run(); + } + private static void ExitMenuItem_Click(object sender, EventArgs e) { + Application.Exit(); } -} +} \ No newline at end of file