Commit c93e4d7e authored by shrike's avatar shrike Committed by Commit bot

Dismiss context menu when download bar is closed.

For some downloaded items like Chrome apps, Chromium hides the download
bar once the download completes if there are no other download items in
it. However, if you cause the download item to display its context menu,
the context menu will remain visible even after the bar disappears.

BUG=480884

Review URL: https://codereview.chromium.org/1125423002

Cr-Commit-Position: refs/heads/master@{#330221}
parent 0c71a4da
// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -17,11 +17,15 @@ ...@@ -17,11 +17,15 @@
@private @private
base::FilePath downloadPath_; base::FilePath downloadPath_;
DownloadItemController* controller_; // weak DownloadItemController* controller_; // weak
base::scoped_nsobject<NSMenu> contextMenu_;
} }
@property(assign, nonatomic) base::FilePath download; @property(assign, nonatomic) base::FilePath download;
@property(assign, nonatomic) DownloadItemController* controller; @property(assign, nonatomic) DownloadItemController* controller;
// Shows the DownloadItemButton's context menu.
- (void)showContextMenu;
// Overridden from DraggableButton. // Overridden from DraggableButton.
- (void)beginDrag:(NSEvent*)event; - (void)beginDrag:(NSEvent*)event;
......
// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -25,6 +25,18 @@ ...@@ -25,6 +25,18 @@
} }
} }
- (void)showContextMenu {
base::scoped_nsobject<DownloadShelfContextMenuController> menuController(
[[DownloadShelfContextMenuController alloc]
initWithItemController:controller_
withDelegate:self]);
contextMenu_.reset([[menuController menu] retain]);
[NSMenu popUpContextMenu:contextMenu_.get()
withEvent:[NSApp currentEvent]
forView:self];
contextMenu_.reset();
}
// Override to show a context menu on mouse down if clicked over the context // Override to show a context menu on mouse down if clicked over the context
// menu area. // menu area.
- (void)mouseDown:(NSEvent*)event { - (void)mouseDown:(NSEvent*)event {
...@@ -35,15 +47,8 @@ ...@@ -35,15 +47,8 @@
if ([reinterpret_cast<DownloadItemCell*>(cell) isMouseOverButtonPart]) { if ([reinterpret_cast<DownloadItemCell*>(cell) isMouseOverButtonPart]) {
[self.draggableButton mouseDownImpl:event]; [self.draggableButton mouseDownImpl:event];
} else { } else {
base::scoped_nsobject<DownloadShelfContextMenuController> menuController(
[[DownloadShelfContextMenuController alloc]
initWithItemController:controller_
withDelegate:self]);
[cell setHighlighted:YES]; [cell setHighlighted:YES];
[NSMenu popUpContextMenu:[menuController menu] [self showContextMenu];
withEvent:[NSApp currentEvent]
forView:self];
} }
} }
...@@ -84,4 +89,16 @@ ...@@ -84,4 +89,16 @@
[self setNeedsDisplay:YES]; [self setNeedsDisplay:YES];
} }
- (BOOL)showingContextMenu
{
return contextMenu_.get() != nil;
}
- (void)viewWillMoveToWindow:(NSWindow *)newWindow {
// If the DownloadItemButton's context menu is still visible, dismiss it.
if (!newWindow) {
[contextMenu_.get() cancelTrackingWithoutAnimation];
}
}
@end @end
// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -370,13 +370,7 @@ class DownloadShelfContextMenuMac : public DownloadShelfContextMenu { ...@@ -370,13 +370,7 @@ class DownloadShelfContextMenuMac : public DownloadShelfContextMenu {
} }
- (IBAction)showContextMenu:(id)sender { - (IBAction)showContextMenu:(id)sender {
base::scoped_nsobject<DownloadShelfContextMenuController> menuController( [progressView_ showContextMenu];
[[DownloadShelfContextMenuController alloc]
initWithItemController:self
withDelegate:nil]);
[NSMenu popUpContextMenu:[menuController menu]
withEvent:[NSApp currentEvent]
forView:[self view]];
} }
@end @end
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "chrome/browser/ui/cocoa/cocoa_profile_test.h" #include "chrome/browser/ui/cocoa/cocoa_profile_test.h"
#import "chrome/browser/ui/cocoa/download/download_item_button.h"
#import "chrome/browser/ui/cocoa/download/download_item_controller.h" #import "chrome/browser/ui/cocoa/download/download_item_controller.h"
#import "chrome/browser/ui/cocoa/download/download_shelf_controller.h" #import "chrome/browser/ui/cocoa/download/download_shelf_controller.h"
#include "content/public/test/mock_download_item.h" #include "content/public/test/mock_download_item.h"
...@@ -44,6 +45,13 @@ using ::testing::ReturnRefOfCopy; ...@@ -44,6 +45,13 @@ using ::testing::ReturnRefOfCopy;
- (void)awakeFromNib; - (void)awakeFromNib;
@end @end
@interface DownloadItemButton(DownloadItemButtonTest)
- (BOOL)showingContextMenu;
@end
@implementation DownloadItemControllerWithInitCallback @implementation DownloadItemControllerWithInitCallback
- (id)initWithDownload:(content::DownloadItem*)downloadItem - (id)initWithDownload:(content::DownloadItem*)downloadItem
...@@ -179,4 +187,31 @@ TEST_F(DownloadItemControllerTest, NormalDownloadBecomesDangerous) { ...@@ -179,4 +187,31 @@ TEST_F(DownloadItemControllerTest, NormalDownloadBecomesDangerous) {
[(id)shelf_ verify]; [(id)shelf_ verify];
} }
TEST_F(DownloadItemControllerTest, DismissesContextMenuWhenRemovedFromWindow) {
base::scoped_nsobject<DownloadItemController> item(CreateItemController());
DownloadItemButton* downloadItemButton = nil;
for (NSView *nextSubview in [[item view] subviews]) {
if ([nextSubview isKindOfClass:[DownloadItemButton class]]) {
downloadItemButton = static_cast<DownloadItemButton *>(nextSubview);
break;
}
}
// showContextMenu: calls [NSMenu popUpContextMenu:...], which blocks until
// the menu is dismissed. Use a block to cancel the menu while waiting for
// [NSMenu popUpContextMenu:...] to return (this block will execute on the
// main thread, on the next pass through the run loop).
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
EXPECT_TRUE([downloadItemButton showingContextMenu]);
// Simulate the item's removal from the shelf. Ideally we would call an
// actual shelf removal method like [item remove] but the shelf and
// download item are mock objects.
[downloadItemButton removeFromSuperview];
}];
// The unit test will stop here until the block causes the DownloadItemButton
// to dismiss the menu.
[item showContextMenu:nil];
}
} // namespace } // namespace
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment