Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(418)

Unified Diff: chrome/browser/ui/cocoa/extensions/browser_action_button_interactive_uitest.mm

Issue 2852233002: Mac[Views]: Make native menus more responsive by pumping private runloop modes. (Closed)
Patch Set: respond to comments Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/message_loop/message_pump_mac.mm ('k') | ui/base/cocoa/menu_controller.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/ui/cocoa/extensions/browser_action_button_interactive_uitest.mm
diff --git a/chrome/browser/ui/cocoa/extensions/browser_action_button_interactive_uitest.mm b/chrome/browser/ui/cocoa/extensions/browser_action_button_interactive_uitest.mm
index fa769cb312511109e2e7014338ee1f605d1650ba..4a53234a40c997548ad75db945e904bb37ce0b09 100644
--- a/chrome/browser/ui/cocoa/extensions/browser_action_button_interactive_uitest.mm
+++ b/chrome/browser/ui/cocoa/extensions/browser_action_button_interactive_uitest.mm
@@ -37,6 +37,13 @@
#include "ui/base/cocoa/cocoa_base_utils.h"
#import "ui/events/test/cocoa_test_event_utils.h"
+// A helper class to wait for a menu to open and close.
+@interface MenuWatcher : NSObject
+- (id)initWithController:(MenuController*)controller;
+@property(nonatomic, assign) base::Closure openClosure;
+@property(nonatomic, assign) base::Closure closeClosure;
+@end
+
namespace {
const int kMenuPadding = 26;
@@ -93,33 +100,40 @@ void MoveMouseToCenter(NSView* view) {
runLoop.Run();
}
-// Simulates a click on the action button in the overflow menu, and runs
-// |closure| upon completion.
-void ClickOnOverflowedAction(ToolbarController* toolbarController,
- const base::Closure& closure) {
- AppMenuController* appMenuController = [toolbarController appMenuController];
+// Simulates a right-click on the action button in the overflow menu.
+void DispatchClickOnOverflowedAction(BrowserActionButton* action_button) {
+ NSEvent* event = nil; // The event doesn't matter when sending directly.
+ [action_button rightMouseDown:event];
+}
+
+// ui_controls:: methods don't play nice when there is an open menu (like the
+// app menu). Instead, ClickOnOverflowedAction() simulates a right click by
+// feeding the event directly to the button. In regular interaction, this is
+// dispatched after menuDidClose:. To simulate that, start the menu closing
+// (with no action), but invoke the action on the button directly when the close
+// is observed.
+void ClickOnOverflowedAction(
+ base::scoped_nsobject<MenuWatcher> app_menu_watcher,
+ AppMenuController* app_menu_controller) {
// The app menu should start as open (since that's where the overflowed
// actions are).
- EXPECT_TRUE([appMenuController isMenuOpen]);
- BrowserActionsController* overflowController =
- [appMenuController browserActionsController];
+ EXPECT_TRUE([app_menu_controller isMenuOpen]);
+
+ BrowserActionsController* overflow_controller =
+ [app_menu_controller browserActionsController];
+
+ ASSERT_TRUE(overflow_controller);
+ BrowserActionButton* action_button = [overflow_controller buttonWithIndex:0];
- ASSERT_TRUE(overflowController);
- BrowserActionButton* actionButton = [overflowController buttonWithIndex:0];
// The action should be attached to a superview.
- EXPECT_TRUE([actionButton superview]);
+ EXPECT_TRUE([action_button superview]);
- // ui_controls:: methods don't play nice when there is an open menu (like the
- // app menu). Instead, simulate a right click by feeding the event directly to
- // the button.
- NSPoint centerPoint = GetCenterPoint(actionButton);
- NSEvent* mouseEvent = cocoa_test_event_utils::RightMouseDownAtPointInWindow(
- centerPoint, [actionButton window]);
- [actionButton rightMouseDown:mouseEvent];
+ base::Closure invoke_action = base::Bind(&DispatchClickOnOverflowedAction,
+ base::Unretained(action_button));
+ [app_menu_watcher setCloseClosure:invoke_action];
- // This should close the app menu.
- EXPECT_FALSE([appMenuController isMenuOpen]);
- base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, closure);
+ // Close the app menu.
+ [app_menu_controller cancel];
}
} // namespace
@@ -132,14 +146,15 @@ void ClickOnOverflowedAction(ToolbarController* toolbarController,
// be used multiple times.
BOOL menuOpened_;
+ // The closure to run when the menu opens, if any.
+ base::Closure openClosure_;
+
// A function to be called to verify state while the menu is open.
base::Closure verify_;
}
-// Bare-bones init.
-- (id)init;
-
@property(nonatomic, assign) BOOL menuOpened;
+@property(nonatomic, assign) base::Closure openClosure;
@property(nonatomic, assign) base::Closure verify;
@end
@@ -148,23 +163,20 @@ void ClickOnOverflowedAction(ToolbarController* toolbarController,
- (void)menuWillOpen:(NSMenu*)menu {
menuOpened_ = YES;
+ if (!openClosure_.is_null())
+ openClosure_.Run();
if (!verify_.is_null())
verify_.Run();
[menu cancelTracking];
}
-- (id)init {
- self = [super init];
- return self;
-}
-
@synthesize menuOpened = menuOpened_;
+@synthesize openClosure = openClosure_;
@synthesize verify = verify_;
@end
-// A helper class to wait for a menu to open and close.
-@interface MenuWatcher : NSObject {
+@implementation MenuWatcher {
// The MenuController for the menu this object is watching.
MenuController* menuController_;
@@ -175,19 +187,6 @@ void ClickOnOverflowedAction(ToolbarController* toolbarController,
base::Closure closeClosure_;
}
-- (id)initWithController:(MenuController*)controller;
-
-// Notifications from the MenuController.
-- (void)menuDidClose:(NSNotification*)notification;
-- (void)menuDidOpen:(NSNotification*)notification;
-
-@property(nonatomic, assign) base::Closure openClosure;
-@property(nonatomic, assign) base::Closure closeClosure;
-
-@end
-
-@implementation MenuWatcher
-
@synthesize openClosure = openClosure_;
@synthesize closeClosure = closeClosure_;
@@ -215,8 +214,11 @@ void ClickOnOverflowedAction(ToolbarController* toolbarController,
- (void)menuDidClose:(NSNotification*)notification {
if (!closeClosure_.is_null()) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::ResetAndReturn(&closeClosure_));
+ // Run |closeClosure_| synchronously since it may depend on objects that are
+ // torn down once the menu is closed and execution has returned to the main
+ // run loop.
+ closeClosure_.Run();
+ closeClosure_.Reset();
}
}
@@ -257,32 +259,34 @@ class BrowserActionButtonUiTest : public ExtensionBrowserTest {
}
// Opens the app menu and the context menu of the overflowed action, and
- // checks that the menus get opened/closed properly. |menuHelper| must be set
- // as the delegate for the context menu.
- void OpenAppMenuAndActionContextMenu(MenuHelper* menuHelper) {
+ // checks that the menus get opened/closed properly.
+ void OpenAppMenuAndActionContextMenu(MenuHelper* context_menu_helper) {
// Move the mouse over the app menu button.
MoveMouseToCenter(appMenuButton());
// No menu yet (on the browser action).
- EXPECT_FALSE([menuHelper menuOpened]);
- base::RunLoop runLoop;
- // Click on the app menu, and pass in a callback to continue the test in
- // ClickOnOverflowedAction. Due to the blocking nature of Cocoa menus, we
- // can't test the menu synchronously here by quitting the run loop when it
- // opens, and instead need to test through a callback.
- base::scoped_nsobject<MenuWatcher> menuWatcher(
+ EXPECT_FALSE([context_menu_helper menuOpened]);
+ base::RunLoop run_loop;
+ base::scoped_nsobject<MenuWatcher> app_menu_watcher(
[[MenuWatcher alloc] initWithController:appMenuController()]);
- [menuWatcher
- setOpenClosure:base::Bind(&ClickOnOverflowedAction,
- base::Unretained(toolbarController()),
- runLoop.QuitClosure())];
+
+ base::Closure close_with_action =
+ base::Bind(&ClickOnOverflowedAction, app_menu_watcher,
+ base::Unretained(appMenuController()));
+ [app_menu_watcher setOpenClosure:close_with_action];
+
+ // Quit the RunLoop below when the context menu opens. This dictates that
+ // the MenuHelper's verify action has also run.
+ [context_menu_helper setOpenClosure:run_loop.QuitClosure()];
+
+ // Show the app menu.
ui_controls::SendMouseEvents(ui_controls::LEFT,
ui_controls::DOWN | ui_controls::UP);
- runLoop.Run();
+ run_loop.Run();
// The menu opened on the main bar's action button rather than the
// overflow's since Cocoa does not support running a menu within a menu.
- EXPECT_TRUE([menuHelper menuOpened]);
+ EXPECT_TRUE([context_menu_helper menuOpened]);
}
ToolbarController* toolbarController() { return toolbarController_; }
« no previous file with comments | « base/message_loop/message_pump_mac.mm ('k') | ui/base/cocoa/menu_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698