diff options
4 files changed, 94 insertions, 8 deletions
diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.h b/chrome/browser/renderer_host/render_widget_host_view_mac.h index fef0336..0a0dd3d 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_mac.h +++ b/chrome/browser/renderer_host/render_widget_host_view_mac.h @@ -7,6 +7,7 @@ #import <Cocoa/Cocoa.h> +#include "base/task.h" #include "base/time.h" #include "chrome/browser/cocoa/base_view.h" #include "chrome/browser/renderer_host/render_widget_host_view.h" @@ -22,8 +23,13 @@ class RenderWidgetHostViewMac; @interface RenderWidgetHostViewCocoa : BaseView { @private RenderWidgetHostViewMac* renderWidgetHostView_; + BOOL canBeKeyView_; + BOOL closeOnDeactivate_; } +- (void)setCanBeKeyView:(BOOL)can; +- (void)setCloseOnDeactivate:(BOOL)b; + @end /////////////////////////////////////////////////////////////////////////////// @@ -53,7 +59,7 @@ class RenderWidgetHostViewMac : public RenderWidgetHostView { base::TimeTicks& whiteout_start_time() { return whiteout_start_time_; } - gfx::NativeView native_view() const { return cocoa_view_; } + RenderWidgetHostViewCocoa* native_view() const { return cocoa_view_; } // Implementation of RenderWidgetHostView: virtual void InitAsPopup(RenderWidgetHostView* parent_host_view, @@ -82,6 +88,8 @@ class RenderWidgetHostViewMac : public RenderWidgetHostView { virtual void SetTooltipText(const std::wstring& tooltip_text); virtual BackingStore* AllocBackingStore(const gfx::Size& size); + void KillSelf(); + private: // Shuts down the render_widget_host_. This is a separate function so we can // invoke it from the message loop. @@ -109,6 +117,9 @@ class RenderWidgetHostViewMac : public RenderWidgetHostView { // The text to be shown in the tooltip, supplied by the renderer. std::wstring tooltip_text_; + // Factory used to safely scope delayed calls to ShutdownHost(). + ScopedRunnableMethodFactory<RenderWidgetHostViewMac> shutdown_factory_; + // The time at which this view started displaying white pixels as a result of // not having anything to paint (empty backing store from renderer). This // value returns true for is_null() if we are not recording whiteout times. diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.mm b/chrome/browser/renderer_host/render_widget_host_view_mac.mm index 0111baf..f726958 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_mac.mm +++ b/chrome/browser/renderer_host/render_widget_host_view_mac.mm @@ -39,7 +39,8 @@ RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget( RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) : render_widget_host_(widget), is_loading_(false), - is_hidden_(false) { + is_hidden_(false), + shutdown_factory_(this) { cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc] initWithRenderWidgetHostViewMac:this] autorelease]; render_widget_host_->set_view(this); @@ -54,7 +55,26 @@ RenderWidgetHostViewMac::~RenderWidgetHostViewMac() { void RenderWidgetHostViewMac::InitAsPopup( RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) { - NOTIMPLEMENTED(); + [parent_host_view->GetPluginNativeView() addSubview:cocoa_view_]; + [cocoa_view_ setCloseOnDeactivate:YES]; + [cocoa_view_ setCanBeKeyView:activatable_ ? YES : NO]; + + // TODO(avi):Why the hell are these screen coordinates? The Windows code calls + // ::MoveWindow() which indicates they should be local, but when running it I + // get global ones instead! + + NSPoint global_origin = NSPointFromCGPoint(pos.origin().ToCGPoint()); + global_origin.y = [[[cocoa_view_ window] screen] frame].size.height - + pos.height() - global_origin.y; + NSPoint window_origin = + [[cocoa_view_ window] convertScreenToBase:global_origin]; + NSPoint view_origin = + [cocoa_view_ convertPoint:window_origin fromView:nil]; + NSRect initial_frame = NSMakeRect(view_origin.x, + view_origin.y, + pos.width(), + pos.height()); + [cocoa_view_ setFrame:initial_frame]; } RenderWidgetHost* RenderWidgetHostViewMac::GetRenderWidgetHost() const { @@ -97,9 +117,7 @@ void RenderWidgetHostViewMac::SetSize(const gfx::Size& size) { } gfx::NativeView RenderWidgetHostViewMac::GetPluginNativeView() { - // All plugin stuff is TBD. TODO(avi,awalker): fill in - // http://crbug.com/8192 - return nil; + return native_view(); } void RenderWidgetHostViewMac::MovePluginWindows( @@ -227,7 +245,17 @@ BackingStore* RenderWidgetHostViewMac::AllocBackingStore( return new BackingStore(size); } +void RenderWidgetHostViewMac::KillSelf() { + if (shutdown_factory_.empty()) { + [cocoa_view_ setHidden:YES]; + MessageLoop::current()->PostTask(FROM_HERE, + shutdown_factory_.NewRunnableMethod( + &RenderWidgetHostViewMac::ShutdownHost)); + } +} + void RenderWidgetHostViewMac::ShutdownHost() { + shutdown_factory_.RevokeAll(); render_widget_host_->Shutdown(); // Do not touch any members at this point, |this| has been deleted. } @@ -241,6 +269,8 @@ void RenderWidgetHostViewMac::ShutdownHost() { self = [super initWithFrame:NSZeroRect]; if (self != nil) { renderWidgetHostView_ = r; + canBeKeyView_ = YES; + closeOnDeactivate_ = NO; } return self; } @@ -251,12 +281,23 @@ void RenderWidgetHostViewMac::ShutdownHost() { [super dealloc]; } +- (void)setCanBeKeyView:(BOOL)can { + canBeKeyView_ = can; +} + +- (void)setCloseOnDeactivate:(BOOL)b { + closeOnDeactivate_ = b; +} + - (void)mouseEvent:(NSEvent *)theEvent { WebMouseEvent event(theEvent, self); renderWidgetHostView_->render_widget_host()->ForwardMouseEvent(event); } - (void)keyEvent:(NSEvent *)theEvent { + // TODO(avi): Possibly kill self? See RenderWidgetHostViewWin::OnKeyEvent and + // http://b/issue?id=1192881 . + NativeWebKeyboardEvent event(theEvent); renderWidgetHostView_->render_widget_host()->ForwardKeyboardEvent(event); } @@ -339,11 +380,11 @@ void RenderWidgetHostViewMac::ShutdownHost() { } - (BOOL)canBecomeKeyView { - return YES; // TODO(avi): be smarter + return canBeKeyView_; } - (BOOL)acceptsFirstResponder { - return YES; // TODO(avi): be smarter + return canBeKeyView_; } - (BOOL)becomeFirstResponder { @@ -353,6 +394,9 @@ void RenderWidgetHostViewMac::ShutdownHost() { } - (BOOL)resignFirstResponder { + if (closeOnDeactivate_) + renderWidgetHostView_->KillSelf(); + renderWidgetHostView_->render_widget_host()->Blur(); return YES; diff --git a/chrome/browser/tab_contents/web_contents_view_mac.h b/chrome/browser/tab_contents/web_contents_view_mac.h index 00ea654..4257274 100644 --- a/chrome/browser/tab_contents/web_contents_view_mac.h +++ b/chrome/browser/tab_contents/web_contents_view_mac.h @@ -65,6 +65,10 @@ class WebContentsViewMac : public WebContentsView, WindowOpenDisposition disposition, const gfx::Rect& initial_pos, bool user_gesture); + virtual RenderWidgetHostView* CreateNewWidgetInternal(int route_id, + bool activatable); + virtual void ShowCreatedWidgetInternal(RenderWidgetHostView* widget_host_view, + const gfx::Rect& initial_pos); virtual void ShowContextMenu(const ContextMenuParams& params); virtual void StartDragging(const WebDropData& drop_data); virtual void UpdateDragCursor(bool is_drop_target); diff --git a/chrome/browser/tab_contents/web_contents_view_mac.mm b/chrome/browser/tab_contents/web_contents_view_mac.mm index d55af95..1cab6e6 100644 --- a/chrome/browser/tab_contents/web_contents_view_mac.mm +++ b/chrome/browser/tab_contents/web_contents_view_mac.mm @@ -217,6 +217,33 @@ void WebContentsViewMac::ShowCreatedWindowInternal( user_gesture); } +RenderWidgetHostView* WebContentsViewMac::CreateNewWidgetInternal( + int route_id, + bool activatable) { + // A RenderWidgetHostViewMac has lifetime scoped to the view. We'll retain it + // to allow it to survive the trip without being hosted. + RenderWidgetHostView* widget_view = + WebContentsView::CreateNewWidgetInternal(route_id, activatable); + RenderWidgetHostViewMac* widget_view_mac = + static_cast<RenderWidgetHostViewMac*>(widget_view); + [widget_view_mac->native_view() retain]; + + return widget_view; +} + +void WebContentsViewMac::ShowCreatedWidgetInternal( + RenderWidgetHostView* widget_host_view, + const gfx::Rect& initial_pos) { + WebContentsView::ShowCreatedWidgetInternal(widget_host_view, initial_pos); + + // A RenderWidgetHostViewMac has lifetime scoped to the view. Now that it's + // properly embedded (or purposefully ignored) we can release the retain we + // took in CreateNewWidgetInternal(). + RenderWidgetHostViewMac* widget_view_mac = + static_cast<RenderWidgetHostViewMac*>(widget_host_view); + [widget_view_mac->native_view() release]; +} + void WebContentsViewMac::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { |