Commit 7f4f6cf3 authored by Trent Apted's avatar Trent Apted Committed by Commit Bot

MacViews: Don't animate in web-modals after the first Show().

Implement the currently unimplemented (on mac) NativeWidget::
SetVisibilityAnimationTransition() for this. Autofill uses this
but not constrained windows.

Constrained windows on aura platforms have bespoke animation
suppression code, which is currently different to the desired
behavior on Mac (i.e. the very first "show" should animate).

Consolidate some of the animation logic in MacViews Widgets.

Bug: 767743
Change-Id: If49d139a66873e896e68030f69efdaa81a8dc948
Reviewed-on: https://chromium-review.googlesource.com/1146408Reviewed-by: default avatarMichael Wasserman <msw@chromium.org>
Reviewed-by: default avatarSidney San Martín <sdy@chromium.org>
Commit-Queue: Trent Apted <tapted@chromium.org>
Cr-Commit-Position: refs/heads/master@{#577343}
parent 86600c69
...@@ -106,6 +106,13 @@ void NativeWebContentsModalDialogManagerViews::Show() { ...@@ -106,6 +106,13 @@ void NativeWebContentsModalDialogManagerViews::Show() {
// shadows are below the constrained dialog in z-order when we do this. // shadows are below the constrained dialog in z-order when we do this.
shown_widgets_.insert(widget); shown_widgets_.insert(widget);
#endif #endif
#if !defined(USE_AURA)
// Don't re-animate when switching tabs. Note this is done on Mac only after
// the initial ShowWidget() call above, and then "sticks" for later calls.
// TODO(tapted): Consolidate this codepath with Aura.
widget->SetVisibilityAnimationTransition(views::Widget::ANIMATE_HIDE);
#endif
} }
void NativeWebContentsModalDialogManagerViews::Hide() { void NativeWebContentsModalDialogManagerViews::Hide() {
......
...@@ -213,8 +213,19 @@ class VIEWS_EXPORT BridgedNativeWidget ...@@ -213,8 +213,19 @@ class VIEWS_EXPORT BridgedNativeWidget
bool wants_to_be_visible() const { return wants_to_be_visible_; } bool wants_to_be_visible() const { return wants_to_be_visible_; }
bool in_fullscreen_transition() const { return in_fullscreen_transition_; } bool in_fullscreen_transition() const { return in_fullscreen_transition_; }
bool GetAnimate() const; // Enables or disables all window animations.
void SetAnimate(bool animate); void SetAnimationEnabled(bool animate);
// Sets which transitions will animate. Currently this only affects non-native
// animations. TODO(tapted): Use scoping to disable native animations at
// appropriate times as well.
void set_transitions_to_animate(int transitions) {
transitions_to_animate_ = transitions;
}
// Whether to run a custom animation for the provided |transition|.
bool ShouldRunCustomAnimationFor(
Widget::VisibilityTransition transition) const;
// ui::CATransactionCoordinator::PreCommitObserver implementation // ui::CATransactionCoordinator::PreCommitObserver implementation
bool ShouldWaitInPreCommit() override; bool ShouldWaitInPreCommit() override;
...@@ -326,6 +337,10 @@ class VIEWS_EXPORT BridgedNativeWidget ...@@ -326,6 +337,10 @@ class VIEWS_EXPORT BridgedNativeWidget
// window in AppKit coordinates is not actually changing in this case. // window in AppKit coordinates is not actually changing in this case.
gfx::Point last_window_frame_origin_; gfx::Point last_window_frame_origin_;
// The transition types to animate when not relying on native NSWindow
// animation behaviors. Bitmask of Widget::VisibilityTransition.
int transitions_to_animate_ = Widget::ANIMATE_BOTH;
// Whether this window wants to be fullscreen. If a fullscreen animation is in // Whether this window wants to be fullscreen. If a fullscreen animation is in
// progress then it might not be actually fullscreen. // progress then it might not be actually fullscreen.
bool target_fullscreen_state_; bool target_fullscreen_state_;
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include "base/command_line.h"
#include "base/logging.h" #include "base/logging.h"
#import "base/mac/foundation_util.h" #import "base/mac/foundation_util.h"
#include "base/mac/mac_util.h" #include "base/mac/mac_util.h"
...@@ -21,6 +22,7 @@ ...@@ -21,6 +22,7 @@
#include "ui/base/ime/input_method.h" #include "ui/base/ime/input_method.h"
#include "ui/base/ime/input_method_factory.h" #include "ui/base/ime/input_method_factory.h"
#include "ui/base/layout.h" #include "ui/base/layout.h"
#include "ui/base/ui_base_switches.h"
#include "ui/compositor/recyclable_compositor_mac.h" #include "ui/compositor/recyclable_compositor_mac.h"
#include "ui/gfx/geometry/dip_util.h" #include "ui/gfx/geometry/dip_util.h"
#import "ui/gfx/mac/coordinate_conversion.h" #import "ui/gfx/mac/coordinate_conversion.h"
...@@ -527,7 +529,7 @@ void BridgedNativeWidget::SetVisibilityState(WindowVisibilityState new_state) { ...@@ -527,7 +529,7 @@ void BridgedNativeWidget::SetVisibilityState(WindowVisibilityState new_state) {
// For non-sheet modal types, use the constrained window animations to make // For non-sheet modal types, use the constrained window animations to make
// the window appear. // the window appear.
if (GetAnimate() && native_widget_mac_->GetWidget()->IsModal()) { if (ShouldRunCustomAnimationFor(Widget::ANIMATE_SHOW)) {
show_animation_.reset( show_animation_.reset(
[[ModalShowAnimationWithLayer alloc] initWithBridgedNativeWidget:this]); [[ModalShowAnimationWithLayer alloc] initWithBridgedNativeWidget:this]);
...@@ -992,16 +994,31 @@ void BridgedNativeWidget::ReparentNativeView(NSView* native_view, ...@@ -992,16 +994,31 @@ void BridgedNativeWidget::ReparentNativeView(NSView* native_view,
} }
} }
bool BridgedNativeWidget::GetAnimate() const { void BridgedNativeWidget::SetAnimationEnabled(bool animate) {
return [window_ animationBehavior] != NSWindowAnimationBehaviorNone;
}
void BridgedNativeWidget::SetAnimate(bool animate) {
[window_ [window_
setAnimationBehavior:(animate ? NSWindowAnimationBehaviorDocumentWindow setAnimationBehavior:(animate ? NSWindowAnimationBehaviorDocumentWindow
: NSWindowAnimationBehaviorNone)]; : NSWindowAnimationBehaviorNone)];
} }
bool BridgedNativeWidget::ShouldRunCustomAnimationFor(
Widget::VisibilityTransition transition) const {
// The logic around this needs to change if new transition types are set.
// E.g. it would be nice to distinguish "hide" from "close". Mac currently
// treats "hide" only as "close". Hide (e.g. Cmd+h) should not animate on Mac.
constexpr int kSupported =
Widget::ANIMATE_SHOW | Widget::ANIMATE_HIDE | Widget::ANIMATE_NONE;
DCHECK_EQ(0, transitions_to_animate_ & ~kSupported);
// Custom animations are only used for tab-modals. Note this also checks the
// native animation property. Clearing that will also disable custom
// animations to ensure that the views::Widget API behaves consistently.
return (transitions_to_animate_ & transition) &&
native_widget_mac_->GetWidget()->IsModal() &&
[window_ animationBehavior] != NSWindowAnimationBehaviorNone &&
!base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableModalAnimations);
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// BridgedNativeWidget, ui::CATransactionObserver // BridgedNativeWidget, ui::CATransactionObserver
......
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#include <utility> #include <utility>
#include "base/bind.h" #include "base/bind.h"
#include "base/command_line.h"
#include "base/mac/foundation_util.h" #include "base/mac/foundation_util.h"
#include "base/mac/scoped_nsobject.h" #include "base/mac/scoped_nsobject.h"
#include "base/strings/sys_string_conversions.h" #include "base/strings/sys_string_conversions.h"
...@@ -17,7 +16,6 @@ ...@@ -17,7 +16,6 @@
#include "components/crash/core/common/crash_key.h" #include "components/crash/core/common/crash_key.h"
#import "ui/base/cocoa/constrained_window/constrained_window_animation.h" #import "ui/base/cocoa/constrained_window/constrained_window_animation.h"
#import "ui/base/cocoa/window_size_constants.h" #import "ui/base/cocoa/window_size_constants.h"
#include "ui/base/ui_base_switches.h"
#include "ui/display/display.h" #include "ui/display/display.h"
#include "ui/display/screen.h" #include "ui/display/screen.h"
#include "ui/gfx/font_list.h" #include "ui/gfx/font_list.h"
...@@ -50,11 +48,6 @@ ...@@ -50,11 +48,6 @@
namespace views { namespace views {
namespace { namespace {
bool AreModalAnimationsEnabled() {
return !base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableModalAnimations);
}
NSInteger StyleMaskForParams(const Widget::InitParams& params) { NSInteger StyleMaskForParams(const Widget::InitParams& params) {
// If the Widget is modal, it will be displayed as a sheet. This works best if // If the Widget is modal, it will be displayed as a sheet. This works best if
// it has NSTitledWindowMask. For example, with NSBorderlessWindowMask, the // it has NSTitledWindowMask. For example, with NSBorderlessWindowMask, the
...@@ -402,8 +395,7 @@ void NativeWidgetMac::Close() { ...@@ -402,8 +395,7 @@ void NativeWidgetMac::Close() {
} }
// For other modal types, animate the close. // For other modal types, animate the close.
if (bridge_->GetAnimate() && AreModalAnimationsEnabled() && if (bridge_->ShouldRunCustomAnimationFor(Widget::ANIMATE_HIDE)) {
delegate_->IsModal()) {
[ViewsNSWindowCloseAnimator closeWindowWithAnimation:window]; [ViewsNSWindowCloseAnimator closeWindowWithAnimation:window];
return; return;
} }
...@@ -634,7 +626,7 @@ void NativeWidgetMac::EndMoveLoop() { ...@@ -634,7 +626,7 @@ void NativeWidgetMac::EndMoveLoop() {
void NativeWidgetMac::SetVisibilityChangedAnimationsEnabled(bool value) { void NativeWidgetMac::SetVisibilityChangedAnimationsEnabled(bool value) {
if (bridge_) if (bridge_)
bridge_->SetAnimate(value); bridge_->SetAnimationEnabled(value);
} }
void NativeWidgetMac::SetVisibilityAnimationDuration( void NativeWidgetMac::SetVisibilityAnimationDuration(
...@@ -644,7 +636,8 @@ void NativeWidgetMac::SetVisibilityAnimationDuration( ...@@ -644,7 +636,8 @@ void NativeWidgetMac::SetVisibilityAnimationDuration(
void NativeWidgetMac::SetVisibilityAnimationTransition( void NativeWidgetMac::SetVisibilityAnimationTransition(
Widget::VisibilityTransition transition) { Widget::VisibilityTransition transition) {
NOTIMPLEMENTED(); if (bridge_)
bridge_->set_transitions_to_animate(transition);
} }
bool NativeWidgetMac::IsTranslucentWindowOpacitySupported() const { bool NativeWidgetMac::IsTranslucentWindowOpacitySupported() const {
......
...@@ -1218,12 +1218,24 @@ TEST_F(NativeWidgetMacTest, ShowAnimationControl) { ...@@ -1218,12 +1218,24 @@ TEST_F(NativeWidgetMacTest, ShowAnimationControl) {
retained_animation.reset(); retained_animation.reset();
// Disable animations and show again. // Disable animations and show again.
modal_dialog_widget->SetVisibilityChangedAnimationsEnabled(false); modal_dialog_widget->SetVisibilityAnimationTransition(Widget::ANIMATE_NONE);
modal_dialog_widget->Show(); modal_dialog_widget->Show();
EXPECT_FALSE(test_api.show_animation()); // No animation this time. EXPECT_FALSE(test_api.show_animation()); // No animation this time.
modal_dialog_widget->Hide(); modal_dialog_widget->Hide();
// Test after re-enabling. // Test after re-enabling.
modal_dialog_widget->SetVisibilityAnimationTransition(Widget::ANIMATE_BOTH);
modal_dialog_widget->Show();
EXPECT_TRUE(test_api.show_animation());
retained_animation.reset(test_api.show_animation(),
base::scoped_policy::RETAIN);
// Test whether disabling native animations also disables custom modal ones.
modal_dialog_widget->SetVisibilityChangedAnimationsEnabled(false);
modal_dialog_widget->Show();
EXPECT_FALSE(test_api.show_animation()); // No animation this time.
modal_dialog_widget->Hide();
// Renable.
modal_dialog_widget->SetVisibilityChangedAnimationsEnabled(true); modal_dialog_widget->SetVisibilityChangedAnimationsEnabled(true);
modal_dialog_widget->Show(); modal_dialog_widget->Show();
EXPECT_TRUE(test_api.show_animation()); EXPECT_TRUE(test_api.show_animation());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment