172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Use of this source code is governed by a BSD-style license that can be 3bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// found in the LICENSE file. 4bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 5bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/automation/testing_automation_provider.h" 6bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 7bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/automation/automation_browser_tracker.h" 8bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/automation/automation_window_tracker.h" 9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_window.h" 1072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/frame/browser_view.h" 1172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/toolbar_view.h" 124a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/common/automation_messages.h" 1372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/point.h" 14bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "views/controls/menu/menu_wrapper.h" 15bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "views/view.h" 16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "views/widget/native_widget.h" 17bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "views/widget/root_view.h" 18bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "views/widget/widget.h" 19bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 20bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsennamespace { 21bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 22bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Helper class that waits until the focus has changed to a view other 23bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// than the one with the provided view id. 24bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenclass ViewFocusChangeWaiter : public views::FocusChangeListener { 25bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen public: 26bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen ViewFocusChangeWaiter(views::FocusManager* focus_manager, 27bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen int previous_view_id, 28bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen AutomationProvider* automation, 29bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen IPC::Message* reply_message) 30bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen : focus_manager_(focus_manager), 31bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen previous_view_id_(previous_view_id), 32bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen automation_(automation), 33bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen reply_message_(reply_message), 34bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { 35bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen focus_manager_->AddFocusChangeListener(this); 36bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Call the focus change notification once in case the focus has 37bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // already changed. 38bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen FocusWillChange(NULL, focus_manager_->GetFocusedView()); 39bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 40bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 41bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen ~ViewFocusChangeWaiter() { 42bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen focus_manager_->RemoveFocusChangeListener(this); 43bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 44bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 45bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Inherited from FocusChangeListener 46bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen virtual void FocusWillChange(views::View* focused_before, 47bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen views::View* focused_now) { 48bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // This listener is called before focus actually changes. Post a task 49bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // that will get run after focus changes. 50bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen MessageLoop::current()->PostTask( 51bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen FROM_HERE, 52bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen method_factory_.NewRunnableMethod( 53bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen &ViewFocusChangeWaiter::FocusChanged, 54bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen focused_before, 55bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen focused_now)); 56bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 57bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 58bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen private: 59bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen void FocusChanged(views::View* focused_before, 60bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen views::View* focused_now) { 61bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (focused_now && focused_now->GetID() != previous_view_id_) { 62bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen AutomationMsg_WaitForFocusedViewIDToChange::WriteReplyParams( 63bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen reply_message_, true, focused_now->GetID()); 64bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 65bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen automation_->Send(reply_message_); 66bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen delete this; 67bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 68bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 69bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 70bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen views::FocusManager* focus_manager_; 71bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen int previous_view_id_; 72bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen AutomationProvider* automation_; 73bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen IPC::Message* reply_message_; 74bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen ScopedRunnableMethodFactory<ViewFocusChangeWaiter> method_factory_; 75bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 76bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen DISALLOW_COPY_AND_ASSIGN(ViewFocusChangeWaiter); 77bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}; 78bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 79bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} // namespace 80bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 81bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenclass TestingAutomationProvider::PopupMenuWaiter : public views::MenuListener { 82bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen public: 83bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen PopupMenuWaiter(ToolbarView* toolbar_view, 84bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen TestingAutomationProvider* automation) 85bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen : toolbar_view_(toolbar_view), 86bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen automation_(automation), 87bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen reply_message_(NULL) { 88bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen toolbar_view_->AddMenuListener(this); 89bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 90bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 91bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Implementation of views::MenuListener 92bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen virtual void OnMenuOpened() { 93bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen toolbar_view_->RemoveMenuListener(this); 94bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen automation_->popup_menu_opened_ = true; 95bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen automation_->popup_menu_waiter_ = NULL; 96bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (reply_message_) { 97bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen AutomationMsg_WaitForPopupMenuToOpen::WriteReplyParams( 98bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen reply_message_, true); 99bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen automation_->Send(reply_message_); 100bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 101bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen delete this; 102bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 103bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 104bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen void set_reply_message(IPC::Message* reply_message) { 105bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen reply_message_ = reply_message; 106bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 107bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 108bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen private: 109bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen ToolbarView* toolbar_view_; 110bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen TestingAutomationProvider* automation_; 111bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen IPC::Message* reply_message_; 112bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 113bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen DISALLOW_COPY_AND_ASSIGN(PopupMenuWaiter); 114bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}; 115bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 116bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid TestingAutomationProvider::WindowGetViewBounds(int handle, 117bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen int view_id, 118bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bool screen_coordinates, 119bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bool* success, 120bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen gfx::Rect* bounds) { 121bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen *success = false; 122bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 123bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (window_tracker_->ContainsHandle(handle)) { 124bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen gfx::NativeWindow window = window_tracker_->GetResource(handle); 125dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen views::NativeWidget* native_widget = 126dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen views::NativeWidget::GetNativeWidgetForNativeWindow(window); 127dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (native_widget) { 128dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen views::View* root_view = native_widget->GetWidget()->GetRootView(); 129bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen views::View* view = root_view->GetViewByID(view_id); 130bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (view) { 131bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen *success = true; 132bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen gfx::Point point; 133bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (screen_coordinates) 134bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen views::View::ConvertPointToScreen(view, &point); 135bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen else 136bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen views::View::ConvertPointToView(view, root_view, &point); 13772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen *bounds = view->GetContentsBounds(); 138bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bounds->set_origin(point); 139bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 140bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 141bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 142bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 143bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 144bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid TestingAutomationProvider::GetFocusedViewID(int handle, int* view_id) { 145bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen *view_id = -1; 146bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (window_tracker_->ContainsHandle(handle)) { 147bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen gfx::NativeWindow window = window_tracker_->GetResource(handle); 148bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen views::FocusManager* focus_manager = 149bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen views::FocusManager::GetFocusManagerForNativeWindow(window); 150bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen DCHECK(focus_manager); 151bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen views::View* focused_view = focus_manager->GetFocusedView(); 152bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (focused_view) 153bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen *view_id = focused_view->GetID(); 154bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 155bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 156bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 157bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid TestingAutomationProvider::WaitForFocusedViewIDToChange( 158bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen int handle, int previous_view_id, IPC::Message* reply_message) { 159bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (!window_tracker_->ContainsHandle(handle)) 160bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return; 161bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen gfx::NativeWindow window = window_tracker_->GetResource(handle); 162bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen views::FocusManager* focus_manager = 163bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen views::FocusManager::GetFocusManagerForNativeWindow(window); 164bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 165bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // The waiter will respond to the IPC and delete itself when done. 166bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen new ViewFocusChangeWaiter(focus_manager, 167bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen previous_view_id, 168bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen this, 169bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen reply_message); 170bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 171bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 172bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid TestingAutomationProvider::StartTrackingPopupMenus( 173bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen int browser_handle, bool* success) { 174bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (browser_tracker_->ContainsHandle(browser_handle)) { 175bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen Browser* browser = browser_tracker_->GetResource(browser_handle); 176bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen BrowserView* browser_view = reinterpret_cast<BrowserView*>( 177bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen browser->window()); 178bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen ToolbarView* toolbar_view = browser_view->GetToolbarView(); 179bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen popup_menu_opened_ = false; 180bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen popup_menu_waiter_ = new PopupMenuWaiter(toolbar_view, this); 181bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen *success = true; 182bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 183bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 184bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 185bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid TestingAutomationProvider::WaitForPopupMenuToOpen( 186bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen IPC::Message* reply_message) { 187bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // See if the menu already opened and return true if so. 188bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (popup_menu_opened_) { 189bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen AutomationMsg_WaitForPopupMenuToOpen::WriteReplyParams( 190bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen reply_message, true); 191bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen Send(reply_message); 192bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return; 193bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 194bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 195bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Otherwise, register this reply message with the waiter, 196bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // which will handle responding to this IPC when the popup 197bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // menu opens. 198bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen popup_menu_waiter_->set_reply_message(reply_message); 199bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 200