diff options
author | torne@chromium.org <torne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-28 14:50:22 +0000 |
---|---|---|
committer | torne@chromium.org <torne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-28 14:50:22 +0000 |
commit | 66db7bc0efc03109bddc3b31f7944d7fe492f643 (patch) | |
tree | 5971098d7302f70a93e9c670ceb845e6bc6d8364 /content | |
parent | 5bfd1e78ca6b5f45a15b1bff9316b2d981389fac (diff) | |
download | chromium_src-66db7bc0efc03109bddc3b31f7944d7fe492f643.zip chromium_src-66db7bc0efc03109bddc3b31f7944d7fe492f643.tar.gz chromium_src-66db7bc0efc03109bddc3b31f7944d7fe492f643.tar.bz2 |
Revert 103113 - Move RenderWidgetHostViewMac to content.
BUG=95573
TEST=no visible change
Review URL: http://codereview.chromium.org/8052026
TBR=avi@chromium.org
Review URL: http://codereview.chromium.org/8066010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@103117 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
12 files changed, 0 insertions, 4331 deletions
diff --git a/content/DEPS b/content/DEPS index 8742fd4..51bda9a 100644 --- a/content/DEPS +++ b/content/DEPS @@ -34,9 +34,7 @@ include_rules = [ "-v8", "-tools", - # Allow inclusion of third-party code: "+third_party/gpsd", - "+third_party/mozilla", "+third_party/npapi/bindings", "+third_party/sqlite", "+third_party/tcmalloc", diff --git a/content/browser/renderer_host/accelerated_plugin_view_mac.h b/content/browser/renderer_host/accelerated_plugin_view_mac.h deleted file mode 100644 index f404c52..0000000 --- a/content/browser/renderer_host/accelerated_plugin_view_mac.h +++ /dev/null @@ -1,58 +0,0 @@ -// 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. - -#ifndef CONTENT_BROWSER_RENDERER_HOST_ACCELERATED_PLUGIN_VIEW_MAC_H -#define CONTENT_BROWSER_RENDERER_HOST_ACCELERATED_PLUGIN_VIEW_MAC_H - -#import <Cocoa/Cocoa.h> -#include <QuartzCore/QuartzCore.h> - -#include "base/memory/scoped_nsobject.h" -#include "ui/gfx/native_widget_types.h" - -class RenderWidgetHostViewMac; - -// Informal protocol implemented by windows that need to be informed explicitly -// about underlay surfaces. -@interface NSObject (UnderlayableSurface) -- (void)underlaySurfaceAdded; -- (void)underlaySurfaceRemoved; -@end - -// This subclass of NSView hosts the output of accelerated plugins on -// the page. -@interface AcceleratedPluginView : NSView { - scoped_nsobject<NSOpenGLPixelFormat> glPixelFormat_; - CGLPixelFormatObj cglPixelFormat_; // weak, backed by |glPixelFormat_|. - scoped_nsobject<NSOpenGLContext> glContext_; - CGLContextObj cglContext_; // weak, backed by |glContext_|. - - RenderWidgetHostViewMac* renderWidgetHostView_; // weak - gfx::PluginWindowHandle pluginHandle_; // weak - - // Rects that should show web content rather than plugin content. - scoped_nsobject<NSArray> cutoutRects_; -} - -- (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r - pluginHandle:(gfx::PluginWindowHandle)pluginHandle; - -// Sets the list of rectangles that should show the web page, rather than the -// accelerated plugin. This is used to simulate the iframe-based trick that web -// pages have long used to show web content above windowed plugins on Windows -// and Linux. -- (void)setCutoutRects:(NSArray*)cutout_rects; - -// NSViews autorelease subviews when they die. The RWHVMac gets destroyed when -// RHWVCocoa gets dealloc'd, which means the AcceleratedPluginView child views -// can be around a little longer than the RWHVMac. This is called when the -// RWHVMac is about to be deleted (but it's still valid while this method runs). -- (void)onRenderWidgetHostViewGone; - -// Draw the view from the UI thread. -- (void)drawView; - -@end - -#endif // CONTENT_BROWSER_RENDERER_HOST_ACCELERATED_PLUGIN_VIEW_MAC_H diff --git a/content/browser/renderer_host/accelerated_plugin_view_mac.mm b/content/browser/renderer_host/accelerated_plugin_view_mac.mm deleted file mode 100644 index 9bcc433..0000000 --- a/content/browser/renderer_host/accelerated_plugin_view_mac.mm +++ /dev/null @@ -1,247 +0,0 @@ -// 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 "content/browser/renderer_host/accelerated_plugin_view_mac.h" - -#include "base/command_line.h" -#include "base/debug/trace_event.h" -#include "content/browser/browser_thread.h" -#include "content/browser/renderer_host/render_widget_host_view_mac.h" -#include "ui/gfx/gl/gl_switches.h" -#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" - -@implementation AcceleratedPluginView - -- (void)drawView { - CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - TRACE_EVENT0("browser", "AcceleratedPluginViewMac::drawView"); - - if (renderWidgetHostView_) { - // TODO(thakis): Pixel or view coordinates for size? - renderWidgetHostView_->DrawAcceleratedSurfaceInstance( - cglContext_, pluginHandle_, [super frame].size); - } - - CGLFlushDrawable(cglContext_); - CGLSetCurrentContext(0); -} - -- (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r - pluginHandle:(gfx::PluginWindowHandle)pluginHandle { - if ((self = [super initWithFrame:NSZeroRect])) { - renderWidgetHostView_ = r; - pluginHandle_ = pluginHandle; - - [self setAutoresizingMask:NSViewMaxXMargin|NSViewMinYMargin]; - - NSOpenGLPixelFormatAttribute attributes[] = - { NSOpenGLPFAAccelerated, NSOpenGLPFADoubleBuffer, 0}; - - // TODO(zmo): remove the diagnostic error messages once we figure out the - // cause of the failure and a fix. - - glPixelFormat_.reset([[NSOpenGLPixelFormat alloc] - initWithAttributes:attributes]); - if (!glPixelFormat_) - LOG(ERROR) << "NSOpenGLPixelFormat initWithAttributes failed"; - - glContext_.reset([[NSOpenGLContext alloc] initWithFormat:glPixelFormat_ - shareContext:nil]); - if (!glContext_) - LOG(ERROR) << "NSOpenGLContext initWithFormat failed"; - - // We "punch a hole" in the window, and have the WindowServer render the - // OpenGL surface underneath so we can draw over it. - GLint belowWindow = -1; - [glContext_ setValues:&belowWindow forParameter:NSOpenGLCPSurfaceOrder]; - - cglContext_ = (CGLContextObj)[glContext_ CGLContextObj]; - if (!cglContext_) - LOG(ERROR) << "CGLContextObj failed"; - - cglPixelFormat_ = (CGLPixelFormatObj)[glPixelFormat_ CGLPixelFormatObj]; - if (!cglPixelFormat_) - LOG(ERROR) << "CGLPixelFormatObj failed"; - - // Draw at beam vsync. - GLint swapInterval; - if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync)) - swapInterval = 0; - else - swapInterval = 1; - [glContext_ setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval]; - - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(globalFrameDidChange:) - name:NSViewGlobalFrameDidChangeNotification - object:self]; - } - return self; -} - -- (void)dealloc { - if (renderWidgetHostView_) - renderWidgetHostView_->DeallocFakePluginWindowHandle(pluginHandle_); - [[NSNotificationCenter defaultCenter] removeObserver:self]; - [super dealloc]; -} - -- (void)setCutoutRects:(NSArray*)cutout_rects { - cutoutRects_.reset([cutout_rects copy]); -} - -- (void)onRenderWidgetHostViewGone { - if (!renderWidgetHostView_) - return; - - // Deallocate the plugin handle while we still can. - renderWidgetHostView_->DeallocFakePluginWindowHandle(pluginHandle_); - renderWidgetHostView_ = NULL; -} - -- (void)drawRect:(NSRect)rect { - TRACE_EVENT0("browser", "AcceleratedPluginView::drawRect"); - const NSRect* dirtyRects; - int dirtyRectCount; - [self getRectsBeingDrawn:&dirtyRects count:&dirtyRectCount]; - - { - gfx::ScopedNSGraphicsContextSaveGState scopedGState; - - // Mask out any cutout rects--somewhat counterintuitively cutout rects are - // places where clearColor is *not* drawn. The trick is that drawing nothing - // lets the parent view (i.e., the web page) show through, whereas drawing - // clearColor punches a hole in the window (letting OpenGL show through). - if ([cutoutRects_.get() count] > 0) { - NSBezierPath* path = [NSBezierPath bezierPath]; - // Trace the bounds clockwise to give a base clip rect of the whole view. - NSRect bounds = [self bounds]; - [path moveToPoint:bounds.origin]; - [path lineToPoint:NSMakePoint(NSMinX(bounds), NSMaxY(bounds))]; - [path lineToPoint:NSMakePoint(NSMaxX(bounds), NSMaxY(bounds))]; - [path lineToPoint:NSMakePoint(NSMaxX(bounds), NSMinY(bounds))]; - [path closePath]; - - // Then trace each cutout rect counterclockwise to remove that region from - // the clip region. - for (NSValue* rectWrapper in cutoutRects_.get()) { - [path appendBezierPathWithRect:[rectWrapper rectValue]]; - } - - [path addClip]; - } - - // Punch a hole so that the OpenGL view shows through. - [[NSColor clearColor] set]; - NSRectFillList(dirtyRects, dirtyRectCount); - } - - [self drawView]; -} - -- (void)rightMouseDown:(NSEvent*)event { - // The NSResponder documentation: "Note: The NSView implementation of this - // method does not pass the message up the responder chain, it handles it - // directly." - // That's bad, we want the next responder (RWHVMac) to handle this event to - // dispatch it to the renderer. - [[self nextResponder] rightMouseDown:event]; -} - -- (void)globalFrameDidChange:(NSNotification*)notification { - // This call to -update can call -globalFrameDidChange: again, see - // http://crbug.com/55754 comments 22 and 24. - [glContext_ update]; - - // You would think that -update updates the viewport. You would be wrong. - CGLSetCurrentContext(cglContext_); - NSSize size = [self frame].size; - glViewport(0, 0, size.width, size.height); - CGLSetCurrentContext(0); -} - -- (void)prepareForGLRendering { - TRACE_EVENT0("browser", "AcceleratedPluginView::prepareForGLRendering"); - - // If we're using OpenGL, make sure it is connected. - if ([glContext_ view] != self) { - [glContext_ setView:self]; - } -} - -- (void)renewGState { - TRACE_EVENT0("browser", "AcceleratedPluginView::renewGState"); - // Synchronize with window server to avoid flashes or corrupt drawing. - [[self window] disableScreenUpdatesUntilFlush]; - [self globalFrameDidChange:nil]; - [super renewGState]; -} - -- (void)setUpGState { - TRACE_EVENT0("browser", "AcceleratedPluginView::setUpGState"); - [self prepareForGLRendering]; -} - -// TODO(jbates): is lockFocus needed anymore? it seems redundant with -// setUpGState in traces. -- (void)lockFocus { - TRACE_EVENT0("browser", "AcceleratedPluginView::lockFocus"); - [super lockFocus]; - [self prepareForGLRendering]; - [glContext_ makeCurrentContext]; -} - -- (void)viewWillMoveToWindow:(NSWindow*)newWindow { - TRACE_EVENT1("browser", "AcceleratedPluginView::viewWillMoveToWindow", - "newWindow", newWindow); - // Inform the window hosting this accelerated view that it needs to be - // transparent. - if (![self isHiddenOrHasHiddenAncestor]) { - if ([[self window] respondsToSelector:@selector(underlaySurfaceRemoved)]) - [static_cast<id>([self window]) underlaySurfaceRemoved]; - if ([newWindow respondsToSelector:@selector(underlaySurfaceAdded)]) - [static_cast<id>(newWindow) underlaySurfaceAdded]; - } -} - -- (void)viewDidHide { - TRACE_EVENT0("browser", "AcceleratedPluginView::viewDidHide"); - [super viewDidHide]; - - if ([[self window] respondsToSelector:@selector(underlaySurfaceRemoved)]) { - [static_cast<id>([self window]) underlaySurfaceRemoved]; - } -} - -- (void)viewDidUnhide { - TRACE_EVENT0("browser", "AcceleratedPluginView::viewDidUnhide"); - [super viewDidUnhide]; - - if ([[self window] respondsToSelector:@selector(underlaySurfaceRemoved)]) { - [static_cast<id>([self window]) underlaySurfaceAdded]; - } -} - -- (BOOL)acceptsFirstResponder { - // Accept first responder if the first responder isn't the RWHVMac, and if the - // RWHVMac accepts first responder. If the RWHVMac does not accept first - // responder, do not accept on its behalf. - return ([[self window] firstResponder] != [self superview] && - [[self superview] acceptsFirstResponder]); -} - -- (BOOL)becomeFirstResponder { - // Delegate first responder to the RWHVMac. - [[self window] makeFirstResponder:[self superview]]; - return YES; -} - -- (void)viewDidMoveToSuperview { - TRACE_EVENT0("browser", "AcceleratedPluginView::viewDidMoveToSuperview"); - if (![self superview]) - [self onRenderWidgetHostViewGone]; -} -@end - diff --git a/content/browser/renderer_host/accelerated_plugin_view_mac_unittest.mm b/content/browser/renderer_host/accelerated_plugin_view_mac_unittest.mm deleted file mode 100644 index 4d902d2..0000000 --- a/content/browser/renderer_host/accelerated_plugin_view_mac_unittest.mm +++ /dev/null @@ -1,188 +0,0 @@ -// 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. - -#include "content/browser/renderer_host/accelerated_plugin_view_mac.h" - -#include "base/logging.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/platform_test.h" - -@interface UnderlayCountingWindow : NSWindow { - @private - int underlayCount_; -} -@property (readonly, nonatomic) int underlayCount; -- (void)underlaySurfaceAdded; -- (void)underlaySurfaceRemoved; -@end - -@implementation UnderlayCountingWindow -@synthesize underlayCount = underlayCount_; - -- (void)underlaySurfaceAdded { - DCHECK_GE(underlayCount_, 0); - ++underlayCount_; -} - -- (void)underlaySurfaceRemoved { - --underlayCount_; - DCHECK_GE(underlayCount_, 0); -} -@end - -class AcceleratedPluginViewTest : public PlatformTest { - protected: - AcceleratedPluginViewTest() {} - - UnderlayCountingWindow* StubUnderlayWindow() { - UnderlayCountingWindow* window = [[[UnderlayCountingWindow alloc] - initWithContentRect:NSMakeRect(20, 20, 300, 200) - styleMask:NSBorderlessWindowMask - backing:NSBackingStoreBuffered - defer:NO] autorelease]; - [window orderFront:nil]; - return window; - } - - AcceleratedPluginView* StubAcceleratedPluginView() { - // It truns out the rwhv and the plugin handle are not necessary for - // this test, and AcceleratedPluginView doesn't crash without them. - AcceleratedPluginView* view = [[[AcceleratedPluginView alloc] - initWithRenderWidgetHostViewMac:NULL - pluginHandle:0] autorelease]; - return view; - } - - private: - DISALLOW_COPY_AND_ASSIGN(AcceleratedPluginViewTest); -}; - -TEST_F(AcceleratedPluginViewTest, Basic) { -} - -TEST_F(AcceleratedPluginViewTest, BasicAdding) { - AcceleratedPluginView* view = StubAcceleratedPluginView(); - - UnderlayCountingWindow* window = StubUnderlayWindow(); - EXPECT_EQ(0, [window underlayCount]); - - [[window contentView] addSubview:view]; - EXPECT_EQ(1, [window underlayCount]); - - [view removeFromSuperview]; - EXPECT_EQ(0, [window underlayCount]); -} - -TEST_F(AcceleratedPluginViewTest, MoveBetweenWindows) { - AcceleratedPluginView* view = StubAcceleratedPluginView(); - - UnderlayCountingWindow* window1 = StubUnderlayWindow(); - UnderlayCountingWindow* window2 = StubUnderlayWindow(); - EXPECT_EQ(0, [window1 underlayCount]); - EXPECT_EQ(0, [window2 underlayCount]); - - [[window1 contentView] addSubview:view]; - EXPECT_EQ(1, [window1 underlayCount]); - EXPECT_EQ(0, [window2 underlayCount]); - - [[window2 contentView] addSubview:view]; - EXPECT_EQ(0, [window1 underlayCount]); - EXPECT_EQ(1, [window2 underlayCount]); -} - -TEST_F(AcceleratedPluginViewTest, HiddenWhenAdding) { - AcceleratedPluginView* view = StubAcceleratedPluginView(); - [view setHidden:YES]; - - UnderlayCountingWindow* window = StubUnderlayWindow(); - EXPECT_EQ(0, [window underlayCount]); - - [[window contentView] addSubview:view]; - EXPECT_EQ(0, [window underlayCount]); - - [view setHidden:NO]; - EXPECT_EQ(1, [window underlayCount]); - - [view setHidden:YES]; - EXPECT_EQ(0, [window underlayCount]); - - [view removeFromSuperview]; - EXPECT_EQ(0, [window underlayCount]); -} - -TEST_F(AcceleratedPluginViewTest, HiddenAfterAdding) { - AcceleratedPluginView* view = StubAcceleratedPluginView(); - - UnderlayCountingWindow* window = StubUnderlayWindow(); - EXPECT_EQ(0, [window underlayCount]); - - [[window contentView] addSubview:view]; - EXPECT_EQ(1, [window underlayCount]); - - [view setHidden:YES]; - EXPECT_EQ(0, [window underlayCount]); - - [view setHidden:NO]; - EXPECT_EQ(1, [window underlayCount]); - - [view removeFromSuperview]; - EXPECT_EQ(0, [window underlayCount]); -} - -TEST_F(AcceleratedPluginViewTest, MoveBetweenWindowsWithHiding) { - AcceleratedPluginView* view = StubAcceleratedPluginView(); - [view setHidden:YES]; - - UnderlayCountingWindow* window1 = StubUnderlayWindow(); - UnderlayCountingWindow* window2 = StubUnderlayWindow(); - EXPECT_EQ(0, [window1 underlayCount]); - EXPECT_EQ(0, [window2 underlayCount]); - - [[window1 contentView] addSubview:view]; - EXPECT_EQ(0, [window1 underlayCount]); - EXPECT_EQ(0, [window2 underlayCount]); - - [view setHidden:NO]; - EXPECT_EQ(1, [window1 underlayCount]); - EXPECT_EQ(0, [window2 underlayCount]); - - // Move view while it's visible. - [[window2 contentView] addSubview:view]; - EXPECT_EQ(0, [window1 underlayCount]); - EXPECT_EQ(1, [window2 underlayCount]); - - [view setHidden:YES]; - EXPECT_EQ(0, [window1 underlayCount]); - EXPECT_EQ(0, [window2 underlayCount]); - - // Move view while it's hidden. - [[window1 contentView] addSubview:view]; - EXPECT_EQ(0, [window1 underlayCount]); - EXPECT_EQ(0, [window2 underlayCount]); - - [view setHidden:NO]; - EXPECT_EQ(1, [window1 underlayCount]); - EXPECT_EQ(0, [window2 underlayCount]); -} - -// Regression test for http://crbug.com/81737 -TEST_F(AcceleratedPluginViewTest, RemoveWithHiddenParent) { - AcceleratedPluginView* view = StubAcceleratedPluginView(); - - NSView* parent = - [[[NSView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)] autorelease]; - [parent addSubview:view]; - - UnderlayCountingWindow* window = StubUnderlayWindow(); - EXPECT_EQ(0, [window underlayCount]); - - [[window contentView] addSubview:parent]; - EXPECT_EQ(1, [window underlayCount]); - - [parent setHidden:YES]; - EXPECT_EQ(0, [window underlayCount]); - - [parent removeFromSuperview]; - EXPECT_EQ(0, [window underlayCount]); -} diff --git a/content/browser/renderer_host/render_widget_host_view_mac.h b/content/browser/renderer_host/render_widget_host_view_mac.h deleted file mode 100644 index 92e48c0..0000000 --- a/content/browser/renderer_host/render_widget_host_view_mac.h +++ /dev/null @@ -1,410 +0,0 @@ -// 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. - -#ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_MAC_H_ -#define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_MAC_H_ -#pragma once - -#import <Cocoa/Cocoa.h> - -#include "base/memory/scoped_nsobject.h" -#include "base/memory/scoped_ptr.h" -#include "base/task.h" -#include "base/time.h" -#include "content/browser/accessibility/browser_accessibility_delegate_mac.h" -#include "content/browser/accessibility/browser_accessibility_manager.h" -#include "content/browser/renderer_host/accelerated_surface_container_manager_mac.h" -#include "content/browser/renderer_host/render_widget_host_view.h" -#include "content/common/edit_command.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/WebCompositionUnderline.h" -#include "ui/base/cocoa/base_view.h" -#include "webkit/glue/webcursor.h" - -@class AcceleratedPluginView; -class RenderWidgetHostViewMac; -@class RenderWidgetHostViewMacDelegate; -class RenderWidgetHostViewMacEditCommandHelper; -@class ToolTip; - -@protocol RenderWidgetHostViewMacOwner -- (RenderWidgetHostViewMac*)renderWidgetHostViewMac; -@end - -// This is the view that lives in the Cocoa view hierarchy. In Windows-land, -// RenderWidgetHostViewWin is both the view and the delegate. We split the roles -// but that means that the view needs to own the delegate and will dispose of it -// when it's removed from the view system. -@interface RenderWidgetHostViewCocoa - : BaseView <RenderWidgetHostViewMacOwner, - NSTextInputClient, - BrowserAccessibilityDelegateCocoa> { - @private - scoped_ptr<RenderWidgetHostViewMac> renderWidgetHostView_; - RenderWidgetHostViewMacDelegate* delegate_; // weak - BOOL canBeKeyView_; - BOOL takesFocusOnlyOnMouseDown_; - BOOL closeOnDeactivate_; - scoped_ptr<RenderWidgetHostViewMacEditCommandHelper> editCommand_helper_; - - // These are part of the magic tooltip code from WebKit's WebHTMLView: - id trackingRectOwner_; // (not retained) - void *trackingRectUserData_; - NSTrackingRectTag lastToolTipTag_; - scoped_nsobject<NSString> toolTip_; - - // Is YES if there was a mouse-down as yet unbalanced with a mouse-up. - BOOL hasOpenMouseDown_; - - NSWindow* lastWindow_; // weak - - // Variables used by our implementaion of the NSTextInput protocol. - // An input method of Mac calls the methods of this protocol not only to - // notify an application of its status, but also to retrieve the status of - // the application. That is, an application cannot control an input method - // directly. - // This object keeps the status of a composition of the renderer and returns - // it when an input method asks for it. - // We need to implement Objective-C methods for the NSTextInput protocol. On - // the other hand, we need to implement a C++ method for an IPC-message - // handler which receives input-method events from the renderer. - - // Represents the input-method attributes supported by this object. - scoped_nsobject<NSArray> validAttributesForMarkedText_; - - // Indicates if we are currently handling a key down event. - BOOL handlingKeyDown_; - - // Indicates if there is any marked text. - BOOL hasMarkedText_; - - // Indicates if unmarkText is called or not when handling a keyboard - // event. - BOOL unmarkTextCalled_; - - // The range of current marked text inside the whole content of the DOM node - // being edited. - // TODO(suzhe): This is currently a fake value, as we do not support accessing - // the whole content yet. - NSRange markedRange_; - - // The selected range, cached from a message sent by the renderer. - NSRange selectedRange_; - - // Text to be inserted which was generated by handling a key down event. - string16 textToBeInserted_; - - // Marked text which was generated by handling a key down event. - string16 markedText_; - - // Underline information of the |markedText_|. - std::vector<WebKit::WebCompositionUnderline> underlines_; - - // Indicates if doCommandBySelector method receives any edit command when - // handling a key down event. - BOOL hasEditCommands_; - - // Contains edit commands received by the -doCommandBySelector: method when - // handling a key down event, not including inserting commands, eg. insertTab, - // etc. - EditCommands editCommands_; - - // The plugin that currently has focus (-1 if no plugin has focus). - int focusedPluginIdentifier_; - - // Whether or not plugin IME is currently enabled active. - BOOL pluginImeActive_; - - // Whether the previous mouse event was ignored due to hitTest check. - BOOL mouseEventWasIgnored_; - - // Event monitor for gesture-end events. - id endGestureMonitor_; -} - -@property(nonatomic, readonly) NSRange selectedRange; - -- (void)setCanBeKeyView:(BOOL)can; -- (void)setTakesFocusOnlyOnMouseDown:(BOOL)b; -- (void)setCloseOnDeactivate:(BOOL)b; -- (void)setToolTipAtMousePoint:(NSString *)string; -// Set frame, then notify the RenderWidgetHost that the frame has been changed, -// but do it in a separate task, using |performSelector:withObject:afterDelay:|. -// This stops the flickering issue in http://crbug.com/31970 -- (void)setFrameWithDeferredUpdate:(NSRect)frame; -// Notify the RenderWidgetHost that the frame was updated so it can resize -// its contents. -- (void)renderWidgetHostWasResized; -// Cancel ongoing composition (abandon the marked text). -- (void)cancelComposition; -// Confirm ongoing composition. -- (void)confirmComposition; -// Enables or disables plugin IME. -- (void)setPluginImeActive:(BOOL)active; -// Updates the current plugin focus state. -- (void)pluginFocusChanged:(BOOL)focused forPlugin:(int)pluginId; -// Evaluates the event in the context of plugin IME, if plugin IME is enabled. -// Returns YES if the event was handled. -- (BOOL)postProcessEventForPluginIme:(NSEvent*)event; - -@end - -/////////////////////////////////////////////////////////////////////////////// -// RenderWidgetHostViewMac -// -// An object representing the "View" of a rendered web page. This object is -// responsible for displaying the content of the web page, and integrating with -// the Cocoa view system. It is the implementation of the RenderWidgetHostView -// that the cross-platform RenderWidgetHost object uses -// to display the data. -// -// Comment excerpted from render_widget_host.h: -// -// "The lifetime of the RenderWidgetHost* is tied to the render process. -// If the render process dies, the RenderWidgetHost* goes away and all -// references to it must become NULL." -// -class RenderWidgetHostViewMac : public RenderWidgetHostView { - public: - // The view will associate itself with the given widget. The native view must - // be hooked up immediately to the view hierarchy, or else when it is - // deleted it will delete this out from under the caller. - explicit RenderWidgetHostViewMac(RenderWidgetHost* widget); - virtual ~RenderWidgetHostViewMac(); - - RenderWidgetHostViewCocoa* native_view() const { return cocoa_view_; } - - void SetDelegate(RenderWidgetHostViewMacDelegate* delegate); - - // Implementation of RenderWidgetHostView: - virtual void InitAsPopup(RenderWidgetHostView* parent_host_view, - const gfx::Rect& pos) OVERRIDE; - virtual void InitAsFullscreen( - RenderWidgetHostView* reference_host_view) OVERRIDE; - virtual RenderWidgetHost* GetRenderWidgetHost() const OVERRIDE; - virtual void DidBecomeSelected() OVERRIDE; - virtual void WasHidden() OVERRIDE; - virtual void SetSize(const gfx::Size& size) OVERRIDE; - virtual void SetBounds(const gfx::Rect& rect) OVERRIDE; - virtual gfx::NativeView GetNativeView() const OVERRIDE; - virtual gfx::NativeViewId GetNativeViewId() const OVERRIDE; - virtual void MovePluginWindows( - const std::vector<webkit::npapi::WebPluginGeometry>& moves) OVERRIDE; - virtual void Focus() OVERRIDE; - virtual void Blur() OVERRIDE; - virtual bool HasFocus() OVERRIDE; - virtual void Show() OVERRIDE; - virtual void Hide() OVERRIDE; - virtual bool IsShowing() OVERRIDE; - virtual gfx::Rect GetViewBounds() const OVERRIDE; - virtual void UpdateCursor(const WebCursor& cursor) OVERRIDE; - virtual void SetIsLoading(bool is_loading) OVERRIDE; - virtual void ImeUpdateTextInputState(ui::TextInputType state, - bool can_compose_inline, - const gfx::Rect& caret_rect) OVERRIDE; - virtual void ImeCancelComposition() OVERRIDE; - virtual void ImeCompositionRangeChanged(const ui::Range& range) OVERRIDE; - virtual void DidUpdateBackingStore( - const gfx::Rect& scroll_rect, int scroll_dx, int scroll_dy, - const std::vector<gfx::Rect>& copy_rects) OVERRIDE; - virtual void RenderViewGone(base::TerminationStatus status, - int error_code) OVERRIDE; - virtual void Destroy() OVERRIDE; - virtual void SetTooltipText(const string16& tooltip_text) OVERRIDE; - virtual void SelectionChanged(const std::string& text, - const ui::Range& range, - const gfx::Point& start, - const gfx::Point& end) OVERRIDE; - virtual void ShowingContextMenu(bool showing) OVERRIDE; - virtual BackingStore* AllocBackingStore(const gfx::Size& size) OVERRIDE; - virtual void SetTakesFocusOnlyOnMouseDown(bool flag) OVERRIDE; - // See comment in RenderWidgetHostView! - virtual gfx::Rect GetViewCocoaBounds() const OVERRIDE; - virtual void SetActive(bool active) OVERRIDE; - virtual void SetWindowVisibility(bool visible) OVERRIDE; - virtual void WindowFrameChanged() OVERRIDE; - virtual void SetBackground(const SkBitmap& background) OVERRIDE; - - virtual void OnAccessibilityNotifications( - const std::vector<ViewHostMsg_AccessibilityNotification_Params>& params - ) OVERRIDE; - - virtual void PluginFocusChanged(bool focused, int plugin_id) OVERRIDE; - virtual void StartPluginIme() OVERRIDE; - virtual bool PostProcessEventForPluginIme( - const NativeWebKeyboardEvent& event) OVERRIDE; - - // Methods associated with GPU-accelerated plug-in instances and the - // accelerated compositor. - virtual gfx::PluginWindowHandle AllocateFakePluginWindowHandle( - bool opaque, bool root) OVERRIDE; - virtual void DestroyFakePluginWindowHandle( - gfx::PluginWindowHandle window) OVERRIDE; - - // Exposed for testing. - AcceleratedPluginView* ViewForPluginWindowHandle( - gfx::PluginWindowHandle window); - - // Helper to do the actual cleanup after a plugin handle has been destroyed. - // Required because DestroyFakePluginWindowHandle() isn't always called for - // all handles (it's e.g. not called on navigation, when the RWHVMac gets - // destroyed anyway). - void DeallocFakePluginWindowHandle(gfx::PluginWindowHandle window); - - virtual void AcceleratedSurfaceSetIOSurface( - gfx::PluginWindowHandle window, - int32 width, - int32 height, - uint64 io_surface_identifier) OVERRIDE; - virtual void AcceleratedSurfaceSetTransportDIB( - gfx::PluginWindowHandle window, - int32 width, - int32 height, - TransportDIB::Handle transport_dib) OVERRIDE; - virtual void AcceleratedSurfaceBuffersSwapped( - gfx::PluginWindowHandle window, - uint64 surface_id, - int renderer_id, - int32 route_id, - int gpu_host_id, - uint64 swap_buffers_count) OVERRIDE; - virtual void GpuRenderingStateDidChange() OVERRIDE; - virtual void GetScreenInfo(WebKit::WebScreenInfo* results) OVERRIDE; - virtual gfx::Rect GetRootWindowBounds() OVERRIDE; - virtual gfx::PluginWindowHandle GetCompositingSurface() OVERRIDE; - - // Returns |true| if a context menu is currently being shown. - bool is_showing_context_menu() const { return is_showing_context_menu_; } - - void DrawAcceleratedSurfaceInstance( - CGLContextObj context, - gfx::PluginWindowHandle plugin_handle, - NSSize size); - // Forces the textures associated with any accelerated plugin instances - // to be reloaded. - void ForceTextureReload(); - - virtual void SetVisuallyDeemphasized(const SkColor* color, bool animate); - - virtual void UnhandledWheelEvent( - const WebKit::WebMouseWheelEvent& event) OVERRIDE; - virtual void SetHasHorizontalScrollbar( - bool has_horizontal_scrollbar) OVERRIDE; - virtual void SetScrollOffsetPinning( - bool is_pinned_to_left, bool is_pinned_to_right) OVERRIDE; - - virtual bool LockMouse() OVERRIDE; - virtual void UnlockMouse() OVERRIDE; - - void KillSelf(); - - void SetTextInputActive(bool active); - - // Sends completed plugin IME notification and text back to the renderer. - void PluginImeCompositionCompleted(const string16& text, int plugin_id); - - const std::string& selected_text() const { return selected_text_; } - - void UpdateRootGpuViewVisibility(bool show_gpu_widget); - - // When rendering transitions from gpu to software, the gpu widget can't be - // hidden until the software backing store has been updated. This method - // checks if the GPU view needs to be hidden and hides it if necessary. It - // should be called after the software backing store has been painted to. - void HandleDelayedGpuViewHiding(); - - // This is called from the display link thread, and provides the GPU - // process a notion of how quickly the browser is able to keep up with it. - void AcknowledgeSwapBuffers(int renderer_id, - int32 route_id, - int gpu_host_id, - uint64 swap_buffers_count); - - // These member variables should be private, but the associated ObjC class - // needs access to them and can't be made a friend. - - // The associated Model. Can be NULL if Destroy() is called when - // someone (other than superview) has retained |cocoa_view_|. - RenderWidgetHost* render_widget_host_; - - // This is true when we are currently painting and thus should handle extra - // paint requests by expanding the invalid rect rather than actually painting. - bool about_to_validate_and_paint_; - - scoped_ptr<BrowserAccessibilityManager> browser_accessibility_manager_; - - // This is true when we have already scheduled a call to - // |-callSetNeedsDisplayInRect:| but it has not been fulfilled yet. Used to - // prevent us from scheduling multiple calls. - bool call_set_needs_display_in_rect_pending_; - - // The invalid rect that needs to be painted by callSetNeedsDisplayInRect. - // This value is only meaningful when - // |call_set_needs_display_in_rect_pending_| is true. - NSRect invalid_rect_; - - // 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. - base::TimeTicks whiteout_start_time_; - - // The time it took after this view was selected for it to be fully painted. - base::TimeTicks tab_switch_paint_time_; - - // Current text input type. - ui::TextInputType text_input_type_; - - typedef std::map<gfx::PluginWindowHandle, AcceleratedPluginView*> - PluginViewMap; - PluginViewMap plugin_views_; // Weak values. - - // Helper class for managing instances of accelerated plug-ins. - AcceleratedSurfaceContainerManagerMac plugin_container_manager_; - - private: - // Returns whether this render view is a popup (autocomplete window). - bool IsPopup() const; - - // Updates the display cursor if the current event is over the view's window. - void UpdateCursorIfNecessary(); - - // Shuts down the render_widget_host_. This is a separate function so we can - // invoke it from the message loop. - void ShutdownHost(); - - // The associated view. This is weak and is inserted into the view hierarchy - // to own this RenderWidgetHostViewMac object. - RenderWidgetHostViewCocoa* cocoa_view_; - - // The cursor for the page. This is passed up from the renderer. - WebCursor current_cursor_; - - // Indicates if the page is loading. - bool is_loading_; - - // true if the View is not visible. - bool is_hidden_; - - // Whether we are showing a context menu. - bool is_showing_context_menu_; - - // The text to be shown in the tooltip, supplied by the renderer. - string16 tooltip_text_; - - // Factory used to safely scope delayed calls to ShutdownHost(). - ScopedRunnableMethodFactory<RenderWidgetHostViewMac> shutdown_factory_; - - // selected text on the renderer. - std::string selected_text_; - - // When rendering transitions from gpu to software, the gpu widget can't be - // hidden until the software backing store has been updated. This variable is - // set when the gpu widget needs to be hidden once a paint is completed. - bool needs_gpu_visibility_update_after_repaint_; - - gfx::PluginWindowHandle compositing_surface_; - - DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewMac); -}; - -#endif // CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_MAC_H_ diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm deleted file mode 100644 index 8f720a3..0000000 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ /dev/null @@ -1,2740 +0,0 @@ -// 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. - -#include "content/browser/renderer_host/render_widget_host_view_mac.h" - -#include <QuartzCore/QuartzCore.h> - -#include "base/debug/trace_event.h" -#include "base/logging.h" -#include "base/mac/mac_util.h" -#include "base/mac/scoped_cftyperef.h" -#import "base/mac/scoped_nsautorelease_pool.h" -#include "base/metrics/histogram.h" -#import "base/memory/scoped_nsobject.h" -#include "base/string_util.h" -#include "base/sys_info.h" -#include "base/sys_string_conversions.h" -#import "content/browser/accessibility/browser_accessibility_cocoa.h" -#include "content/browser/browser_thread.h" -#include "content/browser/gpu/gpu_process_host.h" -#include "content/browser/gpu/gpu_process_host_ui_shim.h" -#include "content/browser/mac/closure_blocks_leopard_compat.h" -#include "content/browser/plugin_process_host.h" -#import "content/browser/renderer_host/accelerated_plugin_view_mac.h" -#include "content/browser/renderer_host/backing_store_mac.h" -#include "content/browser/renderer_host/render_process_host.h" -#include "content/browser/renderer_host/render_view_host.h" -#import "content/browser/renderer_host/render_widget_host_view_mac_delegate.h" -#import "content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.h" -#import "content/browser/renderer_host/text_input_client_mac.h" -#include "content/common/edit_command.h" -#include "content/common/gpu/gpu_messages.h" -#include "content/common/native_web_keyboard_event.h" -#include "content/common/plugin_messages.h" -#include "content/common/view_messages.h" -#include "skia/ext/platform_canvas.h" -#import "third_party/mozilla/ComplexTextInputPanel.h" -#include "third_party/skia/include/core/SkColor.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/mac/WebInputEventFactory.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/mac/WebScreenInfoFactory.h" -#include "ui/gfx/point.h" -#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" -#include "ui/gfx/surface/io_surface_support_mac.h" -#include "webkit/glue/webaccessibility.h" -#include "webkit/plugins/npapi/webplugin.h" - -using WebKit::WebInputEvent; -using WebKit::WebInputEventFactory; -using WebKit::WebMouseEvent; -using WebKit::WebMouseWheelEvent; -using WebKit::WebGestureEvent; - -// Declare things that are part of the 10.6 SDK. -#if !defined(MAC_OS_X_VERSION_10_6) || \ - MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 -enum { - NSEventTypeBeginGesture = 19, - NSEventTypeEndGesture = 20 -}; - -enum { - NSEventMaskBeginGesture = 1 << NSEventTypeBeginGesture, - NSEventMaskEndGesture = 1 << NSEventTypeEndGesture, -}; - -typedef unsigned long long NSEventMask; - -@class NSTextInputContext; -@interface NSResponder (AppKitDetails) -- (NSTextInputContext*)inputContext; -@end -#endif // 10.6 - -// Declare things that are part of the 10.7 SDK. -#if !defined(MAC_OS_X_VERSION_10_7) || \ - MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 -@interface NSEvent (LionAPI) -+ (id)addLocalMonitorForEventsMatchingMask:(NSEventMask)mask - handler:(NSEvent* (^)(NSEvent*))block; -+ (void)removeMonitor:(id)eventMonitor; -@end -#endif // 10.7 - -static inline int ToWebKitModifiers(NSUInteger flags) { - int modifiers = 0; - if (flags & NSControlKeyMask) modifiers |= WebInputEvent::ControlKey; - if (flags & NSShiftKeyMask) modifiers |= WebInputEvent::ShiftKey; - if (flags & NSAlternateKeyMask) modifiers |= WebInputEvent::AltKey; - if (flags & NSCommandKeyMask) modifiers |= WebInputEvent::MetaKey; - return modifiers; -} - -// Private methods: -@interface RenderWidgetHostViewCocoa () -@property(nonatomic, assign) NSRange selectedRange; -@property(nonatomic, assign) NSRange markedRange; - -+ (BOOL)shouldAutohideCursorForEvent:(NSEvent*)event; -- (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r; -- (void)setRWHVDelegate:(RenderWidgetHostViewMacDelegate*)delegate; -- (void)gotUnhandledWheelEvent; -- (void)scrollOffsetPinnedToLeft:(BOOL)left toRight:(BOOL)right; -- (void)setHasHorizontalScrollbar:(BOOL)has_horizontal_scrollbar; -- (void)keyEvent:(NSEvent*)theEvent wasKeyEquivalent:(BOOL)equiv; -- (void)cancelChildPopups; -- (void)checkForPluginImeCancellation; -@end - -// NSEvent subtype for scroll gestures events. -static const short kIOHIDEventTypeScroll = 6; - -namespace { - -// Maximum number of characters we allow in a tooltip. -const size_t kMaxTooltipLength = 1024; - -// TODO(suzhe): Upstream this function. -WebKit::WebColor WebColorFromNSColor(NSColor *color) { - CGFloat r, g, b, a; - [color getRed:&r green:&g blue:&b alpha:&a]; - - return - std::max(0, std::min(static_cast<int>(lroundf(255.0f * a)), 255)) << 24 | - std::max(0, std::min(static_cast<int>(lroundf(255.0f * r)), 255)) << 16 | - std::max(0, std::min(static_cast<int>(lroundf(255.0f * g)), 255)) << 8 | - std::max(0, std::min(static_cast<int>(lroundf(255.0f * b)), 255)); -} - -// Extract underline information from an attributed string. Mostly copied from -// third_party/WebKit/Source/WebKit/mac/WebView/WebHTMLView.mm -void ExtractUnderlines( - NSAttributedString* string, - std::vector<WebKit::WebCompositionUnderline>* underlines) { - int length = [[string string] length]; - int i = 0; - while (i < length) { - NSRange range; - NSDictionary* attrs = [string attributesAtIndex:i - longestEffectiveRange:&range - inRange:NSMakeRange(i, length - i)]; - if (NSNumber *style = [attrs objectForKey:NSUnderlineStyleAttributeName]) { - WebKit::WebColor color = SK_ColorBLACK; - if (NSColor *colorAttr = - [attrs objectForKey:NSUnderlineColorAttributeName]) { - color = WebColorFromNSColor( - [colorAttr colorUsingColorSpaceName:NSDeviceRGBColorSpace]); - } - underlines->push_back(WebKit::WebCompositionUnderline( - range.location, NSMaxRange(range), color, [style intValue] > 1)); - } - i = range.location + range.length; - } -} - -// EnablePasswordInput() and DisablePasswordInput() are copied from -// enableSecureTextInput() and disableSecureTextInput() functions in -// third_party/WebKit/WebCore/platform/SecureTextInput.cpp -// But we don't call EnableSecureEventInput() and DisableSecureEventInput() -// here, because they are already called in webkit and they are system wide -// functions. -void EnablePasswordInput() { - CFArrayRef inputSources = TISCreateASCIICapableInputSourceList(); - TSMSetDocumentProperty(0, kTSMDocumentEnabledInputSourcesPropertyTag, - sizeof(CFArrayRef), &inputSources); - CFRelease(inputSources); -} - -void DisablePasswordInput() { - TSMRemoveDocumentProperty(0, kTSMDocumentEnabledInputSourcesPropertyTag); -} - -// Adjusts an NSRect in Cocoa screen coordinates to have an origin in the upper -// left of the primary screen (Carbon coordinates), and stuffs it into a -// gfx::Rect. -gfx::Rect FlipNSRectToRectScreen(const NSRect& rect) { - gfx::Rect new_rect(NSRectToCGRect(rect)); - if ([[NSScreen screens] count] > 0) { - new_rect.set_y([[[NSScreen screens] objectAtIndex:0] frame].size.height - - new_rect.y() - new_rect.height()); - } - return new_rect; -} - -// Returns the window that visually contains the given view. This is different -// from [view window] in the case of tab dragging, where the view's owning -// window is a floating panel attached to the actual browser window that the tab -// is visually part of. -NSWindow* ApparentWindowForView(NSView* view) { - // TODO(shess): In case of !window, the view has been removed from - // the view hierarchy because the tab isn't main. Could retrieve - // the information from the main tab for our window. - NSWindow* enclosing_window = [view window]; - - // See if this is a tab drag window. The width check is to distinguish that - // case from extension popup windows. - NSWindow* ancestor_window = [enclosing_window parentWindow]; - if (ancestor_window && (NSWidth([enclosing_window frame]) == - NSWidth([ancestor_window frame]))) { - enclosing_window = ancestor_window; - } - - return enclosing_window; -} - -} // namespace - -// RenderWidgetHostView -------------------------------------------------------- - -// static -RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget( - RenderWidgetHost* widget) { - return new RenderWidgetHostViewMac(widget); -} - -/////////////////////////////////////////////////////////////////////////////// -// RenderWidgetHostViewMac, public: - -RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) - : render_widget_host_(widget), - about_to_validate_and_paint_(false), - call_set_needs_display_in_rect_pending_(false), - text_input_type_(ui::TEXT_INPUT_TYPE_NONE), - is_loading_(false), - is_hidden_(false), - is_showing_context_menu_(false), - shutdown_factory_(this), - needs_gpu_visibility_update_after_repaint_(false), - compositing_surface_(gfx::kNullPluginWindow) { - // |cocoa_view_| owns us and we will be deleted when |cocoa_view_| goes away. - // Since we autorelease it, our caller must put |native_view()| into the view - // hierarchy right after calling us. - cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc] - initWithRenderWidgetHostViewMac:this] autorelease]; - render_widget_host_->SetView(this); -} - -RenderWidgetHostViewMac::~RenderWidgetHostViewMac() { -} - -void RenderWidgetHostViewMac::SetDelegate( - RenderWidgetHostViewMacDelegate* delegate) { - [cocoa_view_ setRWHVDelegate:delegate]; -} - -/////////////////////////////////////////////////////////////////////////////// -// RenderWidgetHostViewMac, RenderWidgetHostView implementation: - -void RenderWidgetHostViewMac::InitAsPopup( - 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]; -} - -void RenderWidgetHostViewMac::InitAsFullscreen( - RenderWidgetHostView* /*reference_host_view*/) { - NOTIMPLEMENTED() << "Full screen not implemented on Mac"; -} - -RenderWidgetHost* RenderWidgetHostViewMac::GetRenderWidgetHost() const { - return render_widget_host_; -} - -void RenderWidgetHostViewMac::DidBecomeSelected() { - if (!is_hidden_) - return; - - if (tab_switch_paint_time_.is_null()) - tab_switch_paint_time_ = base::TimeTicks::Now(); - is_hidden_ = false; - render_widget_host_->WasRestored(); -} - -void RenderWidgetHostViewMac::WasHidden() { - if (is_hidden_) - return; - - // If we receive any more paint messages while we are hidden, we want to - // ignore them so we don't re-allocate the backing store. We will paint - // everything again when we become selected again. - is_hidden_ = true; - - // If we have a renderer, then inform it that we are being hidden so it can - // reduce its resource utilization. - render_widget_host_->WasHidden(); -} - -void RenderWidgetHostViewMac::SetSize(const gfx::Size& size) { - gfx::Rect rect = GetViewBounds(); - rect.set_size(size); - SetBounds(rect); -} - -void RenderWidgetHostViewMac::SetBounds(const gfx::Rect& rect) { - // |rect.size()| is view coordinates, |rect.origin| is screen coordinates, - // TODO(thakis): fix, http://crbug.com/73362 - if (is_hidden_) - return; - - // During the initial creation of the RenderWidgetHostView in - // TabContents::CreateRenderViewForRenderManager, SetSize is called with an - // empty size. In the Windows code flow, it is not ignored because subsequent - // sizing calls from the OS flow through TCVW::WasSized which calls SetSize() - // again. On Cocoa, we rely on the Cocoa view struture and resizer flags to - // keep things sized properly. On the other hand, if the size is not empty - // then this is a valid request for a pop-up. - if (rect.size().IsEmpty()) - return; - - // Ignore the position of |rect| for non-popup rwhvs. This is because - // background tabs do not have a window, but the window is required for the - // coordinate conversions. Popups are always for a visible tab. - if (IsPopup()) { - // 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()); - 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]; - } else { - DCHECK([[cocoa_view_ superview] isKindOfClass:[BaseView class]]); - BaseView* superview = static_cast<BaseView*>([cocoa_view_ superview]); - gfx::Rect rect = [superview flipNSRectToRect:[cocoa_view_ frame]]; - rect.set_width(rect.width()); - rect.set_height(rect.height()); - [cocoa_view_ setFrame:[superview flipRectToNSRect:rect]]; - } -} - -gfx::NativeView RenderWidgetHostViewMac::GetNativeView() const { - return native_view(); -} - -gfx::NativeViewId RenderWidgetHostViewMac::GetNativeViewId() const { - return reinterpret_cast<gfx::NativeViewId>(native_view()); -} - -void RenderWidgetHostViewMac::MovePluginWindows( - const std::vector<webkit::npapi::WebPluginGeometry>& moves) { - TRACE_EVENT0("browser", "RenderWidgetHostViewMac::MovePluginWindows"); - CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - // Handle movement of accelerated plugins, which are the only "windowed" - // plugins that exist on the Mac. - for (std::vector<webkit::npapi::WebPluginGeometry>::const_iterator iter = - moves.begin(); - iter != moves.end(); - ++iter) { - webkit::npapi::WebPluginGeometry geom = *iter; - - AcceleratedPluginView* view = ViewForPluginWindowHandle(geom.window); - DCHECK(view); - if (!view) - continue; - - if (geom.rects_valid) { - gfx::Rect rect = geom.window_rect; - if (geom.visible) { - rect.set_x(rect.x() + geom.clip_rect.x()); - rect.set_y(rect.y() + geom.clip_rect.y()); - rect.set_width(geom.clip_rect.width()); - rect.set_height(geom.clip_rect.height()); - } - NSRect new_rect([cocoa_view_ flipRectToNSRect:rect]); - [view setFrame:new_rect]; - NSMutableArray* cutout_rects = - [NSMutableArray arrayWithCapacity:geom.cutout_rects.size()]; - for (unsigned int i = 0; i < geom.cutout_rects.size(); ++i) { - // Convert to NSRect, and flip vertically. - NSRect cutout_rect = NSRectFromCGRect(geom.cutout_rects[i].ToCGRect()); - cutout_rect.origin.y = new_rect.size.height - NSMaxY(cutout_rect); - [cutout_rects addObject:[NSValue valueWithRect:cutout_rect]]; - } - [view setCutoutRects:cutout_rects]; - [view setNeedsDisplay:YES]; - } - - plugin_container_manager_.SetPluginContainerGeometry(geom); - - BOOL visible = - plugin_container_manager_.SurfaceShouldBeVisible(geom.window); - [view setHidden:!visible]; - } -} - -void RenderWidgetHostViewMac::Focus() { - [[cocoa_view_ window] makeFirstResponder:cocoa_view_]; -} - -void RenderWidgetHostViewMac::Blur() { - [[cocoa_view_ window] makeFirstResponder:nil]; -} - -bool RenderWidgetHostViewMac::HasFocus() { - return [[cocoa_view_ window] firstResponder] == cocoa_view_; -} - -void RenderWidgetHostViewMac::Show() { - [cocoa_view_ setHidden:NO]; - - DidBecomeSelected(); -} - -void RenderWidgetHostViewMac::Hide() { - [cocoa_view_ setHidden:YES]; - - WasHidden(); -} - -bool RenderWidgetHostViewMac::IsShowing() { - return ![cocoa_view_ isHidden]; -} - -gfx::Rect RenderWidgetHostViewMac::GetViewBounds() const { - // TODO(shess): In case of !window, the view has been removed from - // the view hierarchy because the tab isn't main. Could retrieve - // the information from the main tab for our window. - NSWindow* enclosing_window = ApparentWindowForView(cocoa_view_); - if (!enclosing_window) - return gfx::Rect(); - - NSRect bounds = [cocoa_view_ bounds]; - bounds = [cocoa_view_ convertRect:bounds toView:nil]; - bounds.origin = [enclosing_window convertBaseToScreen:bounds.origin]; - return FlipNSRectToRectScreen(bounds); -} - -void RenderWidgetHostViewMac::UpdateCursor(const WebCursor& cursor) { - current_cursor_ = cursor; - UpdateCursorIfNecessary(); -} - -void RenderWidgetHostViewMac::UpdateCursorIfNecessary() { - // Do something special (as Win Chromium does) for arrow cursor while loading - // a page? TODO(avi): decide - - // Don't update the cursor if a context menu is being shown. - if (is_showing_context_menu_) - return; - - // Can we synchronize to the event stream? Switch to -[NSWindow - // mouseLocationOutsideOfEventStream] if we cannot. TODO(avi): test and see - NSEvent* event = [[cocoa_view_ window] currentEvent]; - if ([event window] != [cocoa_view_ window]) - return; - - NSCursor* ns_cursor = current_cursor_.GetCursor(); - [ns_cursor set]; -} - -void RenderWidgetHostViewMac::SetIsLoading(bool is_loading) { - is_loading_ = is_loading; - // If we ever decide to show the waiting cursor while the page is loading - // like Chrome does on Windows, call |UpdateCursorIfNecessary()| here. -} - -void RenderWidgetHostViewMac::ImeUpdateTextInputState( - ui::TextInputType type, - bool can_compose_inline, - const gfx::Rect& caret_rect) { - // TODO(kinaba): currently, can_compose_inline is ignored and always treated - // as true. We need to support "can_compose_inline=false" for PPAPI plugins - // that may want to avoid drawing composition-text by themselves and pass - // the responsibility to the browser. - if (text_input_type_ != type) { - text_input_type_ = type; - if (HasFocus()) { - SetTextInputActive(true); - - // Let AppKit cache the new input context to make IMEs happy. - // See http://crbug.com/73039. - [NSApp updateWindows]; - } - } -} - -void RenderWidgetHostViewMac::ImeCancelComposition() { - [cocoa_view_ cancelComposition]; -} - -void RenderWidgetHostViewMac::ImeCompositionRangeChanged( - const ui::Range& range) { - // The RangeChanged message is only sent with valid values. The current - // caret position (start == end) will be sent if there is no IME range. - [cocoa_view_ setMarkedRange:range.ToNSRange()]; -} - -void RenderWidgetHostViewMac::DidUpdateBackingStore( - const gfx::Rect& scroll_rect, int scroll_dx, int scroll_dy, - const std::vector<gfx::Rect>& copy_rects) { - if (!is_hidden_) { - std::vector<gfx::Rect> rects(copy_rects); - - // Because the findbar might be open, we cannot use scrollRect:by: here. For - // now, simply mark all of scroll rect as dirty. - if (!scroll_rect.IsEmpty()) - rects.push_back(scroll_rect); - - for (size_t i = 0; i < rects.size(); ++i) { - NSRect ns_rect = [cocoa_view_ flipRectToNSRect:rects[i]]; - - if (about_to_validate_and_paint_) { - // As much as we'd like to use -setNeedsDisplayInRect: here, we can't. - // We're in the middle of executing a -drawRect:, and as soon as it - // returns Cocoa will clear its record of what needs display. We - // instead use |performSelector:| to call |setNeedsDisplayInRect:| - // after returning to the main loop, at which point |drawRect:| is no - // longer on the stack. - DCHECK([NSThread isMainThread]); - if (!call_set_needs_display_in_rect_pending_) { - [cocoa_view_ performSelector:@selector(callSetNeedsDisplayInRect) - withObject:nil - afterDelay:0]; - call_set_needs_display_in_rect_pending_ = true; - invalid_rect_ = ns_rect; - } else { - // The old invalid rect is probably invalid now, since the view has - // most likely been resized, but there's no harm in dirtying the - // union. In the limit, this becomes equivalent to dirtying the - // whole view. - invalid_rect_ = NSUnionRect(invalid_rect_, ns_rect); - } - } else { - [cocoa_view_ setNeedsDisplayInRect:ns_rect]; - } - } - - if (!about_to_validate_and_paint_) - [cocoa_view_ displayIfNeeded]; - } - - // If |about_to_validate_and_paint_| is set, then -drawRect: is on the stack - // and it's not allowed to call -setHidden on the accelerated view. In that - // case, -callSetNeedsDisplayInRect: will hide it later. - // If |about_to_validate_and_paint_| is not set, do it now. - if (!about_to_validate_and_paint_) - HandleDelayedGpuViewHiding(); -} - -void RenderWidgetHostViewMac::RenderViewGone(base::TerminationStatus status, - int error_code) { - // TODO(darin): keep this around, and draw sad-tab into it. - Destroy(); -} - -void RenderWidgetHostViewMac::Destroy() { - // On Windows, popups are implemented with a popup window style, so that when - // an event comes in that would "cancel" it, it receives the OnCancelMode - // message and can kill itself. Alas, on the Mac, views cannot capture events - // outside of themselves. On Windows, if Destroy is being called on a view, - // then the event causing the destroy had also cancelled any popups by the - // time Destroy() was called. On the Mac we have to destroy all the popups - // ourselves. - - // Depth-first destroy all popups. Use ShutdownHost() to enforce - // deepest-first ordering. - for (NSView* subview in [cocoa_view_ subviews]) { - if ([subview isKindOfClass:[RenderWidgetHostViewCocoa class]]) { - [static_cast<RenderWidgetHostViewCocoa*>(subview) - renderWidgetHostViewMac]->ShutdownHost(); - } else if ([subview isKindOfClass:[AcceleratedPluginView class]]) { - [static_cast<AcceleratedPluginView*>(subview) - onRenderWidgetHostViewGone]; - } - } - - // We've been told to destroy. - [cocoa_view_ retain]; - [cocoa_view_ removeFromSuperview]; - [cocoa_view_ autorelease]; - - // We get this call just before |render_widget_host_| deletes - // itself. But we are owned by |cocoa_view_|, which may be retained - // by some other code. Examples are TabContentsViewMac's - // |latent_focus_view_| and TabWindowController's - // |cachedContentView_|. - render_widget_host_ = NULL; -} - -// Called from the renderer to tell us what the tooltip text should be. It -// calls us frequently so we need to cache the value to prevent doing a lot -// of repeat work. -void RenderWidgetHostViewMac::SetTooltipText(const string16& tooltip_text) { - if (tooltip_text != tooltip_text_ && [[cocoa_view_ window] isKeyWindow]) { - tooltip_text_ = tooltip_text; - - // Clamp the tooltip length to kMaxTooltipLength. It's a DOS issue on - // Windows; we're just trying to be polite. Don't persist the trimmed - // string, as then the comparison above will always fail and we'll try to - // set it again every single time the mouse moves. - string16 display_text = tooltip_text_; - if (tooltip_text_.length() > kMaxTooltipLength) - display_text = tooltip_text_.substr(0, kMaxTooltipLength); - - NSString* tooltip_nsstring = base::SysUTF16ToNSString(display_text); - [cocoa_view_ setToolTipAtMousePoint:tooltip_nsstring]; - } -} - -// -// RenderWidgetHostViewCocoa uses the stored selection text, -// which implements NSServicesRequests protocol. -// -void RenderWidgetHostViewMac::SelectionChanged(const std::string& text, - const ui::Range& range, - const gfx::Point& start, - const gfx::Point& end) { - selected_text_ = text; - [cocoa_view_ setSelectedRange:range.ToNSRange()]; - // Updaes markedRange when there is no marked text so that retrieving - // markedRange immediately after calling setMarkdText: returns the current - // caret position. - if (![cocoa_view_ hasMarkedText]) { - [cocoa_view_ setMarkedRange:range.ToNSRange()]; - } -} - -void RenderWidgetHostViewMac::ShowingContextMenu(bool showing) { - DCHECK_NE(is_showing_context_menu_, showing); - is_showing_context_menu_ = showing; - - // If the menu was closed, restore the cursor to the saved version initially, - // as the renderer will not re-send it if there was no change. - if (!showing) - UpdateCursorIfNecessary(); - - // Create a fake mouse event to inform the render widget that the mouse - // left or entered. - NSWindow* window = [cocoa_view_ window]; - // TODO(asvitkine): If the location outside of the event stream doesn't - // correspond to the current event (due to delayed event processing), then - // this may result in a cursor flicker if there are later mouse move events - // in the pipeline. Find a way to use the mouse location from the event that - // dismissed the context menu. - NSPoint location = [window mouseLocationOutsideOfEventStream]; - NSEvent* event = [NSEvent mouseEventWithType:NSMouseMoved - location:location - modifierFlags:0 - timestamp:0 - windowNumber:[window windowNumber] - context:nil - eventNumber:0 - clickCount:0 - pressure:0]; - WebMouseEvent web_event = - WebInputEventFactory::mouseEvent(event, cocoa_view_); - if (showing) - web_event.type = WebInputEvent::MouseLeave; - render_widget_host_->ForwardMouseEvent(web_event); -} - -bool RenderWidgetHostViewMac::IsPopup() const { - return popup_type_ != WebKit::WebPopupTypeNone; -} - -BackingStore* RenderWidgetHostViewMac::AllocBackingStore( - const gfx::Size& size) { - return new BackingStoreMac(render_widget_host_, size); -} - -// Sets whether or not to accept first responder status. -void RenderWidgetHostViewMac::SetTakesFocusOnlyOnMouseDown(bool flag) { - [cocoa_view_ setTakesFocusOnlyOnMouseDown:flag]; -} - -void RenderWidgetHostViewMac::KillSelf() { - if (shutdown_factory_.empty()) { - [cocoa_view_ setHidden:YES]; - MessageLoop::current()->PostTask(FROM_HERE, - shutdown_factory_.NewRunnableMethod( - &RenderWidgetHostViewMac::ShutdownHost)); - } -} - -void RenderWidgetHostViewMac::PluginFocusChanged(bool focused, int plugin_id) { - [cocoa_view_ pluginFocusChanged:(focused ? YES : NO) forPlugin:plugin_id]; -} - -void RenderWidgetHostViewMac::StartPluginIme() { - [cocoa_view_ setPluginImeActive:YES]; -} - -bool RenderWidgetHostViewMac::PostProcessEventForPluginIme( - const NativeWebKeyboardEvent& event) { - // Check WebInputEvent type since multiple types of events can be sent into - // WebKit for the same OS event (e.g., RawKeyDown and Char), so filtering is - // necessary to avoid double processing. - // Also check the native type, since NSFlagsChanged is considered a key event - // for WebKit purposes, but isn't considered a key event by the OS. - if (event.type == WebInputEvent::RawKeyDown && - [event.os_event type] == NSKeyDown) - return [cocoa_view_ postProcessEventForPluginIme:event.os_event]; - return false; -} - -void RenderWidgetHostViewMac::PluginImeCompositionCompleted( - const string16& text, int plugin_id) { - if (render_widget_host_) { - render_widget_host_->Send(new ViewMsg_PluginImeCompositionCompleted( - render_widget_host_->routing_id(), text, plugin_id)); - } -} - -gfx::PluginWindowHandle -RenderWidgetHostViewMac::AllocateFakePluginWindowHandle(bool opaque, - bool root) { - CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - // |render_widget_host_| is set to NULL when |RWHVMac::Destroy()| has - // completed. If |AllocateFakePluginWindowHandle()| is called after that, - // we will crash when the AcceleratedPluginView we allocate below is - // destroyed. - DCHECK(render_widget_host_); - - // Create an NSView to host the plugin's/compositor's pixels. - gfx::PluginWindowHandle handle = - plugin_container_manager_.AllocateFakePluginWindowHandle(opaque, root); - - scoped_nsobject<AcceleratedPluginView> plugin_view( - [[AcceleratedPluginView alloc] initWithRenderWidgetHostViewMac:this - pluginHandle:handle]); - [plugin_view setHidden:YES]; - - [cocoa_view_ addSubview:plugin_view]; - plugin_views_[handle] = plugin_view; - - return handle; -} - -void RenderWidgetHostViewMac::DestroyFakePluginWindowHandle( - gfx::PluginWindowHandle window) { - CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - PluginViewMap::iterator it = plugin_views_.find(window); - DCHECK(plugin_views_.end() != it); - if (plugin_views_.end() == it) { - return; - } - [it->second removeFromSuperview]; - plugin_views_.erase(it); - - // The view's dealloc will call DeallocFakePluginWindowHandle(), which will - // remove the handle from |plugin_container_manager_|. This code path is - // taken if a plugin is removed, but the RWHVMac itself stays alive. -} - -// This is called by AcceleratedPluginView's -dealloc. -void RenderWidgetHostViewMac::DeallocFakePluginWindowHandle( - gfx::PluginWindowHandle window) { - // When a browser window with a GpuScheduler is closed, the render process - // will attempt to finish all GL commands. It will busy-wait on the GPU - // process until the command queue is empty. If a paint is pending, the GPU - // process won't process any GL commands until the browser sends a paint ack, - // but since the browser window is already closed, it will never arrive. - // To resolve this we ask the GPU process to destroy the command buffer - // associated with the given render widget. Once the command buffer is - // destroyed, all GL commands from the renderer will immediately receive - // channel error. - if (render_widget_host_ && - plugin_container_manager_.IsRootContainer(window)) { - GpuProcessHost::SendOnIO( - render_widget_host_->process()->id(), - content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH, - new GpuMsg_DestroyCommandBuffer( - render_widget_host_->process()->id(), - render_widget_host_->routing_id())); - } - - plugin_container_manager_.DestroyFakePluginWindowHandle(window); -} - -AcceleratedPluginView* RenderWidgetHostViewMac::ViewForPluginWindowHandle( - gfx::PluginWindowHandle window) { - PluginViewMap::iterator it = plugin_views_.find(window); - DCHECK(plugin_views_.end() != it); - if (plugin_views_.end() == it) - return nil; - return it->second; -} - -void RenderWidgetHostViewMac::AcceleratedSurfaceSetIOSurface( - gfx::PluginWindowHandle window, - int32 width, - int32 height, - uint64 io_surface_identifier) { - CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - plugin_container_manager_.SetSizeAndIOSurface(window, - width, - height, - io_surface_identifier); - - if (plugin_container_manager_.IsRootContainer(window)) { - // Fake up a WebPluginGeometry for the root window to set the - // container's size; we will never get a notification from the - // browser about the root window, only plugins. - webkit::npapi::WebPluginGeometry geom; - gfx::Rect rect(0, 0, width, height); - geom.window = window; - geom.window_rect = rect; - geom.clip_rect = rect; - geom.visible = true; - geom.rects_valid = true; - MovePluginWindows(std::vector<webkit::npapi::WebPluginGeometry>(1, geom)); - } -} - -void RenderWidgetHostViewMac::AcceleratedSurfaceSetTransportDIB( - gfx::PluginWindowHandle window, - int32 width, - int32 height, - TransportDIB::Handle transport_dib) { - CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - plugin_container_manager_.SetSizeAndTransportDIB(window, - width, - height, - transport_dib); -} - -void RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped( - gfx::PluginWindowHandle window, - uint64 surface_id, - int renderer_id, - int32 route_id, - int gpu_host_id, - uint64 swap_buffers_count) { - TRACE_EVENT1("browser", - "RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped", - "frameNum", swap_buffers_count); - CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - AcceleratedPluginView* view = ViewForPluginWindowHandle(window); - DCHECK(view); - if (view) { - plugin_container_manager_.SetSurfaceWasPaintedTo(window, surface_id); - - // The surface is hidden until its first paint, to not show gargabe. - if (plugin_container_manager_.SurfaceShouldBeVisible(window)) - [view setHidden:NO]; - [view drawView]; - } - - if (renderer_id != 0 || route_id != 0) { - AcknowledgeSwapBuffers(renderer_id, - route_id, - gpu_host_id, - swap_buffers_count); - } -} - -void RenderWidgetHostViewMac::UpdateRootGpuViewVisibility( - bool show_gpu_widget) { - // Plugins are destroyed on page navigate. The compositor layer on the other - // hand is created on demand and then stays alive until its renderer process - // dies (usually on cross-domain navigation). Instead, only a flag - // |is_accelerated_compositing_active()| is flipped when the compositor output - // should be shown/hidden. - // Show/hide the view belonging to the compositor here. - plugin_container_manager_.set_gpu_rendering_active(show_gpu_widget); - - gfx::PluginWindowHandle root_handle = - plugin_container_manager_.root_container_handle(); - if (root_handle != gfx::kNullPluginWindow) { - AcceleratedPluginView* view = ViewForPluginWindowHandle(root_handle); - DCHECK(view); - bool visible = - plugin_container_manager_.SurfaceShouldBeVisible(root_handle); - [[view window] disableScreenUpdatesUntilFlush]; - [view setHidden:!visible]; - } -} - -void RenderWidgetHostViewMac::HandleDelayedGpuViewHiding() { - if (needs_gpu_visibility_update_after_repaint_) { - UpdateRootGpuViewVisibility(false); - needs_gpu_visibility_update_after_repaint_ = false; - } -} - -void RenderWidgetHostViewMac::AcknowledgeSwapBuffers( - int renderer_id, - int32 route_id, - int gpu_host_id, - uint64 swap_buffers_count) { - TRACE_EVENT1("gpu", "RenderWidgetHostViewMac::AcknowledgeSwapBuffers", - "swap_buffers_count", swap_buffers_count); - // Called on the display link thread. Hand actual work off to the IO thread, - // because |GpuProcessHost::Get()| can only be called there. - // Currently, this is never called for plugins. - if (render_widget_host_) { - DCHECK_EQ(render_widget_host_->process()->id(), renderer_id); - // |render_widget_host_->routing_id()| and |route_id| are usually not - // equal: The former identifies the channel from the RWH in the browser - // process to the corresponding render widget in the renderer process, while - // the latter identifies the channel from the GpuCommandBufferStub in the - // GPU process to the corresponding command buffer client in the renderer. - } - - // TODO(apatrick): Send the acknowledgement via the UI thread when running in - // single process or in process GPU mode for now. This is bad from a - // performance point of view but the plan is to not use AcceleratedSurface at - // all in these cases. - if (gpu_host_id == 0) { - BrowserThread::PostTask( - BrowserThread::UI, - FROM_HERE, - NewRunnableFunction(&GpuProcessHostUIShim::SendToGpuHost, - gpu_host_id, - new GpuMsg_AcceleratedSurfaceBuffersSwappedACK( - renderer_id, - route_id, - swap_buffers_count))); - } else { - GpuProcessHost::SendOnIO( - gpu_host_id, - content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH, - new GpuMsg_AcceleratedSurfaceBuffersSwappedACK( - renderer_id, route_id, swap_buffers_count)); - } -} - -void RenderWidgetHostViewMac::GpuRenderingStateDidChange() { - CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - if (GetRenderWidgetHost()->is_accelerated_compositing_active()) { - UpdateRootGpuViewVisibility( - GetRenderWidgetHost()->is_accelerated_compositing_active()); - } else { - needs_gpu_visibility_update_after_repaint_ = true; - } -} - -void RenderWidgetHostViewMac::GetScreenInfo(WebKit::WebScreenInfo* results) { - *results = WebKit::WebScreenInfoFactory::screenInfo(GetNativeView()); -} - -gfx::Rect RenderWidgetHostViewMac::GetRootWindowBounds() { - // TODO(shess): In case of !window, the view has been removed from - // the view hierarchy because the tab isn't main. Could retrieve - // the information from the main tab for our window. - NSWindow* enclosing_window = ApparentWindowForView(cocoa_view_); - if (!enclosing_window) - return gfx::Rect(); - - NSRect bounds = [enclosing_window frame]; - return FlipNSRectToRectScreen(bounds); -} - -gfx::PluginWindowHandle RenderWidgetHostViewMac::GetCompositingSurface() { - if (compositing_surface_ == gfx::kNullPluginWindow) - compositing_surface_ = AllocateFakePluginWindowHandle( - /*opaque=*/true, /*root=*/true); - return compositing_surface_; -} - -void RenderWidgetHostViewMac::DrawAcceleratedSurfaceInstance( - CGLContextObj context, - gfx::PluginWindowHandle plugin_handle, - NSSize size) { - TRACE_EVENT0("browser", - "RenderWidgetHostViewMac::DrawAcceleratedSurfaceInstance"); - // Called on the display link thread. - CGLSetCurrentContext(context); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - // Note that we place the origin at the upper left corner with +y - // going down - glOrtho(0, size.width, size.height, 0, -1, 1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - plugin_container_manager_.Draw(context, plugin_handle); -} - -void RenderWidgetHostViewMac::ForceTextureReload() { - plugin_container_manager_.ForceTextureReload(); -} - -void RenderWidgetHostViewMac::SetVisuallyDeemphasized(const SkColor* color, - bool animate) { - // This is not used on mac. -} - -void RenderWidgetHostViewMac::UnhandledWheelEvent( - const WebKit::WebMouseWheelEvent& event) { - [cocoa_view_ gotUnhandledWheelEvent]; -} - -void RenderWidgetHostViewMac::SetHasHorizontalScrollbar( - bool has_horizontal_scrollbar) { - [cocoa_view_ setHasHorizontalScrollbar:has_horizontal_scrollbar]; -} - -void RenderWidgetHostViewMac::SetScrollOffsetPinning( - bool is_pinned_to_left, bool is_pinned_to_right) { - [cocoa_view_ scrollOffsetPinnedToLeft:is_pinned_to_left - toRight:is_pinned_to_right]; -} - -bool RenderWidgetHostViewMac::LockMouse() { - NOTIMPLEMENTED(); - return false; -} - -void RenderWidgetHostViewMac::UnlockMouse() { - NOTIMPLEMENTED(); -} - -void RenderWidgetHostViewMac::ShutdownHost() { - shutdown_factory_.RevokeAll(); - render_widget_host_->Shutdown(); - // Do not touch any members at this point, |this| has been deleted. -} - -gfx::Rect RenderWidgetHostViewMac::GetViewCocoaBounds() const { - return gfx::Rect(NSRectToCGRect([cocoa_view_ bounds])); -} - -void RenderWidgetHostViewMac::SetActive(bool active) { - if (render_widget_host_) { - render_widget_host_->Send(new ViewMsg_SetActive( - render_widget_host_->routing_id(), active)); - } - if (HasFocus()) - SetTextInputActive(active); - if (!active) - [cocoa_view_ setPluginImeActive:NO]; -} - -void RenderWidgetHostViewMac::SetWindowVisibility(bool visible) { - if (render_widget_host_) { - render_widget_host_->Send(new ViewMsg_SetWindowVisibility( - render_widget_host_->routing_id(), visible)); - } -} - -void RenderWidgetHostViewMac::WindowFrameChanged() { - if (render_widget_host_) { - render_widget_host_->Send(new ViewMsg_WindowFrameChanged( - render_widget_host_->routing_id(), GetRootWindowBounds(), - GetViewBounds())); - } -} - -void RenderWidgetHostViewMac::SetBackground(const SkBitmap& background) { - RenderWidgetHostView::SetBackground(background); - if (render_widget_host_) - render_widget_host_->Send(new ViewMsg_SetBackground( - render_widget_host_->routing_id(), background)); -} - -void RenderWidgetHostViewMac::OnAccessibilityNotifications( - const std::vector<ViewHostMsg_AccessibilityNotification_Params>& params) { - if (!browser_accessibility_manager_.get()) { - browser_accessibility_manager_.reset( - BrowserAccessibilityManager::CreateEmptyDocument( - cocoa_view_, static_cast<WebAccessibility::State>(0), NULL)); - } - browser_accessibility_manager_->OnAccessibilityNotifications(params); -} - -void RenderWidgetHostViewMac::SetTextInputActive(bool active) { - if (active) { - if (text_input_type_ == ui::TEXT_INPUT_TYPE_PASSWORD) - EnablePasswordInput(); - else - DisablePasswordInput(); - } else { - if (text_input_type_ == ui::TEXT_INPUT_TYPE_PASSWORD) - DisablePasswordInput(); - } -} - -// RenderWidgetHostViewCocoa --------------------------------------------------- - -@implementation RenderWidgetHostViewCocoa - -@synthesize selectedRange = selectedRange_; -@synthesize markedRange = markedRange_; - -- (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { - self = [super initWithFrame:NSZeroRect]; - if (self) { - editCommand_helper_.reset(new RenderWidgetHostViewMacEditCommandHelper); - editCommand_helper_->AddEditingSelectorsToClass([self class]); - - renderWidgetHostView_.reset(r); - canBeKeyView_ = YES; - focusedPluginIdentifier_ = -1; - } - return self; -} - -- (void)dealloc { - if (delegate_ && [delegate_ respondsToSelector:@selector(viewGone:)]) - [delegate_ viewGone:self]; - - [super dealloc]; -} - -- (void)setRWHVDelegate:(RenderWidgetHostViewMacDelegate*)delegate { - delegate_ = delegate; -} - -- (void)gotUnhandledWheelEvent { - if (delegate_ && - [delegate_ respondsToSelector:@selector(gotUnhandledWheelEvent)]) { - [delegate_ gotUnhandledWheelEvent]; - } -} - -- (void)scrollOffsetPinnedToLeft:(BOOL)left toRight:(BOOL)right { - if (delegate_ && [delegate_ respondsToSelector: - @selector(scrollOffsetPinnedToLeft:toRight:)]) { - [delegate_ scrollOffsetPinnedToLeft:left toRight:right]; - } -} - -- (void)setHasHorizontalScrollbar:(BOOL)has_horizontal_scrollbar { - if (delegate_ && - [delegate_ respondsToSelector:@selector(setHasHorizontalScrollbar:)]) { - [delegate_ setHasHorizontalScrollbar:has_horizontal_scrollbar]; - } -} - -- (BOOL)respondsToSelector:(SEL)selector { - // Trickiness: this doesn't mean "does this object's superclass respond to - // this selector" but rather "does the -respondsToSelector impl from the - // superclass say that this class responds to the selector". - if ([super respondsToSelector:selector]) - return YES; - - if (delegate_) - return [delegate_ respondsToSelector:selector]; - else - return NO; -} - -- (NSMethodSignature*)methodSignatureForSelector:(SEL)selector { - // Trickiness: this doesn't mean "does this object's superclass respond to - // this selector" but rather "does the -respondsToSelector impl from the - // superclass say that this class responds to the selector". - if ([super respondsToSelector:selector]) - return [super methodSignatureForSelector:selector]; - - if (delegate_) - return [delegate_ methodSignatureForSelector:selector]; - else - return nil; -} - -- (void)forwardInvocation:(NSInvocation*)invocation { - // TODO(avi): Oh, man, use -forwardingTargetForSelector: when 10.6 is the - // minimum requirement. - - if (delegate_ && [delegate_ respondsToSelector:[invocation selector]]) - [invocation invokeWithTarget:delegate_]; - else - [super forwardInvocation:invocation]; -} - -- (void)setCanBeKeyView:(BOOL)can { - canBeKeyView_ = can; -} - -- (void)setTakesFocusOnlyOnMouseDown:(BOOL)b { - takesFocusOnlyOnMouseDown_ = b; -} - -- (void)setCloseOnDeactivate:(BOOL)b { - closeOnDeactivate_ = b; -} - -- (BOOL)shouldIgnoreMouseEvent:(NSEvent*)theEvent { - NSWindow* window = [self window]; - // If this is a background window, don't handle mouse movement events. This - // is the expected behavior on the Mac as evidenced by other applications. - // Do this only if the window level is NSNormalWindowLevel, as this - // does not necessarily apply in other contexts (e.g. balloons). - if ([theEvent type] == NSMouseMoved && - [window level] == NSNormalWindowLevel && ![window isKeyWindow]) { - return YES; - } - - // Use hitTest to check whether the mouse is over a nonWebContentView - in - // which case the mouse event should not be handled by the render host. - const SEL nonWebContentViewSelector = @selector(nonWebContentView); - NSView* contentView = [window contentView]; - NSView* view = [contentView hitTest:[theEvent locationInWindow]]; - // Traverse the superview hierarchy as the hitTest will return the frontmost - // view, such as an NSTextView, while nonWebContentView may be specified by - // its parent view. - while (view) { - if ([view respondsToSelector:nonWebContentViewSelector] && - [view performSelector:nonWebContentViewSelector]) { - // The cursor is over a nonWebContentView - ignore this mouse event. - return YES; - } - view = [view superview]; - } - return NO; -} - -- (void)mouseEvent:(NSEvent*)theEvent { - if (delegate_ && [delegate_ respondsToSelector:@selector(handleEvent:)]) { - BOOL handled = [delegate_ handleEvent:theEvent]; - if (handled) - return; - } - - if ([self shouldIgnoreMouseEvent:theEvent]) { - // If this is the first such event, send a mouse exit to the host view. - if (!mouseEventWasIgnored_ && renderWidgetHostView_->render_widget_host_) { - WebMouseEvent exitEvent = - WebInputEventFactory::mouseEvent(theEvent, self); - exitEvent.type = WebInputEvent::MouseLeave; - exitEvent.button = WebMouseEvent::ButtonNone; - renderWidgetHostView_->render_widget_host_->ForwardMouseEvent(exitEvent); - } - mouseEventWasIgnored_ = YES; - return; - } - - if (mouseEventWasIgnored_) { - // If this is the first mouse event after a previous event that was ignored - // due to the hitTest, send a mouse enter event to the host view. - if (renderWidgetHostView_->render_widget_host_) { - WebMouseEvent enterEvent = - WebInputEventFactory::mouseEvent(theEvent, self); - enterEvent.type = WebInputEvent::MouseMove; - enterEvent.button = WebMouseEvent::ButtonNone; - renderWidgetHostView_->render_widget_host_->ForwardMouseEvent(enterEvent); - } - } - mouseEventWasIgnored_ = NO; - - // TODO(rohitrao): Probably need to handle other mouse down events here. - if ([theEvent type] == NSLeftMouseDown && takesFocusOnlyOnMouseDown_) { - if (renderWidgetHostView_->render_widget_host_) - renderWidgetHostView_->render_widget_host_->OnMouseActivate(); - - // Manually take focus after the click but before forwarding it to the - // renderer. - [[self window] makeFirstResponder:self]; - } - - // Don't cancel child popups; killing them on a mouse click would prevent the - // user from positioning the insertion point in the text field spawning the - // popup. A click outside the text field would cause the text field to drop - // the focus, and then EditorClientImpl::textFieldDidEndEditing() would cancel - // the popup anyway, so we're OK. - - NSEventType type = [theEvent type]; - if (type == NSLeftMouseDown) - hasOpenMouseDown_ = YES; - else if (type == NSLeftMouseUp) - hasOpenMouseDown_ = NO; - - // TODO(suzhe): We should send mouse events to the input method first if it - // wants to handle them. But it won't work without implementing method - // - (NSUInteger)characterIndexForPoint:. - // See: http://code.google.com/p/chromium/issues/detail?id=47141 - // Instead of sending mouse events to the input method first, we now just - // simply confirm all ongoing composition here. - if (type == NSLeftMouseDown || type == NSRightMouseDown || - type == NSOtherMouseDown) { - [self confirmComposition]; - } - - const WebMouseEvent& event = - WebInputEventFactory::mouseEvent(theEvent, self); - - if (renderWidgetHostView_->render_widget_host_) - renderWidgetHostView_->render_widget_host_->ForwardMouseEvent(event); -} - -- (void)shortCircuitEndGestureWithEvent:(NSEvent*)event { - DCHECK(base::mac::IsOSLionOrLater()); - - if ([event subtype] != kIOHIDEventTypeScroll) - return; - - if (renderWidgetHostView_->render_widget_host_) { - WebGestureEvent webEvent = WebInputEventFactory::gestureEvent(event, self); - renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(webEvent); - } - - if (endGestureMonitor_) { - [NSEvent removeMonitor:endGestureMonitor_]; - endGestureMonitor_ = nil; - } -} - -- (void)beginGestureWithEvent:(NSEvent*)event { - if (base::mac::IsOSLionOrLater() && - [event subtype] == kIOHIDEventTypeScroll && - renderWidgetHostView_->render_widget_host_) { - WebGestureEvent webEvent = WebInputEventFactory::gestureEvent(event, self); - renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(webEvent); - - // Use an NSEvent monitor to get the gesture-end event. This is done in - // order to get the gesture-end, even if the view is not visible, which is - // not the case with -endGestureWithEvent:. An example scenario where this - // may happen is switching tabs while a gesture is in progress. - if (!endGestureMonitor_) { - endGestureMonitor_ = - [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskEndGesture - handler:^(NSEvent* blockEvent) { - [self shortCircuitEndGestureWithEvent:blockEvent]; - return blockEvent; - }]; - } - } -} - -- (BOOL)performKeyEquivalent:(NSEvent*)theEvent { - // |performKeyEquivalent:| is sent to all views of a window, not only down the - // responder chain (cf. "Handling Key Equivalents" in - // http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/EventOverview/HandlingKeyEvents/HandlingKeyEvents.html - // ). We only want to handle key equivalents if we're first responder. - if ([[self window] firstResponder] != self) - return NO; - - // If we return |NO| from this function, cocoa will send the key event to - // the menu and only if the menu does not process the event to |keyDown:|. We - // want to send the event to a renderer _before_ sending it to the menu, so - // we need to return |YES| for all events that might be swallowed by the menu. - // We do not return |YES| for every keypress because we don't get |keyDown:| - // events for keys that we handle this way. - NSUInteger modifierFlags = [theEvent modifierFlags]; - if ((modifierFlags & NSCommandKeyMask) == 0) { - // Make sure the menu does not contain key equivalents that don't - // contain cmd. - DCHECK(![[NSApp mainMenu] performKeyEquivalent:theEvent]); - return NO; - } - - // Command key combinations are sent via performKeyEquivalent rather than - // keyDown:. We just forward this on and if WebCore doesn't want to handle - // it, we let the TabContentsView figure out how to reinject it. - [self keyEvent:theEvent wasKeyEquivalent:YES]; - return YES; -} - -- (BOOL)_wantsKeyDownForEvent:(NSEvent*)event { - // This is a SPI that AppKit apparently calls after |performKeyEquivalent:| - // returned NO. If this function returns |YES|, Cocoa sends the event to - // |keyDown:| instead of doing other things with it. Ctrl-tab will be sent - // to us instead of doing key view loop control, ctrl-left/right get handled - // correctly, etc. - // (However, there are still some keys that Cocoa swallows, e.g. the key - // equivalent that Cocoa uses for toggling the input language. In this case, - // that's actually a good thing, though -- see http://crbug.com/26115 .) - return YES; -} - -- (void)keyEvent:(NSEvent*)theEvent { - if (delegate_ && [delegate_ respondsToSelector:@selector(handleEvent:)]) { - BOOL handled = [delegate_ handleEvent:theEvent]; - if (handled) - return; - } - - [self keyEvent:theEvent wasKeyEquivalent:NO]; -} - -- (void)keyEvent:(NSEvent*)theEvent wasKeyEquivalent:(BOOL)equiv { - DCHECK([theEvent type] != NSKeyDown || - !equiv == !([theEvent modifierFlags] & NSCommandKeyMask)); - - if ([theEvent type] == NSFlagsChanged) { - // Ignore NSFlagsChanged events from the NumLock and Fn keys as - // Safari does in -[WebHTMLView flagsChanged:] (of "WebHTMLView.mm"). - int keyCode = [theEvent keyCode]; - if (!keyCode || keyCode == 10 || keyCode == 63) - return; - } - - // Don't cancel child popups; the key events are probably what's triggering - // the popup in the first place. - - RenderWidgetHost* widgetHost = renderWidgetHostView_->render_widget_host_; - DCHECK(widgetHost); - - NativeWebKeyboardEvent event(theEvent); - - // We only handle key down events and just simply forward other events. - if ([theEvent type] != NSKeyDown) { - widgetHost->ForwardKeyboardEvent(event); - - // Possibly autohide the cursor. - if ([RenderWidgetHostViewCocoa shouldAutohideCursorForEvent:theEvent]) - [NSCursor setHiddenUntilMouseMoves:YES]; - - return; - } - - scoped_nsobject<RenderWidgetHostViewCocoa> keepSelfAlive([self retain]); - - // Records the current marked text state, so that we can know if the marked - // text was deleted or not after handling the key down event. - BOOL oldHasMarkedText = hasMarkedText_; - - // This method should not be called recursively. - DCHECK(!handlingKeyDown_); - - // Tells insertText: and doCommandBySelector: that we are handling a key - // down event. - handlingKeyDown_ = YES; - - // These variables might be set when handling the keyboard event. - // Clear them here so that we can know whether they have changed afterwards. - textToBeInserted_.clear(); - markedText_.clear(); - underlines_.clear(); - unmarkTextCalled_ = NO; - hasEditCommands_ = NO; - editCommands_.clear(); - - // Before doing anything with a key down, check to see if plugin IME has been - // cancelled, since the plugin host needs to be informed of that before - // receiving the keydown. - if ([theEvent type] == NSKeyDown) - [self checkForPluginImeCancellation]; - - // Sends key down events to input method first, then we can decide what should - // be done according to input method's feedback. - // If a plugin is active, bypass this step since events are forwarded directly - // to the plugin IME. - if (focusedPluginIdentifier_ == -1) - [self interpretKeyEvents:[NSArray arrayWithObject:theEvent]]; - - handlingKeyDown_ = NO; - - // Indicates if we should send the key event and corresponding editor commands - // after processing the input method result. - BOOL delayEventUntilAfterImeCompostion = NO; - - // To emulate Windows, over-write |event.windowsKeyCode| to VK_PROCESSKEY - // while an input method is composing or inserting a text. - // Gmail checks this code in its onkeydown handler to stop auto-completing - // e-mail addresses while composing a CJK text. - // If the text to be inserted has only one character, then we don't need this - // trick, because we'll send the text as a key press event instead. - if (hasMarkedText_ || oldHasMarkedText || textToBeInserted_.length() > 1) { - NativeWebKeyboardEvent fakeEvent = event; - fakeEvent.windowsKeyCode = 0xE5; // VKEY_PROCESSKEY - fakeEvent.setKeyIdentifierFromWindowsKeyCode(); - fakeEvent.skip_in_browser = true; - widgetHost->ForwardKeyboardEvent(fakeEvent); - // If this key event was handled by the input method, but - // -doCommandBySelector: (invoked by the call to -interpretKeyEvents: above) - // enqueued edit commands, then in order to let webkit handle them - // correctly, we need to send the real key event and corresponding edit - // commands after processing the input method result. - // We shouldn't do this if a new marked text was set by the input method, - // otherwise the new marked text might be cancelled by webkit. - if (hasEditCommands_ && !hasMarkedText_) - delayEventUntilAfterImeCompostion = YES; - } else { - if (!editCommands_.empty()) { - widgetHost->Send(new ViewMsg_SetEditCommandsForNextKeyEvent( - widgetHost->routing_id(), editCommands_)); - } - widgetHost->ForwardKeyboardEvent(event); - } - - // Calling ForwardKeyboardEvent() could have destroyed the widget. When the - // widget was destroyed, |renderWidgetHostView_->render_widget_host_| will - // be set to NULL. So we check it here and return immediately if it's NULL. - if (!renderWidgetHostView_->render_widget_host_) - return; - - // Then send keypress and/or composition related events. - // If there was a marked text or the text to be inserted is longer than 1 - // character, then we send the text by calling ConfirmComposition(). - // Otherwise, if the text to be inserted only contains 1 character, then we - // can just send a keypress event which is fabricated by changing the type of - // the keydown event, so that we can retain all necessary informations, such - // as unmodifiedText, etc. And we need to set event.skip_in_browser to true to - // prevent the browser from handling it again. - // Note that, |textToBeInserted_| is a UTF-16 string, but it's fine to only - // handle BMP characters here, as we can always insert non-BMP characters as - // text. - BOOL textInserted = NO; - if (textToBeInserted_.length() > - ((hasMarkedText_ || oldHasMarkedText) ? 0u : 1u)) { - widgetHost->ImeConfirmComposition(textToBeInserted_); - textInserted = YES; - } - - // Updates or cancels the composition. If some text has been inserted, then - // we don't need to cancel the composition explicitly. - if (hasMarkedText_ && markedText_.length()) { - // Sends the updated marked text to the renderer so it can update the - // composition node in WebKit. - // When marked text is available, |selectedRange_| will be the range being - // selected inside the marked text. - widgetHost->ImeSetComposition(markedText_, underlines_, - selectedRange_.location, - NSMaxRange(selectedRange_)); - } else if (oldHasMarkedText && !hasMarkedText_ && !textInserted) { - if (unmarkTextCalled_) - widgetHost->ImeConfirmComposition(); - else - widgetHost->ImeCancelComposition(); - } - - // If the key event was handled by the input method but it also generated some - // edit commands, then we need to send the real key event and corresponding - // edit commands here. This usually occurs when the input method wants to - // finish current composition session but still wants the application to - // handle the key event. See http://crbug.com/48161 for reference. - if (delayEventUntilAfterImeCompostion) { - // If |delayEventUntilAfterImeCompostion| is YES, then a fake key down event - // with windowsKeyCode == 0xE5 has already been sent to webkit. - // So before sending the real key down event, we need to send a fake key up - // event to balance it. - NativeWebKeyboardEvent fakeEvent = event; - fakeEvent.type = WebKit::WebInputEvent::KeyUp; - fakeEvent.skip_in_browser = true; - widgetHost->ForwardKeyboardEvent(fakeEvent); - // Not checking |renderWidgetHostView_->render_widget_host_| here because - // a key event with |skip_in_browser| == true won't be handled by browser, - // thus it won't destroy the widget. - - if (!editCommands_.empty()) { - widgetHost->Send(new ViewMsg_SetEditCommandsForNextKeyEvent( - widgetHost->routing_id(), editCommands_)); - } - widgetHost->ForwardKeyboardEvent(event); - - // Calling ForwardKeyboardEvent() could have destroyed the widget. When the - // widget was destroyed, |renderWidgetHostView_->render_widget_host_| will - // be set to NULL. So we check it here and return immediately if it's NULL. - if (!renderWidgetHostView_->render_widget_host_) - return; - } - - const NSUInteger kCtrlCmdKeyMask = NSControlKeyMask | NSCommandKeyMask; - // Only send a corresponding key press event if there is no marked text. - if (!hasMarkedText_) { - if (!textInserted && textToBeInserted_.length() == 1) { - // If a single character was inserted, then we just send it as a keypress - // event. - event.type = WebKit::WebInputEvent::Char; - event.text[0] = textToBeInserted_[0]; - event.text[1] = 0; - event.skip_in_browser = true; - widgetHost->ForwardKeyboardEvent(event); - } else if ((!textInserted || delayEventUntilAfterImeCompostion) && - [[theEvent characters] length] > 0 && - (([theEvent modifierFlags] & kCtrlCmdKeyMask) || - (hasEditCommands_ && editCommands_.empty()))) { - // We don't get insertText: calls if ctrl or cmd is down, or the key event - // generates an insert command. So synthesize a keypress event for these - // cases, unless the key event generated any other command. - event.type = WebKit::WebInputEvent::Char; - event.skip_in_browser = true; - widgetHost->ForwardKeyboardEvent(event); - } - } - - // Possibly autohide the cursor. - if ([RenderWidgetHostViewCocoa shouldAutohideCursorForEvent:theEvent]) - [NSCursor setHiddenUntilMouseMoves:YES]; -} - -- (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) - return; - } - - const WebMouseWheelEvent& event = - WebInputEventFactory::mouseWheelEvent(theEvent, self); - if (renderWidgetHostView_->render_widget_host_) - 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)setFrameSize:(NSSize)newSize { - [super setFrameSize:newSize]; - if (renderWidgetHostView_->render_widget_host_) - renderWidgetHostView_->render_widget_host_->WasResized(); -} - -- (void)setFrame:(NSRect)frameRect { - [super setFrame:frameRect]; - if (renderWidgetHostView_->render_widget_host_) - renderWidgetHostView_->render_widget_host_->WasResized(); -} - -- (void)setFrameWithDeferredUpdate:(NSRect)frameRect { - [super setFrame:frameRect]; - [self performSelector:@selector(renderWidgetHostWasResized) - withObject:nil - afterDelay:0]; -} - -- (void)renderWidgetHostWasResized { - if (renderWidgetHostView_->render_widget_host_) - renderWidgetHostView_->render_widget_host_->WasResized(); -} - -- (void)callSetNeedsDisplayInRect { - DCHECK([NSThread isMainThread]); - DCHECK(renderWidgetHostView_->call_set_needs_display_in_rect_pending_); - [self setNeedsDisplayInRect:renderWidgetHostView_->invalid_rect_]; - renderWidgetHostView_->call_set_needs_display_in_rect_pending_ = false; - renderWidgetHostView_->invalid_rect_ = NSZeroRect; - - renderWidgetHostView_->HandleDelayedGpuViewHiding(); -} - -// Fills with white the parts of the area to the right and bottom for |rect| -// that intersect |damagedRect|. -- (void)fillBottomRightRemainderOfRect:(gfx::Rect)rect - dirtyRect:(gfx::Rect)damagedRect { - if (damagedRect.right() > rect.right()) { - int x = std::max(rect.right(), damagedRect.x()); - int y = std::min(rect.bottom(), damagedRect.bottom()); - int width = damagedRect.right() - x; - int height = damagedRect.y() - y; - - // Extra fun to get around the fact that gfx::Rects can't have - // negative sizes. - if (width < 0) { - x += width; - width = -width; - } - if (height < 0) { - y += height; - height = -height; - } - - NSRect r = [self flipRectToNSRect:gfx::Rect(x, y, width, height)]; - [[NSColor whiteColor] set]; - NSRectFill(r); - } - if (damagedRect.bottom() > rect.bottom()) { - int x = damagedRect.x(); - int y = damagedRect.bottom(); - int width = damagedRect.right() - x; - int height = std::max(rect.bottom(), damagedRect.y()) - y; - - // Extra fun to get around the fact that gfx::Rects can't have - // negative sizes. - if (width < 0) { - x += width; - width = -width; - } - if (height < 0) { - y += height; - height = -height; - } - - NSRect r = [self flipRectToNSRect:gfx::Rect(x, y, width, height)]; - [[NSColor whiteColor] set]; - NSRectFill(r); - } -} - -- (void)drawRect:(NSRect)dirtyRect { - if (!renderWidgetHostView_->render_widget_host_) { - // TODO(shess): Consider using something more noticable? - [[NSColor whiteColor] set]; - NSRectFill(dirtyRect); - return; - } - - const gfx::Rect damagedRect([self flipNSRectToRect:dirtyRect]); - - if (renderWidgetHostView_->render_widget_host_-> - is_accelerated_compositing_active()) { - gfx::Rect gpuRect; - - gfx::PluginWindowHandle root_handle = - renderWidgetHostView_->plugin_container_manager_.root_container_handle(); - if (root_handle != gfx::kNullPluginWindow) { - AcceleratedPluginView* view = - renderWidgetHostView_->ViewForPluginWindowHandle(root_handle); - DCHECK(view); - if (view && ![view isHidden]) { - gpuRect = [self flipNSRectToRect:[view frame]]; - } - } - - [self fillBottomRightRemainderOfRect:gpuRect dirtyRect:damagedRect]; - return; - } - - DCHECK(!renderWidgetHostView_->about_to_validate_and_paint_); - - renderWidgetHostView_->about_to_validate_and_paint_ = true; - BackingStoreMac* backingStore = static_cast<BackingStoreMac*>( - renderWidgetHostView_->render_widget_host_->GetBackingStore(true)); - renderWidgetHostView_->about_to_validate_and_paint_ = false; - - if (backingStore) { - gfx::Rect bitmapRect(0, 0, - backingStore->size().width(), - backingStore->size().height()); - - // Specify the proper y offset to ensure that the view is rooted to the - // upper left corner. This can be negative, if the window was resized - // smaller and the renderer hasn't yet repainted. - int yOffset = NSHeight([self bounds]) - backingStore->size().height(); - - gfx::Rect paintRect = bitmapRect.Intersect(damagedRect); - if (!paintRect.IsEmpty()) { - // if we have a CGLayer, draw that into the window - if (backingStore->cg_layer()) { - CGContextRef context = static_cast<CGContextRef>( - [[NSGraphicsContext currentContext] graphicsPort]); - - // TODO: add clipping to dirtyRect if it improves drawing performance. - CGContextDrawLayerAtPoint(context, CGPointMake(0.0, yOffset), - backingStore->cg_layer()); - } else { - // if we haven't created a layer yet, draw the cached bitmap into - // the window. The CGLayer will be created the next time the renderer - // paints. - CGContextRef context = static_cast<CGContextRef>( - [[NSGraphicsContext currentContext] graphicsPort]); - base::mac::ScopedCFTypeRef<CGImageRef> image( - CGBitmapContextCreateImage(backingStore->cg_bitmap())); - CGRect imageRect = bitmapRect.ToCGRect(); - imageRect.origin.y = yOffset; - CGContextDrawImage(context, imageRect, image); - } - } - - // Fill the remaining portion of the damagedRect with white - [self fillBottomRightRemainderOfRect:bitmapRect dirtyRect:damagedRect]; - - if (!renderWidgetHostView_->whiteout_start_time_.is_null()) { - base::TimeDelta whiteout_duration = base::TimeTicks::Now() - - renderWidgetHostView_->whiteout_start_time_; - UMA_HISTOGRAM_TIMES("MPArch.RWHH_WhiteoutDuration", whiteout_duration); - - // Reset the start time to 0 so that we start recording again the next - // time the backing store is NULL... - renderWidgetHostView_->whiteout_start_time_ = base::TimeTicks(); - } - if (!renderWidgetHostView_->tab_switch_paint_time_.is_null()) { - base::TimeDelta tab_switch_paint_duration = base::TimeTicks::Now() - - renderWidgetHostView_->tab_switch_paint_time_; - UMA_HISTOGRAM_TIMES("MPArch.RWH_TabSwitchPaintDuration", - tab_switch_paint_duration); - // Reset tab_switch_paint_time_ to 0 so future tab selections are - // recorded. - renderWidgetHostView_->tab_switch_paint_time_ = base::TimeTicks(); - } - } else { - [[NSColor whiteColor] set]; - NSRectFill(dirtyRect); - if (renderWidgetHostView_->whiteout_start_time_.is_null()) - renderWidgetHostView_->whiteout_start_time_ = base::TimeTicks::Now(); - } -} - -- (BOOL)canBecomeKeyView { - if (!renderWidgetHostView_->render_widget_host_) - return NO; - - return canBeKeyView_; -} - -- (BOOL)acceptsFirstResponder { - if (!renderWidgetHostView_->render_widget_host_) - return NO; - - return canBeKeyView_ && !takesFocusOnlyOnMouseDown_; -} - -- (BOOL)becomeFirstResponder { - if (!renderWidgetHostView_->render_widget_host_) - return NO; - - renderWidgetHostView_->render_widget_host_->Focus(); - renderWidgetHostView_->render_widget_host_->SetInputMethodActive(true); - renderWidgetHostView_->SetTextInputActive(true); - - // Cancel any onging composition text which was left before we lost focus. - // TODO(suzhe): We should do it in -resignFirstResponder: method, but - // somehow that method won't be called when switching among different tabs. - // See http://crbug.com/47209 - [self cancelComposition]; - - NSNumber* direction = [NSNumber numberWithUnsignedInteger: - [[self window] keyViewSelectionDirection]]; - NSDictionary* userInfo = - [NSDictionary dictionaryWithObject:direction - forKey:kSelectionDirection]; - [[NSNotificationCenter defaultCenter] - postNotificationName:kViewDidBecomeFirstResponder - object:self - userInfo:userInfo]; - - return YES; -} - -- (BOOL)resignFirstResponder { - renderWidgetHostView_->SetTextInputActive(false); - if (!renderWidgetHostView_->render_widget_host_) - return YES; - - if (closeOnDeactivate_) - renderWidgetHostView_->KillSelf(); - - renderWidgetHostView_->render_widget_host_->SetInputMethodActive(false); - renderWidgetHostView_->render_widget_host_->Blur(); - - // We should cancel any onging composition whenever RWH's Blur() method gets - // called, because in this case, webkit will confirm the ongoing composition - // internally. - [self cancelComposition]; - - return YES; -} - -- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item { - if (delegate_ && [delegate_ respondsToSelector: - @selector(validateUserInterfaceItem:isValidItem:)]) { - BOOL valid; - BOOL known = [delegate_ validateUserInterfaceItem:item - isValidItem:&valid]; - if (known) - return valid; - } - - SEL action = [item action]; - - // For now, these actions are always enabled for render view, - // this is sub-optimal. - // TODO(suzhe): Plumb the "can*" methods up from WebCore. - if (action == @selector(undo:) || - action == @selector(redo:) || - action == @selector(cut:) || - action == @selector(copy:) || - action == @selector(copyToFindPboard:) || - action == @selector(paste:) || - action == @selector(pasteAsPlainText:)) { - return renderWidgetHostView_->render_widget_host_->IsRenderView(); - } - - return editCommand_helper_->IsMenuItemEnabled(action, self); -} - -- (RenderWidgetHostViewMac*)renderWidgetHostViewMac { - return renderWidgetHostView_.get(); -} - -// Determine whether we should autohide the cursor (i.e., hide it until mouse -// move) for the given event. Customize here to be more selective about which -// key presses to autohide on. -+ (BOOL)shouldAutohideCursorForEvent:(NSEvent*)event { - return ([event type] == NSKeyDown) ? YES : NO; -} - -- (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute - index:(NSUInteger)index - maxCount:(NSUInteger)maxCount { - NSArray* fullArray = [self accessibilityAttributeValue:attribute]; - NSUInteger totalLength = [fullArray count]; - if (index >= totalLength) - return nil; - NSUInteger length = MIN(totalLength - index, maxCount); - return [fullArray subarrayWithRange:NSMakeRange(index, length)]; -} - -- (NSUInteger)accessibilityArrayAttributeCount:(NSString *)attribute { - NSArray* fullArray = [self accessibilityAttributeValue:attribute]; - return [fullArray count]; -} - -- (id)accessibilityAttributeValue:(NSString *)attribute { - BrowserAccessibilityManager* manager = - renderWidgetHostView_->browser_accessibility_manager_.get(); - - // Contents specifies document view of RenderWidgetHostViewCocoa provided by - // BrowserAccessibilityManager. Children includes all subviews in addition to - // contents. Currently we do not have subviews besides the document view. - if (([attribute isEqualToString:NSAccessibilityChildrenAttribute] || - [attribute isEqualToString:NSAccessibilityContentsAttribute]) && - manager) { - return [NSArray arrayWithObjects:manager-> - GetRoot()->toBrowserAccessibilityCocoa(), nil]; - } else if ([attribute isEqualToString:NSAccessibilityRoleAttribute]) { - return NSAccessibilityScrollAreaRole; - } - id ret = [super accessibilityAttributeValue:attribute]; - return ret; -} - -- (NSArray*)accessibilityAttributeNames { - NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease]; - [ret addObject:NSAccessibilityContentsAttribute]; - [ret addObjectsFromArray:[super accessibilityAttributeNames]]; - return ret; -} - -- (id)accessibilityHitTest:(NSPoint)point { - if (!renderWidgetHostView_->browser_accessibility_manager_.get()) - return self; - NSPoint pointInWindow = [[self window] convertScreenToBase:point]; - NSPoint localPoint = [self convertPoint:pointInWindow fromView:nil]; - localPoint.y = NSHeight([self bounds]) - localPoint.y; - BrowserAccessibilityCocoa* root = renderWidgetHostView_-> - browser_accessibility_manager_-> - GetRoot()->toBrowserAccessibilityCocoa(); - id obj = [root accessibilityHitTest:localPoint]; - return obj; -} - -- (BOOL)accessibilityIsIgnored { - return NO; -} - -- (NSUInteger)accessibilityGetIndexOf:(id)child { - BrowserAccessibilityManager* manager = - renderWidgetHostView_->browser_accessibility_manager_.get(); - // Only child is root. - if (manager && - manager->GetRoot()->toBrowserAccessibilityCocoa() == child) { - return 0; - } else { - return NSNotFound; - } -} - -- (id)accessibilityFocusedUIElement { - BrowserAccessibilityManager* manager = - renderWidgetHostView_->browser_accessibility_manager_.get(); - if (manager) { - BrowserAccessibility* focused_item = manager->GetFocus(NULL); - DCHECK(focused_item); - if (focused_item) { - BrowserAccessibilityCocoa* focused_item_cocoa = - focused_item->toBrowserAccessibilityCocoa(); - DCHECK(focused_item_cocoa); - if (focused_item_cocoa) - return focused_item_cocoa; - } - } - return [super accessibilityFocusedUIElement]; -} - -- (void)doDefaultAction:(int32)accessibilityObjectId { - RenderWidgetHost* rwh = renderWidgetHostView_->render_widget_host_; - rwh->Send(new ViewMsg_AccessibilityDoDefaultAction( - rwh->routing_id(), accessibilityObjectId)); -} - -// Convert a web accessibility's location in web coordinates into a cocoa -// screen coordinate. -- (NSPoint)accessibilityPointInScreen: - (BrowserAccessibilityCocoa*)accessibility { - NSPoint origin = [accessibility origin]; - NSSize size = [[accessibility size] sizeValue]; - origin.y = NSHeight([self bounds]) - origin.y; - NSPoint originInWindow = [self convertPoint:origin toView:nil]; - NSPoint originInScreen = [[self window] convertBaseToScreen:originInWindow]; - originInScreen.y = originInScreen.y - size.height; - return originInScreen; -} - -- (void)setAccessibilityFocus:(BOOL)focus - accessibilityId:(int32)accessibilityObjectId { - if (focus) { - RenderWidgetHost* rwh = renderWidgetHostView_->render_widget_host_; - rwh->Send(new ViewMsg_SetAccessibilityFocus( - rwh->routing_id(), accessibilityObjectId)); - } -} - -- (void)performShowMenuAction:(BrowserAccessibilityCocoa*)accessibility { - // Performs a right click copying WebKit's - // accessibilityPerformShowMenuAction. - NSPoint location = [self accessibilityPointInScreen:accessibility]; - NSSize size = [[accessibility size] sizeValue]; - location = [[self window] convertScreenToBase:location]; - location.x += size.width/2; - location.y += size.height/2; - - NSEvent* fakeRightClick = [NSEvent - mouseEventWithType:NSRightMouseDown - location:location - modifierFlags:nil - timestamp:0 - windowNumber:[[self window] windowNumber] - context:[NSGraphicsContext currentContext] - eventNumber:0 - clickCount:1 - pressure:0]; - - [self mouseEvent:fakeRightClick]; -} - -// Below is the nasty tooltip stuff -- copied from WebKit's WebHTMLView.mm -// with minor modifications for code style and commenting. -// -// The 'public' interface is -setToolTipAtMousePoint:. This differs from -// -setToolTip: in that the updated tooltip takes effect immediately, -// without the user's having to move the mouse out of and back into the view. -// -// Unfortunately, doing this requires sending fake mouseEnter/Exit events to -// the view, which in turn requires overriding some internal tracking-rect -// methods (to keep track of its owner & userdata, which need to be filled out -// in the fake events.) --snej 7/6/09 - - -/* - * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * (C) 2006, 2007 Graham Dennis (graham.dennis@gmail.com) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// Any non-zero value will do, but using something recognizable might help us -// debug some day. -static const NSTrackingRectTag kTrackingRectTag = 0xBADFACE; - -// Override of a public NSView method, replacing the inherited functionality. -// See above for rationale. -- (NSTrackingRectTag)addTrackingRect:(NSRect)rect - owner:(id)owner - userData:(void *)data - assumeInside:(BOOL)assumeInside { - DCHECK(trackingRectOwner_ == nil); - trackingRectOwner_ = owner; - trackingRectUserData_ = data; - return kTrackingRectTag; -} - -// Override of (apparently) a private NSView method(!) See above for rationale. -- (NSTrackingRectTag)_addTrackingRect:(NSRect)rect - owner:(id)owner - userData:(void *)data - assumeInside:(BOOL)assumeInside - useTrackingNum:(int)tag { - DCHECK(tag == 0 || tag == kTrackingRectTag); - DCHECK(trackingRectOwner_ == nil); - trackingRectOwner_ = owner; - trackingRectUserData_ = data; - return kTrackingRectTag; -} - -// Override of (apparently) a private NSView method(!) See above for rationale. -- (void)_addTrackingRects:(NSRect *)rects - owner:(id)owner - userDataList:(void **)userDataList - assumeInsideList:(BOOL *)assumeInsideList - trackingNums:(NSTrackingRectTag *)trackingNums - count:(int)count { - DCHECK(count == 1); - DCHECK(trackingNums[0] == 0 || trackingNums[0] == kTrackingRectTag); - DCHECK(trackingRectOwner_ == nil); - trackingRectOwner_ = owner; - trackingRectUserData_ = userDataList[0]; - trackingNums[0] = kTrackingRectTag; -} - -// Override of a public NSView method, replacing the inherited functionality. -// See above for rationale. -- (void)removeTrackingRect:(NSTrackingRectTag)tag { - if (tag == 0) - return; - - if (tag == kTrackingRectTag) { - trackingRectOwner_ = nil; - return; - } - - if (tag == lastToolTipTag_) { - [super removeTrackingRect:tag]; - lastToolTipTag_ = 0; - return; - } - - // If any other tracking rect is being removed, we don't know how it was - // created and it's possible there's a leak involved (see Radar 3500217). - NOTREACHED(); -} - -// Override of (apparently) a private NSView method(!) -- (void)_removeTrackingRects:(NSTrackingRectTag *)tags count:(int)count { - for (int i = 0; i < count; ++i) { - int tag = tags[i]; - if (tag == 0) - continue; - DCHECK(tag == kTrackingRectTag); - trackingRectOwner_ = nil; - } -} - -// Sends a fake NSMouseExited event to the view for its current tracking rect. -- (void)_sendToolTipMouseExited { - // Nothing matters except window, trackingNumber, and userData. - int windowNumber = [[self window] windowNumber]; - NSEvent* fakeEvent = [NSEvent enterExitEventWithType:NSMouseExited - location:NSMakePoint(0, 0) - modifierFlags:0 - timestamp:0 - windowNumber:windowNumber - context:NULL - eventNumber:0 - trackingNumber:kTrackingRectTag - userData:trackingRectUserData_]; - [trackingRectOwner_ mouseExited:fakeEvent]; -} - -// Sends a fake NSMouseEntered event to the view for its current tracking rect. -- (void)_sendToolTipMouseEntered { - // Nothing matters except window, trackingNumber, and userData. - int windowNumber = [[self window] windowNumber]; - NSEvent* fakeEvent = [NSEvent enterExitEventWithType:NSMouseEntered - location:NSMakePoint(0, 0) - modifierFlags:0 - timestamp:0 - windowNumber:windowNumber - context:NULL - eventNumber:0 - trackingNumber:kTrackingRectTag - userData:trackingRectUserData_]; - [trackingRectOwner_ mouseEntered:fakeEvent]; -} - -// Sets the view's current tooltip, to be displayed at the current mouse -// location. (This does not make the tooltip appear -- as usual, it only -// appears after a delay.) Pass null to remove the tooltip. -- (void)setToolTipAtMousePoint:(NSString *)string { - NSString *toolTip = [string length] == 0 ? nil : string; - if ((toolTip && toolTip_ && [toolTip isEqualToString:toolTip_]) || - (!toolTip && !toolTip_)) { - return; - } - - if (toolTip_) { - [self _sendToolTipMouseExited]; - } - - toolTip_.reset([toolTip copy]); - - if (toolTip) { - // See radar 3500217 for why we remove all tooltips - // rather than just the single one we created. - [self removeAllToolTips]; - NSRect wideOpenRect = NSMakeRect(-100000, -100000, 200000, 200000); - lastToolTipTag_ = [self addToolTipRect:wideOpenRect - owner:self - userData:NULL]; - [self _sendToolTipMouseEntered]; - } -} - -// NSView calls this to get the text when displaying the tooltip. -- (NSString *)view:(NSView *)view - stringForToolTip:(NSToolTipTag)tag - point:(NSPoint)point - userData:(void *)data { - return [[toolTip_ copy] autorelease]; -} - -// Below is our NSTextInputClient implementation. -// -// When WebHTMLView receives a NSKeyDown event, WebHTMLView calls the following -// functions to process this event. -// -// [WebHTMLView keyDown] -> -// EventHandler::keyEvent() -> -// ... -// [WebEditorClient handleKeyboardEvent] -> -// [WebHTMLView _interceptEditingKeyEvent] -> -// [NSResponder interpretKeyEvents] -> -// [WebHTMLView insertText] -> -// Editor::insertText() -// -// Unfortunately, it is hard for Chromium to use this implementation because -// it causes key-typing jank. -// RenderWidgetHostViewMac is running in a browser process. On the other -// hand, Editor and EventHandler are running in a renderer process. -// So, if we used this implementation, a NSKeyDown event is dispatched to -// the following functions of Chromium. -// -// [RenderWidgetHostViewMac keyEvent] (browser) -> -// |Sync IPC (KeyDown)| (*1) -> -// EventHandler::keyEvent() (renderer) -> -// ... -// EditorClientImpl::handleKeyboardEvent() (renderer) -> -// |Sync IPC| (*2) -> -// [RenderWidgetHostViewMac _interceptEditingKeyEvent] (browser) -> -// [self interpretKeyEvents] -> -// [RenderWidgetHostViewMac insertText] (browser) -> -// |Async IPC| -> -// Editor::insertText() (renderer) -// -// (*1) we need to wait until this call finishes since WebHTMLView uses the -// result of EventHandler::keyEvent(). -// (*2) we need to wait until this call finishes since WebEditorClient uses -// the result of [WebHTMLView _interceptEditingKeyEvent]. -// -// This needs many sync IPC messages sent between a browser and a renderer for -// each key event, which would probably result in key-typing jank. -// To avoid this problem, this implementation processes key events (and input -// method events) totally in a browser process and sends asynchronous input -// events, almost same as KeyboardEvents (and TextEvents) of DOM Level 3, to a -// renderer process. -// -// [RenderWidgetHostViewMac keyEvent] (browser) -> -// |Async IPC (RawKeyDown)| -> -// [self interpretKeyEvents] -> -// [RenderWidgetHostViewMac insertText] (browser) -> -// |Async IPC (Char)| -> -// Editor::insertText() (renderer) -// -// Since this implementation doesn't have to wait any IPC calls, this doesn't -// make any key-typing jank. --hbono 7/23/09 -// -extern "C" { -extern NSString *NSTextInputReplacementRangeAttributeName; -} - -- (NSArray *)validAttributesForMarkedText { - // This code is just copied from WebKit except renaming variables. - if (!validAttributesForMarkedText_) { - validAttributesForMarkedText_.reset([[NSArray alloc] initWithObjects: - NSUnderlineStyleAttributeName, - NSUnderlineColorAttributeName, - NSMarkedClauseSegmentAttributeName, - NSTextInputReplacementRangeAttributeName, - nil]); - } - return validAttributesForMarkedText_.get(); -} - -- (NSUInteger)characterIndexForPoint:(NSPoint)thePoint { - DCHECK([self window]); - // |thePoint| is in screen coordinates, but needs to be converted to WebKit - // coordinates (upper left origin). Scroll offsets will be taken care of in - // the renderer. - thePoint = [[self window] convertScreenToBase:thePoint]; - thePoint = [self convertPoint:thePoint fromView:nil]; - thePoint.y = NSHeight([self frame]) - thePoint.y; - - NSUInteger index = - TextInputClientMac::GetInstance()->GetCharacterIndexAtPoint( - renderWidgetHostView_->render_widget_host_, - gfx::Point(thePoint.x, thePoint.y)); - return index; -} - -- (NSRect)firstRectForCharacterRange:(NSRange)theRange - actualRange:(NSRangePointer)actualRange { - // TODO(thakis): Pipe |actualRange| through TextInputClientMac machinery. - if (actualRange) - *actualRange = theRange; - NSRect rect = TextInputClientMac::GetInstance()->GetFirstRectForRange( - renderWidgetHostView_->render_widget_host_, theRange); - - // The returned rectangle is in WebKit coordinates (upper left origin), so - // flip the coordinate system and then convert it into screen coordinates for - // return. - NSRect viewFrame = [self frame]; - rect.origin.y = NSHeight(viewFrame) - rect.origin.y; - rect.origin.y -= rect.size.height; - rect = [self convertRectToBase:rect]; - rect.origin = [[self window] convertBaseToScreen:rect.origin]; - return rect; -} - -- (NSRange)markedRange { - // An input method calls this method to check if an application really has - // a text being composed when hasMarkedText call returns true. - // Returns the range saved in the setMarkedText method so the input method - // calls the setMarkedText method and we can update the composition node - // there. (When this method returns an empty range, the input method doesn't - // call the setMarkedText method.) - return hasMarkedText_ ? markedRange_ : NSMakeRange(NSNotFound, 0); -} - -- (NSAttributedString*)attributedSubstringForProposedRange:(NSRange)range - actualRange:(NSRangePointer)actualRange { - // TODO(thakis): Pipe |actualRange| through TextInputClientMac machinery. - if (actualRange) - *actualRange = range; - NSAttributedString* str = - TextInputClientMac::GetInstance()->GetAttributedSubstringFromRange( - renderWidgetHostView_->render_widget_host_, range); - return str; -} - -- (NSInteger)conversationIdentifier { - return reinterpret_cast<NSInteger>(self); -} - -// Each RenderWidgetHostViewCocoa has its own input context, but we return -// nil when the caret is in non-editable content or password box to avoid -// making input methods do their work. -- (NSTextInputContext *)inputContext { - if (focusedPluginIdentifier_ != -1) - return [[ComplexTextInputPanel sharedComplexTextInputPanel] inputContext]; - - switch(renderWidgetHostView_->text_input_type_) { - case ui::TEXT_INPUT_TYPE_NONE: - case ui::TEXT_INPUT_TYPE_PASSWORD: - return nil; - default: - return [super inputContext]; - } -} - -- (BOOL)hasMarkedText { - // An input method calls this function to figure out whether or not an - // application is really composing a text. If it is composing, it calls - // the markedRange method, and maybe calls the setMarkedText method. - // It seems an input method usually calls this function when it is about to - // cancel an ongoing composition. If an application has a non-empty marked - // range, it calls the setMarkedText method to delete the range. - return hasMarkedText_; -} - -- (void)unmarkText { - // Delete the composition node of the renderer and finish an ongoing - // composition. - // It seems an input method calls the setMarkedText method and set an empty - // text when it cancels an ongoing composition, i.e. I have never seen an - // input method calls this method. - hasMarkedText_ = NO; - markedText_.clear(); - underlines_.clear(); - - // If we are handling a key down event, then ConfirmComposition() will be - // called in keyEvent: method. - if (!handlingKeyDown_) - renderWidgetHostView_->render_widget_host_->ImeConfirmComposition(); - else - unmarkTextCalled_ = YES; -} - -- (void)setMarkedText:(id)string selectedRange:(NSRange)newSelRange - replacementRange:(NSRange)replacementRange { - // An input method updates the composition string. - // We send the given text and range to the renderer so it can update the - // composition node of WebKit. - // TODO(suzhe): It's hard for us to support replacementRange without accessing - // the full web content. - BOOL isAttributedString = [string isKindOfClass:[NSAttributedString class]]; - NSString* im_text = isAttributedString ? [string string] : string; - int length = [im_text length]; - - // |markedRange_| will get set on a callback from ImeSetComposition(). - selectedRange_ = newSelRange; - markedText_ = base::SysNSStringToUTF16(im_text); - hasMarkedText_ = (length > 0); - - underlines_.clear(); - if (isAttributedString) { - ExtractUnderlines(string, &underlines_); - } else { - // Use a thin black underline by default. - underlines_.push_back( - WebKit::WebCompositionUnderline(0, length, SK_ColorBLACK, false)); - } - - // If we are handling a key down event, then SetComposition() will be - // called in keyEvent: method. - // Input methods of Mac use setMarkedText calls with an empty text to cancel - // an ongoing composition. So, we should check whether or not the given text - // is empty to update the input method state. (Our input method backend can - // automatically cancels an ongoing composition when we send an empty text. - // So, it is OK to send an empty text to the renderer.) - if (!handlingKeyDown_) { - renderWidgetHostView_->render_widget_host_->ImeSetComposition( - markedText_, underlines_, - newSelRange.location, NSMaxRange(newSelRange)); - } -} - -- (void)doCommandBySelector:(SEL)selector { - // An input method calls this function to dispatch an editing command to be - // handled by this view. - if (selector == @selector(noop:)) - return; - - std::string command( - [RenderWidgetHostViewMacEditCommandHelper:: - CommandNameForSelector(selector) UTF8String]); - - // If this method is called when handling a key down event, then we need to - // handle the command in the key event handler. Otherwise we can just handle - // it here. - if (handlingKeyDown_) { - hasEditCommands_ = YES; - // We ignore commands that insert characters, because this was causing - // strange behavior (e.g. tab always inserted a tab rather than moving to - // the next field on the page). - if (!StartsWithASCII(command, "insert", false)) - editCommands_.push_back(EditCommand(command, "")); - } else { - RenderWidgetHost* rwh = renderWidgetHostView_->render_widget_host_; - rwh->Send(new ViewMsg_ExecuteEditCommand(rwh->routing_id(), command, "")); - } -} - -- (void)insertText:(id)string replacementRange:(NSRange)replacementRange { - // An input method has characters to be inserted. - // Same as Linux, Mac calls this method not only: - // * when an input method finishs composing text, but also; - // * when we type an ASCII character (without using input methods). - // When we aren't using input methods, we should send the given character as - // a Char event so it is dispatched to an onkeypress() event handler of - // JavaScript. - // On the other hand, when we are using input methods, we should send the - // given characters as an input method event and prevent the characters from - // being dispatched to onkeypress() event handlers. - // Text inserting might be initiated by other source instead of keyboard - // events, such as the Characters dialog. In this case the text should be - // sent as an input method event as well. - // TODO(suzhe): It's hard for us to support replacementRange without accessing - // the full web content. NOTE: If someone adds support for this, make sure - // it works with the default range passed in by -insertText: below. - BOOL isAttributedString = [string isKindOfClass:[NSAttributedString class]]; - NSString* im_text = isAttributedString ? [string string] : string; - if (handlingKeyDown_) { - textToBeInserted_.append(base::SysNSStringToUTF16(im_text)); - } else { - renderWidgetHostView_->render_widget_host_->ImeConfirmComposition( - base::SysNSStringToUTF16(im_text)); - } - - // Inserting text will delete all marked text automatically. - hasMarkedText_ = NO; -} - -- (void)insertText:(id)string { - // This is a method on NSTextInput, not NSTextInputClient. But on 10.5, this - // gets called anyway. Forward to the right method. http://crbug.com/47890 - [self insertText:string replacementRange:NSMakeRange(0, 0)]; -} - -- (void)viewDidMoveToWindow { - if (canBeKeyView_) { - NSWindow* newWindow = [self window]; - // Pointer comparison only, since we don't know if lastWindow_ is still - // valid. - if (newWindow) { - // If we move into a new window, refresh the frame information. We - // don't need to do it if it was the same window as it used to be in, - // since that case is covered by DidBecomeSelected. We only want to - // do this for real browser views, not popups. - if (newWindow != lastWindow_) { - lastWindow_ = newWindow; - renderWidgetHostView_->WindowFrameChanged(); - } - renderWidgetHostView_->ForceTextureReload(); - } - } - - // If we switch windows (or are removed from the view hierarchy), cancel any - // open mouse-downs. - if (hasOpenMouseDown_) { - WebMouseEvent event; - event.type = WebInputEvent::MouseUp; - event.button = WebMouseEvent::ButtonLeft; - if (renderWidgetHostView_->render_widget_host_) - renderWidgetHostView_->render_widget_host_->ForwardMouseEvent(event); - - hasOpenMouseDown_ = NO; - } -} - -- (void)undo:(id)sender { - if (renderWidgetHostView_->render_widget_host_->IsRenderView()) { - static_cast<RenderViewHost*>(renderWidgetHostView_->render_widget_host_)-> - Undo(); - } -} - -- (void)redo:(id)sender { - if (renderWidgetHostView_->render_widget_host_->IsRenderView()) { - static_cast<RenderViewHost*>(renderWidgetHostView_->render_widget_host_)-> - Redo(); - } -} - -- (void)cut:(id)sender { - if (renderWidgetHostView_->render_widget_host_->IsRenderView()) { - static_cast<RenderViewHost*>(renderWidgetHostView_->render_widget_host_)-> - Cut(); - } -} - -- (void)copy:(id)sender { - if (renderWidgetHostView_->render_widget_host_->IsRenderView()) { - static_cast<RenderViewHost*>(renderWidgetHostView_->render_widget_host_)-> - Copy(); - } -} - -- (void)copyToFindPboard:(id)sender { - if (renderWidgetHostView_->render_widget_host_->IsRenderView()) { - static_cast<RenderViewHost*>(renderWidgetHostView_->render_widget_host_)-> - CopyToFindPboard(); - } -} - -- (void)paste:(id)sender { - if (renderWidgetHostView_->render_widget_host_->IsRenderView()) { - static_cast<RenderViewHost*>(renderWidgetHostView_->render_widget_host_)-> - Paste(); - } -} - -- (void)pasteAsPlainText:(id)sender { - if (renderWidgetHostView_->render_widget_host_->IsRenderView()) { - RenderWidgetHost* rwh = renderWidgetHostView_->render_widget_host_; - rwh->Send(new ViewMsg_ExecuteEditCommand( - rwh->routing_id(), "PasteAndMatchStyle", "")); - } -} - -- (void)cancelComposition { - if (!hasMarkedText_) - return; - - // Cancel the ongoing composition. [NSInputManager markedTextAbandoned:] - // doesn't call any NSTextInput functions, such as setMarkedText or - // insertText. So, we need to send an IPC message to a renderer so it can - // delete the composition node. - NSInputManager *currentInputManager = [NSInputManager currentInputManager]; - [currentInputManager markedTextAbandoned:self]; - - hasMarkedText_ = NO; - // Should not call [self unmarkText] here, because it'll send unnecessary - // cancel composition IPC message to the renderer. -} - -- (void)confirmComposition { - if (!hasMarkedText_) - return; - - if (renderWidgetHostView_->render_widget_host_) - renderWidgetHostView_->render_widget_host_->ImeConfirmComposition(); - - [self cancelComposition]; -} - -- (void)setPluginImeActive:(BOOL)active { - if (active == pluginImeActive_) - return; - - pluginImeActive_ = active; - if (!active) { - [[ComplexTextInputPanel sharedComplexTextInputPanel] cancelComposition]; - renderWidgetHostView_->PluginImeCompositionCompleted( - string16(), focusedPluginIdentifier_); - } -} - -- (void)pluginFocusChanged:(BOOL)focused forPlugin:(int)pluginId { - if (focused) - focusedPluginIdentifier_ = pluginId; - else if (focusedPluginIdentifier_ == pluginId) - focusedPluginIdentifier_ = -1; - - // Whenever plugin focus changes, plugin IME resets. - [self setPluginImeActive:NO]; -} - -- (BOOL)postProcessEventForPluginIme:(NSEvent*)event { - if (!pluginImeActive_) - return false; - - ComplexTextInputPanel* inputPanel = - [ComplexTextInputPanel sharedComplexTextInputPanel]; - NSString* composited_string = nil; - BOOL handled = [inputPanel interpretKeyEvent:event - string:&composited_string]; - if (composited_string) { - renderWidgetHostView_->PluginImeCompositionCompleted( - base::SysNSStringToUTF16(composited_string), focusedPluginIdentifier_); - pluginImeActive_ = NO; - } - return handled; -} - -- (void)checkForPluginImeCancellation { - if (pluginImeActive_ && - ![[ComplexTextInputPanel sharedComplexTextInputPanel] inComposition]) { - renderWidgetHostView_->PluginImeCompositionCompleted( - string16(), focusedPluginIdentifier_); - pluginImeActive_ = NO; - } -} - -// Overriding a NSResponder method to support application services. - -- (id)validRequestorForSendType:(NSString*)sendType - returnType:(NSString*)returnType { - id requestor = nil; - BOOL sendTypeIsString = [sendType isEqual:NSStringPboardType]; - BOOL returnTypeIsString = [returnType isEqual:NSStringPboardType]; - BOOL hasText = !renderWidgetHostView_->selected_text().empty(); - BOOL takesText = - renderWidgetHostView_->text_input_type_ != ui::TEXT_INPUT_TYPE_NONE; - - if (sendTypeIsString && hasText && !returnType) { - requestor = self; - } else if (!sendType && returnTypeIsString && takesText) { - requestor = self; - } else if (sendTypeIsString && returnTypeIsString && hasText && takesText) { - requestor = self; - } else { - requestor = [super validRequestorForSendType:sendType - returnType:returnType]; - } - return requestor; -} - -- (void)viewWillStartLiveResize { - [super viewWillStartLiveResize]; - RenderWidgetHost* widget = renderWidgetHostView_->render_widget_host_; - if (widget) - widget->Send(new ViewMsg_SetInLiveResize(widget->routing_id(), true)); -} - -- (void)viewDidEndLiveResize { - [super viewDidEndLiveResize]; - RenderWidgetHost* widget = renderWidgetHostView_->render_widget_host_; - if (widget) - widget->Send(new ViewMsg_SetInLiveResize(widget->routing_id(), false)); -} - -@end - -// -// Supporting application services -// -@implementation RenderWidgetHostViewCocoa(NSServicesRequests) - -- (BOOL)writeSelectionToPasteboard:(NSPasteboard*)pboard - types:(NSArray*)types { - const std::string& str = renderWidgetHostView_->selected_text(); - if (![types containsObject:NSStringPboardType] || str.empty()) return NO; - - scoped_nsobject<NSString> text([[NSString alloc] - initWithUTF8String:str.c_str()]); - NSArray* toDeclare = [NSArray arrayWithObject:NSStringPboardType]; - [pboard declareTypes:toDeclare owner:nil]; - return [pboard setString:text forType:NSStringPboardType]; -} - -- (BOOL)readSelectionFromPasteboard:(NSPasteboard*)pboard { - NSString *string = [pboard stringForType:NSStringPboardType]; - if (!string) return NO; - - // If the user is currently using an IME, confirm the IME input, - // and then insert the text from the service, the same as TextEdit and Safari. - [self confirmComposition]; - [self insertText:string]; - return YES; -} - -@end diff --git a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.h b/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.h deleted file mode 100644 index bdafbaf..0000000 --- a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.h +++ /dev/null @@ -1,70 +0,0 @@ -// 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. - -#ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_MAC_EDITCOMMAND_HELPER_H_ -#define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_MAC_EDITCOMMAND_HELPER_H_ -#pragma once - -#import <Cocoa/Cocoa.h> - -#include "base/basictypes.h" -#include "base/hash_tables.h" -#include "base/gtest_prod_util.h" -#include "content/browser/renderer_host/render_widget_host_view_mac.h" - -// This class mimics the behavior of WebKit's WebView class in a way that makes -// sense for Chrome. -// -// WebCore has the concept of "core commands", basically named actions such as -// "Select All" and "Move Cursor Left". The commands are executed using their -// string value by WebCore. -// -// This class is responsible for 2 things: -// 1. Provide an abstraction to determine the enabled/disabled state of menu -// items that correspond to edit commands. -// 2. Hook up a bunch of objc selectors to the RenderWidgetHostViewCocoa object. -// (note that this is not a misspelling of RenderWidgetHostViewMac, it's in -// fact a distinct object) When these selectors are called, the relevant -// edit command is executed in WebCore. -class RenderWidgetHostViewMacEditCommandHelper { - FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewMacEditCommandHelperTest, - TestAddEditingSelectorsToClass); - FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewMacEditCommandHelperTest, - TestEditingCommandDelivery); - - public: - RenderWidgetHostViewMacEditCommandHelper(); - ~RenderWidgetHostViewMacEditCommandHelper(); - - // Adds editing selectors to the objc class using the objc runtime APIs. - // Each selector is connected to a single c method which forwards the message - // to WebCore's ExecuteEditCommand() function. - // This method is idempotent. - // The class passed in must conform to the RenderWidgetHostViewMacOwner - // protocol. - void AddEditingSelectorsToClass(Class klass); - - // Is a given menu item currently enabled? - // SEL - the objc selector currently associated with an NSMenuItem. - // owner - An object we can retrieve a RenderWidgetHostViewMac from to - // determine the command states. - bool IsMenuItemEnabled(SEL item_action, - id<RenderWidgetHostViewMacOwner> owner); - - // Converts an editing selector into a command name that can be sent to - // webkit. - static NSString* CommandNameForSelector(SEL selector); - - protected: - // Gets a list of all the selectors that AddEditingSelectorsToClass adds to - // the aforementioned class. - // returns an array of NSStrings WITHOUT the trailing ':'s. - NSArray* GetEditSelectorNames(); - - private: - base::hash_set<std::string> edit_command_set_; - DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewMacEditCommandHelper); -}; - -#endif // CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_MAC_EDITCOMMAND_HELPER_H_ diff --git a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.mm b/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.mm deleted file mode 100644 index 4ad3b76..0000000 --- a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.mm +++ /dev/null @@ -1,235 +0,0 @@ -// 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 "content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.h" - -#import <objc/runtime.h> - -#include "content/browser/renderer_host/render_widget_host.h" -#import "content/browser/renderer_host/render_widget_host_view_mac.h" - -namespace { -// The names of all the objc selectors w/o ':'s added to an object by -// AddEditingSelectorsToClass(). -// -// This needs to be kept in Sync with WEB_COMMAND list in the WebKit tree at: -// WebKit/mac/WebView/WebHTMLView.mm . -const char* kEditCommands[] = { - "alignCenter", - "alignJustified", - "alignLeft", - "alignRight", - "copy", - "cut", - "delete", - "deleteBackward", - "deleteBackwardByDecomposingPreviousCharacter", - "deleteForward", - "deleteToBeginningOfLine", - "deleteToBeginningOfParagraph", - "deleteToEndOfLine", - "deleteToEndOfParagraph", - "deleteToMark", - "deleteWordBackward", - "deleteWordForward", - "ignoreSpelling", - "indent", - "insertBacktab", - "insertLineBreak", - "insertNewline", - "insertNewlineIgnoringFieldEditor", - "insertParagraphSeparator", - "insertTab", - "insertTabIgnoringFieldEditor", - "makeTextWritingDirectionLeftToRight", - "makeTextWritingDirectionNatural", - "makeTextWritingDirectionRightToLeft", - "moveBackward", - "moveBackwardAndModifySelection", - "moveDown", - "moveDownAndModifySelection", - "moveForward", - "moveForwardAndModifySelection", - "moveLeft", - "moveLeftAndModifySelection", - "moveParagraphBackwardAndModifySelection", - "moveParagraphForwardAndModifySelection", - "moveRight", - "moveRightAndModifySelection", - "moveToBeginningOfDocument", - "moveToBeginningOfDocumentAndModifySelection", - "moveToBeginningOfLine", - "moveToBeginningOfLineAndModifySelection", - "moveToBeginningOfParagraph", - "moveToBeginningOfParagraphAndModifySelection", - "moveToBeginningOfSentence", - "moveToBeginningOfSentenceAndModifySelection", - "moveToEndOfDocument", - "moveToEndOfDocumentAndModifySelection", - "moveToEndOfLine", - "moveToEndOfLineAndModifySelection", - "moveToEndOfParagraph", - "moveToEndOfParagraphAndModifySelection", - "moveToEndOfSentence", - "moveToEndOfSentenceAndModifySelection", - "moveUp", - "moveUpAndModifySelection", - "moveWordBackward", - "moveWordBackwardAndModifySelection", - "moveWordForward", - "moveWordForwardAndModifySelection", - "moveWordLeft", - "moveWordLeftAndModifySelection", - "moveWordRight", - "moveWordRightAndModifySelection", - "outdent", - "pageDown", - "pageDownAndModifySelection", - "pageUp", - "pageUpAndModifySelection", - "selectAll", - "selectLine", - "selectParagraph", - "selectSentence", - "selectToMark", - "selectWord", - "setMark", - "showGuessPanel", - "subscript", - "superscript", - "swapWithMark", - "transpose", - "underline", - "unscript", - "yank", - "yankAndSelect"}; - - -// This function is installed via the objc runtime as the implementation of all -// the various editing selectors. -// The objc runtime hookup occurs in -// RenderWidgetHostViewMacEditCommandHelper::AddEditingSelectorsToClass(). -// -// self - the object we're attached to; it must implement the -// RenderWidgetHostViewMacOwner protocol. -// _cmd - the selector that fired. -// sender - the id of the object that sent the message. -// -// The selector is translated into an edit comand and then forwarded down the -// pipeline to WebCore. -// The route the message takes is: -// RenderWidgetHostViewMac -> RenderViewHost -> -// | IPC | -> -// RenderView -> currently focused WebFrame. -// The WebFrame is in the Chrome glue layer and forwards the message to WebCore. -void EditCommandImp(id self, SEL _cmd, id sender) { - // Make sure |self| is the right type. - DCHECK([self conformsToProtocol:@protocol(RenderWidgetHostViewMacOwner)]); - - // SEL -> command name string. - NSString* command_name_ns = - RenderWidgetHostViewMacEditCommandHelper::CommandNameForSelector(_cmd); - std::string command([command_name_ns UTF8String]); - - // Forward the edit command string down the pipeline. - RenderWidgetHostViewMac* rwhv = [(id<RenderWidgetHostViewMacOwner>)self - renderWidgetHostViewMac]; - DCHECK(rwhv); - - // The second parameter is the core command value which isn't used here. - RenderWidgetHost* rwh = rwhv->GetRenderWidgetHost(); - rwh->ExecuteEditCommand(command, ""); -} - -} // namespace - -// Maps an objc-selector to a core command name. -// -// Returns the core command name (which is the selector name with the trailing -// ':' stripped in most cases). -// -// Adapted from a function by the same name in -// WebKit/mac/WebView/WebHTMLView.mm . -// Capitalized names are returned from this function, but that's simply -// matching WebHTMLView.mm. -NSString* RenderWidgetHostViewMacEditCommandHelper::CommandNameForSelector( - SEL selector) { - if (selector == @selector(insertParagraphSeparator:) || - selector == @selector(insertNewlineIgnoringFieldEditor:)) - return @"InsertNewline"; - if (selector == @selector(insertTabIgnoringFieldEditor:)) - return @"InsertTab"; - if (selector == @selector(pageDown:)) - return @"MovePageDown"; - if (selector == @selector(pageDownAndModifySelection:)) - return @"MovePageDownAndModifySelection"; - if (selector == @selector(pageUp:)) - return @"MovePageUp"; - if (selector == @selector(pageUpAndModifySelection:)) - return @"MovePageUpAndModifySelection"; - - // Remove the trailing colon. - NSString* selector_str = NSStringFromSelector(selector); - int selector_len = [selector_str length]; - return [selector_str substringToIndex:selector_len - 1]; -} - -RenderWidgetHostViewMacEditCommandHelper:: - RenderWidgetHostViewMacEditCommandHelper() { - for (size_t i = 0; i < arraysize(kEditCommands); ++i) { - edit_command_set_.insert(kEditCommands[i]); - } -} - -RenderWidgetHostViewMacEditCommandHelper:: - ~RenderWidgetHostViewMacEditCommandHelper() {} - -// Dynamically adds Selectors to the aformentioned class. -void RenderWidgetHostViewMacEditCommandHelper::AddEditingSelectorsToClass( - Class klass) { - for (size_t i = 0; i < arraysize(kEditCommands); ++i) { - // Append trailing ':' to command name to get selector name. - NSString* sel_str = [NSString stringWithFormat: @"%s:", kEditCommands[i]]; - - SEL edit_selector = NSSelectorFromString(sel_str); - // May want to use @encode() for the last parameter to this method. - // If class_addMethod fails we assume that all the editing selectors where - // added to the class. - // If a certain class already implements a method then class_addMethod - // returns NO, which we can safely ignore. - class_addMethod(klass, edit_selector, (IMP)EditCommandImp, "v@:@"); - } -} - -bool RenderWidgetHostViewMacEditCommandHelper::IsMenuItemEnabled( - SEL item_action, - id<RenderWidgetHostViewMacOwner> owner) { - const char* selector_name = sel_getName(item_action); - // TODO(jeremy): The final form of this function will check state - // associated with the Browser. - - // For now just mark all edit commands as enabled. - NSString* selector_name_ns = [NSString stringWithUTF8String:selector_name]; - - // Remove trailing ':' - size_t str_len = [selector_name_ns length]; - selector_name_ns = [selector_name_ns substringToIndex:str_len - 1]; - std::string edit_command_name([selector_name_ns UTF8String]); - - // search for presence in set and return. - bool ret = edit_command_set_.find(edit_command_name) != - edit_command_set_.end(); - return ret; -} - -NSArray* RenderWidgetHostViewMacEditCommandHelper::GetEditSelectorNames() { - size_t num_edit_commands = arraysize(kEditCommands); - NSMutableArray* ret = [NSMutableArray arrayWithCapacity:num_edit_commands]; - - for (size_t i = 0; i < num_edit_commands; ++i) { - [ret addObject:[NSString stringWithUTF8String:kEditCommands[i]]]; - } - - return ret; -} diff --git a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm deleted file mode 100644 index c81cc83..0000000 --- a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm +++ /dev/null @@ -1,169 +0,0 @@ -// 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 "content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.h" - -#import <Cocoa/Cocoa.h> - -#include "base/message_loop.h" -#include "content/browser/renderer_host/mock_render_process_host.h" -#include "content/browser/renderer_host/render_widget_host.h" -#include "content/common/view_messages.h" -#include "content/test/test_browser_context.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/platform_test.h" - -class RenderWidgetHostViewMacEditCommandHelperTest : public PlatformTest { -}; - -// Bare bones obj-c class for testing purposes. -@interface RenderWidgetHostViewMacEditCommandHelperTestClass : NSObject -@end - -@implementation RenderWidgetHostViewMacEditCommandHelperTestClass -@end - -// Class that owns a RenderWidgetHostViewMac. -@interface RenderWidgetHostViewMacOwner : - NSObject<RenderWidgetHostViewMacOwner> { - RenderWidgetHostViewMac* rwhvm_; -} - -- (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)rwhvm; -@end - -@implementation RenderWidgetHostViewMacOwner - -- (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)rwhvm { - if ((self = [super init])) { - rwhvm_ = rwhvm; - } - return self; -} - -- (RenderWidgetHostViewMac*)renderWidgetHostViewMac { - return rwhvm_; -} - -@end - - -namespace { - // Returns true if all the edit command names in the array are present - // in test_obj. - // edit_commands is a list of NSStrings, selector names are formed by - // appending a trailing ':' to the string. - bool CheckObjectRespondsToEditCommands(NSArray* edit_commands, - id test_obj) { - for (NSString* edit_command_name in edit_commands) { - NSString* sel_str = [edit_command_name stringByAppendingString:@":"]; - if (![test_obj respondsToSelector:NSSelectorFromString(sel_str)]) { - return false; - } - } - - return true; - } -} // namespace - -// Create a RenderWidget for which we can filter messages. -class RenderWidgetHostEditCommandCounter : public RenderWidgetHost { - public: - RenderWidgetHostEditCommandCounter(RenderProcessHost* process, - int routing_id) - : RenderWidgetHost(process, routing_id), - edit_command_message_count_(0) { - } - - virtual bool Send(IPC::Message* message) { - if (message->type() == ViewMsg_ExecuteEditCommand::ID) - edit_command_message_count_++; - return RenderWidgetHost::Send(message); - } - - unsigned int edit_command_message_count_; -}; - - -// Tests that editing commands make it through the pipeline all the way to -// RenderWidgetHost. -// Disabled, http://crbug.com/93286. -TEST_F(RenderWidgetHostViewMacEditCommandHelperTest, - DISABLED_TestEditingCommandDelivery) { - RenderWidgetHostViewMacEditCommandHelper helper; - NSArray* edit_command_strings = helper.GetEditSelectorNames(); - - // Set up a mock render widget and set expectations. - MessageLoopForUI message_loop; - TestBrowserContext browser_context; - MockRenderProcessHost mock_process(&browser_context); - RenderWidgetHostEditCommandCounter render_widget(&mock_process, 0); - - // RenderWidgetHostViewMac self destructs (RenderWidgetHostViewMacCocoa - // takes ownership) so no need to delete it ourselves. - RenderWidgetHostViewMac* rwhvm = new RenderWidgetHostViewMac(&render_widget); - - RenderWidgetHostViewMacOwner* rwhwvm_owner = - [[[RenderWidgetHostViewMacOwner alloc] - initWithRenderWidgetHostViewMac:rwhvm] autorelease]; - - helper.AddEditingSelectorsToClass([rwhwvm_owner class]); - - for (NSString* edit_command_name in edit_command_strings) { - NSString* sel_str = [edit_command_name stringByAppendingString:@":"]; - [rwhwvm_owner performSelector:NSSelectorFromString(sel_str) withObject:nil]; - } - - size_t num_edit_commands = [edit_command_strings count]; - EXPECT_EQ(render_widget.edit_command_message_count_, num_edit_commands); -} - -// Test RenderWidgetHostViewMacEditCommandHelper::AddEditingSelectorsToClass -TEST_F(RenderWidgetHostViewMacEditCommandHelperTest, - TestAddEditingSelectorsToClass) { - RenderWidgetHostViewMacEditCommandHelper helper; - NSArray* edit_command_strings = helper.GetEditSelectorNames(); - ASSERT_GT([edit_command_strings count], 0U); - - // Create a class instance and add methods to the class. - RenderWidgetHostViewMacEditCommandHelperTestClass* test_obj = - [[[RenderWidgetHostViewMacEditCommandHelperTestClass alloc] init] - autorelease]; - - // Check that edit commands aren't already attached to the object. - ASSERT_FALSE(CheckObjectRespondsToEditCommands(edit_command_strings, - test_obj)); - - helper.AddEditingSelectorsToClass([test_obj class]); - - // Check that all edit commands where added. - ASSERT_TRUE(CheckObjectRespondsToEditCommands(edit_command_strings, - test_obj)); - - // AddEditingSelectorsToClass() should be idempotent. - helper.AddEditingSelectorsToClass([test_obj class]); - - // Check that all edit commands are still there. - ASSERT_TRUE(CheckObjectRespondsToEditCommands(edit_command_strings, - test_obj)); -} - -// Test RenderWidgetHostViewMacEditCommandHelper::IsMenuItemEnabled. -TEST_F(RenderWidgetHostViewMacEditCommandHelperTest, TestMenuItemEnabling) { - RenderWidgetHostViewMacEditCommandHelper helper; - RenderWidgetHostViewMacOwner* rwhvm_owner = - [[[RenderWidgetHostViewMacOwner alloc] init] autorelease]; - - // The select all menu should always be enabled. - SEL select_all = NSSelectorFromString(@"selectAll:"); - ASSERT_TRUE(helper.IsMenuItemEnabled(select_all, rwhvm_owner)); - - // Random selectors should be enabled by the function. - SEL garbage_selector = NSSelectorFromString(@"randomGarbageSelector:"); - ASSERT_FALSE(helper.IsMenuItemEnabled(garbage_selector, rwhvm_owner)); - - // TODO(jeremy): Currently IsMenuItemEnabled just returns true for all edit - // selectors. Once we go past that we should do more extensive testing here. -} diff --git a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm deleted file mode 100644 index 43e5300..0000000 --- a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm +++ /dev/null @@ -1,194 +0,0 @@ -// 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. - -#include "content/browser/renderer_host/render_widget_host_view_mac.h" - -#include "base/mac/scoped_nsautorelease_pool.h" -#include "content/browser/browser_thread.h" -#include "content/browser/renderer_host/test_render_view_host.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/base/test/cocoa_test_event_utils.h" -#import "ui/base/test/ui_cocoa_test_helper.h" -#include "webkit/plugins/npapi/webplugin.h" - -class RenderWidgetHostViewMacTest : public RenderViewHostTestHarness { - public: - RenderWidgetHostViewMacTest() : old_rwhv_(NULL), rwhv_mac_(NULL) {} - - virtual void SetUp() { - RenderViewHostTestHarness::SetUp(); - - // TestRenderViewHost's destruction assumes that its view is a - // TestRenderWidgetHostView, so store its view and reset it back to the - // stored view in |TearDown()|. - old_rwhv_ = rvh()->view(); - - // Owned by its |native_view()|, i.e. |rwhv_cocoa_|. - rwhv_mac_ = new RenderWidgetHostViewMac(rvh()); - rwhv_cocoa_.reset([rwhv_mac_->native_view() retain]); - } - virtual void TearDown() { - // See comment in SetUp(). - rvh()->SetView(old_rwhv_); - - // Make sure the rwhv_mac_ is gone once the superclass's |TearDown()| runs. - rwhv_cocoa_.reset(); - pool_.Recycle(); - MessageLoop::current()->RunAllPending(); - pool_.Recycle(); - - RenderViewHostTestHarness::TearDown(); - } - protected: - // Adds an accelerated plugin view to |rwhv_cocoa_|. Returns a handle to the - // newly-added view. Callers must ensure that a UI thread is present and - // running before calling this function. - gfx::PluginWindowHandle AddAcceleratedPluginView(int w, int h) { - // Create an accelerated view the size of the rhwvmac. - [rwhv_cocoa_.get() setFrame:NSMakeRect(0, 0, w, h)]; - gfx::PluginWindowHandle accelerated_handle = - rwhv_mac_->AllocateFakePluginWindowHandle(/*opaque=*/false, - /*root=*/false); - rwhv_mac_->AcceleratedSurfaceSetIOSurface(accelerated_handle, w, h, 0); - - // The accelerated view isn't shown until it has a valid rect and has been - // painted to. - rwhv_mac_->AcceleratedSurfaceBuffersSwapped(accelerated_handle, - 0, 0, 0, 0, 0); - webkit::npapi::WebPluginGeometry geom; - gfx::Rect rect(0, 0, w, h); - geom.window = accelerated_handle; - geom.window_rect = rect; - geom.clip_rect = rect; - geom.visible = true; - geom.rects_valid = true; - rwhv_mac_->MovePluginWindows( - std::vector<webkit::npapi::WebPluginGeometry>(1, geom)); - - return accelerated_handle; - } - private: - // This class isn't derived from PlatformTest. - base::mac::ScopedNSAutoreleasePool pool_; - - RenderWidgetHostView* old_rwhv_; - - protected: - RenderWidgetHostViewMac* rwhv_mac_; - scoped_nsobject<RenderWidgetHostViewCocoa> rwhv_cocoa_; - - private: - DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewMacTest); -}; - -TEST_F(RenderWidgetHostViewMacTest, Basic) { -} - -// Regression test for http://crbug.com/60318 -TEST_F(RenderWidgetHostViewMacTest, FocusAcceleratedView) { - // The accelerated view methods want to be called on the UI thread. - scoped_ptr<BrowserThread> ui_thread_( - new BrowserThread(BrowserThread::UI, MessageLoop::current())); - - int w = 400, h = 300; - gfx::PluginWindowHandle accelerated_handle = AddAcceleratedPluginView(w, h); - EXPECT_FALSE([rwhv_cocoa_.get() isHidden]); - NSView* accelerated_view = static_cast<NSView*>( - rwhv_mac_->ViewForPluginWindowHandle(accelerated_handle)); - EXPECT_FALSE([accelerated_view isHidden]); - - // Take away first responder from the rwhvmac, then simulate the effect of a - // click on the accelerated view. The rwhvmac should be first responder - // again. - scoped_nsobject<NSWindow> window([[CocoaTestHelperWindow alloc] init]); - scoped_nsobject<NSView> other_view( - [[NSTextField alloc] initWithFrame:NSMakeRect(0, h, w, 40)]); - [[window contentView] addSubview:rwhv_cocoa_.get()]; - [[window contentView] addSubview:other_view.get()]; - - EXPECT_TRUE([rwhv_cocoa_.get() acceptsFirstResponder]); - [window makeFirstResponder:rwhv_cocoa_.get()]; - EXPECT_EQ(rwhv_cocoa_.get(), [window firstResponder]); - EXPECT_FALSE([accelerated_view acceptsFirstResponder]); - - EXPECT_TRUE([other_view acceptsFirstResponder]); - [window makeFirstResponder:other_view]; - EXPECT_NE(rwhv_cocoa_.get(), [window firstResponder]); - - EXPECT_TRUE([accelerated_view acceptsFirstResponder]); - [window makeFirstResponder:accelerated_view]; - EXPECT_EQ(rwhv_cocoa_.get(), [window firstResponder]); - - // Clean up. - rwhv_mac_->DestroyFakePluginWindowHandle(accelerated_handle); -} - -TEST_F(RenderWidgetHostViewMacTest, AcceptsFirstResponder) { - // The RWHVCocoa should normally accept first responder status. - EXPECT_TRUE([rwhv_cocoa_.get() acceptsFirstResponder]); - - // Unless we tell it not to. - rwhv_mac_->SetTakesFocusOnlyOnMouseDown(true); - EXPECT_FALSE([rwhv_cocoa_.get() acceptsFirstResponder]); - - // But we can set things back to the way they were originally. - rwhv_mac_->SetTakesFocusOnlyOnMouseDown(false); - EXPECT_TRUE([rwhv_cocoa_.get() acceptsFirstResponder]); -} - -TEST_F(RenderWidgetHostViewMacTest, TakesFocusOnMouseDown) { - scoped_nsobject<CocoaTestHelperWindow> - window([[CocoaTestHelperWindow alloc] init]); - [[window contentView] addSubview:rwhv_cocoa_.get()]; - - // Even if the RWHVCocoa disallows first responder, clicking on it gives it - // focus. - [window setPretendIsKeyWindow:YES]; - [window makeFirstResponder:nil]; - ASSERT_NE(rwhv_cocoa_.get(), [window firstResponder]); - - rwhv_mac_->SetTakesFocusOnlyOnMouseDown(true); - EXPECT_FALSE([rwhv_cocoa_.get() acceptsFirstResponder]); - - std::pair<NSEvent*, NSEvent*> clicks = - cocoa_test_event_utils::MouseClickInView(rwhv_cocoa_.get(), 1); - [rwhv_cocoa_.get() mouseDown:clicks.first]; - EXPECT_EQ(rwhv_cocoa_.get(), [window firstResponder]); -} - -// Regression test for http://crbug.com/64256 -TEST_F(RenderWidgetHostViewMacTest, TakesFocusOnMouseDownWithAcceleratedView) { - // The accelerated view methods want to be called on the UI thread. - scoped_ptr<BrowserThread> ui_thread_( - new BrowserThread(BrowserThread::UI, MessageLoop::current())); - - int w = 400, h = 300; - gfx::PluginWindowHandle accelerated_handle = AddAcceleratedPluginView(w, h); - EXPECT_FALSE([rwhv_cocoa_.get() isHidden]); - NSView* accelerated_view = static_cast<NSView*>( - rwhv_mac_->ViewForPluginWindowHandle(accelerated_handle)); - EXPECT_FALSE([accelerated_view isHidden]); - - // Add the RWHVCocoa to the window and remove first responder status. - scoped_nsobject<CocoaTestHelperWindow> - window([[CocoaTestHelperWindow alloc] init]); - [[window contentView] addSubview:rwhv_cocoa_.get()]; - [window setPretendIsKeyWindow:YES]; - [window makeFirstResponder:nil]; - EXPECT_NE(rwhv_cocoa_.get(), [window firstResponder]); - - // Tell the RWHVMac to not accept first responder status. The accelerated - // view should also stop accepting first responder. - rwhv_mac_->SetTakesFocusOnlyOnMouseDown(true); - EXPECT_FALSE([accelerated_view acceptsFirstResponder]); - - // A click on the accelerated view should focus the RWHVCocoa. - std::pair<NSEvent*, NSEvent*> clicks = - cocoa_test_event_utils::MouseClickInView(accelerated_view, 1); - [rwhv_cocoa_.get() mouseDown:clicks.first]; - EXPECT_EQ(rwhv_cocoa_.get(), [window firstResponder]); - - // Clean up. - rwhv_mac_->DestroyFakePluginWindowHandle(accelerated_handle); -} diff --git a/content/content_browser.gypi b/content/content_browser.gypi index e18fd38..1051cbc 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -293,8 +293,6 @@ 'browser/plugin_service.h', 'browser/plugin_service_filter.h', 'browser/quota_permission_context.h', - 'browser/renderer_host/accelerated_plugin_view_mac.h', - 'browser/renderer_host/accelerated_plugin_view_mac.mm', 'browser/renderer_host/accelerated_surface_container_mac.cc', 'browser/renderer_host/accelerated_surface_container_mac.h', 'browser/renderer_host/accelerated_surface_container_manager_mac.cc', @@ -404,11 +402,7 @@ 'browser/renderer_host/render_widget_host_view.h', 'browser/renderer_host/render_widget_host_view_gtk.cc', 'browser/renderer_host/render_widget_host_view_gtk.h', - 'browser/renderer_host/render_widget_host_view_mac.h', - 'browser/renderer_host/render_widget_host_view_mac.mm', 'browser/renderer_host/render_widget_host_view_mac_delegate.h', - 'browser/renderer_host/render_widget_host_view_mac_editcommand_helper.h', - 'browser/renderer_host/render_widget_host_view_mac_editcommand_helper.mm', 'browser/renderer_host/render_widget_host_view_win.cc', 'browser/renderer_host/render_widget_host_view_win.h', 'browser/renderer_host/resource_dispatcher_host.cc', @@ -605,20 +599,12 @@ 'sources!': [ 'browser/power_save_blocker_stub.cc', ], - 'sources': [ - # Build necessary Mozilla sources - '../third_party/mozilla/ComplexTextInputPanel.h', - '../third_party/mozilla/ComplexTextInputPanel.mm', - ], 'link_settings': { 'mac_bundle_resources': [ 'browser/gpu.sb', 'browser/worker.sb', ], }, - 'dependencies': [ - 'closure_blocks_leopard_compat', - ], }, { # OS!="mac" 'dependencies': [ '../sandbox/sandbox.gyp:sandbox', diff --git a/content/content_tests.gypi b/content/content_tests.gypi index bc67eb2..c6224ee 100644 --- a/content/content_tests.gypi +++ b/content/content_tests.gypi @@ -12,7 +12,6 @@ '../skia/skia.gyp:skia', '../testing/gmock.gyp:gmock', '../testing/gtest.gyp:gtest', - '../ui/ui.gyp:ui_test_support', ], 'include_dirs': [ '..', @@ -120,7 +119,6 @@ 'browser/in_process_webkit/webkit_thread_unittest.cc', 'browser/mac/closure_blocks_leopard_compat_unittest.cc', 'browser/mach_broker_mac_unittest.cc', - 'browser/renderer_host/accelerated_plugin_view_mac_unittest.mm', 'browser/renderer_host/gtk_key_bindings_handler_unittest.cc', 'browser/renderer_host/media/audio_input_device_manager_unittest.cc', 'browser/renderer_host/media/audio_renderer_host_unittest.cc', @@ -128,8 +126,6 @@ 'browser/renderer_host/media/video_capture_host_unittest.cc', 'browser/renderer_host/media/video_capture_manager_unittest.cc', 'browser/renderer_host/render_view_host_unittest.cc', - 'browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm', - 'browser/renderer_host/render_widget_host_view_mac_unittest.mm', 'browser/renderer_host/resource_dispatcher_host_unittest.cc', 'browser/renderer_host/resource_queue_unittest.cc', 'browser/resolve_proxy_msg_helper_unittest.cc', |