Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(340)

Side by Side Diff: ash/root_window_controller.cc

Issue 2070163002: Fix "modal isn't modal in multi displays" issue (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ash/root_window_controller.h ('k') | ash/shell.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "ash/root_window_controller.h" 5 #include "ash/root_window_controller.h"
6 6
7 #include <queue> 7 #include <queue>
8 #include <vector> 8 #include <vector>
9 9
10 #include "ash/aura/aura_layout_manager_adapter.h" 10 #include "ash/aura/aura_layout_manager_adapter.h"
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 ++iter; 190 ++iter;
191 } 191 }
192 // If the entire window list is modal background windows then stop. 192 // If the entire window list is modal background windows then stop.
193 if (iter == src_container->children().end()) 193 if (iter == src_container->children().end())
194 break; 194 break;
195 ReparentWindow(*iter, dst_container); 195 ReparentWindow(*iter, dst_container);
196 } 196 }
197 } 197 }
198 } 198 }
199 199
200 bool IsWindowAboveContainer(aura::Window* window,
201 aura::Window* blocking_container) {
202 std::vector<aura::Window*> target_path;
203 std::vector<aura::Window*> blocking_path;
204
205 while (window) {
206 target_path.push_back(window);
207 window = window->parent();
208 }
209
210 while (blocking_container) {
211 blocking_path.push_back(blocking_container);
212 blocking_container = blocking_container->parent();
213 }
214
215 // The root window is put at the end so that we compare windows at
216 // the same depth.
217 while (!blocking_path.empty()) {
218 if (target_path.empty())
219 return false;
220
221 aura::Window* target = target_path.back();
222 target_path.pop_back();
223 aura::Window* blocking = blocking_path.back();
224 blocking_path.pop_back();
225
226 // Still on the same path, continue.
227 if (target == blocking)
228 continue;
229
230 // This can happen only if unparented window is passed because
231 // first element must be the same root.
232 if (!target->parent() || !blocking->parent())
233 return false;
234
235 aura::Window* common_parent = target->parent();
236 DCHECK_EQ(common_parent, blocking->parent());
237 aura::Window::Windows windows = common_parent->children();
238 auto blocking_iter = std::find(windows.begin(), windows.end(), blocking);
239 // If the target window is above blocking window, the window can handle
240 // events.
241 return std::find(blocking_iter, windows.end(), target) != windows.end();
242 }
243
244 return true;
245 }
246
200 // A window delegate which does nothing. Used to create a window that 247 // A window delegate which does nothing. Used to create a window that
201 // is a event target, but do nothing. 248 // is a event target, but do nothing.
202 class EmptyWindowDelegate : public aura::WindowDelegate { 249 class EmptyWindowDelegate : public aura::WindowDelegate {
203 public: 250 public:
204 EmptyWindowDelegate() {} 251 EmptyWindowDelegate() {}
205 ~EmptyWindowDelegate() override {} 252 ~EmptyWindowDelegate() override {}
206 253
207 // aura::WindowDelegate overrides: 254 // aura::WindowDelegate overrides:
208 gfx::Size GetMinimumSize() const override { return gfx::Size(); } 255 gfx::Size GetMinimumSize() const override { return gfx::Size(); }
209 gfx::Size GetMaximumSize() const override { return gfx::Size(); } 256 gfx::Size GetMaximumSize() const override { return gfx::Size(); }
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 // Forget with the display ID so that display lookup 403 // Forget with the display ID so that display lookup
357 // ends up with invalid display. 404 // ends up with invalid display.
358 GetRootWindowSettings(root_window)->display_id = 405 GetRootWindowSettings(root_window)->display_id =
359 display::Display::kInvalidDisplayID; 406 display::Display::kInvalidDisplayID;
360 ash_host_->PrepareForShutdown(); 407 ash_host_->PrepareForShutdown();
361 408
362 system_background_.reset(); 409 system_background_.reset();
363 aura::client::SetScreenPositionClient(root_window, NULL); 410 aura::client::SetScreenPositionClient(root_window, NULL);
364 } 411 }
365 412
413 bool RootWindowController::CanWindowReceiveEvents(aura::Window* window) {
414 if (GetRootWindow() != window->GetRootWindow())
415 return false;
416
417 // Always allow events to fall through to the virtual keyboard even if
418 // displaying a system modal dialog.
419 if (IsVirtualKeyboardWindow(window))
420 return true;
421
422 aura::Window* blocking_container = nullptr;
423
424 int modal_container_id = 0;
425 if (Shell::GetInstance()->session_state_delegate()->IsUserSessionBlocked()) {
426 blocking_container =
427 GetContainer(kShellWindowId_LockScreenContainersContainer);
428 modal_container_id = kShellWindowId_LockSystemModalContainer;
429 } else {
430 modal_container_id = kShellWindowId_SystemModalContainer;
431 }
432 aura::Window* modal_container = GetContainer(modal_container_id);
433 SystemModalContainerLayoutManager* modal_layout_manager = nullptr;
434 modal_layout_manager = static_cast<SystemModalContainerLayoutManager*>(
435 modal_container->layout_manager());
436
437 if (modal_layout_manager->has_modal_background())
438 blocking_container = modal_container;
439 else
440 modal_container = nullptr; // Don't check modal dialogs.
441
442 // In normal session.
443 if (!blocking_container)
444 return true;
445
446 if (!IsWindowAboveContainer(window, blocking_container))
447 return false;
448
449 // If the window is in the target modal container, only allow the top most
450 // one.
451 if (modal_container && modal_container->Contains(window))
452 return modal_layout_manager->IsPartOfActiveModalWindow(window);
453
454 return true;
455 }
456
366 SystemModalContainerLayoutManager* 457 SystemModalContainerLayoutManager*
367 RootWindowController::GetSystemModalLayoutManager(aura::Window* window) { 458 RootWindowController::GetSystemModalLayoutManager(aura::Window* window) {
368 aura::Window* modal_container = NULL; 459 aura::Window* modal_container = NULL;
369 if (window) { 460 if (window) {
370 aura::Window* window_container = WmWindowAura::GetAuraWindow( 461 aura::Window* window_container = WmWindowAura::GetAuraWindow(
371 wm::GetContainerForWindow(WmWindowAura::Get(window))); 462 wm::GetContainerForWindow(WmWindowAura::Get(window)));
372 if (window_container && 463 if (window_container &&
373 window_container->id() >= kShellWindowId_LockScreenContainer) { 464 window_container->id() >= kShellWindowId_LockScreenContainer) {
374 modal_container = GetContainer(kShellWindowId_LockSystemModalContainer); 465 modal_container = GetContainer(kShellWindowId_LockSystemModalContainer);
375 } else { 466 } else {
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after
886 aura::Window* primary_root_window = Shell::GetInstance() 977 aura::Window* primary_root_window = Shell::GetInstance()
887 ->window_tree_host_manager() 978 ->window_tree_host_manager()
888 ->GetPrimaryRootWindow(); 979 ->GetPrimaryRootWindow();
889 return GetRootWindowSettings(primary_root_window)->controller; 980 return GetRootWindowSettings(primary_root_window)->controller;
890 } 981 }
891 982
892 return GetRootWindowSettings(root_window)->controller; 983 return GetRootWindowSettings(root_window)->controller;
893 } 984 }
894 985
895 } // namespace ash 986 } // namespace ash
OLDNEW
« no previous file with comments | « ash/root_window_controller.h ('k') | ash/shell.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698