| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/views/controls/menu/menu_message_loop_aura.h" | 5 #include "ui/views/controls/menu/menu_message_loop_aura.h" |
| 6 | 6 |
| 7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
| 8 #include <windowsx.h> | 8 #include <windowsx.h> |
| 9 #endif | 9 #endif |
| 10 | 10 |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 clone.set_root_location(root_loc); | 123 clone.set_root_location(root_loc); |
| 124 root->GetHost()->dispatcher()->RepostEvent(clone); | 124 root->GetHost()->dispatcher()->RepostEvent(clone); |
| 125 } | 125 } |
| 126 | 126 |
| 127 void MenuMessageLoopAura::Run(MenuController* controller, | 127 void MenuMessageLoopAura::Run(MenuController* controller, |
| 128 Widget* owner, | 128 Widget* owner, |
| 129 bool nested_menu) { | 129 bool nested_menu) { |
| 130 // |owner_| may be NULL. | 130 // |owner_| may be NULL. |
| 131 owner_ = owner; | 131 owner_ = owner; |
| 132 aura::Window* root = GetOwnerRootWindow(owner_); | 132 aura::Window* root = GetOwnerRootWindow(owner_); |
| 133 // It is possible for the same MenuMessageLoopAura to start a nested |
| 134 // message-loop while it is already running a nested loop. So make sure the |
| 135 // quit-closure gets reset to the outer loop's quit-closure once the innermost |
| 136 // loop terminates. |
| 137 base::AutoReset<base::Closure> reset_quit_closure(&message_loop_quit_, |
| 138 base::Closure()); |
| 133 | 139 |
| 134 #if defined(OS_WIN) | 140 #if defined(OS_WIN) |
| 135 internal::MenuMessagePumpDispatcher nested_dispatcher(controller); | 141 internal::MenuMessagePumpDispatcher nested_dispatcher(controller); |
| 136 if (root) { | 142 if (root) { |
| 137 scoped_ptr<ActivationChangeObserverImpl> observer; | 143 scoped_ptr<ActivationChangeObserverImpl> observer; |
| 138 if (!nested_menu) | 144 if (!nested_menu) |
| 139 observer.reset(new ActivationChangeObserverImpl(controller, root)); | 145 observer.reset(new ActivationChangeObserverImpl(controller, root)); |
| 140 aura::client::GetDispatcherClient(root) | 146 aura::client::GetDispatcherClient(root) |
| 141 ->RunWithDispatcher(&nested_dispatcher); | 147 ->RunWithDispatcher(&nested_dispatcher, &message_loop_quit_); |
| 142 } else { | 148 } else { |
| 143 base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); | 149 base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); |
| 144 base::MessageLoop::ScopedNestableTaskAllower allow(loop); | 150 base::MessageLoop::ScopedNestableTaskAllower allow(loop); |
| 145 base::RunLoop run_loop(&nested_dispatcher); | 151 base::RunLoop run_loop(&nested_dispatcher); |
| 152 message_loop_quit_ = run_loop.QuitClosure(); |
| 146 run_loop.Run(); | 153 run_loop.Run(); |
| 147 } | 154 } |
| 148 #else | 155 #else |
| 149 internal::MenuEventDispatcher event_dispatcher(controller); | 156 internal::MenuEventDispatcher event_dispatcher(controller); |
| 150 scoped_ptr<ui::ScopedEventDispatcher> old_dispatcher = | 157 scoped_ptr<ui::ScopedEventDispatcher> old_dispatcher = |
| 151 nested_dispatcher_.Pass(); | 158 nested_dispatcher_.Pass(); |
| 152 if (ui::PlatformEventSource::GetInstance()) { | 159 if (ui::PlatformEventSource::GetInstance()) { |
| 153 nested_dispatcher_ = | 160 nested_dispatcher_ = |
| 154 ui::PlatformEventSource::GetInstance()->OverrideDispatcher( | 161 ui::PlatformEventSource::GetInstance()->OverrideDispatcher( |
| 155 &event_dispatcher); | 162 &event_dispatcher); |
| 156 } | 163 } |
| 157 if (root) { | 164 if (root) { |
| 158 scoped_ptr<ActivationChangeObserverImpl> observer; | 165 scoped_ptr<ActivationChangeObserverImpl> observer; |
| 159 if (!nested_menu) | 166 if (!nested_menu) |
| 160 observer.reset(new ActivationChangeObserverImpl(controller, root)); | 167 observer.reset(new ActivationChangeObserverImpl(controller, root)); |
| 161 aura::client::GetDispatcherClient(root)->RunWithDispatcher(NULL); | 168 aura::client::GetDispatcherClient(root)->RunWithDispatcher( |
| 169 NULL, &message_loop_quit_); |
| 162 } else { | 170 } else { |
| 163 base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); | 171 base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); |
| 164 base::MessageLoop::ScopedNestableTaskAllower allow(loop); | 172 base::MessageLoop::ScopedNestableTaskAllower allow(loop); |
| 165 base::RunLoop run_loop; | 173 base::RunLoop run_loop; |
| 174 message_loop_quit_ = run_loop.QuitClosure(); |
| 166 run_loop.Run(); | 175 run_loop.Run(); |
| 167 } | 176 } |
| 168 nested_dispatcher_ = old_dispatcher.Pass(); | 177 nested_dispatcher_ = old_dispatcher.Pass(); |
| 169 #endif | 178 #endif |
| 170 } | 179 } |
| 171 | 180 |
| 172 bool MenuMessageLoopAura::ShouldQuitNow() const { | 181 bool MenuMessageLoopAura::ShouldQuitNow() const { |
| 173 aura::Window* root = GetOwnerRootWindow(owner_); | 182 aura::Window* root = GetOwnerRootWindow(owner_); |
| 174 return !aura::client::GetDragDropClient(root) || | 183 return !aura::client::GetDragDropClient(root) || |
| 175 !aura::client::GetDragDropClient(root)->IsDragDropInProgress(); | 184 !aura::client::GetDragDropClient(root)->IsDragDropInProgress(); |
| 176 } | 185 } |
| 177 | 186 |
| 178 void MenuMessageLoopAura::QuitNow() { | 187 void MenuMessageLoopAura::QuitNow() { |
| 179 if (owner_) { | 188 CHECK(!message_loop_quit_.is_null()); |
| 180 // It's safe to invoke QuitNestedMessageLoop() multiple times, it only | 189 message_loop_quit_.Run(); |
| 181 // effects the current loop. | |
| 182 aura::Window* root = owner_->GetNativeWindow()->GetRootWindow(); | |
| 183 aura::client::GetDispatcherClient(root)->QuitNestedMessageLoop(); | |
| 184 } else { | |
| 185 base::MessageLoop::current()->QuitNow(); | |
| 186 } | |
| 187 // Restore the previous dispatcher. | 190 // Restore the previous dispatcher. |
| 188 nested_dispatcher_.reset(); | 191 nested_dispatcher_.reset(); |
| 189 } | 192 } |
| 190 | 193 |
| 191 void MenuMessageLoopAura::ClearOwner() { | 194 void MenuMessageLoopAura::ClearOwner() { |
| 192 owner_ = NULL; | 195 owner_ = NULL; |
| 193 } | 196 } |
| 194 | 197 |
| 195 } // namespace views | 198 } // namespace views |
| OLD | NEW |