| Index: ui/wm/core/window_modality_controller.cc
|
| diff --git a/ui/wm/core/window_modality_controller.cc b/ui/wm/core/window_modality_controller.cc
|
| index 094acc49189b86f2d21d4dbade56e7b8b7e1486d..42642e1059ef83c067b7d87cf2b2c7735c7a5334 100644
|
| --- a/ui/wm/core/window_modality_controller.cc
|
| +++ b/ui/wm/core/window_modality_controller.cc
|
| @@ -23,6 +23,8 @@
|
|
|
| namespace wm {
|
|
|
| +const char kAllowTransientParentEventsKey[] = "__ALLOW_PARENT_EVENTS__";
|
| +
|
| // Transient child's modal parent.
|
| extern const aura::WindowProperty<aura::Window*>* const kModalParentKey;
|
| DEFINE_WINDOW_PROPERTY_KEY(aura::Window*, kModalParentKey, NULL);
|
| @@ -61,6 +63,28 @@ bool IsModalTransientChild(aura::Window* transient, aura::Window* original) {
|
| (HasAncestor(original, GetModalParent(transient)))));
|
| }
|
|
|
| +aura::Window* GetNonModalTransientChild(
|
| + aura::Window* activatable,
|
| + aura::Window* original) {
|
| + for (aura::Window::Windows::const_iterator it =
|
| + GetTransientChildren(activatable).begin();
|
| + it != GetTransientChildren(activatable).end();
|
| + ++it) {
|
| + aura::Window* transient = *it;
|
| + if (IsModalTransientChild(transient, original) ||
|
| + transient->GetNativeWindowProperty(
|
| + wm::kAllowTransientParentEventsKey)) {
|
| + if (GetTransientChildren(transient).empty())
|
| + return transient;
|
| +
|
| + aura::Window* modal_child = GetNonModalTransientChild(transient,
|
| + original);
|
| + return modal_child ? modal_child : transient;
|
| + }
|
| + }
|
| + return NULL;
|
| +}
|
| +
|
| aura::Window* GetModalTransientChild(
|
| aura::Window* activatable,
|
| aura::Window* original) {
|
| @@ -86,6 +110,18 @@ void SetModalParent(aura::Window* child, aura::Window* parent) {
|
| child->SetProperty(kModalParentKey, parent);
|
| }
|
|
|
| +aura::Window* GetNonModalTransient(aura::Window* window) {
|
| + if (!window)
|
| + return NULL;
|
| +
|
| + // We always want to check the for the transient child of the toplevel window.
|
| + aura::Window* toplevel = GetToplevelWindow(window);
|
| + if (!toplevel)
|
| + return NULL;
|
| +
|
| + return GetNonModalTransientChild(toplevel, window);
|
| +}
|
| +
|
| aura::Window* GetModalTransient(aura::Window* window) {
|
| if (!window)
|
| return NULL;
|
| @@ -128,7 +164,7 @@ void WindowModalityController::OnKeyEvent(ui::KeyEvent* event) {
|
| void WindowModalityController::OnMouseEvent(ui::MouseEvent* event) {
|
| aura::Window* target = static_cast<aura::Window*>(event->target());
|
| if (ProcessLocatedEvent(target, event))
|
| - event->SetHandled();
|
| + event->SetHandled();
|
| }
|
|
|
| void WindowModalityController::OnTouchEvent(ui::TouchEvent* event) {
|
| @@ -174,7 +210,7 @@ void WindowModalityController::OnWindowVisibilityChanged(
|
| bool should_release_capture = true;
|
| if (window->GetProperty(aura::client::kModalKey) ==
|
| ui::MODAL_TYPE_CHILD &&
|
| - !HasAncestor(capture_window, GetModalParent(window))) {
|
| + !HasAncestor(capture_window, GetModalParent(window))) {
|
| // For child modal windows we only need ensure capture is not on a
|
| // descendant of the modal parent. This way we block events to the
|
| // parents subtree appropriately.
|
| @@ -208,6 +244,29 @@ bool WindowModalityController::ProcessLocatedEvent(aura::Window* target,
|
|
|
| AnimateWindow(modal_transient_child, WINDOW_ANIMATION_TYPE_BOUNCE);
|
| }
|
| + if (!modal_transient_child) {
|
| + aura::Window* transient = GetNonModalTransient(target);
|
| + if (transient &&
|
| + transient->GetNativeWindowProperty(kAllowTransientParentEventsKey) &&
|
| + (event->type() == ui::ET_MOUSE_PRESSED ||
|
| + event->type() == ui::ET_TOUCH_PRESSED) &&
|
| + transient->IsVisible()) {
|
| + bool is_child = false;
|
| + for (aura::Window::Windows::const_iterator it =
|
| + GetTransientChildren(target).begin();
|
| + it != GetTransientChildren(target).end();
|
| + ++it) {
|
| + if (*it == transient)
|
| + is_child = true;
|
| + }
|
| + if (!is_child) {
|
| + aura::Window* toplevel = GetToplevelWindow(target);
|
| + DCHECK(toplevel);
|
| + ActivateWindow(toplevel);
|
| + return true;
|
| + }
|
| + }
|
| + }
|
| if (event->type() == ui::ET_TOUCH_CANCELLED)
|
| return false;
|
| return !!modal_transient_child;
|
|
|