[0.1.40] Tray icon stays from startup to shutdown, not only while minimized

This commit is contained in:
Musa Mahmood 2026-10-18 20:24:08 -04:00
parent f4595a6fdc
commit 33163be488
5 changed files with 24 additions and 24 deletions

View File

@ -52,7 +52,7 @@ APP_NAME :: "mcap";
APP_FOLDER_NAME :: "mcap"; APP_FOLDER_NAME :: "mcap";
GIT_BRANCH :: "check"; GIT_BRANCH :: "check";
GIT_HASH :: "-"; GIT_HASH :: "-";
VERSION :: "0.1.39"; VERSION :: "0.1.40";
BUILD_DATE :: "-"; BUILD_DATE :: "-";
DEBUG :: true; DEBUG :: true;
COMPILE_TESTS :: true; COMPILE_TESTS :: true;

View File

@ -8,7 +8,7 @@ APP_NAME :: "mcap";
APP_FOLDER_NAME :: "mcap"; APP_FOLDER_NAME :: "mcap";
APP_BUNDLE_IDENTIFIER :: "com.example.mcap"; APP_BUNDLE_IDENTIFIER :: "com.example.mcap";
VERSION :: "0.1.39"; VERSION :: "0.1.40";
// Where everything goes: bin/, or bin-headless/ for builds made with no_crash_dialog, so automated // Where everything goes: bin/, or bin-headless/ for builds made with no_crash_dialog, so automated
// builds never write over the ones you run by hand. // builds never write over the ones you run by hand.
build_directory := "bin"; build_directory := "bin";

View File

@ -274,11 +274,16 @@ main :: () {
#if OS == .LINUX { #if OS == .LINUX {
linux_platform_setup(); linux_platform_setup();
} }
// The tray icon stays for as long as the app runs, not only while the window is hidden. View
// mode has no tray: closing its window ends it.
if !app.view_mode platform_show_tray_icon();
defer platform_hide_tray_icon();
} }
#if USING_WINDOWS { // :Win32_Initialize_Extended #if USING_WINDOWS { // :Win32_Initialize_Extended
// View mode has no tray: closing its window ends it. // The tray icon stays for as long as the app runs, not only while the window is hidden. View
if !app.view_mode { Win32_Set_Tray_Icon(); Win32_Hide_Tray_Icon(); } // mode has no tray: closing its window ends it.
defer if !app.view_mode Win32_Hide_Tray_Icon(); // exiting from the tray would otherwise leave the icon behind if !app.view_mode Win32_Set_Tray_Icon();
defer Win32_Hide_Tray_Icon(); // Windows would otherwise leave the icon behind until hovered
} }
// [global_hotkeys] was read with the settings, before there was a window to register them for. // [global_hotkeys] was read with the settings, before there was a window to register them for.
// The running instance has them; view mode leaves them alone. // The running instance has them; view mode leaves them alone.

View File

