// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import "chrome/browser/ui/cocoa/app_menu/app_menu_controller.h"

#include <stddef.h>

#include "base/bind.h"
#include "base/mac/bundle_locations.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/histogram_macros.h"
#include "base/scoped_observer.h"
#include "base/strings/string16.h"
#include "base/strings/sys_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/app/chrome_command_ids.h"
#import "chrome/browser/app_controller_mac.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#import "chrome/browser/ui/cocoa/accelerators_cocoa.h"
#import "chrome/browser/ui/cocoa/app_menu/menu_tracked_root_view.h"
#import "chrome/browser/ui/cocoa/app_menu/recent_tabs_menu_model_delegate.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_menu_cocoa_controller.h"
#import "chrome/browser/ui/cocoa/browser_window_controller.h"
#import "chrome/browser/ui/cocoa/extensions/browser_actions_container_view.h"
#import "chrome/browser/ui/cocoa/extensions/browser_actions_controller.h"
#import "chrome/browser/ui/cocoa/l10n_util.h"
#import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
#include "chrome/browser/ui/toolbar/app_menu_model.h"
#include "chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.h"
#include "chrome/browser/ui/toolbar/toolbar_actions_bar.h"
#include "chrome/browser/ui/toolbar/toolbar_actions_bar_observer.h"
#include "chrome/grit/generated_resources.h"
#include "components/zoom/zoom_event_manager.h"
#include "content/public/browser/user_metrics.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/models/menu_model.h"
#include "ui/gfx/geometry/size.h"

namespace {
// Padding amounts on the left/right of a custom menu item (like the browser
// actions overflow container).
const int kLeftPadding = 16;
const int kRightPadding = 10;

// In *very* extreme cases, it's possible that there are so many overflowed
// actions, we won't be able to show them all. Cap the height so that the
// overflow won't make the menu larger than the height of the screen.
// Note: With this height, we can show 104 actions. Less than 0.0002% of our
// users will be affected.
const int kMaxOverflowContainerHeight = 416;
}

namespace app_menu_controller {
const CGFloat kAppMenuBubblePointOffsetY = 6;
}

using base::UserMetricsAction;

@interface AppMenuController (Private)
- (void)createModel;
- (void)adjustPositioning;
- (void)performCommandDispatch:(NSNumber*)tag;
- (NSButton*)zoomDisplay;
- (void)menu:(NSMenu*)menu willHighlightItem:(NSMenuItem*)item;
- (NSMenu*)recentTabsSubmenu;
- (RecentTabsSubMenuModel*)recentTabsMenuModel;
- (int)maxWidthForMenuModel:(ui::MenuModel*)model
                 modelIndex:(int)modelIndex;
@end

namespace AppMenuControllerInternal {

// A C++ delegate that handles the accelerators in the app menu.
class AcceleratorDelegate : public ui::AcceleratorProvider {
 public:
  bool GetAcceleratorForCommandId(
      int command_id,
      ui::Accelerator* out_accelerator) const override {
    AcceleratorsCocoa* keymap = AcceleratorsCocoa::GetInstance();
    const ui::Accelerator* accelerator =
        keymap->GetAcceleratorForCommand(command_id);
    if (!accelerator)
      return false;
    *out_accelerator = *accelerator;
    return true;
  }
};

class ZoomLevelObserver {
 public:
  ZoomLevelObserver(AppMenuController* controller,
                    zoom::ZoomEventManager* manager)
      : controller_(controller) {
    subscription_ = manager->AddZoomLevelChangedCallback(
        base::Bind(&ZoomLevelObserver::OnZoomLevelChanged,
                   base::Unretained(this)));
  }

  ~ZoomLevelObserver() {}

 private:
  void OnZoomLevelChanged(const content::HostZoomMap::ZoomLevelChange& change) {
    AppMenuModel* appMenuModel = [controller_ appMenuModel];
    appMenuModel->UpdateZoomControls();
    const base::string16 level =
        appMenuModel->GetLabelForCommandId(IDC_ZOOM_PERCENT_DISPLAY);
    [[controller_ zoomDisplay] setTitle:SysUTF16ToNSString(level)];
  }

  std::unique_ptr<content::HostZoomMap::Subscription> subscription_;

  AppMenuController* controller_;  // Weak; owns this.

  DISALLOW_COPY_AND_ASSIGN(ZoomLevelObserver);
};

class ToolbarActionsBarObserverHelper : public ToolbarActionsBarObserver {
 public:
  ToolbarActionsBarObserverHelper(AppMenuController* controller,
                                  ToolbarActionsBar* toolbar_actions_bar)
      : controller_(controller),
        scoped_observer_(this),
        weak_ptr_factory_(this) {
    scoped_observer_.Add(toolbar_actions_bar);
  }
  ~ToolbarActionsBarObserverHelper() override {}

 private:
  // ToolbarActionsBarObserver:
  void OnToolbarActionsBarDestroyed() override {
    scoped_observer_.RemoveAll();
  }
  void OnToolbarActionsBarDidStartResize() override {
    // No point in having multiple pending update calls.
    weak_ptr_factory_.InvalidateWeakPtrs();
    // Edge case: If the resize is caused by an action being added while the
    // menu is open, we need to wait for both toolbars to be updated. This can
    // happen if a user's data is synced with the menu open.
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, base::Bind(&ToolbarActionsBarObserverHelper::UpdateSubmenu,
                              weak_ptr_factory_.GetWeakPtr()));
  }

  void UpdateSubmenu() {
    [controller_ updateBrowserActionsSubmenu];
  }

  AppMenuController* controller_;
  ScopedObserver<ToolbarActionsBar, ToolbarActionsBarObserver> scoped_observer_;
  base::WeakPtrFactory<ToolbarActionsBarObserverHelper> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(ToolbarActionsBarObserverHelper);
};

}  // namespace AppMenuControllerInternal

@implementation AppMenuController

- (id)initWithBrowser:(Browser*)browser {
  if ((self = [super init])) {
    browser_ = browser;
    acceleratorDelegate_.reset(
        new AppMenuControllerInternal::AcceleratorDelegate());
    [self createModel];
  }
  return self;
}

- (void)dealloc {
  [self browserWillBeDestroyed];
  [super dealloc];
}

- (void)browserWillBeDestroyed {
  // This method indicates imminent destruction. Destroy owned objects that hold
  // a weak Browser*, or pass this call onto reference counted objects.
  recentTabsMenuModelDelegate_.reset();
  [self setModel:nullptr];
  appMenuModel_.reset();
  buttonViewController_.reset();

  // The observers should most likely already be destroyed (since they're reset
  // in -menuDidClose:), but sometimes shutdown can be funny, so make sure to
  // not leave any dangling observers.
  zoom_level_observer_.reset();
  toolbar_actions_bar_observer_.reset();

  [browserActionsController_ browserWillBeDestroyed];

  browser_ = nullptr;
}

- (void)addItemToMenu:(NSMenu*)menu
              atIndex:(NSInteger)index
            fromModel:(ui::MenuModel*)model {
  // Non-button item types should be built as normal items, with the exception
  // of the extensions overflow menu.
  int command_id = model->GetCommandIdAt(index);
  if (model->GetTypeAt(index) != ui::MenuModel::TYPE_BUTTON_ITEM &&
      command_id != IDC_EXTENSIONS_OVERFLOW_MENU) {
    [super addItemToMenu:menu
                 atIndex:index
               fromModel:model];
    return;
  }

  // Handle the special-cased menu items.
  base::scoped_nsobject<NSMenuItem> customItem(
      [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]);
  MenuTrackedRootView* view = nil;
  switch (command_id) {
    case IDC_EXTENSIONS_OVERFLOW_MENU: {
      browserActionsMenuItem_ = customItem.get();
      view = [buttonViewController_ toolbarActionsOverflowItem];
      BrowserActionsContainerView* containerView =
          [buttonViewController_ overflowActionsContainerView];

      // The overflow browser actions container can't function properly without
      // a main counterpart, so if the browser window hasn't initialized, abort.
      // (This is fine because we re-populate the app menu each time before we
      // show it.)
      if (!browser_->window())
        break;

      BrowserActionsController* mainController =
          [[[BrowserWindowController browserWindowControllerForWindow:browser_->
              window()->GetNativeWindow()] toolbarController]
                  browserActionsController];
      toolbar_actions_bar_observer_.reset(
          new AppMenuControllerInternal::ToolbarActionsBarObserverHelper(
              self, [mainController toolbarActionsBar]));
      browserActionsController_.reset(
          [[BrowserActionsController alloc]
              initWithBrowser:browser_
                containerView:containerView
               mainController:mainController]);
      break;
    }
    case IDC_EDIT_MENU:
      view = [buttonViewController_ editItem];
      break;
    case IDC_ZOOM_MENU:
      view = [buttonViewController_ zoomItem];
      break;
    default:
      NOTREACHED();
      break;
  }
  DCHECK(view);
  [customItem setView:view];
  [view setMenuItem:customItem];
  [self adjustPositioning];
  [menu insertItem:customItem.get() atIndex:index];
}

- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item {
  const BOOL enabled = [super validateUserInterfaceItem:item];

  NSMenuItem* menuItem = (id)item;
  ui::MenuModel* model =
      static_cast<ui::MenuModel*>(
          [[menuItem representedObject] pointerValue]);

  // The section headers in the recent tabs submenu should be bold and black if
  // a font list is specified for the items (bold is already applied in the
  // |MenuController| as the font list returned by |GetLabelFontListAt| is
  // bold).
  if (model && model == [self recentTabsMenuModel]) {
    if (model->GetLabelFontListAt([item tag])) {
      DCHECK([menuItem attributedTitle]);
      base::scoped_nsobject<NSMutableAttributedString> title(
          [[NSMutableAttributedString alloc]
              initWithAttributedString:[menuItem attributedTitle]]);
      [title addAttribute:NSForegroundColorAttributeName
                    value:[NSColor blackColor]
                    range:NSMakeRange(0, [title length])];
      [menuItem setAttributedTitle:title.get()];
    } else {
      // Not a section header. Add a tooltip with the title and the URL.
      std::string url;
      base::string16 title;
      if ([self recentTabsMenuModel]->GetURLAndTitleForItemAtIndex(
              [item tag], &url, &title)) {
        [menuItem setToolTip:
            cocoa_l10n_util::TooltipForURLAndTitle(
                base::SysUTF8ToNSString(url), base::SysUTF16ToNSString(title))];
       }
    }
  }

  return enabled;
}

- (NSMenu*)bookmarkSubMenu {
  NSString* title = l10n_util::GetNSStringWithFixup(IDS_BOOKMARKS_MENU);
  return [[[self menu] itemWithTitle:title] submenu];
}

- (void)updateBookmarkSubMenu {
  NSMenu* bookmarkMenu = [self bookmarkSubMenu];
  DCHECK(bookmarkMenu);

  bookmarkMenuBridge_.reset(new BookmarkMenuBridge(
      [self appMenuModel]->browser()->profile(), bookmarkMenu));
}

- (void)updateBrowserActionsSubmenu {
  MenuTrackedRootView* view =
      [buttonViewController_ toolbarActionsOverflowItem];
  BrowserActionsContainerView* containerView =
      [buttonViewController_ overflowActionsContainerView];

  // Find the preferred container size for the menu width.
  int menuWidth = [[self menu] size].width;
  int maxContainerWidth = menuWidth - kLeftPadding - kRightPadding;
  // Don't let the menu change sizes on us. (We lift this restriction every time
  // the menu updates, so if something changes, this won't leave us with an
  // awkward size.)
  [[self menu] setMinimumWidth:menuWidth];
  gfx::Size preferredContainerSize =
      [browserActionsController_ sizeForOverflowWidth:maxContainerWidth];

  // Set the origins and preferred size for the container.
  // View hierarchy is as follows (from parent > child):
  // |view| > |anonymous view| > containerView. We have to set the origin
  // and size of each for it display properly.
  // The parent views each have a size of the full width of the menu, so we can
  // properly position the container.
  NSSize parentSize = NSMakeSize(menuWidth,
                                 std::min(preferredContainerSize.height(),
                                          kMaxOverflowContainerHeight));
  [view setFrameSize:parentSize];
  [[containerView superview] setFrameSize:parentSize];

  // The container view gets its preferred size.
  [containerView setFrameSize:NSMakeSize(preferredContainerSize.width(),
                                         preferredContainerSize.height())];
  [browserActionsController_ update];

  [view setFrameOrigin:NSZeroPoint];
  [[containerView superview] setFrameOrigin:NSZeroPoint];
  [containerView setFrameOrigin:NSMakePoint(kLeftPadding, 0)];
}

