Commit 369947b4 authored by Mitsuru Oshima's avatar Mitsuru Oshima Committed by Commit Bot

Defer widget creation until surface has come content.

A shell surface widget needs be created when the surface has a content,
(https://cs.chromium.org/chromium/src/components/exo/shell_surface.cc?rcl=63840f211efada36274cae7ade3003a2dc88c74b&l=475)
but it can be created without content if a client requested maximize/fullscreen/minimize state upon creation.

This is necessary since xdg (or gtk3 wayland client) seems to have an issue if we configure before the content
is created, and it stops updating frames, even if we sends new configure events later.

Bug: 892291
Test: Covered by unit tests. Also tested manually. See bug for repro step.
Change-Id: I115ec6540a0ec2fc5258c020bd05c4be623f85da
Reviewed-on: https://chromium-review.googlesource.com/c/1278986
Commit-Queue: Mitsuru Oshima <oshima@chromium.org>
Reviewed-by: default avatarDaniele Castagna <dcastagna@chromium.org>
Cr-Commit-Position: refs/heads/master@{#601382}
parent 76e4f7a9
......@@ -181,8 +181,10 @@ void ShellSurface::SetParent(ShellSurface* parent) {
void ShellSurface::Maximize() {
TRACE_EVENT0("exo", "ShellSurface::Maximize");
if (!widget_)
CreateShellSurfaceWidget(ui::SHOW_STATE_MAXIMIZED);
if (!widget_) {
initial_show_state_ = ui::SHOW_STATE_MAXIMIZED;
return;
}
// Note: This will ask client to configure its surface even if already
// maximized.
......@@ -193,8 +195,10 @@ void ShellSurface::Maximize() {
void ShellSurface::Minimize() {
TRACE_EVENT0("exo", "ShellSurface::Minimize");
if (!widget_)
CreateShellSurfaceWidget(ui::SHOW_STATE_MINIMIZED);
if (!widget_) {
initial_show_state_ = ui::SHOW_STATE_MINIMIZED;
return;
}
// Note: This will ask client to configure its surface even if already
// minimized.
......@@ -205,8 +209,10 @@ void ShellSurface::Minimize() {
void ShellSurface::Restore() {
TRACE_EVENT0("exo", "ShellSurface::Restore");
if (!widget_)
if (!widget_) {
initial_show_state_ = ui::SHOW_STATE_NORMAL;
return;
}
// Note: This will ask client to configure its surface even if not already
// maximized or minimized.
......@@ -217,8 +223,10 @@ void ShellSurface::Restore() {
void ShellSurface::SetFullscreen(bool fullscreen) {
TRACE_EVENT1("exo", "ShellSurface::SetFullscreen", "fullscreen", fullscreen);
if (!widget_)
CreateShellSurfaceWidget(ui::SHOW_STATE_FULLSCREEN);
if (!widget_) {
initial_show_state_ = ui::SHOW_STATE_FULLSCREEN;
return;
}
// Note: This will ask client to configure its surface even if fullscreen
// state doesn't change.
......@@ -478,7 +486,7 @@ bool ShellSurface::OnPreWidgetCommit() {
return false;
}
CreateShellSurfaceWidget(ui::SHOW_STATE_NORMAL);
CreateShellSurfaceWidget(initial_show_state_);
}
// Apply the accumulated pending origin offset to reflect acknowledged
......
......@@ -158,7 +158,7 @@ class ShellSurface : public ShellSurfaceBase,
gfx::Vector2d pending_origin_offset_accumulator_;
int resize_component_ = HTCAPTION; // HT constant (see ui/base/hit_test.h)
int pending_resize_component_ = HTCAPTION;
ui::WindowShowState initial_show_state_ = ui::SHOW_STATE_NORMAL;
bool ignore_window_bounds_changes_ = false;
DISALLOW_COPY_AND_ASSIGN(ShellSurface);
......
......@@ -186,11 +186,12 @@ TEST_F(ShellSurfaceTest, Minimize) {
EXPECT_TRUE(shell_surface->CanMinimize());
// Minimizing can be performed before the surface is committed.
// Minimizing can be performed before the surface is committed, but
// widget creation will be deferred.
shell_surface->Minimize();
EXPECT_TRUE(shell_surface->GetWidget()->IsMinimized());
EXPECT_FALSE(shell_surface->GetWidget());
// Confirm that attaching and commiting doesn't reset the state.
// Attaching the buffer will create a widget with minimized state.
surface->Attach(buffer.get());
surface->Commit();
EXPECT_TRUE(shell_surface->GetWidget()->IsMinimized());
......@@ -508,17 +509,34 @@ TEST_F(ShellSurfaceTest, ConfigureCallback) {
// Commit without contents should result in a configure callback with empty
// suggested size as a mechanims to ask the client size itself.
surface->Commit();
EXPECT_EQ(gfx::Size(), suggested_size);
EXPECT_TRUE(suggested_size.IsEmpty());
// Geometry should not be committed until surface has contents.
EXPECT_EQ(gfx::Size(), shell_surface->CalculatePreferredSize());
EXPECT_TRUE(shell_surface->CalculatePreferredSize().IsEmpty());
// Widget creation is deferred until the surface has contents.
shell_surface->Maximize();
shell_surface->AcknowledgeConfigure(0);
EXPECT_EQ(CurrentContext()->bounds().width(), suggested_size.width());
EXPECT_FALSE(shell_surface->GetWidget());
EXPECT_TRUE(suggested_size.IsEmpty());
EXPECT_EQ(ash::mojom::WindowStateType::NORMAL, has_state_type);
gfx::Size buffer_size(64, 64);
std::unique_ptr<Buffer> buffer(
new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
surface->Attach(buffer.get());
surface->Commit();
gfx::Rect maximized_bounds =
display::Screen::GetScreen()->GetPrimaryDisplay().work_area();
EXPECT_TRUE(shell_surface->GetWidget());
EXPECT_EQ(maximized_bounds.size(), suggested_size);
EXPECT_EQ(ash::mojom::WindowStateType::MAXIMIZED, has_state_type);
shell_surface->Restore();
shell_surface->AcknowledgeConfigure(0);
// It should be restored to the original geometry size.
EXPECT_EQ(geometry.size(), shell_surface->CalculatePreferredSize());
shell_surface->SetFullscreen(true);
shell_surface->AcknowledgeConfigure(0);
......@@ -527,13 +545,6 @@ TEST_F(ShellSurfaceTest, ConfigureCallback) {
EXPECT_EQ(ash::mojom::WindowStateType::FULLSCREEN, has_state_type);
shell_surface->SetFullscreen(false);
shell_surface->AcknowledgeConfigure(0);
gfx::Size buffer_size(64, 64);
std::unique_ptr<Buffer> buffer(
new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
surface->Attach(buffer.get());
surface->Commit();
EXPECT_EQ(geometry.size(), shell_surface->CalculatePreferredSize());
shell_surface->GetWidget()->Activate();
......
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