Skip to content

Commit

Permalink
exo: Implement remote shell interface.
Browse files Browse the repository at this point in the history
This interface is designed for clients that use remote
management for most shell surface functionally but still
want to integrate with the compositor's desktop shell for
activation and window stacking purposes.

BUG=549781
TEST=exo_unittests

Review-Url: https://codereview.chromium.org/2005243002
Cr-Commit-Position: refs/heads/master@{#396181}
  • Loading branch information
reveman-chromium authored and Commit bot committed May 26, 2016
1 parent 4d2e48c commit faefc28
Show file tree
Hide file tree
Showing 10 changed files with 349 additions and 16 deletions.
2 changes: 2 additions & 0 deletions components/exo.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,13 @@
'../ipc/ipc.gyp:ipc',
'../skia/skia.gyp:skia',
'../third_party/wayland-protocols/wayland-protocols.gyp:alpha_compositing_protocol',
'../third_party/wayland-protocols/wayland-protocols.gyp:remote_shell_protocol',
'../third_party/wayland-protocols/wayland-protocols.gyp:scaler_protocol',
'../third_party/wayland-protocols/wayland-protocols.gyp:secure_output_protocol',
'../third_party/wayland-protocols/wayland-protocols.gyp:viewporter_protocol',
'../third_party/wayland-protocols/wayland-protocols.gyp:xdg_shell_protocol',
'../third_party/wayland/wayland.gyp:wayland_server',
'../ui/aura/aura.gyp:aura',
'../ui/events/events.gyp:dom_keycode_converter',
'../ui/display/display.gyp:display',
'../ui/events/events.gyp:events_base',
Expand Down
24 changes: 21 additions & 3 deletions components/exo/display.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <iterator>
#include <utility>

#include "ash/wm/common/wm_shell_window_ids.h"
#include "base/memory/ptr_util.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"
Expand Down Expand Up @@ -103,7 +104,8 @@ std::unique_ptr<ShellSurface> Display::CreateShellSurface(Surface* surface) {
}

return base::WrapUnique(
new ShellSurface(surface, nullptr, gfx::Rect(), true));
new ShellSurface(surface, nullptr, gfx::Rect(), true, true,
ash::kShellWindowId_DefaultContainer));
}

std::unique_ptr<ShellSurface> Display::CreatePopupShellSurface(
Expand All @@ -123,8 +125,24 @@ std::unique_ptr<ShellSurface> Display::CreatePopupShellSurface(
return nullptr;
}

return base::WrapUnique(new ShellSurface(
surface, parent, gfx::Rect(position, gfx::Size(1, 1)), false));
return base::WrapUnique(
new ShellSurface(surface, parent, gfx::Rect(position, gfx::Size(1, 1)),
false, true, ash::kShellWindowId_DefaultContainer));
}

std::unique_ptr<ShellSurface> Display::CreateRemoteShellSurface(
Surface* surface,
int container) {
TRACE_EVENT2("exo", "Display::CreateRemoteShellSurface", "surface",
surface->AsTracedValue(), "container", container);

if (surface->HasSurfaceDelegate()) {
DLOG(ERROR) << "Surface has already been assigned a role";
return nullptr;
}

return base::WrapUnique(new ShellSurface(surface, nullptr, gfx::Rect(1, 1),
true, true, container));
}

