From: lx-s Date: Tue, 19 Dec 2023 15:06:34 +0000 (+0100) Subject: Added second tray icon to show updates because of Windows' balloon limitations X-Git-Tag: 2.4.9.0~20 X-Git-Url: https://repos.lx-s.de/gitweb/?a=commitdiff_plain;h=b0b69fa52e52080ac88d8b183015d9e0e36006b1;p=winmute.git Added second tray icon to show updates because of Windows' balloon limitations --- diff --git a/WinMute/TrayIcon.cpp b/WinMute/TrayIcon.cpp index 516c314..14de540 100644 --- a/WinMute/TrayIcon.cpp +++ b/WinMute/TrayIcon.cpp @@ -40,16 +40,19 @@ TrayIcon::TrayIcon() : TrayIcon::TrayIcon( HWND hWnd, UINT trayID, HICON hIcon, - const std::wstring& tooltip, bool show) - : initialized_(false), iconVisible_(false) + const std::wstring& tooltip, bool show, + int callbackId) + : initialized_(false), iconVisible_(false), callbackId_(callbackId) { Init(hWnd, trayID, hIcon, tooltip, show); } void TrayIcon::Init( HWND hWnd, UINT trayID, HICON hIcon, - const std::wstring& tooltip, bool show) + const std::wstring& tooltip, bool show, + int callbackId) { + callbackId_ = callbackId; if (!hIcon) { hIcon_ = LoadIcon(0, IDI_APPLICATION); } else { @@ -134,8 +137,7 @@ void TrayIcon::ChangeText(const std::wstring& tooltip) void TrayIcon::ShowPopup( const std::wstring& title, - const std::wstring& text, - int callbackID) const + const std::wstring& text) const { if (!initialized_) { TrayIconPopup popup; @@ -151,10 +153,6 @@ void TrayIcon::ShowPopup( tnid.uID = trayID_; tnid.uFlags = NIF_INFO | NIF_SHOWTIP; tnid.dwInfoFlags = NIIF_INFO | NIIF_NOSOUND | NIIF_LARGE_ICON | NIIF_RESPECT_QUIET_TIME; - if (callbackID != 0) { - tnid.uCallbackMessage = callbackID; - tnid.uFlags |= NIF_MESSAGE; - } tnid.uTimeout = 10 * 1000; StringCchCopy(tnid.szInfoTitle, ARRAY_SIZE(tnid.szInfoTitle), title.c_str()); StringCchCopy(tnid.szInfo, ARRAY_SIZE(tnid.szInfo), text.c_str()); @@ -179,10 +177,10 @@ bool TrayIcon::AddNotifyIcon() tnid.uID = trayID_; tnid.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE | NIF_SHOWTIP; tnid.hIcon = hIcon_; - tnid.uCallbackMessage = WM_TRAYICON; + tnid.uCallbackMessage = callbackId_; if (SUCCEEDED(StringCchCopy(tnid.szTip, ARRAY_SIZE(tnid.szTip), tooltip_.c_str()))) { - return Shell_NotifyIcon(NIM_ADD, &tnid) != 0; + return Shell_NotifyIconW(NIM_ADD, &tnid) != 0; } return false; } diff --git a/WinMute/TrayIcon.h b/WinMute/TrayIcon.h index f5d3d12..288234c 100644 --- a/WinMute/TrayIcon.h +++ b/WinMute/TrayIcon.h @@ -46,10 +46,10 @@ class TrayIcon { public: TrayIcon(); TrayIcon(HWND hWnd, UINT trayID, HICON hIcon, const std::wstring& tooltip, - bool show); + bool show, int callbackId = WM_TRAYICON); ~TrayIcon(); void Init(HWND hWnd, UINT trayID, HICON hIcon, const std::wstring& tooltip, - bool show); + bool show, int callbackId = WM_TRAYICON); void Hide(); void Show(); bool IsShown() const noexcept { return iconVisible_; } @@ -57,8 +57,7 @@ public: void ChangeText(const std::wstring& tooltip); void ShowPopup( const std::wstring& title, - const std::wstring& text, - int callbackID = 0) const; + const std::wstring& text) const; private: void DestroyTrayIcon(); @@ -66,8 +65,10 @@ private: bool RemoveNotifyIcon(); bool ChangeText(); + mutable std::vector popupQueue_; + int callbackId_; bool initialized_; bool iconVisible_; UINT trayID_; diff --git a/WinMute/WinMute.cpp b/WinMute/WinMute.cpp index fa8123b..9b987e6 100644 --- a/WinMute/WinMute.cpp +++ b/WinMute/WinMute.cpp @@ -164,7 +164,7 @@ bool WinMute::InitAudio() return false; } - if (!muteCtrl_.Init(hWnd_, &trayIcon_)) { + if (!muteCtrl_.Init(hWnd_, &wmTray_)) { return false; } @@ -241,7 +241,13 @@ bool WinMute::Init() ShowWindowsError(_T("LoadIcon")); return false; } - trayIcon_.Init(hWnd_, 0, hTrayIcon_, L"WinMute", true); + hUpdateIcon_ = LoadIconW(hglobInstance, MAKEINTRESOURCE(IDI_APPUPDATE)); + if (hUpdateIcon_ == nullptr) { + ShowWindowsError(_T("LoadIcon")); + return false; + } + wmTray_.Init(hWnd_, 0, hTrayIcon_, L"WinMute", true); + updateTray_.Init(hWnd_, 1, hUpdateIcon_, L"WinMute Update", false, WM_WINMUTE_UPDATE_POPUP); quietHours_.Init(hWnd_, settings_); @@ -249,7 +255,7 @@ bool WinMute::Init() if (settings_.QueryValue(SettingsKey::MUTE_ON_RDP) && IsCurrentSessionRemoteable()) { - trayIcon_.ShowPopup( + wmTray_.ShowPopup( i18n_.GetTranslationW("popup.remote-session-detected.title"), i18n_.GetTranslationW("popup.remote-session-detected.text")); muteCtrl_.SetMute(true); @@ -311,7 +317,7 @@ bool WinMute::LoadSettings() btDetector_.Unload(); } else { if (!btDetector_.Init(hWnd_)) { - trayIcon_.ShowPopup( + wmTray_.ShowPopup( i18n_.GetTranslationW("popup.bluetooth-muting-disabled.title"), i18n_.GetTranslationW("popup.bluetooth-muting-disabled.text")); settings_.SetValue(SettingsKey::MUTE_ON_BLUETOOTH, FALSE); @@ -327,7 +333,7 @@ bool WinMute::LoadSettings() wifiDetector_.Unload(); } else { if (!wifiDetector_.Init(hWnd_)) { - trayIcon_.ShowPopup( + wmTray_.ShowPopup( i18n_.GetTranslationW("popup.wlan-muting-disabled.title"), i18n_.GetTranslationW("popup.wlan-muting-disabled.text")); settings_.SetValue(SettingsKey::MUTE_ON_WLAN, FALSE); @@ -402,7 +408,7 @@ void WinMute::CheckForUpdatesAsync(std::unique_ptr updateChecker) return; } if (!updateChecker->GetUpdateInfo(updateInfo_)) { - trayIcon_.ShowPopup( + wmTray_.ShowPopup( i18n_.GetTranslationW("popup.error.update-check-failed.title"), i18n_.GetTranslationW("popup.error.update-check-failed.text")); } else if (updateInfo_.beta.shouldUpdate && betaUpdates) { @@ -412,7 +418,8 @@ void WinMute::CheckForUpdatesAsync(std::unique_ptr updateChecker) const std::wstring popupText = std::vformat( i18n_.GetTranslationW("popup.update-available-beta.text"), std::make_wformat_args(updateInfo_.currentVersion)); - trayIcon_.ShowPopup(popupTitle, popupText, WM_WINMUTE_UPDATE_POPUP); + updateTray_.Show(); + updateTray_.ShowPopup(popupTitle, popupText); } else if (updateInfo_.beta.shouldUpdate) { const std::wstring popupTitle = std::vformat( i18n_.GetTranslationW("popup.update-available.title"), @@ -420,7 +427,8 @@ void WinMute::CheckForUpdatesAsync(std::unique_ptr updateChecker) const std::wstring popupText = std::vformat( i18n_.GetTranslationW("popup.update-available.text"), std::make_wformat_args(updateInfo_.currentVersion)); - trayIcon_.ShowPopup(popupTitle, popupText, WM_WINMUTE_UPDATE_POPUP); + updateTray_.Show(); + updateTray_.ShowPopup(popupTitle, popupText); } } @@ -518,10 +526,9 @@ LRESULT WinMute::OnCommand(HWND hWnd, WPARAM wParam, LPARAM) LRESULT WinMute::OnTrayIcon(HWND hWnd, WPARAM, LPARAM lParam) { - switch (lParam) { - case WM_LBUTTONUP: - case WM_RBUTTONUP: - { + if (LOWORD(lParam) == WM_CONTEXTMENU || + lParam == WM_LBUTTONUP || + lParam == WM_RBUTTONUP) { POINT p = { 0 }; GetCursorPos(&p); SetForegroundWindow(hWnd); @@ -529,10 +536,6 @@ LRESULT WinMute::OnTrayIcon(HWND hWnd, WPARAM, LPARAM lParam) GetSubMenu(hTrayMenu_, 0), TPM_NONOTIFY | TPM_TOPALIGN | TPM_LEFTALIGN, p.x, p.y, hWnd_, nullptr); - break; - } - default: - break; } return TRUE; } @@ -567,7 +570,7 @@ LRESULT WinMute::OnQuietHours(HWND, UINT msg, WPARAM, LPARAM) if (msg == WM_WINMUTE_QUIETHOURS_START) { muteCtrl_.NotifyQuietHours(true); if (settings_.QueryValue(SettingsKey::QUIETHOURS_NOTIFICATIONS)) { - trayIcon_.ShowPopup( + wmTray_.ShowPopup( i18n_.GetTranslationW("popup.quiet-hours-started.title"), i18n_.GetTranslationW("popup.quiet-hours-started.text")); } @@ -576,7 +579,7 @@ LRESULT WinMute::OnQuietHours(HWND, UINT msg, WPARAM, LPARAM) } else if (msg == WM_WINMUTE_QUIETHOURS_END) { muteCtrl_.NotifyQuietHours(false); if (settings_.QueryValue(SettingsKey::QUIETHOURS_NOTIFICATIONS)) { - trayIcon_.ShowPopup( + wmTray_.ShowPopup( i18n_.GetTranslationW("popup.quiet-hours-ended.title"), i18n_.GetTranslationW("popup.quiet-hours-ended.text")); } @@ -622,7 +625,7 @@ LRESULT WinMute::OnWifiStatusChange(HWND, WPARAM wParam, LPARAM lParam) i18n_.GetTranslationW("popup.wlan-is-on-mute-list.text"), std::make_wformat_args(wifiName)); } - trayIcon_.ShowPopup( + wmTray_.ShowPopup( i18n_.GetTranslationW("popup.workstation-muted.title"), popupMsg); delete[] wifiName; @@ -646,6 +649,9 @@ LRESULT WinMute::OnUpdatePopup(HWND hWnd, WPARAM, LPARAM lParam) nullptr, nullptr, SW_SHOW); } } + if (lParam == NIN_BALLOONHIDE || lParam == NIN_BALLOONTIMEOUT || lParam == NIN_BALLOONUSERCLICK) { + updateTray_.Hide(); + } return 0; } @@ -701,8 +707,8 @@ LRESULT CALLBACK WinMute::WindowProc( return OnSettingChange(hWnd, wParam, lParam); default: if (msg == uTaskbarRestart) { // Restore trayicon if explorer.exe crashes - trayIcon_.Hide(); - trayIcon_.Show(); + wmTray_.Hide(); + wmTray_.Show(); } break; } diff --git a/WinMute/WinMute.h b/WinMute/WinMute.h index 25481c0..4038e44 100644 --- a/WinMute/WinMute.h +++ b/WinMute/WinMute.h @@ -57,6 +57,7 @@ private: HMENU hTrayMenu_; HICON hAppIcon_; HICON hTrayIcon_; + HICON hUpdateIcon_; struct MuteConfig { MuteConfig(); @@ -65,7 +66,8 @@ private: bool muteOnBluetooth; } muteConfig_; - TrayIcon trayIcon_; + TrayIcon wmTray_; + TrayIcon updateTray_; WifiDetector wifiDetector_; WMSettings& settings_; WMi18n &i18n_; diff --git a/WinMute/WinMute.rc b/WinMute/WinMute.rc index 0a1a12e..ffde6c2 100644 --- a/WinMute/WinMute.rc +++ b/WinMute/WinMute.rc @@ -441,6 +441,8 @@ IDI_APP ICON "icons\\app.ico" IDI_SETTINGS ICON "icons\\settings.ico" +IDI_APPUPDATE ICON "icons\\app-update.ico" + ///////////////////////////////////////////////////////////////////////////// // diff --git a/WinMute/WinMute.vcxproj b/WinMute/WinMute.vcxproj index 10525f5..34d4712 100644 --- a/WinMute/WinMute.vcxproj +++ b/WinMute/WinMute.vcxproj @@ -224,6 +224,7 @@ + diff --git a/WinMute/WinMute.vcxproj.filters b/WinMute/WinMute.vcxproj.filters index 7ca23ba..ff30cb4 100644 --- a/WinMute/WinMute.vcxproj.filters +++ b/WinMute/WinMute.vcxproj.filters @@ -127,6 +127,9 @@ Resource Files + + Resource Files + diff --git a/WinMute/icons/app-update-512.png b/WinMute/icons/app-update-512.png new file mode 100644 index 0000000..48ec92f Binary files /dev/null and b/WinMute/icons/app-update-512.png differ diff --git a/WinMute/icons/app-update.ico b/WinMute/icons/app-update.ico new file mode 100644 index 0000000..d282626 Binary files /dev/null and b/WinMute/icons/app-update.ico differ diff --git a/WinMute/icons/app-update.svg b/WinMute/icons/app-update.svg new file mode 100644 index 0000000..fb056ac --- /dev/null +++ b/WinMute/icons/app-update.svg @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WinMute/icons/app.svg b/WinMute/icons/app.svg index beeeee3..89fe80e 100644 --- a/WinMute/icons/app.svg +++ b/WinMute/icons/app.svg @@ -29,8 +29,8 @@ inkscape:document-units="px" showguides="true" inkscape:zoom="1.1228082" - inkscape:cx="18.257793" - inkscape:cy="217.75758" + inkscape:cx="26.27341" + inkscape:cy="216.86696" inkscape:window-width="2560" inkscape:window-height="1009" inkscape:window-x="-8" @@ -148,8 +148,8 @@ transform="matrix(6.992757,0,0,6.7710102,-2420.2895,-308.68022)">! + id="tspan3">! diff --git a/WinMute/resource.h b/WinMute/resource.h index cac1163..fd04589 100644 --- a/WinMute/resource.h +++ b/WinMute/resource.h @@ -23,6 +23,8 @@ #define IDD_MANAGE_ENDPOINTS 135 #define IDD_DIALOG2 137 #define IDD_MANAGE_ENDPOINTS_ADD 137 +#define IDI_APP_UPDATE 141 +#define IDI_APPUPDATE 141 #define IDC_LINK_HOMEPAGE 1001 #define IDC_LINK_SUPPORT 1002 #define IDC_LINK_PROJECT 1002 @@ -45,7 +47,6 @@ #define IDC_CHECK_FOR_UPDATES_ON_STARTUP 1013 #define IDC_OPENLOG 1014 #define IDC_LICENSETEXT 1015 -#define IDC_CHECK_FOR_UPDATES_ON_STARTUP2 1015 #define IDC_CHECK_FOR_BETA_UPDATES 1015 #define IDC_ABOUT_TAB 1016 #define IDC_ABOUTTEXT 1019 @@ -154,7 +155,7 @@ // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 141 +#define _APS_NEXT_RESOURCE_VALUE 142 #define _APS_NEXT_COMMAND_VALUE 40041 #define _APS_NEXT_CONTROL_VALUE 1072 #define _APS_NEXT_SYMED_VALUE 101