Skip to content

Commit

Permalink
[DoNotCarryForward] [ozone/wayland] Fix kiosk mode.
Browse files Browse the repository at this point in the history
This CL fixes a fullscreen state changes before the surface is
activated.

That is, Wayland may ignore fullscreen changes before the surface
is activated. Thus, store a pending state, and once the surface
is activated, trigger the change.

Change-Id: I8c0b995eb9f282f6be16e82d094d9dd93821a60a
Bug: 843018
  • Loading branch information
msisov committed Oct 11, 2018
1 parent b963e36 commit c3cf95e
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 5 deletions.
28 changes: 26 additions & 2 deletions ui/ozone/platform/wayland/wayland_window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ WaylandWindow::WaylandWindow(PlatformWindowDelegate* delegate,
: delegate_(delegate),
connection_(connection),
xdg_shell_objects_factory_(new XDGShellObjectFactory()),
state_(PlatformWindowState::PLATFORM_WINDOW_STATE_NORMAL) {
state_(PlatformWindowState::PLATFORM_WINDOW_STATE_NORMAL),
pending_state_(PlatformWindowState::PLATFORM_WINDOW_STATE_UNKNOWN) {
// Set a class property key, which allows |this| to be used for interactive
// events, e.g. move or resize.
SetWmMoveResizeHandler(this, AsWmMoveResizeHandler());
Expand Down Expand Up @@ -315,6 +316,17 @@ bool WaylandWindow::HasCapture() const {
void WaylandWindow::ToggleFullscreen() {
DCHECK(xdg_surface_);

// There are some cases, when Chromium triggers a fullscreen state change
// before the surface is activated. In such cases, Wayland may ignore state
// changes and such flags as --kiosk or --start-fullscreen will be ignored.
// To overcome this, set a pending state, and once the surface is activated,
// trigger the change.
if (!is_active_) {
DCHECK(!IsFullscreen());
pending_state_ = PlatformWindowState::PLATFORM_WINDOW_STATE_FULLSCREEN;
return;
}

// TODO(msisov, tonikitoo): add multiscreen support. As the documentation says
// 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.
Expand Down Expand Up @@ -493,7 +505,7 @@ void WaylandWindow::HandleSurfaceConfigure(int32_t width,

// Ensure that manually handled state changes to fullscreen correspond to the
// configuration events from a compositor.
DCHECK(is_fullscreen == IsFullscreen());
DCHECK_EQ(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
Expand Down Expand Up @@ -550,6 +562,8 @@ void WaylandWindow::HandleSurfaceConfigure(int32_t width,

if (did_active_change)
delegate_->OnActivationChanged(is_active_);

MaybeTriggerPendingStateChange();
}

void WaylandWindow::OnCloseRequest() {
Expand Down Expand Up @@ -602,6 +616,16 @@ bool WaylandWindow::IsFullscreen() const {
return state_ == PlatformWindowState::PLATFORM_WINDOW_STATE_FULLSCREEN;
}

void WaylandWindow::MaybeTriggerPendingStateChange() {
if (pending_state_ == PlatformWindowState::PLATFORM_WINDOW_STATE_UNKNOWN ||
!is_active_)
return;
DCHECK_EQ(pending_state_,
PlatformWindowState::PLATFORM_WINDOW_STATE_FULLSCREEN);
pending_state_ = PlatformWindowState::PLATFORM_WINDOW_STATE_UNKNOWN;
ToggleFullscreen();
}

WaylandWindow* WaylandWindow::GetParentWindow(
gfx::AcceleratedWidget parent_widget) {
WaylandWindow* parent_window = connection_->GetWindow(parent_widget);
Expand Down
5 changes: 5 additions & 0 deletions ui/ozone/platform/wayland/wayland_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ class WaylandWindow : public PlatformWindow,
bool IsMaximized() const;
bool IsFullscreen() const;

void MaybeTriggerPendingStateChange();

// Creates a popup window, which is visible as a menu window.
void CreateXdgPopup();
// Creates a surface window, which is visible as a main window.
Expand Down Expand Up @@ -204,6 +206,9 @@ class WaylandWindow : public PlatformWindow,

// Stores current states of the window.
ui::PlatformWindowState state_;
// Stores a pending state of the window, which is used before the surface is
// activated.
ui::PlatformWindowState pending_state_;

bool is_active_ = false;
bool is_minimizing_ = false;
Expand Down
48 changes: 45 additions & 3 deletions ui/ozone/platform/wayland/wayland_window_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ TEST_P(WaylandWindowTest, SetFullscreenAndRestore) {
EXPECT_EQ(PLATFORM_WINDOW_STATE_NORMAL, window_->GetPlatformWindowState());

ScopedWlArray states = InitializeWlArrayWithActivatedState();
SendConfigureEvent(0, 0, 1, states.get());
Sync();

AddStateToWlArray(XDG_SURFACE_STATE_FULLSCREEN, states.get());

Expand All @@ -230,7 +232,7 @@ TEST_P(WaylandWindowTest, SetFullscreenAndRestore) {
// comment in the WaylandWindow::ToggleFullscreen.
EXPECT_EQ(window_->GetPlatformWindowState(),
PLATFORM_WINDOW_STATE_FULLSCREEN);
SendConfigureEvent(0, 0, 1, states.get());
SendConfigureEvent(0, 0, 2, states.get());
Sync();

EXPECT_CALL(*GetXdgSurface(), UnsetFullscreen());
Expand All @@ -240,7 +242,45 @@ TEST_P(WaylandWindowTest, SetFullscreenAndRestore) {
EXPECT_EQ(window_->GetPlatformWindowState(), PLATFORM_WINDOW_STATE_UNKNOWN);
// Reinitialize wl_array, which removes previous old states.
states = InitializeWlArrayWithActivatedState();
SendConfigureEvent(0, 0, 3, states.get());
Sync();
}

TEST_P(WaylandWindowTest, StartWithFullscreen) {
// Make sure the window is initialized to normal state from the beginning.
EXPECT_EQ(PLATFORM_WINDOW_STATE_NORMAL, window_->GetPlatformWindowState());

// The state must not be changed to the fullscreen before the surface is
// activated.
EXPECT_CALL(*GetXdgSurface(), SetFullscreen()).Times(0);
EXPECT_CALL(delegate_, OnWindowStateChanged(_)).Times(0);
window_->ToggleFullscreen();
// The state of the window must still be a normal one.
EXPECT_EQ(window_->GetPlatformWindowState(), PLATFORM_WINDOW_STATE_NORMAL);

Sync();

// Once the surface will be activated, the window will automatically trigger
// the state change.
EXPECT_CALL(*GetXdgSurface(), SetFullscreen());
EXPECT_CALL(delegate_,
OnWindowStateChanged(Eq(PLATFORM_WINDOW_STATE_FULLSCREEN)));

// Activate the surface.
ScopedWlArray states = InitializeWlArrayWithActivatedState();
SendConfigureEvent(0, 0, 1, states.get());

Sync();

// The wayland window manually handles the fullscreen state changes, and it
// must change to a fullscreen before the state change is confirmed by the
// wayland. See comment in the WaylandWindow::ToggleFullscreen.
EXPECT_EQ(window_->GetPlatformWindowState(),
PLATFORM_WINDOW_STATE_FULLSCREEN);

AddStateToWlArray(XDG_SURFACE_STATE_FULLSCREEN, states.get());
SendConfigureEvent(0, 0, 2, states.get());

Sync();
}

Expand Down Expand Up @@ -314,6 +354,8 @@ TEST_P(WaylandWindowTest, RestoreBoundsAfterFullscreen) {
const gfx::Rect current_bounds = window_->GetBounds();

ScopedWlArray states = InitializeWlArrayWithActivatedState();
SendConfigureEvent(0, 0, 1, states.get());
Sync();

gfx::Rect restored_bounds = window_->GetRestoredBoundsInPixels();
EXPECT_EQ(restored_bounds, gfx::Rect());
Expand All @@ -323,7 +365,7 @@ TEST_P(WaylandWindowTest, RestoreBoundsAfterFullscreen) {
EXPECT_CALL(delegate_, OnBoundsChanged(Eq(fullscreen_bounds)));
window_->ToggleFullscreen();
AddStateToWlArray(XDG_SURFACE_STATE_FULLSCREEN, states.get());
SendConfigureEvent(fullscreen_bounds.width(), fullscreen_bounds.height(), 1,
SendConfigureEvent(fullscreen_bounds.width(), fullscreen_bounds.height(), 2,
states.get());
Sync();
restored_bounds = window_->GetRestoredBoundsInPixels();
Expand All @@ -338,7 +380,7 @@ TEST_P(WaylandWindowTest, RestoreBoundsAfterFullscreen) {
window_->Restore();
// Reinitialize wl_array, which removes previous old states.
states = InitializeWlArrayWithActivatedState();
SendConfigureEvent(0, 0, 2, states.get());
SendConfigureEvent(0, 0, 3, states.get());
Sync();
bounds = window_->GetBounds();
EXPECT_EQ(bounds, restored_bounds);
Expand Down

0 comments on commit c3cf95e

Please sign in to comment.