| 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::DispatcherRunLoop run_loop( |
| 141 ->RunWithDispatcher(&nested_dispatcher); | 147 aura::client::GetDispatcherClient(root), &nested_dispatcher); |
| 148 message_loop_quit_ = run_loop.QuitClosure(); |
| 149 run_loop.Run(); |
| 142 } else { | 150 } else { |
| 143 base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); | 151 base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); |
| 144 base::MessageLoop::ScopedNestableTaskAllower allow(loop); | 152 base::MessageLoop::ScopedNestableTaskAllower allow(loop); |
| 145 base::RunLoop run_loop(&nested_dispatcher); | 153 base::RunLoop run_loop(&nested_dispatcher); |
| 154 message_loop_quit_ = run_loop.QuitClosure(); |
| 146 run_loop.Run(); | 155 run_loop.Run(); |
| 147 } | 156 } |
| 148 #else | 157 #else |
| 149 internal::MenuEventDispatcher event_dispatcher(controller); | 158 internal::MenuEventDispatcher event_dispatcher(controller); |
| 150 scoped_ptr<ui::ScopedEventDispatcher> old_dispatcher = | 159 scoped_ptr<ui::ScopedEventDispatcher> old_dispatcher = |
| 151 nested_dispatcher_.Pass(); | 160 nested_dispatcher_.Pass(); |
| 152 if (ui::PlatformEventSource::GetInstance()) { | 161 if (ui::PlatformEventSource::GetInstance()) { |
| 153 nested_dispatcher_ = | 162 nested_dispatcher_ = |
| 154 ui::PlatformEventSource::GetInstance()->OverrideDispatcher( | 163 ui::PlatformEventSource::GetInstance()->OverrideDispatcher( |
| 155 &event_dispatcher); | 164 &event_dispatcher); |
| 156 } | 165 } |
| 157 if (root) { | 166 if (root) { |
| 158 scoped_ptr<ActivationChangeObserverImpl> observer; | 167 scoped_ptr<ActivationChangeObserverImpl> observer; |
| 159 if (!nested_menu) | 168 if (!nested_menu) |
| 160 observer.reset(new ActivationChangeObserverImpl(controller, root)); | 169 observer.reset(new ActivationChangeObserverImpl(controller, root)); |
| 161 aura::client::GetDispatcherClient(root)->RunWithDispatcher(NULL); | 170 aura::client::DispatcherRunLoop run_loop( |
| 171 aura::client::GetDispatcherClient(root), NULL); |
| 172 message_loop_quit_ = run_loop.QuitClosure(); |
| 173 run_loop.Run(); |
| 162 } else { | 174 } else { |
| 163 base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); | 175 base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); |
| 164 base::MessageLoop::ScopedNestableTaskAllower allow(loop); | 176 base::MessageLoop::ScopedNestableTaskAllower allow(loop); |
| 165 base::RunLoop run_loop; | 177 base::RunLoop run_loop; |
| 178 message_loop_quit_ = run_loop.QuitClosure(); |
| 166 run_loop.Run(); | 179 run_loop.Run(); |
| 167 } | 180 } |
| 168 nested_dispatcher_ = old_dispatcher.Pass(); | 181 nested_dispatcher_ = old_dispatcher.Pass(); |
| 169 #endif | 182 #endif |
| 170 } | 183 } |
| 171 | 184 |
| 172 bool MenuMessageLoopAura::ShouldQuitNow() const { | 185 bool MenuMessageLoopAura::ShouldQuitNow() const { |
| 173 aura::Window* root = GetOwnerRootWindow(owner_); | 186 aura::Window* root = GetOwnerRootWindow(owner_); |
| 174 return !aura::client::GetDragDropClient(root) || | 187 return !aura::client::GetDragDropClient(root) || |
| 175 !aura::client::GetDragDropClient(root)->IsDragDropInProgress(); | 188 !aura::client::GetDragDropClient(root)->IsDragDropInProgress(); |
| 176 } | 189 } |
| 177 | 190 |
| 178 void MenuMessageLoopAura::QuitNow() { | 191 void MenuMessageLoopAura::QuitNow() { |
| 179 if (owner_) { | 192 CHECK(!message_loop_quit_.is_null()); |
| 180 // It's safe to invoke QuitNestedMessageLoop() multiple times, it only | 193 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. | 194 // Restore the previous dispatcher. |
| 188 nested_dispatcher_.reset(); | 195 nested_dispatcher_.reset(); |
| 189 } | 196 } |
| 190 | 197 |
| 191 void MenuMessageLoopAura::ClearOwner() { | 198 void MenuMessageLoopAura::ClearOwner() { |
| 192 owner_ = NULL; | 199 owner_ = NULL; |
| 193 } | 200 } |
| 194 | 201 |
| 195 } // namespace views | 202 } // namespace views |
| OLD | NEW |