blob: de4f6f4c0e3d1770742b66b9adfacd3e142925a3 [file] [log] [blame]
// Copyright (c) 2012 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 <list>
#include "base/memory/scoped_nsobject.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time.h"
#include "content/browser/accessibility/browser_accessibility_delegate_mac.h"
#include "content/browser/renderer_host/accelerated_surface_container_manager_mac.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/common/edit_command.h"
#import "content/public/browser/render_widget_host_view_mac_base.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 CompositingIOSurfaceMac;
@class FullscreenWindowManager;
class RenderWidgetHostViewMac;
@protocol RenderWidgetHostViewMacDelegate;
class RenderWidgetHostViewMacEditCommandHelper;
@class ToolTip;
namespace content {
class RenderWidgetHostImpl;
}
@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 <RenderWidgetHostViewMacBase,
RenderWidgetHostViewMacOwner,
NSTextInputClient,
BrowserAccessibilityDelegateCocoa> {
@private
scoped_ptr<RenderWidgetHostViewMac> renderWidgetHostView_;
NSObject<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_;
// OpenGL Support:
// recursive globalFrameDidChange protection:
BOOL handlingGlobalFrameDidChange_;
}
@property(nonatomic, readonly) NSRange selectedRange;
- (void)setCanBeKeyView:(BOOL)can;
- (void)setTakesFocusOnlyOnMouseDown:(BOOL)b;
- (void)setCloseOnDeactivate:(BOOL)b;
- (void)setToolTipAtMousePoint:(NSString *)string;
// True for always-on-top special windows (e.g. Balloons and Panels).
- (BOOL)acceptsMouseEventsWhenInactive;
// 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."
//
// RenderWidgetHostView class hierarchy described in render_widget_host_view.h.
class RenderWidgetHostViewMac : public content::RenderWidgetHostViewBase {
public:
virtual ~RenderWidgetHostViewMac();
RenderWidgetHostViewCocoa* cocoa_view() const { return cocoa_view_; }
void SetDelegate(NSObject<RenderWidgetHostViewMacDelegate>* delegate);
// RenderWidgetHostView implementation.
virtual void InitAsChild(gfx::NativeView parent_view) OVERRIDE;
virtual content::RenderWidgetHost* GetRenderWidgetHost() const 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 gfx::NativeViewAccessible GetNativeViewAccessible() OVERRIDE;
virtual bool HasFocus() const OVERRIDE;
virtual void Show() OVERRIDE;
virtual void Hide() OVERRIDE;
virtual bool IsShowing() OVERRIDE;
virtual gfx::Rect GetViewBounds() const OVERRIDE;
virtual void SetShowingContextMenu(bool showing) OVERRIDE;
virtual void SetActive(bool active) OVERRIDE;
virtual void SetTakesFocusOnlyOnMouseDown(bool flag) OVERRIDE;
virtual void SetWindowVisibility(bool visible) OVERRIDE;
virtual void WindowFrameChanged() OVERRIDE;
virtual void SetBackground(const SkBitmap& background) OVERRIDE;
// Implementation of RenderWidgetHostViewPort.
virtual void InitAsPopup(content::RenderWidgetHostView* parent_host_view,
const gfx::Rect& pos) OVERRIDE;
virtual void InitAsFullscreen(
content::RenderWidgetHostView* reference_host_view) OVERRIDE;
virtual void DidBecomeSelected() OVERRIDE;
virtual void WasHidden() OVERRIDE;
virtual void MovePluginWindows(
const std::vector<webkit::npapi::WebPluginGeometry>& moves) OVERRIDE;
virtual void Focus() OVERRIDE;
virtual void Blur() OVERRIDE;
virtual void UpdateCursor(const WebCursor& cursor) OVERRIDE;
virtual void SetIsLoading(bool is_loading) OVERRIDE;
virtual void TextInputStateChanged(ui::TextInputType state,
bool can_compose_inline) OVERRIDE;
virtual void SelectionBoundsChanged(const gfx::Rect& start_rect,
const gfx::Rect& end_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 string16& text,
size_t offset,
const ui::Range& range) OVERRIDE;
virtual BackingStore* AllocBackingStore(const gfx::Size& size) OVERRIDE;
virtual bool CopyFromCompositingSurface(
const gfx::Size& size,
skia::PlatformCanvas* output) OVERRIDE;
virtual void AsyncCopyFromCompositingSurface(
const gfx::Size& size,
skia::PlatformCanvas* output,
base::Callback<void(bool)> callback) OVERRIDE;
virtual void OnAcceleratedCompositingStateChange() OVERRIDE;
// See comment in RenderWidgetHostView!
virtual gfx::Rect GetViewCocoaBounds() const OVERRIDE;
virtual void OnAccessibilityNotifications(
const std::vector<AccessibilityHostMsg_NotificationParams>& 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.
CONTENT_EXPORT 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(
const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
int gpu_host_id) OVERRIDE;
virtual void AcceleratedSurfacePostSubBuffer(
const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
int gpu_host_id) OVERRIDE;
virtual void AcceleratedSurfaceSuspend() OVERRIDE;
virtual void GetScreenInfo(WebKit::WebScreenInfo* results) OVERRIDE;
virtual gfx::Rect GetRootWindowBounds() OVERRIDE;
virtual gfx::GLSurfaceHandle GetCompositingSurface() OVERRIDE;
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 ProcessTouchAck(WebKit::WebInputEvent::Type type,
bool processed) 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;
virtual void UnhandledWheelEvent(
const WebKit::WebMouseWheelEvent& event) OVERRIDE;
// Forwards the mouse event to the renderer.
void ForwardMouseEvent(const WebKit::WebMouseEvent& event);
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_; }
// Call setNeedsDisplay on the cocoa_view_. The IOSurface will be drawn during
// the next drawRect. The route_id and gpu_host_id are added to a list to be
// acked when the SwapBuffers occurs in drawRect.
void CompositorSwapBuffers(uint64 surface_handle,
int32 route_id,
int32 gpu_host_id);
// Ack pending SwapBuffers requests (queued up by CompositorSwapBuffers), if
// any, to unblock the GPU process. Has no effect if there are no pending
// requests.
void AckPendingCompositorSwapBuffers();
// 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_|.
content::RenderWidgetHostImpl* 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_;
// 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_;
// Whether last rendered frame was accelerated.
bool last_frame_was_accelerated_;
// 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 web_contents_switch_paint_time_;
// Current text input type.
ui::TextInputType text_input_type_;
bool can_compose_inline_;
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_;
scoped_ptr<CompositingIOSurfaceMac> compositing_iosurface_;
NSWindow* pepper_fullscreen_window() const {
return pepper_fullscreen_window_;
}
private:
friend class content::RenderWidgetHostView;
// 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(content::RenderWidgetHost* widget);
// 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_;
// The text to be shown in the tooltip, supplied by the renderer.
string16 tooltip_text_;
// Factory used to safely scope delayed calls to ShutdownHost().
base::WeakPtrFactory<RenderWidgetHostViewMac> weak_factory_;
// selected text on the renderer.
std::string selected_text_;
gfx::PluginWindowHandle compositing_surface_;
// List of pending swaps for deferred acking:
// pairs of (route_id, gpu_host_id).
std::list<std::pair<int32, int32> > pending_swap_buffers_acks_;
// The fullscreen window used for pepper flash.
scoped_nsobject<NSWindow> pepper_fullscreen_window_;
scoped_nsobject<FullscreenWindowManager> fullscreen_window_manager_;
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewMac);
};
#endif // CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_MAC_H_