std::unique_ptr<SubSurface> Display::CreateSubSurface(Surface* surface,
Expand Down
4 changes: 4 additions & 0 deletions components/exo/display.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ class Display {
ShellSurface* parent,
const gfx::Point& position);

// Creates a remote shell surface for an existing surface using |container|.
std::unique_ptr<ShellSurface> CreateRemoteShellSurface(Surface* surface,
int container);

// Creates a sub-surface for an existing surface. The sub-surface will be
// a child of |parent|.
std::unique_ptr<SubSurface> CreateSubSurface(Surface* surface,
Expand Down
23 changes: 23 additions & 0 deletions components/exo/display_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/wm/common/wm_shell_window_ids.h"
#include "components/exo/buffer.h"
#include "components/exo/display.h"
#include "components/exo/shared_memory.h"
Expand Down Expand Up @@ -124,6 +125,28 @@ TEST_F(DisplayTest, CreatePopupShellSurface) {
EXPECT_TRUE(shell_surface2);
}

TEST_F(DisplayTest, CreateRemoteShellSurface) {
std::unique_ptr<Display> display(new Display);

// Create two surfaces.
std::unique_ptr<Surface> surface1 = display->CreateSurface();
ASSERT_TRUE(surface1);
std::unique_ptr<Surface> surface2 = display->CreateSurface();
ASSERT_TRUE(surface2);

// Create a remote shell surface for surface1.
std::unique_ptr<ShellSurface> shell_surface1 =
display->CreateRemoteShellSurface(
surface1.get(), ash::kShellWindowId_SystemModalContainer);
EXPECT_TRUE(shell_surface1);

// Create a remote shell surface for surface2.
std::unique_ptr<ShellSurface> shell_surface2 =
display->CreateRemoteShellSurface(surface2.get(),
ash::kShellWindowId_DefaultContainer);
EXPECT_TRUE(shell_surface2);
}

TEST_F(DisplayTest, CreateSubSurface) {
std::unique_ptr<Display> display(new Display);

Expand Down
4 changes: 3 additions & 1 deletion components/exo/pointer_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// found in the LICENSE file.

#include "ash/shell.h"
#include "ash/wm/common/wm_shell_window_ids.h"
#include "components/exo/buffer.h"
#include "components/exo/pointer.h"
#include "components/exo/pointer_delegate.h"
Expand Down Expand Up @@ -171,7 +172,8 @@ TEST_F(PointerTest, OnPointerMotion) {

std::unique_ptr<Surface> child_surface(new Surface);
std::unique_ptr<ShellSurface> child_shell_surface(new ShellSurface(
child_surface.get(), shell_surface.get(), gfx::Rect(9, 9, 1, 1), true));
child_surface.get(), shell_surface.get(), gfx::Rect(9, 9, 1, 1), true,
true, ash::kShellWindowId_DefaultContainer));
gfx::Size child_buffer_size(15, 15);
std::unique_ptr<Buffer> child_buffer(
new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(child_buffer_size)));
Expand Down
54 changes: 47 additions & 7 deletions components/exo/shell_surface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,18 @@ DEFINE_LOCAL_WINDOW_PROPERTY_KEY(Surface*, kMainSurfaceKey, nullptr)
ShellSurface::ShellSurface(Surface* surface,
ShellSurface* parent,
const gfx::Rect& initial_bounds,
bool activatable)
bool activatable,
bool resizeable,
int container)
: widget_(nullptr),
surface_(surface),
parent_(parent ? parent->GetWidget()->GetNativeWindow() : nullptr),
initial_bounds_(initial_bounds),
activatable_(activatable),
resizeable_(resizeable),
container_(container),
scale_(1.0),
pending_scale_(1.0),
scoped_configure_(nullptr),
ignore_window_bounds_changes_(false),
resize_component_(HTCAPTION),
Expand All @@ -180,12 +186,19 @@ ShellSurface::ShellSurface(Surface* surface,
}

ShellSurface::ShellSurface(Surface* surface)
: ShellSurface(surface, nullptr, gfx::Rect(), true) {}
: ShellSurface(surface,
nullptr,
gfx::Rect(),
true,
true,
ash::kShellWindowId_DefaultContainer) {}

