Bug 1156934 - Notify all content processes when LookAndFeel changes. r=jesup
authorEmilio Cobos Álvarez <emilio@crisal.io>
Sat, 23 May 2020 14:28:40 +0000
changeset 531775 360c1a12d594f6876ebfe2a7e8d46161befe4b09
parent 531774 3883a1bffcbee3c00df6c0388c16b86d707e36ec
child 531776 ea0f8a5cacdce1f500f00df62ade438a55a52e3c
push id37443
push usercbrindusan@mozilla.com
push dateSat, 23 May 2020 21:42:57 +0000
treeherdermozilla-central@9a2f741cef6a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjesup
bugs1156934
milestone78.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1156934 - Notify all content processes when LookAndFeel changes. r=jesup This should fix the issue for preallocated processes that still don't host any document, and also send a few less IPC messages. Differential Revision: https://phabricator.services.mozilla.com/D76537
dom/interfaces/base/nsIRemoteTab.idl
dom/ipc/BrowserChild.cpp
dom/ipc/BrowserChild.h
dom/ipc/BrowserHost.cpp
dom/ipc/BrowserParent.cpp
dom/ipc/BrowserParent.h
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/PBrowser.ipdl
dom/ipc/PContent.ipdl
layout/base/nsPresContext.cpp
--- a/dom/interfaces/base/nsIRemoteTab.idl
+++ b/dom/interfaces/base/nsIRemoteTab.idl
@@ -118,13 +118,9 @@ interface nsIRemoteTab : nsISupports
   void maybeCancelContentJSExecution(
       in nsIRemoteTab_NavigationType aNavigationType,
       [optional] in jsval aCancelContentJSOptions);
 
   /**
    * Notify the remote tab that the resolution has changed.
    */
   [noscript] void notifyResolutionChanged();
-  /**
-   * Notify the remote tab that system theme has changed.
-   */
-  [noscript] void notifyThemeChanged();
 };
--- a/dom/ipc/BrowserChild.cpp
+++ b/dom/ipc/BrowserChild.cpp
@@ -3173,31 +3173,16 @@ mozilla::ipc::IPCResult BrowserChild::Re
     nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(WebNavigation());
     baseWin->SetPositionAndSize(0, 0, screenSize.width, screenSize.height,
                                 nsIBaseWindow::eRepaint);
   }
 
   return IPC_OK();
 }
 
-mozilla::ipc::IPCResult BrowserChild::RecvThemeChanged(
-    nsTArray<LookAndFeelInt>&& aLookAndFeelIntCache) {
-  nsCOMPtr<Document> document(GetTopLevelDocument());
-  if (!document) {
-    return IPC_OK();
-  }
-
-  LookAndFeel::SetIntCache(aLookAndFeelIntCache);
-  RefPtr<nsPresContext> presContext = document->GetPresContext();
-  if (presContext) {
-    presContext->ThemeChanged();
-  }
-  return IPC_OK();
-}
-
 mozilla::ipc::IPCResult BrowserChild::RecvSafeAreaInsetsChanged(
     const mozilla::ScreenIntMargin& aSafeAreaInsets) {
   mPuppetWidget->UpdateSafeAreaInsets(aSafeAreaInsets);
 
   nsCOMPtr<nsIScreenManager> screenMgr =
       do_GetService("@mozilla.org/gfx/screenmanager;1");
   ScreenIntMargin currentSafeAreaInsets;
   if (screenMgr) {
--- a/dom/ipc/BrowserChild.h
+++ b/dom/ipc/BrowserChild.h
@@ -514,19 +514,16 @@ class BrowserChild final : public nsMess
     nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(webNav);
     return GetFrom(docShell);
   }
 
   mozilla::ipc::IPCResult RecvUIResolutionChanged(const float& aDpi,
                                                   const int32_t& aRounding,
                                                   const double& aScale);
 
-  mozilla::ipc::IPCResult RecvThemeChanged(
-      nsTArray<LookAndFeelInt>&& aLookAndFeelIntCache);
-
   mozilla::ipc::IPCResult RecvHandleAccessKey(const WidgetKeyboardEvent& aEvent,
                                               nsTArray<uint32_t>&& aCharCodes);
 
   mozilla::ipc::IPCResult RecvHandledWindowedPluginKeyEvent(
       const mozilla::NativeEventData& aKeyEventData, const bool& aIsConsumed);
 
   mozilla::ipc::IPCResult RecvPrint(const uint64_t& aOuterWindowID,
                                     const PrintData& aPrintData);
--- a/dom/ipc/BrowserHost.cpp
+++ b/dom/ipc/BrowserHost.cpp
@@ -184,26 +184,16 @@ BrowserHost::NotifyResolutionChanged(voi
     return NS_OK;
   }
   VisitAll([](BrowserParent* aBrowserParent) {
     aBrowserParent->NotifyResolutionChanged();
   });
   return NS_OK;
 }
 
