Bug 1639391: Do not call nsWindow::GetAttention for top-level windows being shown during session restore; r=mhowell

When we call nsWindow::Show but Firefox is not foreground, we show the window
and also flash it on the taskbar to get the user's attention.

This is really annoying when restoring a session with `N` windows, as the
user's taskbar ends up with all `N` of them stuck in a flashed state until the
user goes through and manually activates every single window.

There are several ways I thought of to address this, but I think the
simplest one is just to track whether or not we're in the middle of restoring a
session and skip flashing when we are doing so.

Differential Revision: https://phabricator.services.mozilla.com/D76406
This commit is contained in:
Aaron Klotz 2020-05-22 01:49:11 +00:00
Родитель d582323fcb
Коммит 9c0c057f3c
4 изменённых файлов: 50 добавлений и 20 удалений

Просмотреть файл

@ -12,6 +12,7 @@
#include "WinTaskbar.h"
#include "WinMouseScrollHandler.h"
#include "nsWindowDefs.h"
#include "nsWindow.h"
#include "nsString.h"
#include "WinIMEHandler.h"
#include "mozilla/widget/AudioSession.h"
@ -281,33 +282,52 @@ static void InitUIADetection() {
}
}
#endif // defined(ACCESSIBILITY)
NS_IMETHODIMP
nsAppShell::Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData) {
if (XRE_IsParentProcess() && !strcmp(aTopic, "dll-loaded-main-thread")) {
if (a11y::PlatformDisabledState() != a11y::ePlatformIsDisabled &&
!gUiaHook) {
nsDependentString dllName(aData);
if (XRE_IsParentProcess()) {
nsCOMPtr<nsIObserverService> obsServ(
mozilla::services::GetObserverService());
if (StringEndsWith(dllName, NS_LITERAL_STRING("uiautomationcore.dll"),
nsCaseInsensitiveStringComparator())) {
InitUIADetection();
#if defined(ACCESSIBILITY)
if (!strcmp(aTopic, "dll-loaded-main-thread")) {
if (a11y::PlatformDisabledState() != a11y::ePlatformIsDisabled &&
!gUiaHook) {
nsDependentString dllName(aData);
// Now that we've handled the observer notification, we can remove it
nsCOMPtr<nsIObserverService> obsServ(
mozilla::services::GetObserverService());
obsServ->RemoveObserver(this, "dll-loaded-main-thread");
if (StringEndsWith(dllName, NS_LITERAL_STRING("uiautomationcore.dll"),
nsCaseInsensitiveStringComparator())) {
InitUIADetection();
// Now that we've handled the observer notification, we can remove it
obsServ->RemoveObserver(this, "dll-loaded-main-thread");
}
}
return NS_OK;
}
#endif // defined(ACCESSIBILITY)
if (!strcmp(aTopic, "sessionstore-restoring-on-startup")) {
nsWindow::SetIsRestoringSession(true);
// Now that we've handled the observer notification, we can remove it
obsServ->RemoveObserver(this, "sessionstore-restoring-on-startup");
return NS_OK;
}
return NS_OK;
if (!strcmp(aTopic, "sessionstore-windows-restored")) {
nsWindow::SetIsRestoringSession(false);
// Now that we've handled the observer notification, we can remove it
obsServ->RemoveObserver(this, "sessionstore-windows-restored");
return NS_OK;
}
}
return nsBaseAppShell::Observe(aSubject, aTopic, aData);
}
#endif // defined(ACCESSIBILITY)
nsresult nsAppShell::Init() {
LSPAnnotate();
@ -374,12 +394,16 @@ nsresult nsAppShell::Init() {
ScreenHelperWin::RefreshScreens();
}
nsCOMPtr<nsIObserverService> obsServ(
mozilla::services::GetObserverService());
obsServ->AddObserver(this, "sessionstore-restoring-on-startup", false);
obsServ->AddObserver(this, "sessionstore-windows-restored", false);
#if defined(ACCESSIBILITY)
if (::GetModuleHandleW(L"uiautomationcore.dll")) {
InitUIADetection();
} else {
nsCOMPtr<nsIObserverService> obsServ(
mozilla::services::GetObserverService());
obsServ->AddObserver(this, "dll-loaded-main-thread", false);
}
#endif // defined(ACCESSIBILITY)

Просмотреть файл

@ -40,11 +40,8 @@ class nsAppShell : public nsBaseAppShell {
protected:
NS_IMETHOD Run() override;
NS_IMETHOD Exit() override;
#if defined(ACCESSIBILITY)
NS_IMETHOD Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData) override;
#endif // defined(ACCESSIBILITY)
virtual void ScheduleNativeEventCallback();
virtual bool ProcessNextNativeEvent(bool mayWait);

Просмотреть файл

@ -274,6 +274,7 @@ LONG nsWindow::sLastClickCount = 0L;
BYTE nsWindow::sLastMouseButton = 0;
bool nsWindow::sHaveInitializedPrefs = false;
bool nsWindow::sIsRestoringSession = false;
TriStateBool nsWindow::sHasBogusPopupsDropShadowOnMultiMonitor = TRI_UNKNOWN;
@ -1615,7 +1616,10 @@ void nsWindow::Show(bool bState) {
::ShowWindow(mWnd, SW_SHOWNORMAL);
} else {
::ShowWindow(mWnd, SW_SHOWNOACTIVATE);
Unused << GetAttention(2);
// Don't flicker the window if we're restoring session
if (!sIsRestoringSession) {
Unused << GetAttention(2);
}
}
break;
}

Просмотреть файл

@ -306,6 +306,10 @@ class nsWindow final : public nsWindowBase {
void SetSmallIcon(HICON aIcon);
void SetBigIcon(HICON aIcon);
static void SetIsRestoringSession(const bool aIsRestoringSession) {
sIsRestoringSession = aIsRestoringSession;
}
/**
* AssociateDefaultIMC() associates or disassociates the default IMC for
* the window.
@ -621,6 +625,7 @@ class nsWindow final : public nsWindowBase {
static bool sJustGotActivate;
static bool sIsInMouseCapture;
static bool sHaveInitializedPrefs;
static bool sIsRestoringSession;
PlatformCompositorWidgetDelegate* mCompositorWidgetDelegate;