| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/wm/core/window_modality_controller.h" | 5 #include "ui/wm/core/window_modality_controller.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 | 10 |
| 11 #include "ui/aura/client/aura_constants.h" | 11 #include "ui/aura/client/aura_constants.h" |
| 12 #include "ui/aura/client/capture_client.h" | 12 #include "ui/aura/client/capture_client.h" |
| 13 #include "ui/aura/env.h" | 13 #include "ui/aura/env.h" |
| 14 #include "ui/aura/window.h" | 14 #include "ui/aura/window.h" |
| 15 #include "ui/aura/window_event_dispatcher.h" | 15 #include "ui/aura/window_event_dispatcher.h" |
| 16 #include "ui/aura/window_property.h" | 16 #include "ui/aura/window_property.h" |
| 17 #include "ui/base/ui_base_types.h" | 17 #include "ui/base/ui_base_types.h" |
| 18 #include "ui/events/event.h" | 18 #include "ui/events/event.h" |
| 19 #include "ui/events/event_target.h" | 19 #include "ui/events/event_target.h" |
| 20 #include "ui/events/gestures/gesture_recognizer.h" | 20 #include "ui/events/gestures/gesture_recognizer.h" |
| 21 #include "ui/wm/core/window_animations.h" | 21 #include "ui/wm/core/window_animations.h" |
| 22 #include "ui/wm/core/window_util.h" | 22 #include "ui/wm/core/window_util.h" |
| 23 | 23 |
| 24 namespace wm { | 24 namespace wm { |
| 25 | 25 |
| 26 const char kAllowTransientParentEventsKey[] = "__ALLOW_PARENT_EVENTS__"; |
| 27 |
| 26 // Transient child's modal parent. | 28 // Transient child's modal parent. |
| 27 extern const aura::WindowProperty<aura::Window*>* const kModalParentKey; | 29 extern const aura::WindowProperty<aura::Window*>* const kModalParentKey; |
| 28 DEFINE_WINDOW_PROPERTY_KEY(aura::Window*, kModalParentKey, NULL); | 30 DEFINE_WINDOW_PROPERTY_KEY(aura::Window*, kModalParentKey, NULL); |
| 29 | 31 |
| 30 namespace { | 32 namespace { |
| 31 | 33 |
| 32 bool HasAncestor(aura::Window* window, aura::Window* ancestor) { | 34 bool HasAncestor(aura::Window* window, aura::Window* ancestor) { |
| 33 if (!window) | 35 if (!window) |
| 34 return false; | 36 return false; |
| 35 if (window == ancestor) | 37 if (window == ancestor) |
| (...skipping 18 matching lines...) Expand all Loading... |
| 54 } | 56 } |
| 55 | 57 |
| 56 bool IsModalTransientChild(aura::Window* transient, aura::Window* original) { | 58 bool IsModalTransientChild(aura::Window* transient, aura::Window* original) { |
| 57 return transient->IsVisible() && | 59 return transient->IsVisible() && |
| 58 (TransientChildIsWindowModal(transient) || | 60 (TransientChildIsWindowModal(transient) || |
| 59 TransientChildIsSystemModal(transient) || | 61 TransientChildIsSystemModal(transient) || |
| 60 (TransientChildIsChildModal(transient) && | 62 (TransientChildIsChildModal(transient) && |
| 61 (HasAncestor(original, GetModalParent(transient))))); | 63 (HasAncestor(original, GetModalParent(transient))))); |
| 62 } | 64 } |
| 63 | 65 |
| 66 aura::Window* GetNonModalTransientChild( |
| 67 aura::Window* activatable, |
| 68 aura::Window* original) { |
| 69 for (aura::Window::Windows::const_iterator it = |
| 70 GetTransientChildren(activatable).begin(); |
| 71 it != GetTransientChildren(activatable).end(); |
| 72 ++it) { |
| 73 aura::Window* transient = *it; |
| 74 if (IsModalTransientChild(transient, original) || |
| 75 transient->GetNativeWindowProperty( |
| 76 wm::kAllowTransientParentEventsKey)) { |
| 77 if (GetTransientChildren(transient).empty()) |
| 78 return transient; |
| 79 |
| 80 aura::Window* modal_child = GetNonModalTransientChild(transient, |
| 81 original); |
| 82 return modal_child ? modal_child : transient; |
| 83 } |
| 84 } |
| 85 return NULL; |
| 86 } |
| 87 |
| 64 aura::Window* GetModalTransientChild( | 88 aura::Window* GetModalTransientChild( |
| 65 aura::Window* activatable, | 89 aura::Window* activatable, |
| 66 aura::Window* original) { | 90 aura::Window* original) { |
| 67 for (aura::Window::Windows::const_iterator it = | 91 for (aura::Window::Windows::const_iterator it = |
| 68 GetTransientChildren(activatable).begin(); | 92 GetTransientChildren(activatable).begin(); |
| 69 it != GetTransientChildren(activatable).end(); | 93 it != GetTransientChildren(activatable).end(); |
| 70 ++it) { | 94 ++it) { |
| 71 aura::Window* transient = *it; | 95 aura::Window* transient = *it; |
| 72 if (IsModalTransientChild(transient, original)) { | 96 if (IsModalTransientChild(transient, original)) { |
| 73 if (GetTransientChildren(transient).empty()) | 97 if (GetTransientChildren(transient).empty()) |
| 74 return transient; | 98 return transient; |
| 75 | 99 |
| 76 aura::Window* modal_child = GetModalTransientChild(transient, original); | 100 aura::Window* modal_child = GetModalTransientChild(transient, original); |
| 77 return modal_child ? modal_child : transient; | 101 return modal_child ? modal_child : transient; |
| 78 } | 102 } |
| 79 } | 103 } |
| 80 return NULL; | 104 return NULL; |
| 81 } | 105 } |
| 82 | 106 |
| 83 } // namespace | 107 } // namespace |
| 84 | 108 |
| 85 void SetModalParent(aura::Window* child, aura::Window* parent) { | 109 void SetModalParent(aura::Window* child, aura::Window* parent) { |
| 86 child->SetProperty(kModalParentKey, parent); | 110 child->SetProperty(kModalParentKey, parent); |
| 87 } | 111 } |
| 88 | 112 |
| 113 aura::Window* GetNonModalTransient(aura::Window* window) { |
| 114 if (!window) |
| 115 return NULL; |
| 116 |
| 117 // We always want to check the for the transient child of the toplevel window. |
| 118 aura::Window* toplevel = GetToplevelWindow(window); |
| 119 if (!toplevel) |
| 120 return NULL; |
| 121 |
| 122 return GetNonModalTransientChild(toplevel, window); |
| 123 } |
| 124 |
| 89 aura::Window* GetModalTransient(aura::Window* window) { | 125 aura::Window* GetModalTransient(aura::Window* window) { |
| 90 if (!window) | 126 if (!window) |
| 91 return NULL; | 127 return NULL; |
| 92 | 128 |
| 93 // We always want to check the for the transient child of the toplevel window. | 129 // We always want to check the for the transient child of the toplevel window. |
| 94 aura::Window* toplevel = GetToplevelWindow(window); | 130 aura::Window* toplevel = GetToplevelWindow(window); |
| 95 if (!toplevel) | 131 if (!toplevel) |
| 96 return NULL; | 132 return NULL; |
| 97 | 133 |
| 98 return GetModalTransientChild(toplevel, window); | 134 return GetModalTransientChild(toplevel, window); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 121 | 157 |
| 122 void WindowModalityController::OnKeyEvent(ui::KeyEvent* event) { | 158 void WindowModalityController::OnKeyEvent(ui::KeyEvent* event) { |
| 123 aura::Window* target = static_cast<aura::Window*>(event->target()); | 159 aura::Window* target = static_cast<aura::Window*>(event->target()); |
| 124 if (GetModalTransient(target)) | 160 if (GetModalTransient(target)) |
| 125 event->SetHandled(); | 161 event->SetHandled(); |
| 126 } | 162 } |
| 127 | 163 |
| 128 void WindowModalityController::OnMouseEvent(ui::MouseEvent* event) { | 164 void WindowModalityController::OnMouseEvent(ui::MouseEvent* event) { |
| 129 aura::Window* target = static_cast<aura::Window*>(event->target()); | 165 aura::Window* target = static_cast<aura::Window*>(event->target()); |
| 130 if (ProcessLocatedEvent(target, event)) | 166 if (ProcessLocatedEvent(target, event)) |
| 131 event->SetHandled(); | 167 event->SetHandled(); |
| 132 } | 168 } |
| 133 | 169 |
| 134 void WindowModalityController::OnTouchEvent(ui::TouchEvent* event) { | 170 void WindowModalityController::OnTouchEvent(ui::TouchEvent* event) { |
| 135 aura::Window* target = static_cast<aura::Window*>(event->target()); | 171 aura::Window* target = static_cast<aura::Window*>(event->target()); |
| 136 if (ProcessLocatedEvent(target, event)) | 172 if (ProcessLocatedEvent(target, event)) |
| 137 event->SetHandled(); | 173 event->SetHandled(); |
| 138 } | 174 } |
| 139 | 175 |
| 140 //////////////////////////////////////////////////////////////////////////////// | 176 //////////////////////////////////////////////////////////////////////////////// |
| 141 // WindowModalityController, aura::EnvObserver implementation: | 177 // WindowModalityController, aura::EnvObserver implementation: |
| (...skipping 25 matching lines...) Expand all Loading... |
| 167 if (visible && | 203 if (visible && |
| 168 window->GetProperty(aura::client::kModalKey) != ui::MODAL_TYPE_NONE) { | 204 window->GetProperty(aura::client::kModalKey) != ui::MODAL_TYPE_NONE) { |
| 169 ui::GestureRecognizer::Get()->CancelActiveTouchesExcept(nullptr); | 205 ui::GestureRecognizer::Get()->CancelActiveTouchesExcept(nullptr); |
| 170 // Make sure no other window has capture, otherwise |window| won't get mouse | 206 // Make sure no other window has capture, otherwise |window| won't get mouse |
| 171 // events. | 207 // events. |
| 172 aura::Window* capture_window = aura::client::GetCaptureWindow(window); | 208 aura::Window* capture_window = aura::client::GetCaptureWindow(window); |
| 173 if (capture_window) { | 209 if (capture_window) { |
| 174 bool should_release_capture = true; | 210 bool should_release_capture = true; |
| 175 if (window->GetProperty(aura::client::kModalKey) == | 211 if (window->GetProperty(aura::client::kModalKey) == |
| 176 ui::MODAL_TYPE_CHILD && | 212 ui::MODAL_TYPE_CHILD && |
| 177 !HasAncestor(capture_window, GetModalParent(window))) { | 213 !HasAncestor(capture_window, GetModalParent(window))) { |
| 178 // For child modal windows we only need ensure capture is not on a | 214 // For child modal windows we only need ensure capture is not on a |
| 179 // descendant of the modal parent. This way we block events to the | 215 // descendant of the modal parent. This way we block events to the |
| 180 // parents subtree appropriately. | 216 // parents subtree appropriately. |
| 181 should_release_capture = false; | 217 should_release_capture = false; |
| 182 } | 218 } |
| 183 | 219 |
| 184 if (should_release_capture) | 220 if (should_release_capture) |
| 185 capture_window->ReleaseCapture(); | 221 capture_window->ReleaseCapture(); |
| 186 } | 222 } |
| 187 } | 223 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 201 event->type() == ui::ET_TOUCH_PRESSED)) { | 237 event->type() == ui::ET_TOUCH_PRESSED)) { |
| 202 // Activate top window if transient child window is window modal. | 238 // Activate top window if transient child window is window modal. |
| 203 if (TransientChildIsWindowModal(modal_transient_child)) { | 239 if (TransientChildIsWindowModal(modal_transient_child)) { |
| 204 aura::Window* toplevel = GetToplevelWindow(target); | 240 aura::Window* toplevel = GetToplevelWindow(target); |
| 205 DCHECK(toplevel); | 241 DCHECK(toplevel); |
| 206 ActivateWindow(toplevel); | 242 ActivateWindow(toplevel); |
| 207 } | 243 } |
| 208 | 244 |
| 209 AnimateWindow(modal_transient_child, WINDOW_ANIMATION_TYPE_BOUNCE); | 245 AnimateWindow(modal_transient_child, WINDOW_ANIMATION_TYPE_BOUNCE); |
| 210 } | 246 } |
| 247 if (!modal_transient_child) { |
| 248 aura::Window* transient = GetNonModalTransient(target); |
| 249 if (transient && |
| 250 transient->GetNativeWindowProperty(kAllowTransientParentEventsKey) && |
| 251 (event->type() == ui::ET_MOUSE_PRESSED || |
| 252 event->type() == ui::ET_TOUCH_PRESSED) && |
| 253 transient->IsVisible()) { |
| 254 bool is_child = false; |
| 255 for (aura::Window::Windows::const_iterator it = |
| 256 GetTransientChildren(target).begin(); |
| 257 it != GetTransientChildren(target).end(); |
| 258 ++it) { |
| 259 if (*it == transient) |
| 260 is_child = true; |
| 261 } |
| 262 if (!is_child) { |
| 263 aura::Window* toplevel = GetToplevelWindow(target); |
| 264 DCHECK(toplevel); |
| 265 ActivateWindow(toplevel); |
| 266 return true; |
| 267 } |
| 268 } |
| 269 } |
| 211 if (event->type() == ui::ET_TOUCH_CANCELLED) | 270 if (event->type() == ui::ET_TOUCH_CANCELLED) |
| 212 return false; | 271 return false; |
| 213 return !!modal_transient_child; | 272 return !!modal_transient_child; |
| 214 } | 273 } |
| 215 | 274 |
| 216 } // namespace wm | 275 } // namespace wm |
| OLD | NEW |