-NS_IMETHODIMP
-BrowserHost::NotifyThemeChanged(void) {
-  if (!mRoot) {
-    return NS_OK;
-  }
-  VisitAll(
-      [](BrowserParent* aBrowserParent) { aBrowserParent->ThemeChanged(); });
-  return NS_OK;
-}
-
 /* void deprioritize (); */
 NS_IMETHODIMP
 BrowserHost::Deprioritize(void) {
   if (!mRoot) {
     return NS_OK;
   }
   VisitAll(
       [](BrowserParent* aBrowserParent) { aBrowserParent->Deprioritize(); });
--- a/dom/ipc/BrowserParent.cpp
+++ b/dom/ipc/BrowserParent.cpp
@@ -1114,27 +1114,16 @@ DimensionInfo BrowserParent::GetDimensio
 
 void BrowserParent::SizeModeChanged(const nsSizeMode& aSizeMode) {
   if (!mIsDestroyed && aSizeMode != mSizeMode) {
     mSizeMode = aSizeMode;
     Unused << SendSizeModeChanged(aSizeMode);
   }
 }
 
-void BrowserParent::ThemeChanged() {
-  if (!mIsDestroyed) {
-    // The theme has changed, and any cached values we had sent down
-    // to the child have been invalidated. When this method is called,
-    // LookAndFeel should have the up-to-date values, which we now
-    // send down to the child. We do this for every remote tab for now,
-    // but bug 1156934 has been filed to do it once per content process.
-    Unused << SendThemeChanged(LookAndFeel::GetIntCache());
-  }
-}
-
 #if defined(MOZ_WIDGET_ANDROID)
 void BrowserParent::DynamicToolbarMaxHeightChanged(ScreenIntCoord aHeight) {
   if (!mIsDestroyed) {
     Unused << SendDynamicToolbarMaxHeightChanged(aHeight);
   }
 }
 
 void BrowserParent::DynamicToolbarOffsetChanged(ScreenIntCoord aOffset) {
--- a/dom/ipc/BrowserParent.h
+++ b/dom/ipc/BrowserParent.h
@@ -503,18 +503,16 @@ class BrowserParent final : public PBrow
   void UpdateDimensions(const nsIntRect& aRect, const ScreenIntSize& aSize);
 
   DimensionInfo GetDimensionInfo();
 
   nsresult UpdatePosition();
 
   void SizeModeChanged(const nsSizeMode& aSizeMode);
 
-  void ThemeChanged();
-
   void HandleAccessKey(const WidgetKeyboardEvent& aEvent,
                        nsTArray<uint32_t>& aCharCodes);
 
 #if defined(MOZ_WIDGET_ANDROID)
   void DynamicToolbarMaxHeightChanged(ScreenIntCoord aHeight);
   void DynamicToolbarOffsetChanged(ScreenIntCoord aOffset);
 #endif
 
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -2312,16 +2312,23 @@ mozilla::ipc::IPCResult ContentChild::Re
     }
     auto status = result.visited() ? IHistory::VisitedStatus::Visited
                                    : IHistory::VisitedStatus::Unvisited;
     history->NotifyVisited(newURI, status);
   }
   return IPC_OK();
 }
 
