Commit 8f2591ae authored by Maksim Sisov's avatar Maksim Sisov Committed by Commit Bot

[ozone/wayland] Manually handle fullscreen states.

In order to ensure media files can enter fullscreen mode, manually
handle fullscreen states. Basically, a compositor sends configuration
events on each request for state changes from clients asynchronously,
which is unefficient for media files when they enter a fullscreen mode.

For example, when a youtube video file is being set to fullscreen, a
WaylandWindow is also set to a fullscreen mode, but the return value from
the WaylandWindow::GetPlatformWindowState still contains an old value until
the compositor calls with a configuration event. This short race is
enough for a media content to be placed in a forever "entering fullscreen"
state, which never results in a fullscreen state for media files.

Bug: 843018
TEST: XdgVersionV5Test/WaylandWindowTest.SetFullscreenAndRestore/0
XdgVersionV6Test/WaylandWindowTest.SetFullscreenAndRestore/0

Change-Id: Ib9bc8c0ce09412c36437d165efc6a0cad60c4d17
Reviewed-on: https://chromium-review.googlesource.com/1107636Reviewed-by: default avatarRobert Kroeger <rjkroege@chromium.org>
Commit-Queue: Maksim Sisov <msisov@igalia.com>
Cr-Commit-Position: refs/heads/master@{#569172}
parent d11a5c2a
......@@ -236,6 +236,13 @@ void WaylandWindow::ToggleFullscreen() {
// if xdg_surface_set_fullscreen() is not provided with wl_output, it's up to
// the compositor to choose which display will be used to map this surface.
if (!IsFullscreen()) {
// Fullscreen state changes have to be handled manually and then checked
// against configuration events, which come from a compositor. The reason
// of manually changing the |state_| is that the compositor answers about
// state changes asynchronously, which leads to a wrong return value in
// DesktopWindowTreeHostPlatform::IsFullscreen, for example, and media
// files can never be set to fullscreen.
state_ = PlatformWindowState::PLATFORM_WINDOW_STATE_FULLSCREEN;
// Client might have requested a fullscreen state while the window was in
// a maximized state. Thus, |restored_bounds_| can contain the bounds of a
// "normal" state before the window was maximized. We don't override them
......@@ -245,6 +252,9 @@ void WaylandWindow::ToggleFullscreen() {
restored_bounds_ = bounds_;
xdg_surface_->SetFullscreen();
} else {
// Check the comment above. If it's not handled synchronously, media files
// may not leave the fullscreen mode.
state_ = PlatformWindowState::PLATFORM_WINDOW_STATE_UNKNOWN;
xdg_surface_->UnSetFullscreen();
}
......@@ -382,6 +392,11 @@ void WaylandWindow::HandleSurfaceConfigure(int32_t width,
bool is_activated) {
// Propagate the window state information to the client.
PlatformWindowState old_state = state_;
// Ensure that manually handled state changes to fullscreen correspond to the
// configuration events from a compositor.
DCHECK(is_fullscreen == IsFullscreen());
// There are two cases, which must be handled for the minimized state.
// The first one is the case, when the surface goes into the minimized state
// (check comment in WaylandWindow::Minimize), and the second case is when the
......@@ -392,7 +407,10 @@ void WaylandWindow::HandleSurfaceConfigure(int32_t width,
is_minimizing_ = false;
state_ = PlatformWindowState::PLATFORM_WINDOW_STATE_MINIMIZED;
} else if (is_fullscreen) {
state_ = PlatformWindowState::PLATFORM_WINDOW_STATE_FULLSCREEN;
// To ensure the |delegate_| is notified about state changes to fullscreen,
// assume the old_state is UNKNOWN (check comment in ToggleFullscreen).
old_state = PlatformWindowState::PLATFORM_WINDOW_STATE_UNKNOWN;
DCHECK(state_ == PlatformWindowState::PLATFORM_WINDOW_STATE_FULLSCREEN);
} else if (is_maximized) {
state_ = PlatformWindowState::PLATFORM_WINDOW_STATE_MAXIMIZED;
} else {
......
......@@ -173,6 +173,9 @@ TEST_P(WaylandWindowTest, Minimize) {
}
TEST_P(WaylandWindowTest, SetFullscreenAndRestore) {
// Ensure the initial state is unknown.
EXPECT_EQ(window_->GetPlatformWindowState(), PLATFORM_WINDOW_STATE_UNKNOWN);
wl_array states;
InitializeWlArrayWithActivatedState(&states);
......@@ -182,6 +185,10 @@ TEST_P(WaylandWindowTest, SetFullscreenAndRestore) {
EXPECT_CALL(delegate_,
OnWindowStateChanged(Eq(PLATFORM_WINDOW_STATE_FULLSCREEN)));
window_->ToggleFullscreen();
// Make sure than WaylandWindow manually handles fullscreen states. Check the
// comment in the WaylandWindow::ToggleFullscreen.
EXPECT_EQ(window_->GetPlatformWindowState(),
PLATFORM_WINDOW_STATE_FULLSCREEN);
SendConfigureEvent(0, 0, 1, &states);
Sync();
......@@ -189,6 +196,7 @@ TEST_P(WaylandWindowTest, SetFullscreenAndRestore) {
EXPECT_CALL(delegate_,
OnWindowStateChanged(Eq(PLATFORM_WINDOW_STATE_NORMAL)));
window_->Restore();
EXPECT_EQ(window_->GetPlatformWindowState(), PLATFORM_WINDOW_STATE_UNKNOWN);
// Reinitialize wl_array, which removes previous old states.
InitializeWlArrayWithActivatedState(&states);
SendConfigureEvent(0, 0, 2, &states);
......
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