From 8bc4d57eb2d933c180106943e58ca7d1ea83081c Mon Sep 17 00:00:00 2001 From: calamity Date: Wed, 10 Jun 2015 21:48:04 -0700 Subject: [PATCH] Fix WindowModalityController's GetModalTransientChild[Ash] This CL fixes an issue where menus would break dialog modality, allowing a non-modal view to get focus, causing input to be blocked for the whole system. This would arise when comboboxes were used in modal dialogs. This has been fixed by making the modal transient child check return the lowest modal transient in the window tree rather than null when the leaf nodes of the tree weren't modal. BUG=456697 Review URL: https://codereview.chromium.org/1161233004 Cr-Commit-Position: refs/heads/master@{#333893} --- ash/wm/window_modality_controller_unittest.cc | 6 ++++++ ui/wm/core/window_modality_controller.cc | 7 +++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ash/wm/window_modality_controller_unittest.cc b/ash/wm/window_modality_controller_unittest.cc index 765d12d7e69a..977e70ce6b60 100644 --- a/ash/wm/window_modality_controller_unittest.cc +++ b/ash/wm/window_modality_controller_unittest.cc @@ -184,9 +184,15 @@ TEST_F(WindowModalityControllerTest, Events) { gfx::Rect(0, 0, 100, 100))); scoped_ptr w11(CreateTestWindowInShellWithDelegate(&d, -11, gfx::Rect(20, 20, 50, 50))); + scoped_ptr w111( + CreateTestWindowInShellWithDelegate(&d, -111, gfx::Rect(20, 20, 50, 50))); ::wm::AddTransientChild(w1.get(), w11.get()); + // Add a non-modal child to the modal window in order to ensure modality still + // works in this case. This is a regression test for https://crbug.com/456697. + ::wm::AddTransientChild(w11.get(), w111.get()); + { // Clicking a point within w1 should activate that window. ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), diff --git a/ui/wm/core/window_modality_controller.cc b/ui/wm/core/window_modality_controller.cc index b18fe9c7621b..8b7d66a4fecb 100644 --- a/ui/wm/core/window_modality_controller.cc +++ b/ui/wm/core/window_modality_controller.cc @@ -68,8 +68,11 @@ aura::Window* GetModalTransientChild( ++it) { aura::Window* transient = *it; if (IsModalTransientChild(transient, original)) { - return GetTransientChildren(transient).empty() ? - transient : GetModalTransientChild(transient, original); + if (GetTransientChildren(transient).empty()) + return transient; + + aura::Window* modal_child = GetModalTransientChild(transient, original); + return modal_child ? modal_child : transient; } } return NULL; -- 2.11.4.GIT