@ -17,6 +17,7 @@ Platform :: struct { // Windows
global_hotkeys_failed: string; // the combinations that could not be registered, for the main window; heap global_hotkeys_failed: string; // the combinations that could not be registered, for the main window; heap
tray_icon_configured: bool; // nid and its icon are ready; adding it can still fail while Explorer is not tray_icon_configured: bool; // nid and its icon are ready; adding it can still fail while Explorer is not
tray_icon_failed: bool; // minimizing then goes to the taskbar; the main window says so tray_icon_failed: bool; // minimizing then goes to the taskbar; the main window says so
tray_icon_added: bool; // the icon is in the notification area now
hwnd: HWND; hwnd: HWND;
@ -173,8 +174,10 @@ WndProc :: (hWnd: HWND, message: u32, wParam: WPARAM, lParam: LPARAM) -> LRESULT
if swallow_hotkey_character && (message == WM_KEYDOWN || message == WM_SYSKEYDOWN) return 0; if swallow_hotkey_character && (message == WM_KEYDOWN || message == WM_SYSKEYDOWN) return 0;
if taskbar_created_message && message == taskbar_created_message { if taskbar_created_message && message == taskbar_created_message {
// Without the icon, a window hidden in the tray could only come back by hotkey. // The icon stays for as long as the app runs, so it goes back. Without it, a window hidden
if app.minimized_to_tray && !Win32_Show_Tray_Icon() { // in the tray could only come back by hotkey.
tray_icon_added = false;
if !Win32_Show_Tray_Icon() && app.minimized_to_tray {
ShowWindow(hwnd, SW_MINIMIZE); ShowWindow(hwnd, SW_MINIMIZE);
app.minimized_to_tray = false; app.minimized_to_tray = false;
} }
@ -346,9 +349,11 @@ win32_virtual_key :: (key: ImGui.Key) -> u32 {
return 0; return 0;
} }
// Also fails while Explorer is not running, so it is checked on every call. // Adds the icon unless it is already there. Fails while Explorer is not running, so a failed add
// is tried again on the next call.
Win32_Show_Tray_Icon :: () -> bool { using platform; Win32_Show_Tray_Icon :: () -> bool { using platform;
if !tray_icon_configured return false; if !tray_icon_configured return false;
if tray_icon_added return true;
if !cast(bool) Shell_NotifyIconW(NIM_ADD, *nid) { if !cast(bool) Shell_NotifyIconW(NIM_ADD, *nid) {
log_error("Shell_NotifyIconW(NIM_ADD) failed; minimizing to the taskbar instead of the tray."); log_error("Shell_NotifyIconW(NIM_ADD) failed; minimizing to the taskbar instead of the tray.");
os_log_error(); os_log_error();
@ -356,11 +361,13 @@ Win32_Show_Tray_Icon :: () -> bool { using platform;
return false; return false;
} }
tray_icon_failed = false; // an earlier failure while Explorer was down has passed tray_icon_failed = false; // an earlier failure while Explorer was down has passed
tray_icon_added = true;
return true; return true;
} }
Win32_Hide_Tray_Icon :: () { using platform; Win32_Hide_Tray_Icon :: () { using platform;
if tray_icon_configured Shell_NotifyIconW(NIM_DELETE, *nid); if tray_icon_added Shell_NotifyIconW(NIM_DELETE, *nid);
tray_icon_added = false;
} }
Win32_Set_Tray_Icon :: () { using platform; Win32_Set_Tray_Icon :: () { using platform;
@ -386,13 +393,9 @@ Win32_Set_Tray_Icon :: () { using platform;
nid.hIcon = tray_icon; nid.hIcon = tray_icon;
memcpy(nid.szTip.data, Tooltip_Text_u16, Tooltip_Text.count * size_of(u16)); memcpy(nid.szTip.data, Tooltip_Text_u16, Tooltip_Text.count * size_of(u16));
// Configured even if this first add fails: at autostart Explorer's notification area may not be // Configured even if this first add fails: at autostart Explorer's notification area may not be
// ready yet, and Win32_Show_Tray_Icon adds the icon again on every minimize. // ready yet, and Win32_Show_Tray_Icon tries again on every minimize and when Explorer starts.
tray_icon_configured = true; tray_icon_configured = true;
if !cast(bool) Shell_NotifyIconW(NIM_ADD, *nid) { Win32_Show_Tray_Icon();
log_error("Shell_NotifyIconW(NIM_ADD) failed; minimizing to the taskbar until it succeeds.");
os_log_error();
tray_icon_failed = true;
}
} }
// ImGui rescales the fonts per monitor by itself, but the theme's sizes are baked at one scale, so // ImGui rescales the fonts per monitor by itself, but the theme's sizes are baked at one scale, so
@ -431,7 +434,6 @@ Win32_Restore_Window_From_Tray :: () {
if app.minimized_to_tray { if app.minimized_to_tray {
ShowWindow(hwnd, SW_SHOW); ShowWindow(hwnd, SW_SHOW);
app.minimized_to_tray = false; app.minimized_to_tray = false;
Win32_Hide_Tray_Icon();
} }
} }

View File

@ -49,13 +49,6 @@ platform_restore_window :: () {
// A global hotkey arrives while another app is active, and raising the window alone does not // A global hotkey arrives while another app is active, and raising the window alone does not
// make this the active app. // make this the active app.
NSApplication.activateIgnoringOtherApps(NSApplication.sharedApplication(), YES); NSApplication.activateIgnoringOtherApps(NSApplication.sharedApplication(), YES);
platform_hide_tray_icon();
}
#if OS == .LINUX {
// Right now, this doesn't work on my XFCE Arch Desktop, so I'm just going to leave the icon in the tray. Sad.
if platform.desktop_environment == .XFCE {
log("platform_hide_tray_icon is broken on XFCE, so it is currently disabled!");
} else platform_hide_tray_icon();
} }
app.minimized_to_tray = false; app.minimized_to_tray = false;