Index: chrome/browser/ui/cocoa/web_intent_picker_cocoa.mm |
diff --git a/chrome/browser/ui/cocoa/web_intent_picker_cocoa.mm b/chrome/browser/ui/cocoa/web_intent_picker_cocoa.mm |
index 2aab61a1e29ede1fa76753d8c9402f6260111456..b6a3a4f6a878d929ec9c3b83efc243ea07dcd60b 100644 |
--- a/chrome/browser/ui/cocoa/web_intent_picker_cocoa.mm |
+++ b/chrome/browser/ui/cocoa/web_intent_picker_cocoa.mm |
@@ -12,8 +12,9 @@ |
#include "chrome/browser/ui/browser.h" |
#include "chrome/browser/ui/browser_window.h" |
#import "chrome/browser/ui/cocoa/browser_window_controller.h" |
+#include "chrome/browser/ui/cocoa/constrained_window_mac.h" |
#import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h" |
-#import "chrome/browser/ui/cocoa/web_intent_bubble_controller.h" |
+#import "chrome/browser/ui/cocoa/web_intent_sheet_controller.h" |
#include "chrome/browser/ui/intents/web_intent_inline_disposition_delegate.h" |
#include "chrome/browser/ui/intents/web_intent_picker.h" |
#include "chrome/browser/ui/intents/web_intent_picker_delegate.h" |
@@ -24,6 +25,49 @@ |
using content::WebContents; |
+namespace { |
+ |
+// Since any delegates for constrained windows are tasked with deleting |
+// themselves, and the WebIntentPicker needs to live longer than the |
+// constrained window, we need this forwarding class. |
+class ConstrainedPickerSheetDelegate : |
+ public ConstrainedWindowMacDelegateCustomSheet { |
+ public: |
+ ConstrainedPickerSheetDelegate( |
+ WebIntentPickerCocoa* picker, |
+ WebIntentPickerSheetController* sheet_controller); |
+ virtual ~ConstrainedPickerSheetDelegate() {} |
+ |
+ // ConstrainedWindowMacDelegateCustomSheet interface |
+ virtual void DeleteDelegate() OVERRIDE; |
+ |
+ private: |
+ WebIntentPickerCocoa* picker_; // Weak reference to picker |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ConstrainedPickerSheetDelegate); |
+}; |
+ |
+ConstrainedPickerSheetDelegate::ConstrainedPickerSheetDelegate( |
+ WebIntentPickerCocoa* picker, |
+ WebIntentPickerSheetController* sheet_controller) |
+ : picker_(picker) { |
+ init([sheet_controller window], sheet_controller, |
+ @selector(sheetDidEnd:returnCode:contextInfo:)); |
+ set_sheet([sheet_controller window]); |
Nico
2012/03/06 22:56:26
init() already sets the sheet, so this line should
groby-ooo-7-16
2012/03/07 00:50:42
Done.
|
+} |
+ |
+void ConstrainedPickerSheetDelegate::DeleteDelegate() { |
+ if (is_sheet_open()) |
+ [NSApp endSheet:sheet()]; |
+ |
+ if (picker_) |
+ picker_->OnCancelled(); |
+ |
+ delete this; |
+} |
+ |
+} // namespace |
+ |
// static |
WebIntentPicker* WebIntentPicker::Create(Browser* browser, |
TabContentsWrapper* wrapper, |
@@ -36,39 +80,32 @@ WebIntentPickerCocoa::WebIntentPickerCocoa() |
: delegate_(NULL), |
model_(NULL), |
browser_(NULL), |
- controller_(nil), |
- weak_ptr_factory_(this), |
+ sheet_controller_(nil), |
service_invoked(false) { |
} |
- |
WebIntentPickerCocoa::WebIntentPickerCocoa(Browser* browser, |
TabContentsWrapper* wrapper, |
WebIntentPickerDelegate* delegate, |
WebIntentPickerModel* model) |
- : delegate_(delegate), |
- model_(model), |
- browser_(browser), |
- controller_(nil), |
- weak_ptr_factory_(this), |
- service_invoked(false) { |
+ : delegate_(delegate), |
+ model_(model), |
+ browser_(browser), |
+ sheet_controller_(nil), |
+ service_invoked(false) { |
model_->set_observer(this); |
- DCHECK(browser); |
DCHECK(delegate); |
- NSWindow* parentWindow = browser->window()->GetNativeHandle(); |
- |
- // Compute the anchor point, relative to location bar. |
- BrowserWindowController* controller = [parentWindow windowController]; |
- LocationBarViewMac* locationBar = [controller locationBarBridge]; |
- NSPoint anchor = locationBar->GetPageInfoBubblePoint(); |
- anchor = [browser->window()->GetNativeHandle() convertBaseToScreen:anchor]; |
- |
- // The controller is deallocated when the window is closed, so no need to |
- // worry about it here. |
- [[WebIntentBubbleController alloc] initWithPicker:this |
- parentWindow:parentWindow |
- anchoredAt:anchor]; |
+ DCHECK(wrapper); |
+ |
+ sheet_controller_ = [ |
+ [WebIntentPickerSheetController alloc] initWithPicker:this]; |
+ |
+ // Deleted when ConstrainedPickerSheetDelegate::DeleteDelegate() runs. |
+ ConstrainedPickerSheetDelegate* constrained_delegate = |
+ new ConstrainedPickerSheetDelegate(this, sheet_controller_); |
+ |
+ window_ = new ConstrainedWindowMac(wrapper, constrained_delegate); |
} |
WebIntentPickerCocoa::~WebIntentPickerCocoa() { |
@@ -76,50 +113,38 @@ WebIntentPickerCocoa::~WebIntentPickerCocoa() { |
model_->set_observer(NULL); |
} |
+void WebIntentPickerCocoa::OnSheetDidEnd(NSWindow* sheet) { |
+ [sheet orderOut:sheet_controller_]; |
+ if (window_) |
+ window_->CloseConstrainedWindow(); |
+} |
+ |
void WebIntentPickerCocoa::Close() { |
- DCHECK(controller_); |
- [controller_ close]; |
+ DCHECK(sheet_controller_); |
+ [sheet_controller_ closeSheet]; |
+ |
if (inline_disposition_tab_contents_.get()) |
inline_disposition_tab_contents_->web_contents()->OnCloseStarted(); |
} |
-void WebIntentPickerCocoa::PerformDelayedLayout() { |
- // Check to see if a layout has already been scheduled. |
- if (weak_ptr_factory_.HasWeakPtrs()) |
- return; |
- |
- // Delay performing layout by a second so that all the animations from |
- // InfoBubbleWindow and origin updates from BaseBubbleController finish, so |
- // that we don't all race trying to change the frame's origin. |
- // |
- // Using MessageLoop is superior here to |-performSelector:| because it will |
- // not retain its target; if the child outlives its parent, zombies get left |
- // behind (http://crbug.com/59619). This will cancel the scheduled task if |
- // the controller get destroyed before the message |
- // can be delivered. |
- MessageLoop::current()->PostDelayedTask(FROM_HERE, |
- base::Bind(&WebIntentPickerCocoa::PerformLayout, |
- weak_ptr_factory_.GetWeakPtr()), |
- 100 /* milliseconds */); |
-} |
- |
void WebIntentPickerCocoa::PerformLayout() { |
- DCHECK(controller_); |
+ DCHECK(sheet_controller_); |
// If the window is animating closed when this is called, the |
// animation could be holding the last reference to |controller_| |
// (and thus |this|). Pin it until the task is completed. |
- scoped_nsobject<WebIntentBubbleController> keep_alive([controller_ retain]); |
- [controller_ performLayoutWithModel:model_]; |
+ scoped_nsobject<WebIntentPickerSheetController> |
+ keep_alive([sheet_controller_ retain]); |
+ [sheet_controller_ performLayoutWithModel:model_]; |
} |
void WebIntentPickerCocoa::OnModelChanged(WebIntentPickerModel* model) { |
- PerformDelayedLayout(); |
+ PerformLayout(); |
} |
void WebIntentPickerCocoa::OnFaviconChanged(WebIntentPickerModel* model, |
size_t index) { |
// We don't handle individual icon changes - just redo the whole model. |
- PerformDelayedLayout(); |
+ PerformLayout(); |
} |
void WebIntentPickerCocoa::OnExtensionIconChanged( |
@@ -129,6 +154,7 @@ void WebIntentPickerCocoa::OnExtensionIconChanged( |
} |
void WebIntentPickerCocoa::OnInlineDisposition(WebIntentPickerModel* model) { |
+ DCHECK(browser_); |
const WebIntentPickerModel::InstalledService& installed_service = |
model->GetInstalledServiceAt(model->inline_disposition_index()); |
@@ -148,9 +174,9 @@ void WebIntentPickerCocoa::OnInlineDisposition(WebIntentPickerModel* model) { |
content::PAGE_TRANSITION_START_PAGE, |
std::string()); |
- [controller_ setInlineDispositionTabContents: |
+ [sheet_controller_ setInlineDispositionTabContents: |
inline_disposition_tab_contents_.get()]; |
- PerformDelayedLayout(); |
+ PerformLayout(); |
} |
void WebIntentPickerCocoa::OnCancelled() { |
@@ -169,7 +195,3 @@ void WebIntentPickerCocoa::OnServiceChosen(size_t index) { |
delegate_->OnServiceChosen(index, installed_service.disposition); |
} |
-void WebIntentPickerCocoa::set_controller( |
- WebIntentBubbleController* controller) { |
- controller_ = controller; |
-} |