+mozilla::ipc::IPCResult ContentChild::RecvThemeChanged(
+    nsTArray<LookAndFeelInt>&& aLookAndFeelIntCache) {
+  LookAndFeel::SetIntCache(aLookAndFeelIntCache);
+  LookAndFeel::NotifyChangedAllWindows();
+  return IPC_OK();
+}
+
 mozilla::ipc::IPCResult ContentChild::RecvLoadProcessScript(
     const nsString& aURL) {
   auto* global = ContentProcessMessageManager::Get();
   global->LoadScript(aURL);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult ContentChild::RecvAsyncMessage(
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -301,16 +301,17 @@ class ContentChild final : public PConte
 
   mozilla::ipc::IPCResult RecvSetConnectivity(const bool& connectivity);
   mozilla::ipc::IPCResult RecvSetCaptivePortalState(const int32_t& state);
 
   mozilla::ipc::IPCResult RecvBidiKeyboardNotify(const bool& isLangRTL,
                                                  const bool& haveBidiKeyboards);
 
   mozilla::ipc::IPCResult RecvNotifyVisited(nsTArray<VisitedQueryResult>&&);
+  mozilla::ipc::IPCResult RecvThemeChanged(nsTArray<LookAndFeelInt>&&);
 
   // auto remove when alertfinished is received.
   nsresult AddRemoteAlertObserver(const nsString& aData,
                                   nsIObserver* aObserver);
 
   mozilla::ipc::IPCResult RecvPreferenceUpdate(const Pref& aPref);
   mozilla::ipc::IPCResult RecvVarUpdate(const GfxVarUpdate& pref);
 
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -929,22 +929,16 @@ child:
      * and default scale with the notification.
      * If we don't know the dpi and default scale, we just pass in a negative
      * value (-1) but in the majority of the cases this saves us from two
      * sync requests from the child to the parent.
      */
     async UIResolutionChanged(float dpi, int32_t rounding, double scale);
 
     /**
-     * Tell the child that the system theme has changed, and that a repaint
-     * is necessary.
-     */
-    async ThemeChanged(LookAndFeelInt[] lookAndFeelIntCache);
-
-    /**
      * Tell the child that the safe area of widget has changed.
      *
      */
     async SafeAreaInsetsChanged(ScreenIntMargin aSafeAreaInsets);
 
     /**
      * Tell the browser that its frame loader has been swapped
      * with another.
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -534,16 +534,22 @@ child:
     async ClearImageCache(bool privateLoader, bool chrome);
 
     async SetOffline(bool offline);
     async SetConnectivity(bool connectivity);
     async SetCaptivePortalState(int32_t aState);
 
     async NotifyVisited(VisitedQueryResult[] uri);
 
+    /**
+     * Tell the child that the system theme has changed, and that a repaint
+     * is necessary.
+     */
+    async ThemeChanged(LookAndFeelInt[] lookAndFeelIntCache);
+
     async PreferenceUpdate(Pref pref);
     async VarUpdate(GfxVarUpdate var);
 
     async UpdatePerfStatsCollectionMask(uint64_t aMask);
     async CollectPerfStatsJSON() returns (nsCString aStats);
 
     async DataStoragePut(nsString aFilename, DataStorageItem aItem);
     async DataStorageRemove(nsString aFilename, nsCString aKey, DataStorageType aType);
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -14,16 +14,17 @@
 #  include "mozilla/AsyncEventDispatcher.h"
 #endif
 #include "mozilla/DebugOnly.h"
 #include "mozilla/Encoding.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventStateManager.h"
 #include "mozilla/PresShell.h"
 #include "mozilla/PresShellInlines.h"
+#include "mozilla/dom/ContentParent.h"
 
 #include "base/basictypes.h"
 
 #include "nsCOMPtr.h"
 #include "nsCSSFrameConstructor.h"
 #include "nsDocShell.h"
 #include "nsIContentViewer.h"
 #include "nsPIDOMWindow.h"
@@ -1342,32 +1343,29 @@ void nsPresContext::ThemeChangedInternal
     // Clear all cached LookAndFeel colors.
     LookAndFeel::Refresh();
     sLookAndFeelChanged = false;
 
     // Vector images (SVG) may be using theme colors so we discard all cached
     // surfaces. (We could add a vector image only version of DiscardAll, but
     // in bug 940625 we decided theme changes are rare enough not to bother.)
     image::SurfaceCacheUtils::DiscardAll();
+
+    if (XRE_IsParentProcess()) {
+      nsTArray<ContentParent*> cp;
+      ContentParent::GetAll(cp);
+      auto cache = LookAndFeel::GetIntCache();
+      for (ContentParent* c : cp) {
+        Unused << c->SendThemeChanged(cache);
+      }
+    }
   }
 
   RefreshSystemMetrics();
   PreferenceSheet::Refresh();
-
-  // Recursively notify all remote leaf descendants that the
-  // system theme has changed.
-  if (nsPIDOMWindowOuter* window = mDocument->GetWindow()) {
-    if (RefPtr<nsPIWindowRoot> topLevelWin = window->GetTopWindowRoot()) {
-      topLevelWin->EnumerateBrowsers(
-          [](nsIRemoteTab* aBrowserParent, void*) {
-            aBrowserParent->NotifyThemeChanged();
-          },
-          nullptr);
-    }
-  }
 }
 
 void nsPresContext::SysColorChanged() {
   if (!mPendingSysColorChanged) {
     sLookAndFeelChanged = true;
     nsCOMPtr<nsIRunnable> ev =
         NewRunnableMethod("nsPresContext::SysColorChangedInternal", this,
                           &nsPresContext::SysColorChangedInternal);