| // Copyright 2022 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/test/task_environment.h" |
| #include "components/remote_cocoa/app_shim/native_widget_ns_window_fullscreen_controller.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace remote_cocoa::test { |
| |
| using testing::_; |
| using testing::Invoke; |
| using testing::Return; |
| |
| class MockClient : public NativeWidgetNSWindowFullscreenController::Client { |
| public: |
| MOCK_METHOD1(FullscreenControllerTransitionStart, void(bool)); |
| MOCK_METHOD1(FullscreenControllerTransitionComplete, void(bool)); |
| MOCK_METHOD3(FullscreenControllerSetFrame, |
| void(const gfx::Rect&, |
| bool animate, |
| base::OnceCallback<void()> animation_complete)); |
| |
| MOCK_METHOD0(FullscreenControllerToggleFullscreen, void()); |
| MOCK_METHOD0(FullscreenControllerCloseWindow, void()); |
| MOCK_CONST_METHOD0(FullscreenControllerGetDisplayId, int64_t()); |
| MOCK_CONST_METHOD1(FullscreenControllerGetFrameForDisplay, |
| gfx::Rect(int64_t display_id)); |
| MOCK_CONST_METHOD0(FullscreenControllerGetFrame, gfx::Rect()); |
| }; |
| |
| class MacFullscreenControllerTest : public testing::Test { |
| public: |
| void SetUp() override { |
| EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen()).Times(0); |
| EXPECT_CALL(mock_client_, FullscreenControllerSetFrame(_, _, _)).Times(0); |
| EXPECT_CALL(mock_client_, FullscreenControllerCloseWindow()).Times(0); |
| } |
| |
| protected: |
| const gfx::Rect kWindowRect{1, 2, 3, 4}; |
| const int64_t kDisplay0Id = 0; |
| const int64_t kDisplay1Id = 1; |
| const gfx::Rect kDisplay0Frame{9, 10, 11, 12}; |
| const gfx::Rect kDisplay1Frame{13, 14, 15, 16}; |
| |
| MockClient mock_client_; |
| NativeWidgetNSWindowFullscreenController controller_{&mock_client_}; |
| base::test::SingleThreadTaskEnvironment task_environment_; |
| }; |
| |
| // Fake implementation of FullscreenControllerSetFrame |
| // which executes the given callback immediately. |
| void FullscreenControllerSetFrameFake(const gfx::Rect&, |
| bool, |
| base::OnceCallback<void()> callback) { |
| std::move(callback).Run(); |
| } |
| |
| // Simple enter-and-exit fullscreen via the green traffic light button. |
| TEST_F(MacFullscreenControllerTest, SimpleUserInitiated) { |
| // Enter fullscreen the way that clicking the green traffic light does it. |
| EXPECT_CALL(mock_client_, FullscreenControllerGetFrame()) |
| .Times(1) |
| .WillOnce(Return(kWindowRect)); |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1); |
| controller_.OnWindowWillEnterFullscreen(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // The controller should do nothing, and wait until it receives |
| // OnWindowDidEnterFullscreen. |
| task_environment_.RunUntilIdle(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| |
| // Calling EnterFullscreen inside the transition will do nothing. |
| controller_.EnterFullscreen(display::kInvalidDisplayId); |
| task_environment_.RunUntilIdle(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Complete the transition. |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true)) |
| .Times(1); |
| controller_.OnWindowDidEnterFullscreen(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Calling EnterFullscreen while fullscreen should do nothing. |
| controller_.EnterFullscreen(display::kInvalidDisplayId); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| task_environment_.RunUntilIdle(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Calling EnterFullscreen specifying the display that we are currently on |
| // will also be a no-op. |
| EXPECT_CALL(mock_client_, FullscreenControllerGetDisplayId()) |
| .WillOnce(Return(kDisplay0Id)); |
| controller_.EnterFullscreen(kDisplay0Id); |
| task_environment_.RunUntilIdle(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Exit fullscreen via the green traffic light. |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(false)) |
| .Times(1); |
| controller_.OnWindowWillExitFullscreen(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_FALSE(controller_.GetTargetFullscreenState()); |
| |
| // Calling ExitFullscreen inside the transition will do nothing. |
| controller_.ExitFullscreen(); |
| task_environment_.RunUntilIdle(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_FALSE(controller_.GetTargetFullscreenState()); |
| |
| // Complete the transition. |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(false)) |
| .Times(1); |
| controller_.OnWindowDidExitFullscreen(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_FALSE(controller_.GetTargetFullscreenState()); |
| task_environment_.RunUntilIdle(); |
| } |
| |
| // Simple enter-and-exit fullscreen programmatically. |
| TEST_F(MacFullscreenControllerTest, SimpleProgrammatic) { |
| // Enter fullscreen. |
| EXPECT_CALL(mock_client_, FullscreenControllerGetFrame()) |
| .Times(1) |
| .WillOnce(Return(kWindowRect)); |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1); |
| controller_.EnterFullscreen(display::kInvalidDisplayId); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| |
| // The call to ToggleFullscreen is sent via a posted task, so it shouldn't |
| // happen until after the run loop is pumped. The function |
| // OnWindowWillEnterFullscreen is called from within ToggleFullscreen. |
| EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen()) |
| .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController:: |
| OnWindowWillEnterFullscreen)); |
| task_environment_.RunUntilIdle(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| |
| // Complete the transition. |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true)) |
| .Times(1); |
| controller_.OnWindowDidEnterFullscreen(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| |
| // Exit fullscreen. |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(false)) |
| .Times(1); |
| controller_.ExitFullscreen(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| |
| // Make ToggleFullscreen happen, and invoke OnWindowWillExitFullscreen. |
| EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen()) |
| .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController:: |
| OnWindowWillExitFullscreen)); |
| task_environment_.RunUntilIdle(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| |
| // Complete the transition. |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(false)) |
| .Times(1); |
| controller_.OnWindowDidExitFullscreen(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| task_environment_.RunUntilIdle(); |
| } |
| |
| // A transition that fails to enter fullscreen. |
| TEST_F(MacFullscreenControllerTest, FailEnterFullscreenSimple) { |
| // Enter fullscreen. |
| EXPECT_CALL(mock_client_, FullscreenControllerGetFrame()) |
| .Times(1) |
| .WillOnce(Return(kWindowRect)); |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1); |
| controller_.EnterFullscreen(display::kInvalidDisplayId); |
| EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen()) |
| .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController:: |
| OnWindowWillEnterFullscreen)); |
| task_environment_.RunUntilIdle(); |
| |
| // Fail the transition. |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(false)) |
| .Times(1); |
| controller_.OnWindowDidExitFullscreen(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_FALSE(controller_.GetTargetFullscreenState()); |
| task_environment_.RunUntilIdle(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_FALSE(controller_.GetTargetFullscreenState()); |
| } |
| |
| // A transition that fails to exit fullscreen. |
| TEST_F(MacFullscreenControllerTest, FailExitFullscreen) { |
| // Enter fullscreen. |
| EXPECT_CALL(mock_client_, FullscreenControllerGetFrame()) |
| .Times(1) |
| .WillOnce(Return(kWindowRect)); |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1); |
| controller_.EnterFullscreen(display::kInvalidDisplayId); |
| EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen()) |
| .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController:: |
| OnWindowWillEnterFullscreen)); |
| task_environment_.RunUntilIdle(); |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true)) |
| .Times(1); |
| controller_.OnWindowDidEnterFullscreen(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Start to exit fullscreen, through OnWindowWillExitFullscreen. |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(false)) |
| .Times(1); |
| controller_.ExitFullscreen(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen()) |
| .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController:: |
| OnWindowWillExitFullscreen)); |
| task_environment_.RunUntilIdle(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| |
| // Fail the transition. |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true)) |
| .Times(1); |
| controller_.OnWindowDidEnterFullscreen(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| task_environment_.RunUntilIdle(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| } |
| |
| // A simple cross-screen transition. |
| TEST_F(MacFullscreenControllerTest, SimpleCrossScreen) { |
| // Enter fullscreen on display 1, from display 0. |
| EXPECT_CALL(mock_client_, FullscreenControllerGetFrame()) |
| .Times(1) |
| .WillOnce(Return(kWindowRect)); |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1); |
| controller_.EnterFullscreen(kDisplay1Id); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| |
| // This will trigger a call to MoveToTargetDisplayThenToggleFullscreen, even |
| // though we are not actually moving displays. It will also then post a task |
| // to ToggleFullscreen (because RunUntilIdle will pick up that posted task). |
| EXPECT_CALL(mock_client_, FullscreenControllerGetFrameForDisplay(kDisplay1Id)) |
| .Times(1) |
| .WillOnce(Return(kDisplay1Frame)); |
| EXPECT_CALL(mock_client_, |
| FullscreenControllerSetFrame(kDisplay1Frame, true, _)) |
| .WillOnce(FullscreenControllerSetFrameFake); |
| EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen()) |
| .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController:: |
| OnWindowWillEnterFullscreen)); |
| task_environment_.RunUntilIdle(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Complete the transition to fullscreen on the new display. |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true)) |
| .Times(1); |
| controller_.OnWindowDidEnterFullscreen(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Re-entering fullscreen on our current display should be a no-op. |
| EXPECT_CALL(mock_client_, FullscreenControllerGetDisplayId()) |
| .WillOnce(Return(kDisplay1Id)); |
| controller_.EnterFullscreen(kDisplay1Id); |
| task_environment_.RunUntilIdle(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Exit fullscreen. This will post a task to restore bounds. |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(false)) |
| .Times(1); |
| controller_.ExitFullscreen(); |
| EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen()) |
| .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController:: |
| OnWindowWillExitFullscreen)); |
| task_environment_.RunUntilIdle(); |
| controller_.OnWindowDidExitFullscreen(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_FALSE(controller_.GetTargetFullscreenState()); |
| |
| // Let the run loop run, it will restore the bounds. |
| EXPECT_CALL(mock_client_, FullscreenControllerSetFrame(kWindowRect, true, _)) |
| .WillOnce(FullscreenControllerSetFrameFake); |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(false)) |
| .Times(1); |
| task_environment_.RunUntilIdle(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_FALSE(controller_.GetTargetFullscreenState()); |
| } |
| |
| // A cross-screen transition after having entered fullscreen. |
| TEST_F(MacFullscreenControllerTest, CrossScreenFromFullscreen) { |
| // Enter fullscreen the way that clicking the green traffic light does it. |
| EXPECT_CALL(mock_client_, FullscreenControllerGetFrame()) |
| .Times(1) |
| .WillOnce(Return(kWindowRect)); |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1); |
| controller_.OnWindowWillEnterFullscreen(); |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true)) |
| .Times(1); |
| controller_.OnWindowDidEnterFullscreen(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Enter fullscreen on a different display. |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1); |
| EXPECT_CALL(mock_client_, FullscreenControllerGetDisplayId()) |
| .WillRepeatedly(Return(kDisplay0Id)); |
| controller_.EnterFullscreen(kDisplay1Id); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Execute the task posted to ToggleFullscreen. |
| EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen()) |
| .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController:: |
| OnWindowWillExitFullscreen)); |
| task_environment_.RunUntilIdle(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Complete the transition to windowed. This will post a task to move to the |
| // target display's frame. |
| EXPECT_CALL(mock_client_, FullscreenControllerGetFrameForDisplay(kDisplay1Id)) |
| .Times(1) |
| .WillOnce(Return(kDisplay1Frame)); |
| controller_.OnWindowDidExitFullscreen(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Execute the posted task to set the new frame. This will also re-toggle |
| // fullscreen in the RunUntilIdle. |
| EXPECT_CALL(mock_client_, |
| FullscreenControllerSetFrame(kDisplay1Frame, true, _)) |
| .WillOnce(FullscreenControllerSetFrameFake); |
| EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen()) |
| .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController:: |
| OnWindowWillEnterFullscreen)); |
| task_environment_.RunUntilIdle(); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Complete the transition. |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true)) |
| .Times(1); |
| controller_.OnWindowDidEnterFullscreen(); |
| task_environment_.RunUntilIdle(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Exit fullscreen. This will restore bounds. |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(false)) |
| .Times(1); |
| controller_.ExitFullscreen(); |
| EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen()) |
| .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController:: |
| OnWindowWillExitFullscreen)); |
| task_environment_.RunUntilIdle(); |
| controller_.OnWindowDidExitFullscreen(); |
| EXPECT_CALL(mock_client_, FullscreenControllerSetFrame(kWindowRect, true, _)) |
| .WillOnce(FullscreenControllerSetFrameFake); |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(false)) |
| .Times(1); |
| task_environment_.RunUntilIdle(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_FALSE(controller_.GetTargetFullscreenState()); |
| } |
| |
| // Fail a cross-screen transition when exiting fullscreen. |
| TEST_F(MacFullscreenControllerTest, CrossScreenFromFullscreenFailExit) { |
| // Enter fullscreen the way that clicking the green traffic light does it. |
| EXPECT_CALL(mock_client_, FullscreenControllerGetFrame()) |
| .Times(1) |
| .WillOnce(Return(kWindowRect)); |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1); |
| controller_.OnWindowWillEnterFullscreen(); |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true)) |
| .Times(1); |
| controller_.OnWindowDidEnterFullscreen(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Attempt to enter fullscreen on a different display. Get as far as toggling |
| // fullscreen to get back to windowed mode. |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1); |
| EXPECT_CALL(mock_client_, FullscreenControllerGetDisplayId()) |
| .WillRepeatedly(Return(kDisplay0Id)); |
| controller_.EnterFullscreen(kDisplay1Id); |
| EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen()) |
| .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController:: |
| OnWindowWillExitFullscreen)); |
| task_environment_.RunUntilIdle(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Fail the transition back to windowed. This should just leave us as being |
| // fullscreen. It will issue the TransitionComplete notification indicating |
| // that the transition is over, and that we're in fullscreen mode (no mention |
| // of which display). |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true)) |
| .Times(1); |
| controller_.OnWindowDidEnterFullscreen(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // No further tasks should run. |
| task_environment_.RunUntilIdle(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| } |
| |
| // Fail a cross-screen transition when entering fullscreen. |
| TEST_F(MacFullscreenControllerTest, CrossScreenFromFullscreenFailEnter) { |
| // Enter fullscreen the way that clicking the green traffic light does it. |
| EXPECT_CALL(mock_client_, FullscreenControllerGetFrame()) |
| .Times(1) |
| .WillOnce(Return(kWindowRect)); |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1); |
| controller_.OnWindowWillEnterFullscreen(); |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true)) |
| .Times(1); |
| controller_.OnWindowDidEnterFullscreen(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Enter fullscreen on a different display. Get as far as toggling fullscreen |
| // to get back to windowed mode, moving the window, and then toggling |
| // fullscreen on the new display. |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1); |
| EXPECT_CALL(mock_client_, FullscreenControllerGetDisplayId()) |
| .WillRepeatedly(Return(kDisplay0Id)); |
| controller_.EnterFullscreen(kDisplay1Id); |
| EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen()) |
| .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController:: |
| OnWindowWillExitFullscreen)); |
| task_environment_.RunUntilIdle(); |
| EXPECT_CALL(mock_client_, FullscreenControllerGetFrameForDisplay(kDisplay1Id)) |
| .Times(1) |
| .WillOnce(Return(kDisplay1Frame)); |
| controller_.OnWindowDidExitFullscreen(); |
| EXPECT_CALL(mock_client_, |
| FullscreenControllerSetFrame(kDisplay1Frame, true, _)) |
| .WillOnce(FullscreenControllerSetFrameFake); |
| EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen()) |
| .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController:: |
| OnWindowWillEnterFullscreen)); |
| task_environment_.RunUntilIdle(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Fail the transition to fullscreen mode. This will cause us to post tasks |
| // to stay in windowed mode. |
| controller_.OnWindowDidExitFullscreen(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_FALSE(controller_.GetTargetFullscreenState()); |
| |
| // This will cause us to restore the window's original frame, and then declare |
| // the transition complete, with the final state after transition as being |
| // windowed. |
| EXPECT_CALL(mock_client_, FullscreenControllerSetFrame(kWindowRect, true, _)) |
| .WillOnce(FullscreenControllerSetFrameFake); |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(false)) |
| .Times(1); |
| task_environment_.RunUntilIdle(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_FALSE(controller_.GetTargetFullscreenState()); |
| } |
| |
| // Be instructed to exit fullscreen while entering fullscreen. |
| TEST_F(MacFullscreenControllerTest, ExitWhileEntering) { |
| // Enter fullscreen the way that clicking the green traffic light does it. |
| EXPECT_CALL(mock_client_, FullscreenControllerGetFrame()) |
| .Times(1) |
| .WillOnce(Return(kWindowRect)); |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1); |
| controller_.OnWindowWillEnterFullscreen(); |
| task_environment_.RunUntilIdle(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| |
| // Call ExitFullscreen inside the transition. |
| controller_.ExitFullscreen(); |
| task_environment_.RunUntilIdle(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_FALSE(controller_.GetTargetFullscreenState()); |
| |
| // Complete the transition to fullscreen. This will report that it is still |
| // in transition to windowed. |
| controller_.OnWindowDidEnterFullscreen(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_FALSE(controller_.GetTargetFullscreenState()); |
| |
| // The above call will have posted a ToggleFullscreen task. |
| EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen()) |
| .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController:: |
| OnWindowWillExitFullscreen)); |
| task_environment_.RunUntilIdle(); |
| |
| // Complete the transition to windowed mode. |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(false)) |
| .Times(1); |
| controller_.OnWindowDidExitFullscreen(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_FALSE(controller_.GetTargetFullscreenState()); |
| |
| // Nothing more should happen. |
| task_environment_.RunUntilIdle(); |
| } |
| |
| // Be instructed to enter fullscreen while exiting fullscreen. |
| TEST_F(MacFullscreenControllerTest, EnterWhileExiting) { |
| // Enter fullscreen the way that clicking the green traffic light does it. |
| EXPECT_CALL(mock_client_, FullscreenControllerGetFrame()) |
| .Times(1) |
| .WillOnce(Return(kWindowRect)); |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1); |
| controller_.OnWindowWillEnterFullscreen(); |
| task_environment_.RunUntilIdle(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true)) |
| .Times(1); |
| controller_.OnWindowDidEnterFullscreen(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Exit fullscreen. |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(false)) |
| .Times(1); |
| controller_.OnWindowWillExitFullscreen(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_FALSE(controller_.GetTargetFullscreenState()); |
| |
| // Call EnterFullscreen inside the transition. |
| controller_.EnterFullscreen(display::kInvalidDisplayId); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Complete the transition to windowed mode. This will report that it is |
| // still in transition to fullscreen. |
| controller_.OnWindowDidExitFullscreen(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // The above call will have posted a ToggleFullscreen task. |
| EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen()) |
| .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController:: |
| OnWindowWillEnterFullscreen)); |
| task_environment_.RunUntilIdle(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Complete the transition to fullscreen mode. |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true)) |
| .Times(1); |
| controller_.OnWindowDidEnterFullscreen(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Nothing more should happen. |
| task_environment_.RunUntilIdle(); |
| } |
| |
| // Be instructed to enter fullscreen on a different screen, while exiting |
| // fullscreen. |
| TEST_F(MacFullscreenControllerTest, EnterCrossScreenWhileExiting) { |
| // Enter fullscreen the way that clicking the green traffic light does it. |
| EXPECT_CALL(mock_client_, FullscreenControllerGetFrame()) |
| .Times(1) |
| .WillOnce(Return(kWindowRect)); |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1); |
| controller_.OnWindowWillEnterFullscreen(); |
| task_environment_.RunUntilIdle(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true)) |
| .Times(1); |
| controller_.OnWindowDidEnterFullscreen(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Exit fullscreen. |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(false)) |
| .Times(1); |
| controller_.OnWindowWillExitFullscreen(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_FALSE(controller_.GetTargetFullscreenState()); |
| |
| // Call EnterFullscreen inside the transition. |
| controller_.EnterFullscreen(kDisplay1Id); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Complete the transition to windowed mode. This will report that it is |
| // still in transition to fullscreen. |
| controller_.OnWindowDidExitFullscreen(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // The above call will have posted a MoveToTargetDisplayThenToggleFullscreen |
| // task, which will then post a ToggleFullscreen task. |
| EXPECT_CALL(mock_client_, FullscreenControllerGetFrameForDisplay(kDisplay1Id)) |
| .Times(1) |
| .WillOnce(Return(kDisplay1Frame)); |
| EXPECT_CALL(mock_client_, |
| FullscreenControllerSetFrame(kDisplay1Frame, true, _)) |
| .WillOnce(FullscreenControllerSetFrameFake); |
| EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen()) |
| .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController:: |
| OnWindowWillEnterFullscreen)); |
| task_environment_.RunUntilIdle(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Complete the transition to fullscreen mode. |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true)) |
| .Times(1); |
| controller_.OnWindowDidEnterFullscreen(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Nothing more should happen. |
| task_environment_.RunUntilIdle(); |
| } |
| |
| // Be instructed to enter fullscreen on a different screen, while entering |
| // fullscreen. |
| TEST_F(MacFullscreenControllerTest, EnterCrossScreenWhileEntering) { |
| // Enter fullscreen the way that clicking the green traffic light does it. |
| EXPECT_CALL(mock_client_, FullscreenControllerGetFrame()) |
| .Times(1) |
| .WillOnce(Return(kWindowRect)); |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1); |
| controller_.OnWindowWillEnterFullscreen(); |
| task_environment_.RunUntilIdle(); |
| |
| // Call EnterFullscreen inside the transition. |
| controller_.EnterFullscreen(kDisplay1Id); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Complete the original fullscreen transition. This will check to see if |
| // the display we are on is the display we wanted to be on. Seeing that it |
| // isn't, it will post a task to exit fullscreen before moving to the correct |
| // display. |
| EXPECT_CALL(mock_client_, FullscreenControllerGetDisplayId()) |
| .WillOnce(Return(kDisplay0Id)); |
| controller_.OnWindowDidEnterFullscreen(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // The above will have posted a task to ToggleFullscreen. |
| EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen()) |
| .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController:: |
| OnWindowWillExitFullscreen)); |
| task_environment_.RunUntilIdle(); |
| |
| // Complete the transition to windowed mode. This will once again check to see |
| // if the display we are on is the display we wanted to be on. Seeing that it |
| // isn't, it will move to the correct display and toggle fullscreen. |
| EXPECT_CALL(mock_client_, FullscreenControllerGetDisplayId()) |
| .WillOnce(Return(kDisplay0Id)); |
| controller_.OnWindowDidExitFullscreen(); |
| EXPECT_CALL(mock_client_, FullscreenControllerGetFrameForDisplay(kDisplay1Id)) |
| .Times(1) |
| .WillOnce(Return(kDisplay1Frame)); |
| EXPECT_CALL(mock_client_, |
| FullscreenControllerSetFrame(kDisplay1Frame, true, _)) |
| .WillOnce(FullscreenControllerSetFrameFake); |
| EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen()) |
| .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController:: |
| OnWindowWillEnterFullscreen)); |
| task_environment_.RunUntilIdle(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Complete the transition to fullscreen. |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true)) |
| .Times(1); |
| controller_.OnWindowDidEnterFullscreen(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Exit fullscreen. |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(false)) |
| .Times(1); |
| controller_.OnWindowWillExitFullscreen(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_FALSE(controller_.GetTargetFullscreenState()); |
| |
| // Complete the transition to windowed mode. The frame frame should be reset. |
| controller_.OnWindowDidExitFullscreen(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_CALL(mock_client_, FullscreenControllerSetFrame(kWindowRect, true, _)) |
| .WillOnce(FullscreenControllerSetFrameFake); |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(false)) |
| .Times(1); |
| task_environment_.RunUntilIdle(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_FALSE(controller_.GetTargetFullscreenState()); |
| } |
| |
| // Be instructed to enter fullscreen while restoring the windowed frame. |
| TEST_F(MacFullscreenControllerTest, EnterCrossScreenWhileRestoring) { |
| // Enter fullscreen on display 1, from display 0. |
| EXPECT_CALL(mock_client_, FullscreenControllerGetFrame()) |
| .WillOnce(Return(kWindowRect)); |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1); |
| controller_.EnterFullscreen(kDisplay1Id); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // This will trigger a call to MoveToTargetDisplayThenToggleFullscreen, even |
| // though we are not actually moving displays. It will also then post a task |
| // to ToggleFullscreen (because RunUntilIdle will pick up that posted task). |
| EXPECT_CALL(mock_client_, FullscreenControllerGetFrameForDisplay(kDisplay1Id)) |
| .WillOnce(Return(kDisplay1Frame)); |
| EXPECT_CALL(mock_client_, |
| FullscreenControllerSetFrame(kDisplay1Frame, true, _)) |
| .WillOnce(FullscreenControllerSetFrameFake); |
| EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen()) |
| .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController:: |
| OnWindowWillEnterFullscreen)); |
| task_environment_.RunUntilIdle(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Complete the transition to fullscreen on the new display. |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true)) |
| .Times(1); |
| controller_.OnWindowDidEnterFullscreen(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Exit fullscreen. This will post a task to restore the windowed frame. |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(false)) |
| .Times(1); |
| controller_.OnWindowWillExitFullscreen(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_FALSE(controller_.GetTargetFullscreenState()); |
| task_environment_.RunUntilIdle(); |
| controller_.OnWindowDidExitFullscreen(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_FALSE(controller_.GetTargetFullscreenState()); |
| |
| // Enter fullscreen on display 1 again, while restoring the windowed frame. |
| // This does not call FullscreenControllerGetFrame() to update the cached |
| // windowed frame, since the window is still in transition. It also will not |
| // call FullscreenControllerTransitionComplete(false) to signal the successful |
| // exit, since that might ambiguously signal that entering fullscreen failed. |
| // It also will not call FullscreenControllerTransitionStart(true), since the |
| // window is already in a transition. |
| controller_.EnterFullscreen(kDisplay1Id); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Let the run loop run, the task to restore the windowed frame will execute |
| // before handling the new pending state from EnterFullscreen. |
| EXPECT_CALL(mock_client_, FullscreenControllerSetFrame(kWindowRect, true, _)) |
| .WillOnce(FullscreenControllerSetFrameFake); |
| // This will trigger a call to MoveToTargetDisplayThenToggleFullscreen, even |
| // though we are not actually moving displays. It will also then post a task |
| // to ToggleFullscreen (because RunUntilIdle will pick up that posted task). |
| EXPECT_CALL(mock_client_, FullscreenControllerGetFrameForDisplay(kDisplay1Id)) |
| .WillOnce(Return(kDisplay1Frame)); |
| EXPECT_CALL(mock_client_, |
| FullscreenControllerSetFrame(kDisplay1Frame, true, _)) |
| .WillOnce(FullscreenControllerSetFrameFake); |
| EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen()) |
| .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController:: |
| OnWindowWillEnterFullscreen)); |
| task_environment_.RunUntilIdle(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Complete the transition to fullscreen on the new display. |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true)) |
| .Times(1); |
| controller_.OnWindowDidEnterFullscreen(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_TRUE(controller_.GetTargetFullscreenState()); |
| |
| // Exit fullscreen. This will post a task to restore bounds. |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(false)) |
| .Times(1); |
| controller_.OnWindowWillExitFullscreen(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_FALSE(controller_.GetTargetFullscreenState()); |
| task_environment_.RunUntilIdle(); |
| controller_.OnWindowDidExitFullscreen(); |
| EXPECT_TRUE(controller_.IsInFullscreenTransition()); |
| EXPECT_FALSE(controller_.GetTargetFullscreenState()); |
| |
| // Let the run loop run, it will restore the bounds (and not crash). |
| // The original bounds should still be stored, even though they were |
| // previously restored, since the second fullscreen transition begun while |
| // already in a transition to restore bounds after exiting fullscreen. |
| EXPECT_CALL(mock_client_, FullscreenControllerSetFrame(kWindowRect, true, _)) |
| .WillOnce(FullscreenControllerSetFrameFake); |
| EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(false)) |
| .Times(1); |
| task_environment_.RunUntilIdle(); |
| EXPECT_FALSE(controller_.IsInFullscreenTransition()); |
| EXPECT_FALSE(controller_.GetTargetFullscreenState()); |
| } |
| |
| } // namespace remote_cocoa::test |