summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authortorne@chromium.org <torne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-28 14:50:22 +0000
committertorne@chromium.org <torne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-28 14:50:22 +0000
commit66db7bc0efc03109bddc3b31f7944d7fe492f643 (patch)
tree5971098d7302f70a93e9c670ceb845e6bc6d8364 /content
parent5bfd1e78ca6b5f45a15b1bff9316b2d981389fac (diff)
downloadchromium_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')
-rw-r--r--content/DEPS2
-rw-r--r--content/browser/renderer_host/accelerated_plugin_view_mac.h58
-rw-r--r--content/browser/renderer_host/accelerated_plugin_view_mac.mm247
-rw-r--r--content/browser/renderer_host/accelerated_plugin_view_mac_unittest.mm188
-rw-r--r--content/browser/renderer_host/render_widget_host_view_mac.h410
-rw-r--r--content/browser/renderer_host/render_widget_host_view_mac.mm2740
-rw-r--r--content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.h70
-rw-r--r--content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.mm235
-rw-r--r--content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm169
-rw-r--r--content/browser/renderer_host/render_widget_host_view_mac_unittest.mm194
-rw-r--r--content/content_browser.gypi14
-rw-r--r--content/content_tests.gypi4
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',