0

split view: Adjust logic of when overview shall not steal focus at start

The present CL follows up after [1] about overview not stealing focus
from a window snapped in split view. The present CL makes the solution
simpler and less error prone.

[1] https://chromium-review.googlesource.com/c/chromium/src/+/1756550

Test: ash_unittests TabletModeControllerTest.StartSplitViewAndThenOverview
Bug: 993403
Change-Id: I9c25fbdfa8fd63050769817e1e2b4380389bd015
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1768833
Reviewed-by: Ahmed Fakhry <afakhry@chromium.org>
Commit-Queue: Avery Musbach <amusbach@chromium.org>
Cr-Commit-Position: refs/heads/master@{#691881}
This commit is contained in:
Avery Musbach
2019-08-30 00:34:53 +00:00
committed by Commit Bot
parent 2437f13677
commit 387ec9cdb1
6 changed files with 40 additions and 32 deletions

@ -643,6 +643,21 @@ bool OverviewController::ToggleOverview(
OnEndingAnimationComplete(/*canceled=*/true);
delayed_animations_.clear();
// |should_focus_overview_| shall be true except when split view mode starts
// on transition between clamshell mode and tablet mode, on transition
// between user sessions, or on transition between virtual desks. Those are
// the cases where code arranges split view by first snapping a window on
// one side and then starting overview to be seen on the other side, meaning
// that the split view state here will be |SplitViewState::kLeftSnapped| or
// |SplitViewState::kRightSnapped|. We have to check the split view state
// before |SplitViewController::OnOverviewModeStarting|, because in case of
// |SplitViewState::kBothSnapped|, that function will insert one of the two
// snapped windows to overview.
const SplitViewState split_view_state =
Shell::Get()->split_view_controller()->state();
should_focus_overview_ = split_view_state == SplitViewState::kNoSnap ||
split_view_state == SplitViewState::kBothSnapped;
// Suspend occlusion tracker until the enter animation is complete.
PauseOcclusionTracker();
@ -706,8 +721,10 @@ void OverviewController::OnStartingAnimationComplete(bool canceled) {
for (auto& observer : observers_)
observer.OnOverviewModeStartingAnimationComplete(canceled);
if (overview_session_)
overview_session_->OnStartingAnimationComplete(canceled);
if (overview_session_) {
overview_session_->OnStartingAnimationComplete(canceled,
should_focus_overview_);
}
UnpauseOcclusionTracker(kOcclusionPauseDurationForStartMs);
TRACE_EVENT_ASYNC_END1("ui", "OverviewController::EnterOverview", this,
"canceled", canceled);

@ -143,6 +143,10 @@ class ASH_EXPORT OverviewController : public OverviewDelegate,
// notify shell that the starting animations have been completed.
std::vector<std::unique_ptr<DelayedAnimationObserver>> start_animations_;
// Indicates that overview shall gain focus when the starting animations have
// completed.
bool should_focus_overview_ = false;
std::unique_ptr<aura::WindowOcclusionTracker::ScopedPause>
occlusion_tracker_pauser_;

@ -642,19 +642,20 @@ void OverviewSession::UpdateRoundedCornersAndShadow() {
window->UpdateRoundedCornersAndShadow();
}
void OverviewSession::OnStartingAnimationComplete(bool canceled) {
void OverviewSession::OnStartingAnimationComplete(bool canceled,
bool should_focus_overview) {
for (auto& grid : grid_list_)
grid->OnStartingAnimationComplete(canceled);
if (!canceled) {
if (overview_focus_widget_) {
if (enter_exit_overview_type_ == EnterExitOverviewType::kStartUnfocused)
overview_focus_widget_->ShowInactive();
else
overview_focus_widget_->Show();
}
Shell::Get()->overview_controller()->DelayedUpdateRoundedCornersAndShadow();
if (canceled)
return;
if (overview_focus_widget_) {
if (should_focus_overview)
overview_focus_widget_->Show();
else
overview_focus_widget_->ShowInactive();
}
Shell::Get()->overview_controller()->DelayedUpdateRoundedCornersAndShadow();
}
void OverviewSession::OnWindowActivating(

@ -90,10 +90,6 @@ class ASH_EXPORT OverviewSession : public display::DisplayObserver,
// the source desk is in overview mode, while the target desk is not.
// This should not be used for entering overview mode.
kImmediateExit,
// Prevents overview from stealing the input focus. Used by code that starts
// overview after a window has already been snapped in split view. The
// purpose is so that overview does not steal focus from the snapped window.
kStartUnfocused,
};
// Callback which fills out the passed settings object. Used by several
@ -215,8 +211,12 @@ class ASH_EXPORT OverviewSession : public display::DisplayObserver,
// Updates all the overview items' mask and shadow.
void UpdateRoundedCornersAndShadow();
// Called when the overview mode starting animation completes.
void OnStartingAnimationComplete(bool canceled);
// Called when the overview mode starting animation completes. |canceled| is
// true when the starting animation is interrupted by ending overview mode. If
// |canceled| is false and |should_focus_overview| is true, then
// |overview_focus_widget_| shall gain focus. |should_focus_overview| has no
// effect when |canceled| is true.
void OnStartingAnimationComplete(bool canceled, bool should_focus_overview);
// Called when windows are being activated/deactivated during
// overview mode.

@ -17,7 +17,6 @@
#include "ash/shell.h"
#include "ash/shell_delegate.h"
#include "ash/wm/overview/overview_controller.h"
#include "ash/wm/overview/overview_session.h"
#include "ash/wm/tablet_mode/internal_input_devices_event_blocker.h"
#include "ash/wm/tablet_mode/tablet_mode_window_manager.h"
#include "ash/wm/window_state.h"
@ -1012,8 +1011,7 @@ void TabletModeController::FinishInitTabletMode() {
const auto state = Shell::Get()->split_view_controller()->state();
if (state == SplitViewState::kLeftSnapped ||
state == SplitViewState::kRightSnapped) {
Shell::Get()->overview_controller()->StartOverview(
OverviewSession::EnterExitOverviewType::kStartUnfocused);
Shell::Get()->overview_controller()->StartOverview();
}
UpdateInternalInputDevicesEventBlocker();

@ -1467,18 +1467,6 @@ TEST_F(TabletModeControllerTest, StartTabletActiveLeftSnapPreviousLeftSnap) {
EXPECT_EQ(window1.get(), window_util::GetActiveWindow());
}
// Test that it is okay to write code that first starts split view by snapping a
// window on one side, and then starts overview to be seen on the other side.
TEST_F(TabletModeControllerTest,
ProgrammaticallyStartSplitViewAndThenOverview) {
SplitViewController* split_view_controller =
Shell::Get()->split_view_controller();
tablet_mode_controller()->SetEnabledForTest(true);
std::unique_ptr<aura::Window> window = CreateTestWindow();
split_view_controller->SnapWindow(window.get(), SplitViewController::LEFT);
EXPECT_TRUE(Shell::Get()->overview_controller()->StartOverview());
}
// Test that tablet mode controller does not respond to the input device changes
// during its suspend.
TEST_F(TabletModeControllerTest, DoNotObserverInputDeviceChangeDuringSuspend) {