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

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: Modal fix 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
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/ash_switches.h" 10 #include "ash/ash_switches.h"
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 } 255 }
256 } 256 }
257 257
258 private: 258 private:
259 aura::Window* root_window_; 259 aura::Window* root_window_;
260 ShelfLayoutManager* shelf_ = nullptr; 260 ShelfLayoutManager* shelf_ = nullptr;
261 261
262 DISALLOW_COPY_AND_ASSIGN(WorkspaceLayoutManagerDelegateImpl); 262 DISALLOW_COPY_AND_ASSIGN(WorkspaceLayoutManagerDelegateImpl);
263 }; 263 };
264 264
265 bool IsWindowAboveContainer(aura::Window* window,
James Cook 2016/06/16 20:31:35 nit: move up above the class definitions, near the
oshima 2016/06/17 00:06:12 Done.
266 aura::Window* blocking_container) {
267 std::vector<aura::Window*> target_path;
268 std::vector<aura::Window*> blocking_path;
269
270 while (window) {
271 target_path.push_back(window);
272 window = window->parent();
273 }
274
275 while (blocking_container) {
276 blocking_path.push_back(blocking_container);
277 blocking_container = blocking_container->parent();
278 }
279
280 while (!blocking_path.empty()) {
281 if (target_path.empty())
282 return false;
283
284 aura::Window* target = target_path.back();
285 target_path.pop_back();
286 aura::Window* blocking = blocking_path.back();
287 blocking_path.pop_back();
288
289 // Still on the same path, continue.
290 if (target == blocking)
291 continue;
292
293 // This can happen only if unparented window is passed because
294 // first element must be the same root.
295 if (!target->parent() || !blocking->parent())
296 return false;
297
298 aura::Window* common_parent = target->parent();
299 DCHECK_EQ(common_parent, blocking->parent());
James Cook 2016/06/16 20:31:35 I don't understand how this algorithm works. Maybe
oshima 2016/06/17 00:06:12 Comparison start from the root and that's probably
James Cook 2016/06/17 16:04:43 Ah, yes, I missed that the roots were at the end o
300 aura::Window::Windows windows = common_parent->children();
301 auto blocking_iter = std::find(windows.begin(), windows.end(), blocking);
302 // If the target window is above blocking window, the window can handle
303 // events.
304 return std::find(blocking_iter, windows.end(), target) != windows.end();
305 }
306
307 return true;
308 }
309
265 } // namespace 310 } // namespace
266 311
267 void RootWindowController::CreateForPrimaryDisplay(AshWindowTreeHost* host) { 312 void RootWindowController::CreateForPrimaryDisplay(AshWindowTreeHost* host) {
268 RootWindowController* controller = new RootWindowController(host); 313 RootWindowController* controller = new RootWindowController(host);
269 controller->Init(RootWindowController::PRIMARY, 314 controller->Init(RootWindowController::PRIMARY,
270 Shell::GetInstance()->delegate()->IsFirstRunAfterBoot()); 315 Shell::GetInstance()->delegate()->IsFirstRunAfterBoot());
271 } 316 }
272 317
273 void RootWindowController::CreateForSecondaryDisplay(AshWindowTreeHost* host) { 318 void RootWindowController::CreateForSecondaryDisplay(AshWindowTreeHost* host) {
274 RootWindowController* controller = new RootWindowController(host); 319 RootWindowController* controller = new RootWindowController(host);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 // Forget with the display ID so that display lookup 401 // Forget with the display ID so that display lookup
357 // ends up with invalid display. 402 // ends up with invalid display.
358 GetRootWindowSettings(root_window)->display_id = 403 GetRootWindowSettings(root_window)->display_id =
359 display::Display::kInvalidDisplayID; 404 display::Display::kInvalidDisplayID;
360 ash_host_->PrepareForShutdown(); 405 ash_host_->PrepareForShutdown();
361 406
362 system_background_.reset(); 407 system_background_.reset();
363 aura::client::SetScreenPositionClient(root_window, NULL); 408 aura::client::SetScreenPositionClient(root_window, NULL);
364 } 409 }
365 410
411 bool RootWindowController::CanWindowReceiveEvents(aura::Window* window) {
412 if (GetRootWindow() != window->GetRootWindow())
413 return false;
414
415 // Always allow events to fall through to the virtual keyboard even if
416 // displaying a system modal dialog.
417 if (IsVirtualKeyboardWindow(window))
418 return true;
419
420 aura::Window* blocking_container = nullptr;
421
422 int modal_container_id = 0;
423 if (Shell::GetInstance()->session_state_delegate()->IsUserSessionBlocked()) {
424 blocking_container =
425 GetContainer(kShellWindowId_LockScreenContainersContainer);
426 modal_container_id = kShellWindowId_LockSystemModalContainer;
427 } else {
428 modal_container_id = kShellWindowId_SystemModalContainer;
429 }
430 aura::Window* modal_container = GetContainer(modal_container_id);
431 SystemModalContainerLayoutManager* modal_layout_manager = nullptr;
432 if (modal_container) {
James Cook 2016/06/16 20:31:35 Shouldn't we always have a modal_container?
oshima 2016/06/17 00:06:11 yes, you're right. Done.
433 modal_layout_manager = static_cast<SystemModalContainerLayoutManager*>(
434 modal_container->layout_manager());
435 if (modal_layout_manager->has_modal_background())
436 blocking_container = modal_container;
437 else
438 modal_layout_manager = nullptr;
James Cook 2016/06/16 20:31:35 do you need this else clause?
oshima 2016/06/17 00:06:12 Changed to modal_container for line 450. The condi
439 }
440
441 // In normal session.
442 if (blocking_container == nullptr)
443 return true;
444
445 if (!IsWindowAboveContainer(window, blocking_container))
446 return false;
447
448 // If the window is in the target modal container, only allow the top most
449 // one.
450 if (modal_container && modal_container->Contains(window))
451 return modal_layout_manager->IsActiveModalWindows(window);
452
453 return true;
454 }
455
366 SystemModalContainerLayoutManager* 456 SystemModalContainerLayoutManager*
367 RootWindowController::GetSystemModalLayoutManager(aura::Window* window) { 457 RootWindowController::GetSystemModalLayoutManager(aura::Window* window) {
368 aura::Window* modal_container = NULL; 458 aura::Window* modal_container = NULL;
369 if (window) { 459 if (window) {
370 aura::Window* window_container = WmWindowAura::GetAuraWindow( 460 aura::Window* window_container = WmWindowAura::GetAuraWindow(
371 wm::GetContainerForWindow(WmWindowAura::Get(window))); 461 wm::GetContainerForWindow(WmWindowAura::Get(window)));
372 if (window_container && 462 if (window_container &&
373 window_container->id() >= kShellWindowId_LockScreenContainer) { 463 window_container->id() >= kShellWindowId_LockScreenContainer) {
374 modal_container = GetContainer(kShellWindowId_LockSystemModalContainer); 464 modal_container = GetContainer(kShellWindowId_LockSystemModalContainer);
375 } else { 465 } else {
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after
886 aura::Window* primary_root_window = Shell::GetInstance() 976 aura::Window* primary_root_window = Shell::GetInstance()
887 ->window_tree_host_manager() 977 ->window_tree_host_manager()
888 ->GetPrimaryRootWindow(); 978 ->GetPrimaryRootWindow();
889 return GetRootWindowSettings(primary_root_window)->controller; 979 return GetRootWindowSettings(primary_root_window)->controller;
890 } 980 }
891 981
892 return GetRootWindowSettings(root_window)->controller; 982 return GetRootWindowSettings(root_window)->controller;
893 } 983 }
894 984
895 } // namespace ash 985 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698