1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file.
4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/views/controls/menu/menu_message_loop_aura.h"
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_WIN)
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <windowsx.h>
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/run_loop.h"
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/aura/client/screen_position_client.h"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/aura/env.h"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/aura/window.h"
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h"
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/aura/window_tree_host.h"
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/events/event.h"
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/events/platform/platform_event_source.h"
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/events/platform/scoped_event_dispatcher.h"
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/views/controls/menu/menu_controller.h"
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/views/widget/widget.h"
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/wm/public/activation_change_observer.h"
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/wm/public/activation_client.h"
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/wm/public/dispatcher_client.h"
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/wm/public/drag_drop_client.h"
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_WIN)
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/base/win/internal_constants.h"
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/views/controls/menu/menu_message_pump_dispatcher_win.h"
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/views/win/hwnd_util.h"
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#else
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/views/controls/menu/menu_event_dispatcher_linux.h"
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)using aura::client::ScreenPositionClient;
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace views {
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace {
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)aura::Window* GetOwnerRootWindow(views::Widget* owner) {
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return owner ? owner->GetNativeWindow()->GetRootWindow() : NULL;
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// ActivationChangeObserverImpl is used to observe activation changes and close
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// the menu. Additionally it listens for the root window to be destroyed and
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// cancel the menu as well.
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class ActivationChangeObserverImpl
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    : public aura::client::ActivationChangeObserver,
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      public aura::WindowObserver,
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      public ui::EventHandler {
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ActivationChangeObserverImpl(MenuController* controller, aura::Window* root)
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      : controller_(controller), root_(root) {
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    aura::client::GetActivationClient(root_)->AddObserver(this);
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    root_->AddObserver(this);
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    root_->AddPreTargetHandler(this);
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual ~ActivationChangeObserverImpl() { Cleanup(); }
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // aura::client::ActivationChangeObserver:
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void OnWindowActivated(aura::Window* gained_active,
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                 aura::Window* lost_active) OVERRIDE {
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!controller_->drag_in_progress())
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      controller_->CancelAll();
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // aura::WindowObserver:
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void OnWindowDestroying(aura::Window* window) OVERRIDE { Cleanup(); }
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // ui::EventHandler:
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void OnCancelMode(ui::CancelModeEvent* event) OVERRIDE {
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    controller_->CancelAll();
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void Cleanup() {
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!root_)
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return;
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // The ActivationClient may have been destroyed by the time we get here.
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    aura::client::ActivationClient* client =
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        aura::client::GetActivationClient(root_);
84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (client)
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      client->RemoveObserver(this);
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    root_->RemovePreTargetHandler(this);
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    root_->RemoveObserver(this);
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    root_ = NULL;
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MenuController* controller_;
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  aura::Window* root_;
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ActivationChangeObserverImpl);
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// static
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)MenuMessageLoop* MenuMessageLoop::Create() {
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return new MenuMessageLoopAura;
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)MenuMessageLoopAura::MenuMessageLoopAura() : owner_(NULL) {
105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)MenuMessageLoopAura::~MenuMessageLoopAura() {
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void MenuMessageLoopAura::RepostEventToWindow(const ui::LocatedEvent& event,
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                              gfx::NativeWindow window,
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                              const gfx::Point& screen_loc) {
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  aura::Window* root = window->GetRootWindow();
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ScreenPositionClient* spc = aura::client::GetScreenPositionClient(root);
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!spc)
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  gfx::Point root_loc(screen_loc);
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  spc->ConvertPointFromScreen(root, &root_loc);
120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ui::MouseEvent clone(static_cast<const ui::MouseEvent&>(event));
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  clone.set_location(root_loc);
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  clone.set_root_location(root_loc);
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  root->GetHost()->dispatcher()->RepostEvent(clone);
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void MenuMessageLoopAura::Run(MenuController* controller,
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              Widget* owner,
129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              bool nested_menu) {
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // |owner_| may be NULL.
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  owner_ = owner;
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  aura::Window* root = GetOwnerRootWindow(owner_);
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // It is possible for the same MenuMessageLoopAura to start a nested
134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // message-loop while it is already running a nested loop. So make sure the
135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // quit-closure gets reset to the outer loop's quit-closure once the innermost
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // loop terminates.
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::AutoReset<base::Closure> reset_quit_closure(&message_loop_quit_,
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                                    base::Closure());
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_WIN)
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  internal::MenuMessagePumpDispatcher nested_dispatcher(controller);
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (root) {
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scoped_ptr<ActivationChangeObserverImpl> observer;
144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!nested_menu)
145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      observer.reset(new ActivationChangeObserverImpl(controller, root));
146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    aura::client::DispatcherRunLoop run_loop(
147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        aura::client::GetDispatcherClient(root), &nested_dispatcher);
148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    message_loop_quit_ = run_loop.QuitClosure();
149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    run_loop.Run();
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else {
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::MessageLoop::ScopedNestableTaskAllower allow(loop);
153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::RunLoop run_loop(&nested_dispatcher);
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    message_loop_quit_ = run_loop.QuitClosure();
155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    run_loop.Run();
156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#else
158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  internal::MenuEventDispatcher event_dispatcher(controller);
159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<ui::ScopedEventDispatcher> old_dispatcher =
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      nested_dispatcher_.Pass();
161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (ui::PlatformEventSource::GetInstance()) {
162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    nested_dispatcher_ =
163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        ui::PlatformEventSource::GetInstance()->OverrideDispatcher(
164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            &event_dispatcher);
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (root) {
167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scoped_ptr<ActivationChangeObserverImpl> observer;
168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!nested_menu)
169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      observer.reset(new ActivationChangeObserverImpl(controller, root));
170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    aura::client::DispatcherRunLoop run_loop(
171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        aura::client::GetDispatcherClient(root), NULL);
172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    message_loop_quit_ = run_loop.QuitClosure();
173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    run_loop.Run();
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else {
175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::MessageLoop::ScopedNestableTaskAllower allow(loop);
177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::RunLoop run_loop;
178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    message_loop_quit_ = run_loop.QuitClosure();
179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    run_loop.Run();
180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  nested_dispatcher_ = old_dispatcher.Pass();
182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif
183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool MenuMessageLoopAura::ShouldQuitNow() const {
186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  aura::Window* root = GetOwnerRootWindow(owner_);
187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return !aura::client::GetDragDropClient(root) ||
188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)         !aura::client::GetDragDropClient(root)->IsDragDropInProgress();
189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void MenuMessageLoopAura::QuitNow() {
192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CHECK(!message_loop_quit_.is_null());
193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  message_loop_quit_.Run();
194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Restore the previous dispatcher.
195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  nested_dispatcher_.reset();
196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void MenuMessageLoopAura::ClearOwner() {
199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  owner_ = NULL;
200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace views
203