ShellSurface::~ShellSurface() {
DCHECK(!scoped_configure_);
ash::Shell::GetInstance()->activation_client()->RemoveObserver(this);
if (surface_) {
if (scale_ != 1.0)
surface_->SetTransform(gfx::Transform());
surface_->SetSurfaceDelegate(nullptr);
surface_->RemoveSurfaceObserver(this);
}
Expand Down Expand Up @@ -340,6 +353,17 @@ void ShellSurface::SetGeometry(const gfx::Rect& geometry) {
pending_geometry_ = geometry;
}

void ShellSurface::SetScale(double scale) {
TRACE_EVENT1("exo", "ShellSurface::SetScale", "scale", scale);

if (scale <= 0.0) {
DLOG(WARNING) << "Surface scale must be greater than 0";
return;
}

pending_scale_ = scale;
}

// static
void ShellSurface::SetMainSurface(aura::Window* window, Surface* surface) {
window->SetProperty(kMainSurfaceKey, surface);
Expand All @@ -365,7 +389,14 @@ std::unique_ptr<base::trace_event::TracedValue> ShellSurface::AsTracedValue()
void ShellSurface::OnSurfaceCommit() {
surface_->CommitSurfaceHierarchy();

// Apply new window geometry.
// Apply new window geometry. Widget origin needs to be adjusted to avoid
// having changes to geometry origin cause a change of the surface position
// on screen.
if (widget_ && pending_geometry_.origin() != geometry_.origin()) {
gfx::Rect new_widget_bounds = widget_->GetNativeWindow()->bounds();
new_widget_bounds.Offset(pending_geometry_.origin() - geometry_.origin());
widget_->SetBounds(new_widget_bounds);
}
geometry_ = pending_geometry_;

if (enabled() && !widget_)
Expand Down Expand Up @@ -405,6 +436,15 @@ void ShellSurface::OnSurfaceCommit() {
// Update surface bounds.
surface_->SetBounds(gfx::Rect(surface_origin, surface_->layer()->size()));

// Update surface scale.
if (pending_scale_ != scale_) {
gfx::Transform transform;
DCHECK_NE(pending_scale_, 0.0);
transform.Scale(1.0 / pending_scale_, 1.0 / pending_scale_);
surface_->SetTransform(transform);
scale_ = pending_scale_;
}

// Show widget if not already visible.
if (!widget_->IsClosed() && !widget_->IsVisible())
widget_->Show();
Expand Down Expand Up @@ -443,11 +483,11 @@ void ShellSurface::OnSurfaceDestroying(Surface* surface) {
// views::WidgetDelegate overrides:

bool ShellSurface::CanMaximize() const {
return true;
return resizeable_;
}

bool ShellSurface::CanResize() const {
return true;
return resizeable_;
}

base::string16 ShellSurface::GetWindowTitle() const {
Expand Down Expand Up @@ -652,8 +692,8 @@ void ShellSurface::CreateShellSurfaceWidget(ui::WindowShowState show_state) {
params.shadow_type = views::Widget::InitParams::SHADOW_TYPE_NONE;
params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
params.show_state = show_state;
params.parent = ash::Shell::GetContainer(
ash::Shell::GetPrimaryRootWindow(), ash::kShellWindowId_DefaultContainer);
params.parent =
ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(), container_);
if (!initial_bounds_.IsEmpty()) {
params.bounds = initial_bounds_;
if (parent_) {
Expand Down
13 changes: 12 additions & 1 deletion components/exo/shell_surface.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ class ShellSurface : public SurfaceDelegate,
ShellSurface(Surface* surface,
ShellSurface* parent,
const gfx::Rect& initial_bounds,
bool activatable);
bool activatable,
bool resizeable,
int container);
explicit ShellSurface(Surface* surface);
~ShellSurface() override;

Expand Down Expand Up @@ -123,6 +125,10 @@ class ShellSurface : public SurfaceDelegate,
// for the surface from the user's perspective.
void SetGeometry(const gfx::Rect& geometry);

// Set scale factor for surface. The scale factor will be applied to surface
// and all descendants.
void SetScale(double scale);

// Sets the main surface for the window.
static void SetMainSurface(aura::Window* window, Surface* surface);
static Surface* GetMainSurface(const aura::Window* window);
Expand Down Expand Up @@ -219,10 +225,15 @@ class ShellSurface : public SurfaceDelegate,
aura::Window* parent_;
const gfx::Rect initial_bounds_;
const bool activatable_;
const bool resizeable_;
// Container Window Id (see ash/wm/common/wm_shell_window_ids.h)
const int container_;
base::string16 title_;
std::string application_id_;
gfx::Rect geometry_;
gfx::Rect pending_geometry_;
double scale_;
double pending_scale_;
base::Closure close_callback_;
base::Closure surface_destroyed_callback_;
ConfigureCallback configure_callback_;
Expand Down
18 changes: 18 additions & 0 deletions components/exo/shell_surface_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,24 @@ TEST_F(ShellSurfaceTest, SetGeometry) {
surface->bounds().ToString());
}

TEST_F(ShellSurfaceTest, SetScale) {
gfx::Size buffer_size(64, 64);
std::unique_ptr<Buffer> buffer(
new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
std::unique_ptr<Surface> surface(new Surface);
std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));

double scale = 1.5;
shell_surface->SetScale(scale);
surface->Attach(buffer.get());
surface->Commit();

gfx::Transform transform;
transform.Scale(1.0 / scale, 1.0 / scale);
EXPECT_EQ(transform.ToString(),
surface->layer()->GetTargetTransform().ToString());
}

void Close(int* close_call_count) {
(*close_call_count)++;
}
Expand Down
2 changes: 2 additions & 0 deletions components/exo/wayland/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@ source_set("wayland") {
"//skia",
"//third_party/wayland:wayland_server",
"//third_party/wayland-protocols:alpha_compositing_protocol",
"//third_party/wayland-protocols:remote_shell_protocol",
"//third_party/wayland-protocols:scaler_protocol",
"//third_party/wayland-protocols:secure_output_protocol",
"//third_party/wayland-protocols:viewporter_protocol",
"//third_party/wayland-protocols:xdg_shell_protocol",
"//ui/aura:aura",
"//ui/events:dom_keycode_converter",
"//ui/events:events_base",
"//ui/views",
Expand Down
Loading

0 comments on commit faefc28

Please sign in to comment.