This source file includes following definitions.
- GetAllTransientAncestors
- FindCommonTransientAncestor
- SkipNullDelegates
- AdjustStacking
#include "ui/wm/core/transient_window_stacking_client.h"
#include <algorithm>
#include "ui/wm/core/transient_window_manager.h"
#include "ui/wm/core/window_util.h"
using aura::Window;
namespace wm {
namespace {
bool GetAllTransientAncestors(Window* window, Window::Windows* ancestors) {
Window* parent = window->parent();
for (; window; window = GetTransientParent(window)) {
if (window->parent() == parent)
ancestors->push_back(window);
}
return (!ancestors->empty());
}
void FindCommonTransientAncestor(Window** window1, Window** window2) {
DCHECK(window1);
DCHECK(window2);
DCHECK(*window1);
DCHECK(*window2);
Window::Windows ancestors1;
Window::Windows ancestors2;
if (!GetAllTransientAncestors(*window1, &ancestors1) ||
!GetAllTransientAncestors(*window2, &ancestors2)) {
return;
}
Window::Windows::reverse_iterator it1 = ancestors1.rbegin();
Window::Windows::reverse_iterator it2 = ancestors2.rbegin();
for (; it1 != ancestors1.rend() && it2 != ancestors2.rend(); ++it1, ++it2) {
if (*it1 != *it2) {
*window1 = *it1;
*window2 = *it2;
break;
}
}
}
void SkipNullDelegates(Window::StackDirection direction, Window** target) {
const Window::Windows& children((*target)->parent()->children());
size_t target_i =
std::find(children.begin(), children.end(), *target) -
children.begin();
while (target_i > 0) {
const size_t index = direction == Window::STACK_ABOVE ?
target_i : target_i - 1;
if (!children[index]->layer() ||
children[index]->layer()->delegate() != NULL)
break;
--target_i;
}
*target = children[target_i];
}
}
TransientWindowStackingClient* TransientWindowStackingClient::instance_ = NULL;
TransientWindowStackingClient::TransientWindowStackingClient() {
instance_ = this;
}
TransientWindowStackingClient::~TransientWindowStackingClient() {
if (instance_ == this)
instance_ = NULL;
}
bool TransientWindowStackingClient::AdjustStacking(
Window** child,
Window** target,
Window::StackDirection* direction) {
const TransientWindowManager* transient_manager =
TransientWindowManager::Get((*child)->parent());
if (transient_manager &&
transient_manager->IsStackingTransient(*child, *target))
return true;
FindCommonTransientAncestor(child, target);
if (*direction == Window::STACK_ABOVE &&
!HasTransientAncestor(*child, *target)) {
const Window::Windows& siblings((*child)->parent()->children());
size_t target_i =
std::find(siblings.begin(), siblings.end(), *target) - siblings.begin();
while (target_i + 1 < siblings.size() &&
HasTransientAncestor(siblings[target_i + 1], *target)) {
++target_i;
}
*target = siblings[target_i];
}
SkipNullDelegates(*direction, target);
if (*direction == Window::STACK_ABOVE &&
((*target)->layer() && (*target)->layer()->delegate() == NULL)) {
return false;
}
return *child != *target;
}
}