- (void)menuWillOpen:(NSMenu*)menu {
  [super menuWillOpen:menu];

  zoom_level_observer_.reset(new AppMenuControllerInternal::ZoomLevelObserver(
      self, zoom::ZoomEventManager::GetForBrowserContext(browser_->profile())));
  NSString* title = base::SysUTF16ToNSString(
      [self appMenuModel]->GetLabelForCommandId(IDC_ZOOM_PERCENT_DISPLAY));
  [[[buttonViewController_ zoomItem] viewWithTag:IDC_ZOOM_PERCENT_DISPLAY]
      setTitle:title];
  [[[[buttonViewController_ zoomItem]
      viewWithTag:IDC_ZOOM_MINUS] image]
          setAccessibilityDescription:l10n_util::GetNSString(
              IDS_TEXT_SMALLER_MAC)];
  [[[[buttonViewController_ zoomItem]
      viewWithTag:IDC_ZOOM_PLUS] image]
        setAccessibilityDescription:l10n_util::GetNSString(
              IDS_TEXT_BIGGER_MAC)];
  content::RecordAction(UserMetricsAction("ShowAppMenu"));

  NSImage* icon = [self appMenuModel]->browser()->window()->IsFullscreen()
                      ? [NSImage imageNamed:NSImageNameExitFullScreenTemplate]
                      : [NSImage imageNamed:NSImageNameEnterFullScreenTemplate];
  [[buttonViewController_ zoomFullScreen] setImage:icon];

  menuOpenTime_ = base::TimeTicks::Now();
}

- (void)menuDidClose:(NSMenu*)menu {
  [super menuDidClose:menu];
  // We don't need to observe changes to zoom or toolbar size when the menu is
  // closed, since we instantiate it with the proper value and recreate the menu
  // on each show. (We do this in -menuNeedsUpdate:, which is called when the
  // menu is about to be displayed at the start of a tracking session.)
  zoom_level_observer_.reset();
  toolbar_actions_bar_observer_.reset();
  // Make sure to reset() the BrowserActionsController since the view will also
  // be destroyed. If a new one's needed, it'll be created when we create the
  // model in -menuNeedsUpdate:.
  browserActionsController_.reset();
  UMA_HISTOGRAM_TIMES("Toolbar.AppMenuTimeToAction",
                      base::TimeTicks::Now() - menuOpenTime_);
  menuOpenTime_ = base::TimeTicks();
}

- (void)menuNeedsUpdate:(NSMenu*)menu {
  // We should never have a BrowserActionsController before creating the menu.
  DCHECK(!browserActionsController_.get());

  // First empty out the menu and create a new model.
  [menu removeAllItems];
  [self createModel];
  [menu setMinimumWidth:0];

  // Create a new menu, which cannot be swapped because the tracking is about to
  // start, so simply copy the items.
  NSMenu* newMenu = [self menuFromModel:model_];
  NSArray* itemArray = [newMenu itemArray];
  [newMenu removeAllItems];
  for (NSMenuItem* item in itemArray) {
    [menu addItem:item];
  }

  [self updateRecentTabsSubmenu];
  [self updateBookmarkSubMenu];
  [self updateBrowserActionsSubmenu];
}

// Used to dispatch commands from the App menu. The custom items within the
// menu cannot be hooked up directly to First Responder because the window in
// which the controls reside is not the BrowserWindowController, but a
// NSCarbonMenuWindow; this screws up the typical |-commandDispatch:| system.
- (IBAction)dispatchAppMenuCommand:(id)sender {
  NSInteger tag = [sender tag];
  if (sender == [buttonViewController_ zoomPlus] ||
      sender == [buttonViewController_ zoomMinus]) {
    // Do a direct dispatch rather than scheduling on the outermost run loop,
    // which would not get hit until after the menu had closed.
    [self performCommandDispatch:[NSNumber numberWithInt:tag]];

    // The zoom buttons should not close the menu if opened sticky.
    if ([sender respondsToSelector:@selector(isTracking)] &&
        [sender performSelector:@selector(isTracking)]) {
      [menu_ cancelTracking];
    }
  } else {
    // The custom views within the App menu are abnormal and keep the menu open
    // after a target-action.  Close the menu manually.
    [menu_ cancelTracking];

    // Executing certain commands from the nested run loop of the menu can lead
    // to wonky behavior (e.g. http://crbug.com/49716). To avoid this, schedule
    // the dispatch on the outermost run loop.
    [self performSelector:@selector(performCommandDispatch:)
               withObject:[NSNumber numberWithInt:tag]
               afterDelay:0.0];
  }
}

// Used to perform the actual dispatch on the outermost runloop.
- (void)performCommandDispatch:(NSNumber*)tag {
  [self appMenuModel]->ExecuteCommand([tag intValue], 0);
}

- (AppMenuModel*)appMenuModel {
  // Don't use |appMenuModel_| so that a test can override the generic one.
  return static_cast<AppMenuModel*>(model_);
}

- (void)updateRecentTabsSubmenu {
  ui::MenuModel* model = [self recentTabsMenuModel];
  if (model) {
    recentTabsMenuModelDelegate_.reset(
        new RecentTabsMenuModelDelegate(model, [self recentTabsSubmenu]));
  }
}

- (BrowserActionsController*)browserActionsController {
  return browserActionsController_.get();
}

- (void)createModel {
  DCHECK(browser_);
  recentTabsMenuModelDelegate_.reset();
  appMenuModel_.reset(new AppMenuModel(acceleratorDelegate_.get(), browser_));
  [self setModel:appMenuModel_.get()];

  buttonViewController_.reset(
      [[AppMenuButtonViewController alloc] initWithController:self]);
  [buttonViewController_ view];

  // See comment in containerSuperviewFrameChanged:.
  NSView* containerSuperview =
      [[buttonViewController_ overflowActionsContainerView] superview];
  [containerSuperview setPostsFrameChangedNotifications:YES];
}

// Fit the localized strings into the Cut/Copy/Paste control, then resize the
// whole menu item accordingly.
- (void)adjustPositioning {
  const CGFloat kButtonPadding = 12;
  CGFloat delta = 0;

  // Go through the three buttons from right-to-left, adjusting the size to fit
  // the localized strings while keeping them all aligned on their horizontal
  // edges.
  NSButton* views[] = {
      [buttonViewController_ editPaste],
      [buttonViewController_ editCopy],
      [buttonViewController_ editCut]
  };
  for (size_t i = 0; i < arraysize(views); ++i) {
    NSButton* button = views[i];
    CGFloat originalWidth = NSWidth([button frame]);

    // Do not let |-sizeToFit| change the height of the button.
    NSSize size = [button frame].size;
    [button sizeToFit];
    size.width = [button frame].size.width + kButtonPadding;
    [button setFrameSize:size];

    CGFloat newWidth = size.width;
    delta += newWidth - originalWidth;

    NSRect frame = [button frame];
    frame.origin.x -= delta;
    [button setFrame:frame];
  }

  // Resize the menu item by the total amound the buttons changed so that the
  // spacing between the buttons and the title remains the same.
  NSRect itemFrame = [[buttonViewController_ editItem] frame];
  itemFrame.size.width += delta;
  [[buttonViewController_ editItem] setFrame:itemFrame];

  // Also resize the superview of the buttons, which is an NSView used to slide
  // when the item title is too big and GTM resizes it.
  NSRect parentFrame = [[[buttonViewController_ editCut] superview] frame];
  parentFrame.size.width += delta;
  parentFrame.origin.x -= delta;
  [[[buttonViewController_ editCut] superview] setFrame:parentFrame];
}

- (NSButton*)zoomDisplay {
  return [buttonViewController_ zoomDisplay];
}

- (void)menu:(NSMenu*)menu willHighlightItem:(NSMenuItem*)item {
  if (browserActionsController_.get()) {
    [browserActionsController_ setFocusedInOverflow:
        (item == browserActionsMenuItem_)];
  }
}

