This source file includes following definitions.
- SetShelfItemDetailsForShelfItem
- HasShelfItemForWindow
- IsDragging
- OnWindowDestroying
- OnWindowParentChanged
- OnWindowDestroyed
- observed_activation_clients_
- AddShelfItem
- RemoveShelfItem
- OnRootWindowAdded
- OnRootWindowRemoved
- UpdateShelfItemStatus
- GetShelfItemIndexForWindow
- StartObservingRemovedWindow
- FinishObservingRemovedWindow
- OnWindowActivated
- OnWindowAdded
- OnWillRemoveWindow
- OnWindowDestroying
- OnWindowPropertyChanged
- OnDisplayBoundsChanged
- OnDisplayAdded
- OnDisplayRemoved
#include "ash/shelf/shelf_window_watcher.h"
#include "ash/ash_switches.h"
#include "ash/display/display_controller.h"
#include "ash/shelf/shelf_constants.h"
#include "ash/shelf/shelf_item_delegate_manager.h"
#include "ash/shelf/shelf_model.h"
#include "ash/shelf/shelf_util.h"
#include "ash/shelf/shelf_window_watcher_item_delegate.h"
#include "ash/shell.h"
#include "ash/shell_window_ids.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_util.h"
#include "base/memory/scoped_ptr.h"
#include "ui/aura/window.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/screen.h"
#include "ui/wm/public/activation_client.h"
namespace {
void SetShelfItemDetailsForShelfItem(ash::ShelfItem* item,
const ash::ShelfItemDetails& details) {
item->type = details.type;
if (details.image_resource_id != ash::kInvalidImageResourceID) {
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
item->image = *rb.GetImageSkiaNamed(details.image_resource_id);
}
}
bool HasShelfItemForWindow(aura::Window* window) {
if (ash::GetShelfItemDetailsForWindow(window) != NULL &&
ash::GetShelfIDForWindow(window) != ash::kInvalidShelfID)
return true;
return false;
}
bool IsDragging(aura::Window* window) {
return ash::wm::GetWindowState(window)->is_dragged();
}
}
namespace ash {
ShelfWindowWatcher::RootWindowObserver::RootWindowObserver(
ShelfWindowWatcher* window_watcher)
: window_watcher_(window_watcher) {
}
ShelfWindowWatcher::RootWindowObserver::~RootWindowObserver() {
}
void ShelfWindowWatcher::RootWindowObserver::OnWindowDestroying(
aura::Window* window) {
window_watcher_->OnRootWindowRemoved(window);
}
ShelfWindowWatcher::RemovedWindowObserver::RemovedWindowObserver(
ShelfWindowWatcher* window_watcher)
: window_watcher_(window_watcher) {
}
ShelfWindowWatcher::RemovedWindowObserver::~RemovedWindowObserver() {
}
void ShelfWindowWatcher::RemovedWindowObserver::OnWindowParentChanged(
aura::Window* window,
aura::Window* parent) {
if (!parent)
return;
if (switches::UseDockedWindows() &&
IsDragging(window) &&
parent->id() == kShellWindowId_DockedContainer)
return;
window_watcher_->FinishObservingRemovedWindow(window);
}
void ShelfWindowWatcher::RemovedWindowObserver::OnWindowDestroyed(
aura::Window* window) {
DCHECK(HasShelfItemForWindow(window));
window_watcher_->FinishObservingRemovedWindow(window);
}
ShelfWindowWatcher::ShelfWindowWatcher(
ShelfModel* model,
ShelfItemDelegateManager* item_delegate_manager)
: model_(model),
item_delegate_manager_(item_delegate_manager),
root_window_observer_(this),
removed_window_observer_(this),
observed_windows_(this),
observed_root_windows_(&root_window_observer_),
observed_removed_windows_(&removed_window_observer_),
observed_activation_clients_(this) {
aura::Window::Windows root_windows = Shell::GetAllRootWindows();
for (aura::Window::Windows::const_iterator it = root_windows.begin();
it != root_windows.end(); ++it)
OnRootWindowAdded(*it);
Shell::GetScreen()->AddObserver(this);
}
ShelfWindowWatcher::~ShelfWindowWatcher() {
Shell::GetScreen()->RemoveObserver(this);
}
void ShelfWindowWatcher::AddShelfItem(aura::Window* window) {
const ShelfItemDetails* item_details =
GetShelfItemDetailsForWindow(window);
ShelfItem item;
ShelfID id = model_->next_id();
item.status = wm::IsActiveWindow(window) ? STATUS_ACTIVE: STATUS_RUNNING;
SetShelfItemDetailsForShelfItem(&item, *item_details);
SetShelfIDForWindow(id, window);
scoped_ptr<ShelfItemDelegate> item_delegate(
new ShelfWindowWatcherItemDelegate(window, model_));
item_delegate_manager_->SetShelfItemDelegate(id, item_delegate.Pass());
model_->Add(item);
}
void ShelfWindowWatcher::RemoveShelfItem(aura::Window* window) {
model_->RemoveItemAt(model_->ItemIndexByID(GetShelfIDForWindow(window)));
SetShelfIDForWindow(kInvalidShelfID, window);
}
void ShelfWindowWatcher::OnRootWindowAdded(aura::Window* root_window) {
observed_activation_clients_.Add(
aura::client::GetActivationClient(root_window));
observed_root_windows_.Add(root_window);
aura::Window* default_container = Shell::GetContainer(
root_window,
kShellWindowId_DefaultContainer);
observed_windows_.Add(default_container);
for (size_t i = 0; i < default_container->children().size(); ++i)
observed_windows_.Add(default_container->children()[i]);
}
void ShelfWindowWatcher::OnRootWindowRemoved(aura::Window* root_window) {
observed_root_windows_.Remove(root_window);
observed_activation_clients_.Remove(
aura::client::GetActivationClient(root_window));
}
void ShelfWindowWatcher::UpdateShelfItemStatus(aura::Window* window,
bool is_active) {
int index = GetShelfItemIndexForWindow(window);
DCHECK_GE(index, 0);
ShelfItem item = model_->items()[index];
item.status = is_active ? STATUS_ACTIVE : STATUS_RUNNING;
model_->Set(index, item);
}
int ShelfWindowWatcher::GetShelfItemIndexForWindow(
aura::Window* window) const {
return model_->ItemIndexByID(GetShelfIDForWindow(window));
}
void ShelfWindowWatcher::StartObservingRemovedWindow(aura::Window* window) {
observed_removed_windows_.Add(window);
}
void ShelfWindowWatcher::FinishObservingRemovedWindow(aura::Window* window) {
observed_removed_windows_.Remove(window);
RemoveShelfItem(window);
}
void ShelfWindowWatcher::OnWindowActivated(aura::Window* gained_active,
aura::Window* lost_active) {
if (gained_active && HasShelfItemForWindow(gained_active))
UpdateShelfItemStatus(gained_active, true);
if (lost_active && HasShelfItemForWindow(lost_active))
UpdateShelfItemStatus(lost_active, false);
}
void ShelfWindowWatcher::OnWindowAdded(aura::Window* window) {
observed_windows_.Add(window);
if (observed_removed_windows_.IsObserving(window)) {
DCHECK(HasShelfItemForWindow(window));
observed_removed_windows_.Remove(window);
return;
}
if (GetShelfIDForWindow(window) == kInvalidShelfID &&
GetShelfItemDetailsForWindow(window))
AddShelfItem(window);
}
void ShelfWindowWatcher::OnWillRemoveWindow(aura::Window* window) {
if (observed_windows_.IsObserving(window))
observed_windows_.Remove(window);
if (HasShelfItemForWindow(window))
StartObservingRemovedWindow(window);
}
void ShelfWindowWatcher::OnWindowDestroying(aura::Window* window) {
if (observed_windows_.IsObserving(window))
observed_windows_.Remove(window);
}
void ShelfWindowWatcher::OnWindowPropertyChanged(aura::Window* window,
const void* key,
intptr_t old) {
if (key != kShelfItemDetailsKey)
return;
if (GetShelfItemDetailsForWindow(window) == NULL) {
if (reinterpret_cast<ShelfItemDetails*>(old) != NULL)
RemoveShelfItem(window);
return;
}
if (HasShelfItemForWindow(window)) {
int index = GetShelfItemIndexForWindow(window);
DCHECK_GE(index, 0);
ShelfItem item = model_->items()[index];
const ShelfItemDetails* details =
GetShelfItemDetailsForWindow(window);
SetShelfItemDetailsForShelfItem(&item, *details);
model_->Set(index, item);
return;
}
AddShelfItem(window);
}
void ShelfWindowWatcher::OnDisplayBoundsChanged(const gfx::Display& display) {
}
void ShelfWindowWatcher::OnDisplayAdded(const gfx::Display& new_display) {
aura::Window* root_window = Shell::GetInstance()->display_controller()->
GetRootWindowForDisplayId(new_display.id());
if (!observed_root_windows_.IsObserving(root_window))
OnRootWindowAdded(root_window);
}
void ShelfWindowWatcher::OnDisplayRemoved(const gfx::Display& old_display) {
}
}