Chromium Code Reviews| Index: content/browser/renderer_host/render_widget_host_view_mac.mm |
| diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm |
| index 724884b8dac50d8a7a6cfd3995adf953bcce0495..0088f60d60abccbb7940bdb60c831b1948d716e7 100644 |
| --- a/content/browser/renderer_host/render_widget_host_view_mac.mm |
| +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm |
| @@ -40,6 +40,7 @@ |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/native_web_keyboard_event.h" |
| #import "content/public/browser/render_widget_host_view_mac_delegate.h" |
| +#include "content/public/browser/web_contents_view_delegate.h" |
| #include "skia/ext/platform_canvas.h" |
| #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" |
| #include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h" |
| @@ -47,6 +48,7 @@ |
| #include "third_party/WebKit/Source/WebKit/chromium/public/mac/WebScreenInfoFactory.h" |
| #import "third_party/mozilla/ComplexTextInputPanel.h" |
| #include "third_party/skia/include/core/SkColor.h" |
| +#import "ui/base/cocoa/event_hook_application.h" |
| #import "ui/base/cocoa/fullscreen_window_manager.h" |
| #import "ui/base/cocoa/underlay_opengl_hosting_window.h" |
| #include "ui/base/keycodes/keyboard_codes.h" |
| @@ -137,7 +139,6 @@ static float ScaleFactor(NSView* view) { |
| - (void)scrollOffsetPinnedToLeft:(BOOL)left toRight:(BOOL)right; |
| - (void)setHasHorizontalScrollbar:(BOOL)has_horizontal_scrollbar; |
| - (void)keyEvent:(NSEvent*)theEvent wasKeyEquivalent:(BOOL)equiv; |
| -- (void)cancelChildPopups; |
| - (void)windowDidChangeBackingProperties:(NSNotification*)notification; |
| - (void)windowChangedGlobalFrame:(NSNotification*)notification; |
| - (void)checkForPluginImeCancellation; |
| @@ -167,6 +168,74 @@ static const short kIOHIDEventTypeScroll = 6; |
| @end |
| +@interface RenderWidgetPopupWindow : NSWindow<CrEventHookProtocol> |
| +@end |
| + |
| +@implementation RenderWidgetPopupWindow |
| + |
| +- (id)initWithContentRect:(NSRect)contentRect |
| + styleMask:(NSUInteger)windowStyle |
| + backing:(NSBackingStoreType)bufferingType |
| + defer:(BOOL)deferCreation { |
| + if (self = [super initWithContentRect:contentRect |
| + styleMask:windowStyle |
| + backing:bufferingType |
| + defer:deferCreation]) { |
| + [self setOpaque:NO]; |
| + [self setBackgroundColor:[NSColor clearColor]]; |
| + [self startObservingClicks]; |
| + } |
| + return self; |
| +} |
| + |
| +- (void)close { |
| + [self stopObservingClicks]; |
| + [super close]; |
| +} |
| + |
| +// Gets called for all events in application. Watching for a click outside the |
| +// window so we can close. |
| +- (void)hookForEvent:(NSEvent*)theEvent { |
| + if ([theEvent window] == self) |
| + return; |
| + NSEventType eventType = [theEvent type]; |
| + if (eventType == NSLeftMouseDown || eventType == NSRightMouseDown) |
| + [self close]; |
| +} |
|
Avi (use Gerrit)
2012/12/13 16:04:01
You could fix WebKit to close popups on scroll eve
keishi
2012/12/14 02:23:27
Hiding popups on scroll wheel event is a webview s
|
| + |
| +// Gets called when the menubar is clicked. |
| +// Needed because the hookForEvent method doesn't see the click on the menubar. |
| +- (void)begunTracking:(NSNotification*)notification { |
| + [self close]; |
| +} |
| + |
| +// Install the callback. |
| +- (void)startObservingClicks { |
| + CrEventHookApplication* app = static_cast<CrEventHookApplication*>( |
| + [CrEventHookApplication sharedApplication]); |
| + [app addEventHook:self]; |
| + |
| + NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; |
| + [nc addObserver:self |
| + selector:@selector(begunTracking:) |
| + name:NSMenuDidBeginTrackingNotification |
| + object:[NSApp mainMenu]]; |
| +} |
| + |
| +// Remove the callback. |
| +- (void)stopObservingClicks { |
| + CrEventHookApplication* app = static_cast<CrEventHookApplication*>( |
| + [CrEventHookApplication sharedApplication]); |
| + [app removeEventHook:self]; |
| + |
| + NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; |
| + [nc removeObserver:self |
| + name:NSMenuDidBeginTrackingNotification |
| + object:[NSApp mainMenu]]; |
| +} |
| + |
| +@end |
| + |
| namespace { |
| // Maximum number of characters we allow in a tooltip. |
| @@ -329,27 +398,34 @@ void RenderWidgetHostViewMac::InitAsChild( |
| } |
| void RenderWidgetHostViewMac::InitAsPopup( |
| - RenderWidgetHostView* parent_host_view, |
| - const gfx::Rect& pos) { |
| + RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) { |
| bool activatable = popup_type_ == WebKit::WebPopupTypeNone; |
| [cocoa_view_ setCloseOnDeactivate:YES]; |
| [cocoa_view_ setCanBeKeyView:activatable ? YES : NO]; |
| - [parent_host_view->GetNativeView() addSubview:cocoa_view_]; |
| NSPoint origin_global = NSPointFromCGPoint(pos.origin().ToCGPoint()); |
| if ([[NSScreen screens] count] > 0) { |
| origin_global.y = [[[NSScreen screens] objectAtIndex:0] frame].size.height - |
| pos.height() - origin_global.y; |
| } |
| - NSPoint origin_window = |
| - [[cocoa_view_ window] convertScreenToBase:origin_global]; |
| - NSPoint origin_view = |
| - [cocoa_view_ convertPoint:origin_window fromView:nil]; |
| - NSRect initial_frame = NSMakeRect(origin_view.x, |
| - origin_view.y, |
| - pos.width(), |
| - pos.height()); |
| - [cocoa_view_ setFrame:initial_frame]; |
| + |
| + popup_window_.reset([[RenderWidgetPopupWindow alloc] |
| + initWithContentRect:NSMakeRect(origin_global.x, origin_global.y, |
| + pos.width(), pos.height()) |
| + styleMask:NSBorderlessWindowMask |
| + backing:NSBackingStoreBuffered |
| + defer:NO]); |
| + [popup_window_ setLevel:NSPopUpMenuWindowLevel]; |
| + [popup_window_ setReleasedWhenClosed:NO]; |
| + [popup_window_ makeKeyAndOrderFront:nil]; |
| + [[popup_window_ contentView] addSubview:cocoa_view_]; |
| + [cocoa_view_ setFrame:[[popup_window_ contentView] bounds]]; |
| + [cocoa_view_ setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; |
| + [[NSNotificationCenter defaultCenter] |
| + addObserver:cocoa_view_ |
| + selector:@selector(popupWindowWillClose:) |
| + name:NSWindowWillCloseNotification |
| + object:popup_window_]; |
| } |
| // This function creates the fullscreen window and hides the dock and menubar if |
| @@ -458,24 +534,17 @@ void RenderWidgetHostViewMac::SetBounds(const gfx::Rect& rect) { |
| // The position of |rect| is screen coordinate system and we have to |
| // consider Cocoa coordinate system is upside-down and also multi-screen. |
| NSPoint origin_global = NSPointFromCGPoint(rect.origin().ToCGPoint()); |
| + NSSize size = NSMakeSize(rect.width(), rect.height()); |
| + size = [cocoa_view_ convertSize:size toView:nil]; |
| if ([[NSScreen screens] count] > 0) { |
| - NSSize size = NSMakeSize(rect.width(), rect.height()); |
| - size = [cocoa_view_ convertSize:size toView:nil]; |
| NSScreen* screen = |
| static_cast<NSScreen*>([[NSScreen screens] objectAtIndex:0]); |
| origin_global.y = |
| NSHeight([screen frame]) - size.height - origin_global.y; |
| } |
| - |
| - // Then |origin_global| is converted to client coordinate system. |
| - DCHECK([cocoa_view_ window]); |
| - NSPoint origin_window = |
| - [[cocoa_view_ window] convertScreenToBase:origin_global]; |
| - NSPoint origin_view = |
| - [[cocoa_view_ superview] convertPoint:origin_window fromView:nil]; |
| - NSRect frame = NSMakeRect(origin_view.x, origin_view.y, |
| - rect.width(), rect.height()); |
| - [cocoa_view_ setFrame:frame]; |
| + [popup_window_ setFrame:NSMakeRect(origin_global.x, origin_global.y, |
| + size.width, size.height) |
| + display:YES]; |
| } else { |
| DCHECK([[cocoa_view_ superview] isKindOfClass:[BaseView class]]); |
| BaseView* superview = static_cast<BaseView*>([cocoa_view_ superview]); |
| @@ -725,11 +794,19 @@ void RenderWidgetHostViewMac::Destroy() { |
| } |
| } |
| + [[NSNotificationCenter defaultCenter] |
| + removeObserver:cocoa_view_ |
| + name:NSWindowWillCloseNotification |
| + object:popup_window_]; |
| + |
| // We've been told to destroy. |
| [cocoa_view_ retain]; |
| [cocoa_view_ removeFromSuperview]; |
| [cocoa_view_ autorelease]; |
|
Avi (use Gerrit)
2012/12/13 16:04:01
Is it necessary to remove the view from the window
keishi
2012/12/14 02:23:27
I think cocoa_view_ is used for non popup widgets
Avi (use Gerrit)
2012/12/14 04:08:36
Ah, yes, this is the general case Destroy.
|
| + [popup_window_ close]; |
| + popup_window_.autorelease(); |
| + |
| [fullscreen_window_manager_ exitFullscreenMode]; |
| fullscreen_window_manager_.reset(); |
| [pepper_fullscreen_window_ close]; |
| @@ -2102,10 +2179,6 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) { |
| } |
| - (void)scrollWheel:(NSEvent*)theEvent { |
| - // Cancel popups before calling the delegate because even if the delegate eats |
| - // the event, it's still an explicit user action outside the popup. |
| - [self cancelChildPopups]; |
| - |
| if (delegate_ && [delegate_ respondsToSelector:@selector(handleEvent:)]) { |
| BOOL handled = [delegate_ handleEvent:theEvent]; |
| if (handled) |
| @@ -2118,23 +2191,6 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) { |
| renderWidgetHostView_->render_widget_host_->ForwardWheelEvent(event); |
| } |
| -// See the comment in RenderWidgetHostViewMac::Destroy() about cancellation |
| -// events. On the Mac we must kill popups on outside events, thus this lovely |
| -// case of filicide caused by events on parent views. |
| -- (void)cancelChildPopups { |
| - // If this view can be the key view, it is not a popup. Therefore, if it has |
| - // any children, they are popups that need to be canceled. |
| - if (canBeKeyView_) { |
| - for (NSView* subview in [self subviews]) { |
| - if (![subview isKindOfClass:[RenderWidgetHostViewCocoa class]]) |
| - continue; // Skip plugin views. |
| - |
| - [static_cast<RenderWidgetHostViewCocoa*>(subview) |
| - renderWidgetHostViewMac]->KillSelf(); |
| - } |
| - } |
| -} |
| - |
| - (void)viewWillMoveToWindow:(NSWindow*)newWindow { |
| // We're messing with the window, so do this to ensure no flashes. This one |
| // prevents a flash when the current tab is closed. |
| @@ -3353,6 +3409,10 @@ extern NSString *NSTextInputReplacementRangeAttributeName; |
| [[self window] invalidateCursorRectsForView:self]; |
| } |
| +- (void)popupWindowWillClose:(NSNotification *)notification { |
| + renderWidgetHostView_->KillSelf(); |
| +} |
| + |
| @end |
| // |