Browse Source

suppress fade animation when adding and removing WCVs

Jeremy Rose 2 years ago
parent
commit
fea43a4727

+ 2 - 0
filenames.gni

@@ -123,6 +123,8 @@ filenames = {
   lib_sources_mac = [
     "shell/app/electron_main_delegate_mac.h",
     "shell/app/electron_main_delegate_mac.mm",
+    "shell/browser/animation_util.h",
+    "shell/browser/animation_util_mac.mm",
     "shell/browser/api/electron_api_app_mac.mm",
     "shell/browser/api/electron_api_menu_mac.h",
     "shell/browser/api/electron_api_menu_mac.mm",

+ 18 - 0
shell/browser/animation_util.h

@@ -0,0 +1,18 @@
+// Copyright (c) 2022 Salesforce, Inc.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+#ifndef ELECTRON_SHELL_ANIMATION_UTIL_H_
+#define ELECTRON_SHELL_ANIMATION_UTIL_H_
+
+#include "build/build_config.h"
+
+#if BUILDFLAG(IS_MAC)
+class ScopedCAActionDisabler {
+ public:
+  ScopedCAActionDisabler();
+  ~ScopedCAActionDisabler();
+};
+#endif
+
+#endif

+ 17 - 0
shell/browser/animation_util_mac.mm

@@ -0,0 +1,17 @@
+// Copyright (c) 2022 Salesforce, Inc.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+#include "shell/browser/animation_util.h"
+
+#import <QuartzCore/QuartzCore.h>
+
+// Disables actions within a scope.
+ScopedCAActionDisabler::ScopedCAActionDisabler() {
+  [CATransaction begin];
+  [CATransaction setDisableActions:YES];
+}
+
+ScopedCAActionDisabler::~ScopedCAActionDisabler() {
+  [CATransaction commit];
+}

+ 19 - 0
shell/browser/api/electron_api_view.cc

@@ -22,6 +22,10 @@
 #include "ui/views/layout/flex_layout.h"
 #include "ui/views/layout/layout_manager_base.h"
 
+#if BUILDFLAG(IS_MAC)
+#include "shell/browser/animation_util.h"
+#endif
+
 namespace gin {
 
 template <>
@@ -188,6 +192,18 @@ void View::AddChildViewAt(gin::Handle<View> child, size_t index) {
     return;
   child_views_.emplace(child_views_.begin() + index,     // index
                        isolate(), child->GetWrapper());  // v8::Global(args...)
+#if BUILDFLAG(IS_MAC)
+  // Disable the implicit CALayer animations that happen by default when adding
+  // or removing sublayers.
+  // See
+  // https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreAnimation_guide/ReactingtoLayerChanges/ReactingtoLayerChanges.html
+  // and https://github.com/electron/electron/pull/14911
+  // TODO(nornagon): Disabling these CALayer animations (which are specific to
+  // WebContentsView, I think) seems like this is something that remote_cocoa
+  // or views should be taking care of, but isn't. This should be pushed
+  // upstream.
+  ScopedCAActionDisabler disable_animations;
+#endif
   view_->AddChildViewAt(child->view(), index);
 }
 
@@ -195,6 +211,9 @@ void View::RemoveChildView(gin::Handle<View> child) {
   CHECK(view_);
   auto it = std::find(child_views_.begin(), child_views_.end(), child.ToV8());
   if (it != child_views_.end()) {
+#if BUILDFLAG(IS_MAC)
+    ScopedCAActionDisabler disable_animations;
+#endif
     view_->RemoveChildView(child->view());
     child_views_.erase(it);
   }