0

Add mash shelf application id support.

Add an app_id mus window property; used to group shelf items, etc.
Populate app_id from the identity name via WindowManagerConnection.

Track multiple windows in ShelfDelegateMus & ShelfItemDelegateMus.
Show new ShelfMenuModelMus with titles on multi-window item click.

Rename ShelfController::[Pin|Unpin]Item (was [Add|Remove]Item).
Plumb identity; remove incorrect window_property.h comment.

TODO: Support dynamic app_id or custom init, for extensions, etc.?
TODO: Support window application titles (eg. 'Chrome' vs. 'New Tab')

BUG=557406
TEST=In "mojo_runner mojo:mash_session", type 'quick_launch' and hit CTRL+ENTER; a second quick launch window should open and share the existing shelf item.
R=sky@chromium.org,jam@chromium.org

Review URL: https://codereview.chromium.org/1899323002

Cr-Commit-Position: refs/heads/master@{#389508}
This commit is contained in:
msw
2016-04-25 11:16:27 -07:00
committed by Commit bot
parent 2a03e86fcf
commit 5dce124e0d
28 changed files with 248 additions and 114 deletions

@ -10,6 +10,7 @@
#include "ash/shelf/shelf_item_delegate.h"
#include "ash/shelf/shelf_item_delegate_manager.h"
#include "ash/shelf/shelf_layout_manager.h"
#include "ash/shelf/shelf_menu_model.h"
#include "ash/shelf/shelf_model.h"
#include "ash/shelf/shelf_types.h"
#include "ash/shelf/shelf_widget.h"
@ -37,38 +38,90 @@ namespace {
// A ShelfItemDelegate used for pinned items and open user windows.
class ShelfItemDelegateMus : public ShelfItemDelegate {
public:
ShelfItemDelegateMus(uint32_t window_id,
const base::string16& title,
UserWindowController* user_window_controller)
: window_id_(window_id),
title_(title),
user_window_controller_(user_window_controller) {}
explicit ShelfItemDelegateMus(UserWindowController* user_window_controller)
: user_window_controller_(user_window_controller) {}
~ShelfItemDelegateMus() override {}
void UpdateTitle(const base::string16& new_title) { title_ = new_title; }
bool pinned() const { return pinned_; }
void set_pinned(bool pinned) { pinned_ = pinned; }
void AddWindow(uint32_t id, const base::string16& title) {
DCHECK(!window_id_to_title_.count(id));
window_id_to_title_.insert(std::make_pair(id, title));
}
void RemoveWindow(uint32_t id) { window_id_to_title_.erase(id); }
void SetWindowTitle(uint32_t id, const base::string16& title) {
DCHECK(window_id_to_title_.count(id));
window_id_to_title_[id] = title;
}
const std::map<uint32_t, base::string16>& window_id_to_title() const {
return window_id_to_title_;
}
const base::string16& title() { return title_; }
void set_title(const base::string16& title) { title_ = title; }
private:
// This application menu model for ShelfItemDelegateMus lists open windows.
class ShelfMenuModelMus : public ShelfMenuModel,
public ui::SimpleMenuModel::Delegate {
public:
explicit ShelfMenuModelMus(ShelfItemDelegateMus* item_delegate)
: ShelfMenuModel(this), item_delegate_(item_delegate) {
AddSeparator(ui::SPACING_SEPARATOR);
AddItem(0, item_delegate_->GetTitle());
AddSeparator(ui::SPACING_SEPARATOR);
for (const auto& window : item_delegate_->window_id_to_title())
AddItem(window.first, window.second);
AddSeparator(ui::SPACING_SEPARATOR);
}
~ShelfMenuModelMus() override {}
// ShelfMenuModel:
bool IsCommandActive(int command_id) const override { return false; }
// ui::SimpleMenuModel::Delegate:
bool IsCommandIdChecked(int command_id) const override { return false; }
bool IsCommandIdEnabled(int command_id) const override {
return command_id > 0;
}
bool GetAcceleratorForCommandId(int command_id,
ui::Accelerator* accelerator) override {
return false;
}
void ExecuteCommand(int command_id, int event_flags) override {
item_delegate_->user_window_controller_->FocusUserWindow(command_id);
}
private:
ShelfItemDelegateMus* item_delegate_;
DISALLOW_COPY_AND_ASSIGN(ShelfMenuModelMus);
};
// ShelfItemDelegate:
ShelfItemDelegate::PerformedAction ItemSelected(
const ui::Event& event) override {
if (window_id_ != 0) {
user_window_controller_->FocusUserWindow(window_id_);
if (window_id_to_title_.size() == 1) {
user_window_controller_->FocusUserWindow(
window_id_to_title_.begin()->first);
return kExistingWindowActivated;
}
NOTIMPLEMENTED();
return kNoAction;
}
base::string16 GetTitle() override { return title_; }
base::string16 GetTitle() override {
return window_id_to_title_.empty() ? title_
: window_id_to_title_.begin()->second;
}
bool CanPin() const override {
NOTIMPLEMENTED();
return false;
return true;
}
ShelfMenuModel* CreateApplicationMenu(int event_flags) override {
NOTIMPLEMENTED();
return nullptr;
return new ShelfMenuModelMus(this);
}
bool IsDraggable() override {
@ -80,14 +133,20 @@ class ShelfItemDelegateMus : public ShelfItemDelegate {
void Close() override { NOTIMPLEMENTED(); }
// TODO(msw): Support multiple open windows per button.
uint32_t window_id_;
bool pinned_ = false;
std::map<uint32_t, base::string16> window_id_to_title_;
base::string16 title_;
UserWindowController* user_window_controller_;
DISALLOW_COPY_AND_ASSIGN(ShelfItemDelegateMus);
};
ShelfItemDelegateMus* GetShelfItemDelegate(ShelfID shelf_id) {
return static_cast<ShelfItemDelegateMus*>(
Shell::GetInstance()->shelf_item_delegate_manager()->GetShelfItemDelegate(
shelf_id));
}
// Returns an icon image from an SkBitmap, or the default shelf icon
// image if the bitmap is empty. Assumes the bitmap is a 1x icon.
// TODO(jamescook): Support other scale factors.
@ -210,31 +269,43 @@ void ShelfDelegateMus::SetAutoHideBehavior(
Shell::GetPrimaryRootWindow());
}
void ShelfDelegateMus::AddItem(
void ShelfDelegateMus::PinItem(
mash::shelf::mojom::ShelfItemPtr item,
mash::shelf::mojom::ShelfItemDelegateAssociatedPtrInfo delegate) {
std::string app_id(item->app_id.To<std::string>());
if (app_id_to_shelf_id_.count(app_id)) {
ShelfID shelf_id = app_id_to_shelf_id_[app_id];
ShelfItemDelegateMus* item_delegate = GetShelfItemDelegate(shelf_id);
item_delegate->set_pinned(true);
return;
}
ShelfID shelf_id = model_->next_id();
app_id_to_shelf_id_.insert(std::make_pair(app_id, shelf_id));
ShelfItem shelf_item;
shelf_item.type = TYPE_APP_SHORTCUT;
shelf_item.status = STATUS_CLOSED;
shelf_item.image = GetShelfIconFromBitmap(item->image.To<SkBitmap>());
std::string item_id(item->id.To<std::string>());
if (app_id_to_shelf_id_.count(item_id))
return;
ShelfID shelf_id = model_->next_id();
app_id_to_shelf_id_.insert(std::make_pair(item_id, shelf_id));
model_->Add(shelf_item);
std::unique_ptr<ShelfItemDelegateMus> item_delegate(new ShelfItemDelegateMus(
0, item->title.To<base::string16>(), user_window_controller_.get()));
std::unique_ptr<ShelfItemDelegateMus> item_delegate(
new ShelfItemDelegateMus(user_window_controller_.get()));
item_delegate->set_pinned(true);
item_delegate->set_title(item->app_title.To<base::string16>());
Shell::GetInstance()->shelf_item_delegate_manager()->SetShelfItemDelegate(
shelf_id, std::move(item_delegate));
}
void ShelfDelegateMus::RemoveItem(const mojo::String& id) {
std::string item_id(id.To<std::string>());
DCHECK(app_id_to_shelf_id_.count(item_id));
model_->RemoveItemAt(model_->ItemIndexByID(app_id_to_shelf_id_[item_id]));
void ShelfDelegateMus::UnpinItem(const mojo::String& app_id) {
if (!app_id_to_shelf_id_.count(app_id.To<std::string>()))
return;
ShelfID shelf_id = app_id_to_shelf_id_[app_id.To<std::string>()];
ShelfItemDelegateMus* item_delegate = GetShelfItemDelegate(shelf_id);
DCHECK(item_delegate->pinned());
item_delegate->set_pinned(false);
if (item_delegate->window_id_to_title().empty())
model_->RemoveItemAt(model_->ItemIndexByID(shelf_id));
}
void ShelfDelegateMus::OnUserWindowObserverAdded(
@ -245,27 +316,47 @@ void ShelfDelegateMus::OnUserWindowObserverAdded(
void ShelfDelegateMus::OnUserWindowAdded(
mash::wm::mojom::UserWindowPtr user_window) {
ShelfItem item;
item.type = TYPE_PLATFORM_APP;
item.status = user_window->window_has_focus ? STATUS_ACTIVE : STATUS_RUNNING;
item.image = GetShelfIconFromSerializedBitmap(user_window->window_app_icon);
DCHECK(!window_id_to_shelf_id_.count(user_window->window_id));
std::string app_id(user_window->window_app_id.To<std::string>());
if (app_id_to_shelf_id_.count(app_id)) {
ShelfID shelf_id = app_id_to_shelf_id_[app_id];
window_id_to_shelf_id_.insert(
std::make_pair(user_window->window_id, shelf_id));
ShelfItemDelegateMus* item_delegate = GetShelfItemDelegate(shelf_id);
item_delegate->AddWindow(user_window->window_id,
user_window->window_title.To<base::string16>());
return;
}
ShelfID shelf_id = model_->next_id();
window_id_to_shelf_id_.insert(
std::make_pair(user_window->window_id, shelf_id));
app_id_to_shelf_id_.insert(std::make_pair(app_id, shelf_id));
ShelfItem item;
item.type = TYPE_PLATFORM_APP;
item.status = user_window->window_has_focus ? STATUS_ACTIVE : STATUS_RUNNING;
item.image = GetShelfIconFromSerializedBitmap(user_window->window_app_icon);
model_->Add(item);
std::unique_ptr<ShelfItemDelegate> item_delegate(new ShelfItemDelegateMus(
user_window->window_id, user_window->window_title.To<base::string16>(),
user_window_controller_.get()));
std::unique_ptr<ShelfItemDelegateMus> item_delegate(
new ShelfItemDelegateMus(user_window_controller_.get()));
item_delegate->AddWindow(user_window->window_id,
user_window->window_title.To<base::string16>());
Shell::GetInstance()->shelf_item_delegate_manager()->SetShelfItemDelegate(
shelf_id, std::move(item_delegate));
}
void ShelfDelegateMus::OnUserWindowRemoved(uint32_t window_id) {
DCHECK(window_id_to_shelf_id_.count(window_id));
model_->RemoveItemAt(
model_->ItemIndexByID(window_id_to_shelf_id_[window_id]));
ShelfID shelf_id = window_id_to_shelf_id_[window_id];
ShelfItemDelegateMus* item_delegate = GetShelfItemDelegate(shelf_id);
item_delegate->RemoveWindow(window_id);
window_id_to_shelf_id_.erase(window_id);
if (item_delegate->window_id_to_title().empty() && !item_delegate->pinned())
model_->RemoveItemAt(model_->ItemIndexByID(shelf_id));
}
void ShelfDelegateMus::OnUserWindowTitleChanged(
@ -273,12 +364,8 @@ void ShelfDelegateMus::OnUserWindowTitleChanged(
const mojo::String& window_title) {
DCHECK(window_id_to_shelf_id_.count(window_id));
ShelfID shelf_id = window_id_to_shelf_id_[window_id];
ShelfItemDelegateManager* manager =
Shell::GetInstance()->shelf_item_delegate_manager();
ShelfItemDelegate* delegate = manager->GetShelfItemDelegate(shelf_id);
DCHECK(delegate);
static_cast<ShelfItemDelegateMus*>(delegate)->UpdateTitle(
window_title.To<base::string16>());
ShelfItemDelegateMus* item_delegate = GetShelfItemDelegate(shelf_id);
item_delegate->SetWindowTitle(window_id, window_title.To<base::string16>());
// There's nothing in the ShelfItem that needs to be updated. But we still
// need to update the ShelfModel so that the observers can pick up any

@ -46,10 +46,10 @@ class ShelfDelegateMus : public ShelfDelegate,
void SetAlignment(mash::shelf::mojom::Alignment alignment) override;
void SetAutoHideBehavior(
mash::shelf::mojom::AutoHideBehavior auto_hide) override;
void AddItem(
void PinItem(
mash::shelf::mojom::ShelfItemPtr item,
mash::shelf::mojom::ShelfItemDelegateAssociatedPtrInfo delegate) override;
void RemoveItem(const mojo::String& id) override;
void UnpinItem(const mojo::String& app_id) override;
// mash::wm::mojom::UserWindowObserver:
void OnUserWindowObserverAdded(

@ -193,10 +193,11 @@ class AshInit {
aura::Window* root() { return ash::Shell::GetPrimaryRootWindow(); }
void Initialize(::shell::Connector* connector) {
void Initialize(::shell::Connector* connector,
const ::shell::Identity& identity) {
InitializeResourceBundle(connector);
aura_init_.reset(new views::AuraInit(connector, "views_mus_resources.pak"));
views::WindowManagerConnection::Create(connector);
views::WindowManagerConnection::Create(connector, identity);
gfx::Screen* screen = gfx::Screen::GetScreen();
DCHECK(screen);
@ -306,7 +307,7 @@ void SysUIApplication::Initialize(::shell::Connector* connector,
const ::shell::Identity& identity,
uint32_t id) {
ash_init_.reset(new AshInit());
ash_init_->Initialize(connector);
ash_init_->Initialize(connector, identity);
}
bool SysUIApplication::AcceptConnection(::shell::Connection* connection) {

@ -74,14 +74,14 @@ void ChromeMashShelfController::Init() {
// Create a test shortcut item to a fake application.
mash::shelf::mojom::ShelfItemPtr item(mash::shelf::mojom::ShelfItem::New());
std::string item_id("mojo:fake_app");
item->id = item_id;
item->title = "Fake Mojo App (test pinned shelf item)";
item->app_id = item_id;
item->app_title = "Fake Mojo App (test pinned shelf item)";
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
const gfx::Image& image = rb.GetImageNamed(IDR_PRODUCT_LOGO_32);
item->image = skia::mojom::Bitmap::From(*image.ToSkBitmap());
std::unique_ptr<ChromeShelfItemDelegate> delegate(
new ChromeShelfItemDelegate());
shelf_controller_->AddItem(std::move(item),
shelf_controller_->PinItem(std::move(item),
delegate->CreateInterfacePtrInfoAndBind(
shelf_controller_.associated_group()));
app_id_to_item_delegate_.insert(std::make_pair(item_id, std::move(delegate)));

@ -7,9 +7,6 @@
#include <stdint.h>
// This header should be included by code that defines WindowProperties. It
// should not be included by code that only gets and sets WindowProperties.
//
// To define a new WindowProperty:
//
// #include "components/mus/public/cpp/window_property.h"

@ -40,6 +40,8 @@ interface WindowManager {
const string kWindowType_Property = "prop:window-type";
// The window's title. Type: mojom::String
const string kWindowTitle_Property = "prop:window-title";
// The application ID (eg. 'mojo:foo'). Type: mojom::String
const string kAppID_Property = "prop:app-id";
// When the WindowManager completes a request it must call back to
// WindowManagerClient::WmResponse().

@ -1188,9 +1188,11 @@ int BrowserMainLoop::BrowserThreadsStarted() {
MojoShellConnectionImpl::Get()->BindToRequestFromCommandLine();
}
#if defined(MOJO_SHELL_CLIENT) && defined(USE_AURA)
if (MojoShellConnection::Get()) {
MojoShellConnection* mojo_shell_connection = MojoShellConnection::Get();
if (mojo_shell_connection) {
views::WindowManagerConnection::Create(
MojoShellConnection::Get()->GetConnector());
mojo_shell_connection->GetConnector(),
mojo_shell_connection->GetIdentity());
}
#endif
}

@ -130,6 +130,11 @@ shell::Connector* MojoShellConnectionImpl::GetConnector() {
return shell_connection_->connector();
}
const shell::Identity& MojoShellConnectionImpl::GetIdentity() const {
DCHECK(shell_connection_);
return shell_connection_->identity();
}
bool MojoShellConnectionImpl::UsingExternalShell() const {
return external_;
}

@ -55,6 +55,7 @@ class MojoShellConnectionImpl : public MojoShellConnection,
// MojoShellConnection:
shell::Connector* GetConnector() override;
const shell::Identity& GetIdentity() const override;
bool UsingExternalShell() const override;
void SetConnectionLostClosure(const base::Closure& closure) override;
void AddListener(std::unique_ptr<Listener> listener) override;

@ -106,6 +106,7 @@ source_set("common_sources") {
"//mojo/common",
"//net",
"//ppapi/c",
"//services/shell/public/cpp",
"//skia",
"//storage/common",
"//third_party/WebKit/public:blink_headers",

@ -9,6 +9,7 @@
#include "base/callback_forward.h"
#include "content/common/content_export.h"
#include "services/shell/public/cpp/identity.h"
#include "services/shell/public/interfaces/shell_client.mojom.h"
namespace shell {
@ -57,6 +58,8 @@ class CONTENT_EXPORT MojoShellConnection {
virtual shell::Connector* GetConnector() = 0;
virtual const shell::Identity& GetIdentity() const = 0;
// Indicates whether the shell connection is to an external shell (true) or
// a shell embedded in the browser process (false).
virtual bool UsingExternalShell() const = 0;

@ -182,7 +182,7 @@ void CatalogViewer::Initialize(shell::Connector* connector,
tracing_.Initialize(connector, identity.name());
aura_init_.reset(new views::AuraInit(connector, "views_mus_resources.pak"));
views::WindowManagerConnection::Create(connector);
views::WindowManagerConnection::Create(connector, identity);
}
bool CatalogViewer::AcceptConnection(shell::Connection* connection) {

@ -22,7 +22,7 @@ void ViewsExamplesApplicationDelegate::Initialize(
uint32_t id) {
tracing_.Initialize(connector, identity.name());
aura_init_.reset(new views::AuraInit(connector, "views_mus_resources.pak"));
views::WindowManagerConnection::Create(connector);
views::WindowManagerConnection::Create(connector, identity);
}
bool ViewsExamplesApplicationDelegate::AcceptConnection(

@ -399,7 +399,7 @@ void WindowTypeLauncher::Initialize(shell::Connector* connector,
connector_ = connector;
aura_init_.reset(new views::AuraInit(connector, "views_mus_resources.pak"));
views::WindowManagerConnection::Create(connector);
views::WindowManagerConnection::Create(connector, identity);
}
bool WindowTypeLauncher::AcceptConnection(shell::Connection* connection) {

@ -36,11 +36,13 @@ class Login;
class UI : public views::WidgetDelegateView,
public views::ButtonListener {
public:
static void Show(shell::Connector* connector, Login* login) {
static void Show(shell::Connector* connector,
const shell::Identity& identity,
Login* login) {
UI* ui = new UI(login, connector);
ui->StartWindowManager();
views::WindowManagerConnection::Create(connector);
views::WindowManagerConnection::Create(connector, identity);
views::Widget* widget = new views::Widget;
views::Widget::InitParams params(
@ -149,6 +151,7 @@ class Login : public shell::ShellClient,
const shell::Identity& identity,
uint32_t id) override {
connector_ = connector;
identity_ = identity;
tracing_.Initialize(connector, identity.name());
aura_init_.reset(new views::AuraInit(connector, "views_mus_resources.pak"));
@ -168,16 +171,13 @@ class Login : public shell::ShellClient,
}
// mojom::Login:
void ShowLoginUI() override {
UI::Show(connector_, this);
}
void SwitchUser() override {
UI::Show(connector_, this);
}
void ShowLoginUI() override { UI::Show(connector_, identity_, this); }
void SwitchUser() override { UI::Show(connector_, identity_, this); }
void StartWindowManager();
shell::Connector* connector_;
shell::Identity identity_;
mojo::TracingImpl tracing_;
std::unique_ptr<views::AuraInit> aura_init_;
mojo::BindingSet<mojom::Login> bindings_;

@ -174,7 +174,7 @@ void QuickLaunchApplication::Initialize(shell::Connector* connector,
tracing_.Initialize(connector, identity.name());
aura_init_.reset(new views::AuraInit(connector, "views_mus_resources.pak"));
views::WindowManagerConnection::Create(connector);
views::WindowManagerConnection::Create(connector, identity);
Launch(mojom::kWindow, mojom::LaunchMode::MAKE_NEW);
}

@ -86,7 +86,7 @@ void Screenlock::Initialize(shell::Connector* connector,
bindings_.CreateInterfacePtrAndBind(this));
aura_init_.reset(new views::AuraInit(connector, "views_mus_resources.pak"));
views::WindowManagerConnection::Create(connector);
views::WindowManagerConnection::Create(connector, identity);
views::Widget* widget = new views::Widget;
views::Widget::InitParams params(

@ -16,8 +16,8 @@ interface ShelfController {
SetAlignment(Alignment alignment);
SetAutoHideBehavior(AutoHideBehavior auto_hide);
AddItem(ShelfItem item, associated ShelfItemDelegate delegate);
RemoveItem(string id);
PinItem(ShelfItem item, associated ShelfItemDelegate delegate);
UnpinItem(string app_id);
};
// ShelfObserver is notified on shelf changes; used to persist profile settings.
@ -55,11 +55,11 @@ struct ContextMenuItem {
// ShelfItem contains the basic fields needed to pin shortcut items.
struct ShelfItem {
// An id, used to correlate windows and shortcuts (eg. 'exe:chrome').
string id;
// An app id, used to correlate windows and shortcuts (eg. 'mojo:foo').
string app_id;
// A title, used for tooltips, etc. (eg. 'Chrome').
string title;
// A app title, used for tooltips, etc. (eg. 'Foo Application').
string app_title;
// An icon image Bitmap, shown on the shelf.
skia.mojom.Bitmap image;

@ -290,7 +290,7 @@ void TaskViewer::Initialize(shell::Connector* connector,
tracing_.Initialize(connector, identity.name());
aura_init_.reset(new views::AuraInit(connector, "views_mus_resources.pak"));
views::WindowManagerConnection::Create(connector);
views::WindowManagerConnection::Create(connector, identity);
}
bool TaskViewer::AcceptConnection(shell::Connection* connection) {

@ -149,5 +149,18 @@ mojo::Array<uint8_t> GetWindowAppIcon(const mus::Window* window) {
return mojo::Array<uint8_t>();
}
void SetAppID(mus::Window* window, const base::string16& app_id) {
window->SetSharedProperty<base::string16>(
mus::mojom::WindowManager::kAppID_Property, app_id);
}
base::string16 GetAppID(const mus::Window* window) {
if (!window->HasSharedProperty(mus::mojom::WindowManager::kAppID_Property))
return base::string16();
return window->GetSharedProperty<base::string16>(
mus::mojom::WindowManager::kAppID_Property);
}
} // namespace wm
} // namespace mash

@ -55,6 +55,9 @@ base::string16 GetWindowTitle(const mus::Window* window);
mojo::Array<uint8_t> GetWindowAppIcon(const mus::Window* window);
void SetAppID(mus::Window* window, const base::string16& app_id);
base::string16 GetAppID(const mus::Window* window);
} // namespace wm
} // namespace mash

@ -5,10 +5,11 @@
module mash.wm.mojom;
struct UserWindow {
uint32 window_id;
string window_title;
bool window_has_focus;
array<uint8> window_app_icon; // Serialized SkBitmap.
uint32 window_id; // The local window id, defined by UserWindowController.
string window_title; // The window title.
bool window_has_focus; // A flag; true if the window is currently focused.
array<uint8> window_app_icon; // A serialized SkBitmap.
string window_app_id; // The window application ID (ie. 'mojo:foo').
};
// An observer of user windows within mojom::Container::USER_WINDOWS.
@ -21,7 +22,7 @@ interface UserWindowObserver {
OnUserWindowRemoved(uint32 window_id);
OnUserWindowTitleChanged(uint32 window_id, string window_title);
// |app_icon| is a serialized SkBitmap.
OnUserWindowAppIconChanged(uint32 window_id, array<uint8> app_icon);

@ -38,6 +38,7 @@ mojom::UserWindowPtr GetUserWindow(mus::Window* window) {
user_window->window_id = window->GetLocalProperty(kUserWindowIdKey);
user_window->window_title = mojo::String::From(GetWindowTitle(window));
user_window->window_app_icon = GetWindowAppIcon(window);
user_window->window_app_id = mojo::String::From(GetAppID(window));
mus::Window* focused = window->connection()->GetFocusedWindow();
focused = GetTopLevelWindow(focused, window->parent());
user_window->window_has_focus = focused == window;

@ -49,6 +49,7 @@ void ShellConnection::SetAppTestConnectorForTesting(
void ShellConnection::Initialize(mojom::IdentityPtr identity,
uint32_t id,
const InitializeCallback& callback) {
identity_ = identity.To<Identity>();
if (!initialize_handler_.is_null())
initialize_handler_.Run();
@ -57,7 +58,7 @@ void ShellConnection::Initialize(mojom::IdentityPtr identity,
DCHECK(binding_.is_bound());
binding_.set_connection_error_handler([this] { OnConnectionError(); });
client_->Initialize(connector_.get(), identity.To<Identity>(), id);
client_->Initialize(connector_.get(), identity_, id);
}
void ShellConnection::AcceptConnection(

@ -54,6 +54,7 @@ class ShellConnection : public mojom::ShellClient {
~ShellConnection() override;
Connector* connector() { return connector_.get(); }
const Identity& identity() { return identity_; }
// TODO(rockot): Remove this. http://crbug.com/594852.
void set_initialize_handler(const base::Closure& callback);
@ -66,37 +67,38 @@ class ShellConnection : public mojom::ShellClient {
connection_lost_closure_ = closure;
}
private:
// mojom::ShellClient:
void Initialize(mojom::IdentityPtr identity,
uint32_t id,
const InitializeCallback& callback) override;
void AcceptConnection(mojom::IdentityPtr source,
uint32_t source_id,
mojom::InterfaceProviderRequest remote_interfaces,
mojom::InterfaceProviderPtr local_interfaces,
mojom::CapabilityRequestPtr allowed_capabilities,
const mojo::String& name) override;
private:
// mojom::ShellClient:
void Initialize(mojom::IdentityPtr identity,
uint32_t id,
const InitializeCallback& callback) override;
void AcceptConnection(mojom::IdentityPtr source,
uint32_t source_id,
mojom::InterfaceProviderRequest remote_interfaces,
mojom::InterfaceProviderPtr local_interfaces,
mojom::CapabilityRequestPtr allowed_capabilities,
const mojo::String& name) override;
void OnConnectionError();
void OnConnectionError();
// A callback called when Initialize() is run.
base::Closure initialize_handler_;
// A callback called when Initialize() is run.
base::Closure initialize_handler_;
// We track the lifetime of incoming connection registries as it more
// convenient for the client.
ScopedVector<Connection> incoming_connections_;
// We track the lifetime of incoming connection registries as it more
// convenient for the client.
ScopedVector<Connection> incoming_connections_;
// A pending Connector request which will eventually be passed to the shell.
mojom::ConnectorRequest pending_connector_request_;
// A pending Connector request which will eventually be passed to the shell.
mojom::ConnectorRequest pending_connector_request_;
shell::ShellClient* client_;
mojo::Binding<mojom::ShellClient> binding_;
std::unique_ptr<Connector> connector_;
shell::ShellClient* client_;
mojo::Binding<mojom::ShellClient> binding_;
std::unique_ptr<Connector> connector_;
shell::Identity identity_;
base::Closure connection_lost_closure_;
base::Closure connection_lost_closure_;
DISALLOW_COPY_AND_ASSIGN(ShellConnection);
DISALLOW_COPY_AND_ASSIGN(ShellConnection);
};
} // namespace shell

@ -59,7 +59,7 @@ class PlatformTestHelperMus : public PlatformTestHelper {
// one.
shell::Connector* connector = shell_connection_->connector();
connector->Connect("mojo:desktop_wm");
WindowManagerConnection::Create(connector);
WindowManagerConnection::Create(connector, shell_connection_->identity());
// On X we need to reset the ContextFactory before every NativeWidgetMus
// is created.

@ -8,6 +8,9 @@
#include "base/lazy_instance.h"
#include "base/threading/thread_local.h"
#include "components/mus/public/cpp/property_type_converters.h"
#include "components/mus/public/cpp/window.h"
#include "components/mus/public/cpp/window_property.h"
#include "components/mus/public/cpp/window_tree_connection.h"
#include "components/mus/public/interfaces/window_tree.mojom.h"
#include "mojo/converters/geometry/geometry_type_converters.h"
@ -31,9 +34,10 @@ base::LazyInstance<WindowManagerConnectionPtr>::Leaky lazy_tls_ptr =
} // namespace
// static
void WindowManagerConnection::Create(shell::Connector* connector) {
void WindowManagerConnection::Create(shell::Connector* connector,
const shell::Identity& identity) {
DCHECK(!lazy_tls_ptr.Pointer()->Get());
lazy_tls_ptr.Pointer()->Set(new WindowManagerConnection(connector));
lazy_tls_ptr.Pointer()->Set(new WindowManagerConnection(connector, identity));
}
// static
@ -65,12 +69,18 @@ NativeWidget* WindowManagerConnection::CreateNativeWidgetMus(
internal::NativeWidgetDelegate* delegate) {
std::map<std::string, std::vector<uint8_t>> properties = props;
NativeWidgetMus::ConfigurePropertiesForNewWindow(init_params, &properties);
properties[mus::mojom::WindowManager::kAppID_Property] =
mojo::ConvertTo<std::vector<uint8_t>>(identity_.name());
return new NativeWidgetMus(delegate, connector_, NewWindow(properties),
mus::mojom::SurfaceType::DEFAULT);
}
WindowManagerConnection::WindowManagerConnection(shell::Connector* connector)
: connector_(connector), window_tree_connection_(nullptr) {
WindowManagerConnection::WindowManagerConnection(
shell::Connector* connector,
const shell::Identity& identity)
: connector_(connector),
identity_(identity),
window_tree_connection_(nullptr) {
window_tree_connection_.reset(
mus::WindowTreeConnection::Create(this, connector_));

@ -11,6 +11,7 @@
#include "base/macros.h"
#include "components/mus/public/cpp/window_tree_delegate.h"
#include "services/shell/public/cpp/identity.h"
#include "ui/views/mus/mus_export.h"
#include "ui/views/mus/screen_mus_delegate.h"
#include "ui/views/widget/widget.h"
@ -38,7 +39,8 @@ class VIEWS_MUS_EXPORT WindowManagerConnection
: public NON_EXPORTED_BASE(mus::WindowTreeDelegate),
public ScreenMusDelegate {
public:
static void Create(shell::Connector* connector);
static void Create(shell::Connector* connector,
const shell::Identity& identity);
static WindowManagerConnection* Get();
static bool Exists();
@ -56,7 +58,8 @@ class VIEWS_MUS_EXPORT WindowManagerConnection
internal::NativeWidgetDelegate* delegate);
private:
explicit WindowManagerConnection(shell::Connector* connector);
WindowManagerConnection(shell::Connector* connector,
const shell::Identity& identity);
~WindowManagerConnection() override;
// mus::WindowTreeDelegate:
@ -67,6 +70,7 @@ class VIEWS_MUS_EXPORT WindowManagerConnection
void OnWindowManagerFrameValuesChanged() override;
shell::Connector* connector_;
shell::Identity identity_;
std::unique_ptr<ScreenMus> screen_;
std::unique_ptr<mus::WindowTreeConnection> window_tree_connection_;