Commit ed9269ec authored by Sammie Quon's avatar Sammie Quon Committed by Commit Bot

desks: Allow multiple keyboard press to switch desks quickly.

Second CL to allow chaining keyboard shortcuts.

Follow up to crrev.com/c/2354798 which allows RootWindowDeskSwitch to
handle more than two screenshots. This CL fills it out by handling
taking third and fourth screenshots and placing them on the animation
layer to get a nice smooth continuous animation. Tests in a follow up.

Test: manual
Bug: 1111445, 1068508
Change-Id: I33f4a26ae794fca799888953b23d617a9f8d0832
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2376418
Commit-Queue: Sammie Quon <sammiequon@chromium.org>
Reviewed-by: default avatarAhmed Fakhry <afakhry@chromium.org>
Cr-Commit-Position: refs/heads/master@{#803583}
parent 4a1b8427
...@@ -47,6 +47,15 @@ bool DeskActivationAnimation::Replace(bool moving_left, ...@@ -47,6 +47,15 @@ bool DeskActivationAnimation::Replace(bool moving_left,
if (source != switch_source_) if (source != switch_source_)
return false; return false;
// If any of the animators are still taking either screenshot, do not replace
// the animation.
for (const auto& animator : desk_switch_animators_) {
if (!animator->starting_desk_screenshot_taken() ||
!animator->ending_desk_screenshot_taken()) {
return false;
}
}
const int new_ending_desk_index = ending_desk_index_ + (moving_left ? -1 : 1); const int new_ending_desk_index = ending_desk_index_ + (moving_left ? -1 : 1);
// Already at the leftmost or rightmost desk, nothing to replace. // Already at the leftmost or rightmost desk, nothing to replace.
if (new_ending_desk_index < 0 || if (new_ending_desk_index < 0 ||
...@@ -55,14 +64,56 @@ bool DeskActivationAnimation::Replace(bool moving_left, ...@@ -55,14 +64,56 @@ bool DeskActivationAnimation::Replace(bool moving_left,
} }
ending_desk_index_ = new_ending_desk_index; ending_desk_index_ = new_ending_desk_index;
for (const auto& animator : desk_switch_animators_)
animator->ReplaceAnimation(new_ending_desk_index); // List of animators that need a screenshot. It should be either empty or
// match the size of |desk_switch_animators_| as all the animations should be
// in sync.
// TODO(sammiequon): Verify all the animations are in sync.
std::vector<RootWindowDeskSwitchAnimator*> pending_animators;
for (const auto& animator : desk_switch_animators_) {
if (animator->ReplaceAnimation(new_ending_desk_index))
pending_animators.push_back(animator.get());
}
// No screenshot needed. Call OnEndingDeskScreenshotTaken which will start the
// animation.
if (pending_animators.empty()) {
OnEndingDeskScreenshotTaken();
return true;
}
// Activate the target desk and take a screenshot.
DCHECK_EQ(pending_animators.size(), desk_switch_animators_.size());
PrepareDeskForScreenshot(new_ending_desk_index);
for (auto* animator : pending_animators)
animator->TakeEndingDeskScreenshot();
return true; return true;
} }
void DeskActivationAnimation::OnStartingDeskScreenshotTakenInternal( void DeskActivationAnimation::OnStartingDeskScreenshotTakenInternal(
int ending_desk_index) { int ending_desk_index) {
DCHECK_EQ(ending_desk_index_, ending_desk_index); DCHECK_EQ(ending_desk_index_, ending_desk_index);
PrepareDeskForScreenshot(ending_desk_index);
}
void DeskActivationAnimation::OnDeskSwitchAnimationFinishedInternal() {
// During a chained animation we may not switch desks if a replaced target
// desk does not require a new screenshot. If that is the case, activate the
// proper desk here.
controller_->ActivateDeskInternal(
controller_->desks()[ending_desk_index_].get(),
/*update_window_activation=*/true);
}
metrics_util::ReportCallback DeskActivationAnimation::GetReportCallback()
const {
return metrics_util::ForSmoothness(base::BindRepeating([](int smoothness) {
UMA_HISTOGRAM_PERCENTAGE(kDeskActivationSmoothnessHistogramName,
smoothness);
}));
}
void DeskActivationAnimation::PrepareDeskForScreenshot(int index) {
// The order here matters. Overview must end before ending tablet split view // The order here matters. Overview must end before ending tablet split view
// before switching desks. (If clamshell split view is active on one or more // before switching desks. (If clamshell split view is active on one or more
// displays, then it simply will end when we end overview.) That's because // displays, then it simply will end when we end overview.) That's because
...@@ -92,23 +143,6 @@ void DeskActivationAnimation::OnStartingDeskScreenshotTakenInternal( ...@@ -92,23 +143,6 @@ void DeskActivationAnimation::OnStartingDeskScreenshotTakenInternal(
MaybeRestoreSplitView(/*refresh_snapped_windows=*/true); MaybeRestoreSplitView(/*refresh_snapped_windows=*/true);
} }
void DeskActivationAnimation::OnDeskSwitchAnimationFinishedInternal() {
// During a chained animation we may not switch desks if a replaced target
// desk does not require a new screenshot. If that is the case, activate the
// proper desk here.
controller_->ActivateDeskInternal(
controller_->desks()[ending_desk_index_].get(),
/*update_window_activation=*/true);
}
metrics_util::ReportCallback DeskActivationAnimation::GetReportCallback()
const {
return metrics_util::ForSmoothness(base::BindRepeating([](int smoothness) {
UMA_HISTOGRAM_PERCENTAGE(kDeskActivationSmoothnessHistogramName,
smoothness);
}));
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// DeskRemovalAnimation: // DeskRemovalAnimation:
......
...@@ -30,6 +30,11 @@ class DeskActivationAnimation : public DeskAnimationBase { ...@@ -30,6 +30,11 @@ class DeskActivationAnimation : public DeskAnimationBase {
metrics_util::ReportCallback GetReportCallback() const override; metrics_util::ReportCallback GetReportCallback() const override;
private: private:
// Prepares the desk associated with |index| for taking a screenshot. Exits
// overview and splitview if necessary and then activates the desk. Restores
// splitview if necessary after activating the desk.
void PrepareDeskForScreenshot(int index);
// The switch source that requested this animation. // The switch source that requested this animation.
const DesksSwitchSource switch_source_; const DesksSwitchSource switch_source_;
}; };
......
...@@ -151,6 +151,12 @@ namespace ash { ...@@ -151,6 +151,12 @@ namespace ash {
// the desks screenshots are animating horizontally. // the desks screenshots are animating horizontally.
// This gives the effect that the removed desk windows are jumping from their // This gives the effect that the removed desk windows are jumping from their
// desk to the target desk. // desk to the target desk.
//
// TODO(sammiequon): Update the class docs. It has been modified slightly to
// accommodate the chained desk animations feature, and will be modified
// slightly more to accommodate the continuous desk animations feature. The base
// algorithm is still valid, but once the features are near completion these
// need to be updated.
class RootWindowDeskSwitchAnimator : public ui::ImplicitAnimationObserver { class RootWindowDeskSwitchAnimator : public ui::ImplicitAnimationObserver {
public: public:
class Delegate { class Delegate {
...@@ -209,8 +215,9 @@ class RootWindowDeskSwitchAnimator : public ui::ImplicitAnimationObserver { ...@@ -209,8 +215,9 @@ class RootWindowDeskSwitchAnimator : public ui::ImplicitAnimationObserver {
void StartAnimation(); void StartAnimation();
// Replace the current animation with one that goes to // Replace the current animation with one that goes to
// |new_ending_desk_index|. // |new_ending_desk_index|. Returns true if a screenshot of the new desk needs
void ReplaceAnimation(int new_ending_desk_index); // to be taken.
bool ReplaceAnimation(int new_ending_desk_index);
// ui::ImplicitAnimationObserver: // ui::ImplicitAnimationObserver:
void OnImplicitAnimationsCompleted() override; void OnImplicitAnimationsCompleted() override;
...@@ -231,6 +238,15 @@ class RootWindowDeskSwitchAnimator : public ui::ImplicitAnimationObserver { ...@@ -231,6 +238,15 @@ class RootWindowDeskSwitchAnimator : public ui::ImplicitAnimationObserver {
void OnEndingDeskScreenshotTaken( void OnEndingDeskScreenshotTaken(
std::unique_ptr<viz::CopyOutputResult> copy_result); std::unique_ptr<viz::CopyOutputResult> copy_result);
// Called when a screenshot layer is created and added to the animation layer.
// Sets its bounds and transforms the animation layer to the correct starting
// position.
void OnScreenshotLayerCreated();
// Gets the x position of the |screenshot_layer_| associated with |index| in
// its parent layer's coordinates (|animation_layer_owner_->root()|).
int GetXPositionOfScreenshot(int index);
// The root window that this animator is associated with. // The root window that this animator is associated with.
aura::Window* const root_window_; aura::Window* const root_window_;
...@@ -283,6 +299,11 @@ class RootWindowDeskSwitchAnimator : public ui::ImplicitAnimationObserver { ...@@ -283,6 +299,11 @@ class RootWindowDeskSwitchAnimator : public ui::ImplicitAnimationObserver {
// True when phase (3) finishes. // True when phase (3) finishes.
bool animation_finished_ = false; bool animation_finished_ = false;
// True while setting a new transform for chaining. If a animation is active,
// calling SetTranform will trigger OnImplicitAnimationsCompleted. In these
// cases we do not want to notify our delegate that the animation is finished.
bool setting_new_transform_ = false;
base::WeakPtrFactory<RootWindowDeskSwitchAnimator> weak_ptr_factory_{this}; base::WeakPtrFactory<RootWindowDeskSwitchAnimator> weak_ptr_factory_{this};
}; };
......
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