| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "ui/views/controls/menu/menu_message_loop_aura.h" | |
| 6 | |
| 7 #include "base/macros.h" | |
| 8 #include "base/run_loop.h" | |
| 9 #include "build/build_config.h" | |
| 10 #include "ui/aura/client/drag_drop_client.h" | |
| 11 #include "ui/aura/client/screen_position_client.h" | |
| 12 #include "ui/aura/window.h" | |
| 13 #include "ui/aura/window_event_dispatcher.h" | |
| 14 #include "ui/aura/window_tree_host.h" | |
| 15 #include "ui/events/event.h" | |
| 16 #include "ui/events/platform/platform_event_source.h" | |
| 17 #include "ui/events/platform/scoped_event_dispatcher.h" | |
| 18 #include "ui/views/controls/menu/menu_controller.h" | |
| 19 #include "ui/views/widget/widget.h" | |
| 20 #include "ui/wm/public/activation_change_observer.h" | |
| 21 #include "ui/wm/public/activation_client.h" | |
| 22 | |
| 23 | |
| 24 using aura::client::ScreenPositionClient; | |
| 25 | |
| 26 namespace views { | |
| 27 | |
| 28 // static | |
| 29 MenuMessageLoop* MenuMessageLoop::Create() { | |
| 30 return new MenuMessageLoopAura; | |
| 31 } | |
| 32 | |
| 33 // static | |
| 34 void MenuMessageLoop::RepostEventToWindow(const ui::LocatedEvent* event, | |
| 35 gfx::NativeWindow window, | |
| 36 const gfx::Point& screen_loc) { | |
| 37 aura::Window* root = window->GetRootWindow(); | |
| 38 aura::client::ScreenPositionClient* spc = | |
| 39 aura::client::GetScreenPositionClient(root); | |
| 40 if (!spc) | |
| 41 return; | |
| 42 | |
| 43 gfx::Point root_loc(screen_loc); | |
| 44 spc->ConvertPointFromScreen(root, &root_loc); | |
| 45 | |
| 46 std::unique_ptr<ui::Event> clone = ui::Event::Clone(*event); | |
| 47 std::unique_ptr<ui::LocatedEvent> located_event( | |
| 48 static_cast<ui::LocatedEvent*>(clone.release())); | |
| 49 located_event->set_location(root_loc); | |
| 50 located_event->set_root_location(root_loc); | |
| 51 | |
| 52 root->GetHost()->dispatcher()->RepostEvent(located_event.get()); | |
| 53 } | |
| 54 | |
| 55 MenuMessageLoopAura::MenuMessageLoopAura() {} | |
| 56 | |
| 57 MenuMessageLoopAura::~MenuMessageLoopAura() {} | |
| 58 | |
| 59 void MenuMessageLoopAura::Run() { | |
| 60 // It is possible for the same MenuMessageLoopAura to start a nested | |
| 61 // message-loop while it is already running a nested loop. So make sure the | |
| 62 // quit-closure gets reset to the outer loop's quit-closure once the innermost | |
| 63 // loop terminates. | |
| 64 base::AutoReset<base::Closure> reset_quit_closure(&message_loop_quit_, | |
| 65 base::Closure()); | |
| 66 | |
| 67 base::MessageLoop* loop = base::MessageLoop::current(); | |
| 68 base::MessageLoop::ScopedNestableTaskAllower allow(loop); | |
| 69 base::RunLoop run_loop; | |
| 70 message_loop_quit_ = run_loop.QuitClosure(); | |
| 71 | |
| 72 run_loop.Run(); | |
| 73 } | |
| 74 | |
| 75 void MenuMessageLoopAura::QuitNow() { | |
| 76 CHECK(!message_loop_quit_.is_null()); | |
| 77 message_loop_quit_.Run(); | |
| 78 | |
| 79 #if !defined(OS_WIN) | |
| 80 // Ask PlatformEventSource to stop dispatching events in this message loop | |
| 81 // iteration. We want our menu's loop to return before the next event. | |
| 82 if (ui::PlatformEventSource::GetInstance()) | |
| 83 ui::PlatformEventSource::GetInstance()->StopCurrentEventStream(); | |
| 84 #endif | |
| 85 } | |
| 86 | |
| 87 } // namespace views | |
| OLD | NEW |