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 |