diff --git a/mailnews/base/src/MailNotificationManager.jsm b/mailnews/base/src/MailNotificationManager.jsm index b20ab2fd41..76361dc612 100644 --- a/mailnews/base/src/MailNotificationManager.jsm +++ b/mailnews/base/src/MailNotificationManager.jsm @@ -75,7 +75,7 @@ class MailNotificationManager { Services.obs.addObserver(this, "new-directed-incoming-message"); } if (AppConstants.platform == "win") { - Services.obs.addObserver(this, "window-restored-from-tray"); + Services.obs.addObserver(this, "windows-refresh-badge-tray"); Services.prefs.addObserver("mail.biff.show_badge", this); } } @@ -99,7 +99,7 @@ class MailNotificationManager { case "new-directed-incoming-messenger": this._animateDockIcon(); return; - case "window-restored-from-tray": + case "windows-refresh-badge-tray": this._updateUnreadCount(); return; case "profile-before-change": diff --git a/mailnews/base/src/nsMessengerWinIntegration.cpp b/mailnews/base/src/nsMessengerWinIntegration.cpp index 3345997441..e2ed1c3078 100644 --- a/mailnews/base/src/nsMessengerWinIntegration.cpp +++ b/mailnews/base/src/nsMessengerWinIntegration.cpp @@ -106,63 +106,93 @@ LRESULT CALLBACK nsMessengerWinIntegration::IconWindowProc(HWND msgWindow, UINT msg, WPARAM wp, LPARAM lp) { nsresult rv; - if (msg == WM_USER && lp == WM_LBUTTONDOWN) { - nsCOMPtr prefBranch = - do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, FALSE); - bool showTrayIcon; - rv = prefBranch->GetBoolPref(SHOW_TRAY_ICON_PREF, &showTrayIcon); - NS_ENSURE_SUCCESS(rv, FALSE); - if (!showTrayIcon || !sUnreadCount) { - ::Shell_NotifyIconW(NIM_DELETE, &sMailIconData); - if (auto instance = reinterpret_cast( - ::GetWindowLongPtrW(msgWindow, GWLP_USERDATA))) { - instance->mTrayIconShown = false; + static UINT sTaskbarRecreated; + + switch (msg) { + case WM_USER: + if (msg == WM_USER && lp == WM_LBUTTONDOWN) { + nsCOMPtr prefBranch = + do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, FALSE); + bool showTrayIcon; + rv = prefBranch->GetBoolPref(SHOW_TRAY_ICON_PREF, &showTrayIcon); + NS_ENSURE_SUCCESS(rv, FALSE); + if (!showTrayIcon || !sUnreadCount) { + ::Shell_NotifyIconW(NIM_DELETE, &sMailIconData); + if (auto instance = reinterpret_cast( + ::GetWindowLongPtrW(msgWindow, GWLP_USERDATA))) { + instance->mTrayIconShown = false; + } + } + + // No minimzed window, bring the most recent 3pane window to the front. + if (sHiddenWindows.Length() == 0) { + nsCOMPtr windowMediator = + do_GetService(NS_WINDOWMEDIATOR_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, FALSE); + + nsCOMPtr domWindow; + rv = windowMediator->GetMostRecentBrowserWindow( + getter_AddRefs(domWindow)); + NS_ENSURE_SUCCESS(rv, FALSE); + if (domWindow) { + activateWindow(domWindow); + return TRUE; + } + } + + // Bring the minimized windows to the front. + for (uint32_t i = 0; i < sHiddenWindows.Length(); i++) { + auto window = sHiddenWindows.SafeElementAt(i); + if (!window) { + continue; + } + window->SetVisibility(true); + + nsCOMPtr widget; + window->GetMainWidget(getter_AddRefs(widget)); + if (!widget) { + continue; + } + + HWND hwnd = (HWND)(widget->GetNativeData(NS_NATIVE_WIDGET)); + ::ShowWindow(hwnd, SW_RESTORE); + ::SetForegroundWindow(hwnd); + + nsCOMPtr obs = + mozilla::services::GetObserverService(); + obs->NotifyObservers(window, "windows-refresh-badge-tray", 0); + } + + sHiddenWindows.Clear(); } - } - - // No minimzed window, bring the most recent 3pane window to the front. - if (sHiddenWindows.Length() == 0) { - nsCOMPtr windowMediator = - do_GetService(NS_WINDOWMEDIATOR_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, FALSE); - - nsCOMPtr domWindow; - rv = - windowMediator->GetMostRecentBrowserWindow(getter_AddRefs(domWindow)); - NS_ENSURE_SUCCESS(rv, FALSE); - if (domWindow) { - activateWindow(domWindow); - return TRUE; + break; + case WM_CREATE: + sTaskbarRecreated = ::RegisterWindowMessageW(L"TaskbarCreated"); + break; + default: + if (msg == sTaskbarRecreated) { + // When taskbar is recreated (e.g. by restarting Windows Explorer), all + // tray icons are removed. If there are windows minimized to tray icon, + // we have to recreate the tray icon, otherwise the windows can't be + // restored. + if (auto instance = reinterpret_cast( + ::GetWindowLongPtrW(msgWindow, GWLP_USERDATA))) { + instance->mTrayIconShown = false; + } + for (uint32_t i = 0; i < sHiddenWindows.Length(); i++) { + auto window = sHiddenWindows.SafeElementAt(i); + if (!window) { + continue; + } + nsCOMPtr obs = + mozilla::services::GetObserverService(); + obs->NotifyObservers(window, "windows-refresh-badge-tray", 0); + } } - } - - // Bring the minimized windows to the front. - for (uint32_t i = 0; i < sHiddenWindows.Length(); i++) { - auto window = sHiddenWindows.SafeElementAt(i); - if (!window) { - continue; - } - window->SetVisibility(true); - - nsCOMPtr widget; - window->GetMainWidget(getter_AddRefs(widget)); - if (!widget) { - continue; - } - - HWND hwnd = (HWND)(widget->GetNativeData(NS_NATIVE_WIDGET)); - ::ShowWindow(hwnd, SW_RESTORE); - ::SetForegroundWindow(hwnd); - - nsCOMPtr obs = - mozilla::services::GetObserverService(); - obs->NotifyObservers(window, "window-restored-from-tray", 0); - } - - sHiddenWindows.Clear(); + break; } - return TRUE; + return ::DefWindowProc(msgWindow, msg, wp, lp); } nsresult nsMessengerWinIntegration::HideWindow(nsIBaseWindow* aWindow) {