- (NSMenu*)recentTabsSubmenu {
  NSString* title = l10n_util::GetNSStringWithFixup(IDS_RECENT_TABS_MENU);
  return [[[self menu] itemWithTitle:title] submenu];
}

// The recent tabs menu model is recognized by the existence of either the
// kRecentlyClosedHeaderCommandId or the kDisabledRecentlyClosedHeaderCommandId.
- (RecentTabsSubMenuModel*)recentTabsMenuModel {
  int index = 0;
  // Start searching at the app menu model level, |model| will be updated only
  // if the command we're looking for is found in one of the [sub]menus.
  ui::MenuModel* model = [self appMenuModel];
  if (ui::MenuModel::GetModelAndIndexForCommandId(
          RecentTabsSubMenuModel::kRecentlyClosedHeaderCommandId, &model,
          &index)) {
    return static_cast<RecentTabsSubMenuModel*>(model);
  }
  if (ui::MenuModel::GetModelAndIndexForCommandId(
          RecentTabsSubMenuModel::kDisabledRecentlyClosedHeaderCommandId,
          &model, &index)) {
    return static_cast<RecentTabsSubMenuModel*>(model);
  }
  return NULL;
}

// This overrdies the parent class to return a custom width for recent tabs
// menu.
- (int)maxWidthForMenuModel:(ui::MenuModel*)model
                 modelIndex:(int)modelIndex {
  RecentTabsSubMenuModel* recentTabsMenuModel = [self recentTabsMenuModel];
  if (recentTabsMenuModel && recentTabsMenuModel == model) {
    return recentTabsMenuModel->GetMaxWidthForItemAtIndex(modelIndex);
  }
  return -1;
}

@end  // @implementation AppMenuController

////////////////////////////////////////////////////////////////////////////////

@interface AppMenuButtonViewController ()
- (void)containerSuperviewFrameChanged:(NSNotification*)notification;
@end

@implementation AppMenuButtonViewController

@synthesize editItem = editItem_;
@synthesize editCut = editCut_;
@synthesize editCopy = editCopy_;
@synthesize editPaste = editPaste_;
@synthesize zoomItem = zoomItem_;
@synthesize zoomPlus = zoomPlus_;
@synthesize zoomDisplay = zoomDisplay_;
@synthesize zoomMinus = zoomMinus_;
@synthesize zoomFullScreen = zoomFullScreen_;
@synthesize toolbarActionsOverflowItem = toolbarActionsOverflowItem_;
@synthesize overflowActionsContainerView = overflowActionsContainerView_;

- (id)initWithController:(AppMenuController*)controller {
  if ((self = [super initWithNibName:@"AppMenu"
                              bundle:base::mac::FrameworkBundle()])) {
    propertyReleaser_.Init(self, [AppMenuButtonViewController class]);
    controller_ = controller;
    [[NSNotificationCenter defaultCenter]
        addObserver:self
           selector:@selector(containerSuperviewFrameChanged:)
               name:NSViewFrameDidChangeNotification
             object:[overflowActionsContainerView_ superview]];
  }
  return self;
}

- (void)dealloc {
  [[NSNotificationCenter defaultCenter] removeObserver:self];
  [super dealloc];
}

- (IBAction)dispatchAppMenuCommand:(id)sender {
  [controller_ dispatchAppMenuCommand:sender];
}

- (void)containerSuperviewFrameChanged:(NSNotification*)notification {
  // AppKit menus were probably never designed with a view like the browser
  // actions container in mind, and, as a result, we come across a few oddities.
  // One of these is that the container's superview will, on some versions of
  // OSX, change frame position sometime after the the menu begins tracking
  // (and thus, after all our ability to adjust it normally). Throw in the
  // towel, and simply don't let the frame move from where it's supposed to be.
  // TODO(devlin): Yet another Cocoa hack. It'd be good to find a workaround,
  // but unlikely unless we replace the Cocoa menu implementation.
  NSView* containerSuperview = [overflowActionsContainerView_ superview];
  if (NSMinX([containerSuperview frame]) != 0)
    [containerSuperview setFrameOrigin:NSZeroPoint];
}

@end  // @implementation AppMenuButtonViewController
