1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_MAC_H_
6 #define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_MAC_H_
8 #import <Cocoa/Cocoa.h>
9 #include <IOSurface/IOSurfaceAPI.h>
16 #include "base/mac/scoped_nsobject.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/memory/weak_ptr.h"
19 #include "base/time/time.h"
20 #include "content/browser/compositor/browser_compositor_view_mac.h"
21 #include "content/browser/compositor/delegated_frame_host.h"
22 #include "content/browser/renderer_host/compositing_iosurface_layer_mac.h"
23 #include "content/browser/renderer_host/display_link_mac.h"
24 #include "content/browser/renderer_host/render_widget_host_view_base.h"
25 #include "content/browser/renderer_host/software_frame_manager.h"
26 #include "content/common/content_export.h"
27 #include "content/common/cursors/webcursor.h"
28 #include "content/common/edit_command.h"
29 #import "content/public/browser/render_widget_host_view_mac_base.h"
30 #include "ipc/ipc_sender.h"
31 #include "third_party/WebKit/public/web/WebCompositionUnderline.h"
32 #include "ui/base/cocoa/base_view.h"
33 #include "ui/base/cocoa/remote_layer_api.h"
34 #include "ui/gfx/display_observer.h"
36 struct ViewHostMsg_TextInputState_Params
;
39 class BrowserCompositorviewMac
;
40 class RenderWidgetHostViewMac
;
41 class RenderWidgetHostViewMacEditCommandHelper
;
50 @
class FullscreenWindowManager
;
51 @protocol RenderWidgetHostViewMacDelegate
;
54 @protocol RenderWidgetHostViewMacOwner
55 - (content::RenderWidgetHostViewMac
*)renderWidgetHostViewMac
;
58 // This is the view that lives in the Cocoa view hierarchy. In Windows-land,
59 // RenderWidgetHostViewWin is both the view and the delegate. We split the roles
60 // but that means that the view needs to own the delegate and will dispose of it
61 // when it's removed from the view system.
62 @interface RenderWidgetHostViewCocoa
63 : BaseView
<RenderWidgetHostViewMacBase
,
64 RenderWidgetHostViewMacOwner
,
67 scoped_ptr
<content::RenderWidgetHostViewMac
> renderWidgetHostView_
;
68 // This ivar is the cocoa delegate of the NSResponder.
69 base::scoped_nsobject
<NSObject
<RenderWidgetHostViewMacDelegate
>>
72 BOOL takesFocusOnlyOnMouseDown_
;
73 BOOL closeOnDeactivate_
;
74 scoped_ptr
<content::RenderWidgetHostViewMacEditCommandHelper
>
77 // These are part of the magic tooltip code from WebKit's WebHTMLView:
78 id trackingRectOwner_
; // (not retained)
79 void* trackingRectUserData_
;
80 NSTrackingRectTag lastToolTipTag_
;
81 base::scoped_nsobject
<NSString
> toolTip_
;
83 // Is YES if there was a mouse-down as yet unbalanced with a mouse-up.
84 BOOL hasOpenMouseDown_
;
86 NSWindow
* lastWindow_
; // weak
88 // The cursor for the page. This is passed up from the renderer.
89 base::scoped_nsobject
<NSCursor
> currentCursor_
;
91 // Variables used by our implementaion of the NSTextInput protocol.
92 // An input method of Mac calls the methods of this protocol not only to
93 // notify an application of its status, but also to retrieve the status of
94 // the application. That is, an application cannot control an input method
96 // This object keeps the status of a composition of the renderer and returns
97 // it when an input method asks for it.
98 // We need to implement Objective-C methods for the NSTextInput protocol. On
99 // the other hand, we need to implement a C++ method for an IPC-message
100 // handler which receives input-method events from the renderer.
102 // Represents the input-method attributes supported by this object.
103 base::scoped_nsobject
<NSArray
> validAttributesForMarkedText_
;
105 // Indicates if we are currently handling a key down event.
106 BOOL handlingKeyDown_
;
108 // Indicates if there is any marked text.
111 // Indicates if unmarkText is called or not when handling a keyboard
113 BOOL unmarkTextCalled_
;
115 // The range of current marked text inside the whole content of the DOM node
117 // TODO(suzhe): This is currently a fake value, as we do not support accessing
118 // the whole content yet.
119 NSRange markedRange_
;
121 // The selected range, cached from a message sent by the renderer.
122 NSRange selectedRange_
;
124 // Text to be inserted which was generated by handling a key down event.
125 base::string16 textToBeInserted_
;
127 // Marked text which was generated by handling a key down event.
128 base::string16 markedText_
;
130 // Underline information of the |markedText_|.
131 std::vector
<blink::WebCompositionUnderline
> underlines_
;
133 // Indicates if doCommandBySelector method receives any edit command when
134 // handling a key down event.
135 BOOL hasEditCommands_
;
137 // Contains edit commands received by the -doCommandBySelector: method when
138 // handling a key down event, not including inserting commands, eg. insertTab,
140 content::EditCommands editCommands_
;
142 // The plugin that currently has focus (-1 if no plugin has focus).
143 int focusedPluginIdentifier_
;
145 // Whether or not plugin IME is currently enabled active.
146 BOOL pluginImeActive_
;
148 // Whether the previous mouse event was ignored due to hitTest check.
149 BOOL mouseEventWasIgnored_
;
151 // Event monitor for scroll wheel end event.
154 // If true then escape key down events are suppressed until the first escape
155 // key up event. (The up event is suppressed as well). This is used by the
156 // flash fullscreen code to avoid sending a key up event without a matching
158 BOOL suppressNextEscapeKeyUp_
;
161 @
property(nonatomic
, readonly
) NSRange selectedRange
;
162 @
property(nonatomic
, readonly
) BOOL suppressNextEscapeKeyUp
;
164 - (void)setCanBeKeyView
:(BOOL
)can
;
165 - (void)setTakesFocusOnlyOnMouseDown
:(BOOL
)b
;
166 - (void)setCloseOnDeactivate
:(BOOL
)b
;
167 - (void)setToolTipAtMousePoint
:(NSString
*)string
;
168 // True for always-on-top special windows (e.g. Balloons and Panels).
169 - (BOOL
)acceptsMouseEventsWhenInactive
;
170 // Cancel ongoing composition (abandon the marked text).
171 - (void)cancelComposition
;
172 // Confirm ongoing composition.
173 - (void)confirmComposition
;
174 // Enables or disables plugin IME.
175 - (void)setPluginImeActive
:(BOOL
)active
;
176 // Updates the current plugin focus state.
177 - (void)pluginFocusChanged
:(BOOL
)focused forPlugin
:(int)pluginId
;
178 // Evaluates the event in the context of plugin IME, if plugin IME is enabled.
179 // Returns YES if the event was handled.
180 - (BOOL
)postProcessEventForPluginIme
:(NSEvent
*)event
;
181 - (void)updateCursor
:(NSCursor
*)cursor
;
182 - (NSRect
)firstViewRectForCharacterRange
:(NSRange
)theRange
183 actualRange
:(NSRangePointer
)actualRange
;
187 class RenderWidgetHostImpl
;
189 ///////////////////////////////////////////////////////////////////////////////
190 // RenderWidgetHostViewMac
192 // An object representing the "View" of a rendered web page. This object is
193 // responsible for displaying the content of the web page, and integrating with
194 // the Cocoa view system. It is the implementation of the RenderWidgetHostView
195 // that the cross-platform RenderWidgetHost object uses
196 // to display the data.
198 // Comment excerpted from render_widget_host.h:
200 // "The lifetime of the RenderWidgetHost* is tied to the render process.
201 // If the render process dies, the RenderWidgetHost* goes away and all
202 // references to it must become NULL."
204 // RenderWidgetHostView class hierarchy described in render_widget_host_view.h.
205 class CONTENT_EXPORT RenderWidgetHostViewMac
206 : public RenderWidgetHostViewBase
,
207 public DelegatedFrameHostClient
,
208 public BrowserCompositorViewMacClient
,
210 public CompositingIOSurfaceLayerClient
,
211 public gfx::DisplayObserver
{
213 // The view will associate itself with the given widget. The native view must
214 // be hooked up immediately to the view hierarchy, or else when it is
215 // deleted it will delete this out from under the caller.
216 explicit RenderWidgetHostViewMac(RenderWidgetHost
* widget
);
217 virtual ~RenderWidgetHostViewMac();
219 RenderWidgetHostViewCocoa
* cocoa_view() const { return cocoa_view_
; }
221 // |delegate| is used to separate out the logic from the NSResponder delegate.
222 // |delegate| is retained by this class.
223 // |delegate| should be set at most once.
224 CONTENT_EXPORT
void SetDelegate(
225 NSObject
<RenderWidgetHostViewMacDelegate
>* delegate
);
226 void SetAllowPauseForResizeOrRepaint(bool allow
);
228 // RenderWidgetHostView implementation.
229 virtual bool OnMessageReceived(const IPC::Message
& msg
) OVERRIDE
;
230 virtual void InitAsChild(gfx::NativeView parent_view
) OVERRIDE
;
231 virtual RenderWidgetHost
* GetRenderWidgetHost() const OVERRIDE
;
232 virtual void SetSize(const gfx::Size
& size
) OVERRIDE
;
233 virtual void SetBounds(const gfx::Rect
& rect
) OVERRIDE
;
234 virtual gfx::NativeView
GetNativeView() const OVERRIDE
;
235 virtual gfx::NativeViewId
GetNativeViewId() const OVERRIDE
;
236 virtual gfx::NativeViewAccessible
GetNativeViewAccessible() OVERRIDE
;
237 virtual bool HasFocus() const OVERRIDE
;
238 virtual bool IsSurfaceAvailableForCopy() const OVERRIDE
;
239 virtual void Show() OVERRIDE
;
240 virtual void Hide() OVERRIDE
;
241 virtual bool IsShowing() OVERRIDE
;
242 virtual gfx::Rect
GetViewBounds() const OVERRIDE
;
243 virtual void SetShowingContextMenu(bool showing
) OVERRIDE
;
244 virtual void SetActive(bool active
) OVERRIDE
;
245 virtual void SetTakesFocusOnlyOnMouseDown(bool flag
) OVERRIDE
;
246 virtual void SetWindowVisibility(bool visible
) OVERRIDE
;
247 virtual void WindowFrameChanged() OVERRIDE
;
248 virtual void ShowDefinitionForSelection() OVERRIDE
;
249 virtual bool SupportsSpeech() const OVERRIDE
;
250 virtual void SpeakSelection() OVERRIDE
;
251 virtual bool IsSpeaking() const OVERRIDE
;
252 virtual void StopSpeaking() OVERRIDE
;
253 virtual void SetBackgroundOpaque(bool opaque
) OVERRIDE
;
255 // Implementation of RenderWidgetHostViewBase.
256 virtual void InitAsPopup(RenderWidgetHostView
* parent_host_view
,
257 const gfx::Rect
& pos
) OVERRIDE
;
258 virtual void InitAsFullscreen(
259 RenderWidgetHostView
* reference_host_view
) OVERRIDE
;
260 virtual void WasShown() OVERRIDE
;
261 virtual void WasHidden() OVERRIDE
;
262 virtual void MovePluginWindows(
263 const std::vector
<WebPluginGeometry
>& moves
) OVERRIDE
;
264 virtual void Focus() OVERRIDE
;
265 virtual void Blur() OVERRIDE
;
266 virtual void UpdateCursor(const WebCursor
& cursor
) OVERRIDE
;
267 virtual void SetIsLoading(bool is_loading
) OVERRIDE
;
268 virtual void TextInputStateChanged(
269 const ViewHostMsg_TextInputState_Params
& params
) OVERRIDE
;
270 virtual void ImeCancelComposition() OVERRIDE
;
271 virtual void ImeCompositionRangeChanged(
272 const gfx::Range
& range
,
273 const std::vector
<gfx::Rect
>& character_bounds
) OVERRIDE
;
274 virtual void RenderProcessGone(base::TerminationStatus status
,
275 int error_code
) OVERRIDE
;
276 virtual void Destroy() OVERRIDE
;
277 virtual void SetTooltipText(const base::string16
& tooltip_text
) OVERRIDE
;
278 virtual void SelectionChanged(const base::string16
& text
,
280 const gfx::Range
& range
) OVERRIDE
;
281 virtual void SelectionBoundsChanged(
282 const ViewHostMsg_SelectionBounds_Params
& params
) OVERRIDE
;
283 virtual void CopyFromCompositingSurface(
284 const gfx::Rect
& src_subrect
,
285 const gfx::Size
& dst_size
,
286 const base::Callback
<void(bool, const SkBitmap
&)>& callback
,
287 SkColorType color_type
) OVERRIDE
;
288 virtual void CopyFromCompositingSurfaceToVideoFrame(
289 const gfx::Rect
& src_subrect
,
290 const scoped_refptr
<media::VideoFrame
>& target
,
291 const base::Callback
<void(bool)>& callback
) OVERRIDE
;
292 virtual bool CanCopyToVideoFrame() const OVERRIDE
;
293 virtual bool CanSubscribeFrame() const OVERRIDE
;
294 virtual void BeginFrameSubscription(
295 scoped_ptr
<RenderWidgetHostViewFrameSubscriber
> subscriber
) OVERRIDE
;
296 virtual void EndFrameSubscription() OVERRIDE
;
297 virtual void OnSwapCompositorFrame(
298 uint32 output_surface_id
, scoped_ptr
<cc::CompositorFrame
> frame
) OVERRIDE
;
299 virtual void AcceleratedSurfaceInitialized(int host_id
,
300 int route_id
) OVERRIDE
;
301 virtual BrowserAccessibilityManager
* CreateBrowserAccessibilityManager(
302 BrowserAccessibilityDelegate
* delegate
) OVERRIDE
;
303 virtual gfx::Point
AccessibilityOriginInScreen(const gfx::Rect
& bounds
)
305 virtual void AccessibilityShowMenu(const gfx::Point
& point
) OVERRIDE
;
306 virtual bool PostProcessEventForPluginIme(
307 const NativeWebKeyboardEvent
& event
) OVERRIDE
;
309 virtual void AcceleratedSurfaceBuffersSwapped(
310 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params
& params
,
311 int gpu_host_id
) OVERRIDE
;
312 virtual void AcceleratedSurfacePostSubBuffer(
313 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params
& params
,
314 int gpu_host_id
) OVERRIDE
;
315 virtual void AcceleratedSurfaceSuspend() OVERRIDE
;
316 virtual void AcceleratedSurfaceRelease() OVERRIDE
;
317 virtual bool HasAcceleratedSurface(const gfx::Size
& desired_size
) OVERRIDE
;
318 virtual void GetScreenInfo(blink::WebScreenInfo
* results
) OVERRIDE
;
319 virtual gfx::Rect
GetBoundsInRootWindow() OVERRIDE
;
320 virtual gfx::GLSurfaceHandle
GetCompositingSurface() OVERRIDE
;
322 virtual bool LockMouse() OVERRIDE
;
323 virtual void UnlockMouse() OVERRIDE
;
324 virtual void WheelEventAck(const blink::WebMouseWheelEvent
& event
,
325 InputEventAckState ack_result
) OVERRIDE
;
327 // IPC::Sender implementation.
328 virtual bool Send(IPC::Message
* message
) OVERRIDE
;
330 virtual SkColorType
PreferredReadbackFormat() OVERRIDE
;
332 // CompositingIOSurfaceLayerClient implementation.
333 virtual bool AcceleratedLayerShouldAckImmediately() const OVERRIDE
;
334 virtual void AcceleratedLayerDidDrawFrame() OVERRIDE
;
335 virtual void AcceleratedLayerHitError() OVERRIDE
;
337 // gfx::DisplayObserver implementation.
338 virtual void OnDisplayAdded(const gfx::Display
& new_display
) OVERRIDE
;
339 virtual void OnDisplayRemoved(const gfx::Display
& old_display
) OVERRIDE
;
340 virtual void OnDisplayMetricsChanged(const gfx::Display
& display
,
341 uint32_t metrics
) OVERRIDE
;
343 // Forwards the mouse event to the renderer.
344 void ForwardMouseEvent(const blink::WebMouseEvent
& event
);
348 void SetTextInputActive(bool active
);
350 // Sends completed plugin IME notification and text back to the renderer.
351 void PluginImeCompositionCompleted(const base::string16
& text
, int plugin_id
);
353 const std::string
& selected_text() const { return selected_text_
; }
355 // Returns true and stores first rectangle for character range if the
356 // requested |range| is already cached, otherwise returns false.
357 // Exposed for testing.
358 CONTENT_EXPORT
bool GetCachedFirstRectForCharacterRange(
359 NSRange range
, NSRect
* rect
, NSRange
* actual_range
);
361 // Returns true if there is line break in |range| and stores line breaking
362 // point to |line_breaking_point|. The |line_break_point| is valid only if
363 // this function returns true.
364 bool GetLineBreakIndex(const std::vector
<gfx::Rect
>& bounds
,
365 const gfx::Range
& range
,
366 size_t* line_break_point
);
368 // Returns composition character boundary rectangle. The |range| is
369 // composition based range. Also stores |actual_range| which is corresponding
370 // to actually used range for returned rectangle.
371 gfx::Rect
GetFirstRectForCompositionRange(const gfx::Range
& range
,
372 gfx::Range
* actual_range
);
374 // Converts from given whole character range to composition oriented range. If
375 // the conversion failed, return gfx::Range::InvalidRange.
376 gfx::Range
ConvertCharacterRangeToCompositionRange(
377 const gfx::Range
& request_range
);
379 WebContents
* GetWebContents();
381 // These member variables should be private, but the associated ObjC class
382 // needs access to them and can't be made a friend.
384 // The associated Model. Can be NULL if Destroy() is called when
385 // someone (other than superview) has retained |cocoa_view_|.
386 RenderWidgetHostImpl
* render_widget_host_
;
388 // Current text input type.
389 ui::TextInputType text_input_type_
;
390 bool can_compose_inline_
;
392 // The background CoreAnimation layer which is hosted by |cocoa_view_|.
393 base::scoped_nsobject
<CALayer
> background_layer_
;
395 // Delegated frame management and compositior.
396 scoped_ptr
<DelegatedFrameHost
> delegated_frame_host_
;
397 scoped_ptr
<ui::Layer
> root_layer_
;
399 // Container for the NSView drawn by the browser compositor.
400 scoped_ptr
<BrowserCompositorViewMac
> browser_compositor_view_
;
402 // Placeholder that is allocated while browser_compositor_view_ is NULL,
403 // indicating that a BrowserCompositorViewMac may be allocated. This is to
404 // help in recycling the internals of BrowserCompositorViewMac.
405 scoped_ptr
<BrowserCompositorViewPlaceholderMac
>
406 browser_compositor_view_placeholder_
;
408 NSWindow
* pepper_fullscreen_window() const {
409 return pepper_fullscreen_window_
;
412 CONTENT_EXPORT
void release_pepper_fullscreen_window_for_testing();
414 RenderWidgetHostViewMac
* fullscreen_parent_host_view() const {
415 return fullscreen_parent_host_view_
;
418 int window_number() const;
420 // The scale factor for the screen that the view is currently on.
421 float ViewScaleFactor() const;
423 // Update the scale factor for the backing store and for any CALayers.
424 void UpdateBackingStoreScaleFactor();
426 // Ensure that the display link is associated with the correct display.
427 void UpdateDisplayLink();
429 void PauseForPendingResizeOrRepaintsAndDraw();
431 // DelegatedFrameHostClient implementation.
432 virtual ui::Compositor
* GetCompositor() const OVERRIDE
;
433 virtual ui::Layer
* GetLayer() OVERRIDE
;
434 virtual RenderWidgetHostImpl
* GetHost() OVERRIDE
;
435 virtual bool IsVisible() OVERRIDE
;
436 virtual scoped_ptr
<ResizeLock
> CreateResizeLock(
437 bool defer_compositor_lock
) OVERRIDE
;
438 virtual gfx::Size
DesiredFrameSize() OVERRIDE
;
439 virtual float CurrentDeviceScaleFactor() OVERRIDE
;
440 virtual gfx::Size
ConvertViewSizeToPixel(const gfx::Size
& size
) OVERRIDE
;
441 virtual DelegatedFrameHost
* GetDelegatedFrameHost() const OVERRIDE
;
443 // BrowserCompositorViewMacClient implementation.
444 virtual bool BrowserCompositorViewShouldAckImmediately() const OVERRIDE
;
445 virtual void BrowserCompositorViewFrameSwapped(
446 const std::vector
<ui::LatencyInfo
>& latency_info
) OVERRIDE
;
447 virtual NSView
* BrowserCompositorSuperview() OVERRIDE
;
448 virtual ui::Layer
* BrowserCompositorRootLayer() OVERRIDE
;
451 friend class RenderWidgetHostViewMacTest
;
453 // Returns whether this render view is a popup (autocomplete window).
454 bool IsPopup() const;
456 // Shuts down the render_widget_host_. This is a separate function so we can
457 // invoke it from the message loop.
460 // Tear down all components of the browser compositor in an order that will
461 // ensure no dangling references.
462 void ShutdownBrowserCompositor();
464 void EnsureBrowserCompositorView();
465 void DestroyBrowserCompositorView();
467 // IPC message handlers.
468 void OnPluginFocusChanged(bool focused
, int plugin_id
);
469 void OnStartPluginIme();
470 void OnGetRenderedTextCompleted(const std::string
& text
);
472 // Send updated vsync parameters to the renderer.
473 void SendVSyncParametersToRenderer();
475 // Dispatches a TTS session.
476 void SpeakText(const std::string
& text
);
478 // The associated view. This is weak and is inserted into the view hierarchy
479 // to own this RenderWidgetHostViewMac object. Set to nil at the start of the
481 RenderWidgetHostViewCocoa
* cocoa_view_
;
483 // Indicates if the page is loading.
486 // Whether it's allowed to pause waiting for a new frame.
487 bool allow_pause_for_resize_or_repaint_
;
489 // The text to be shown in the tooltip, supplied by the renderer.
490 base::string16 tooltip_text_
;
492 // Factory used to safely scope delayed calls to ShutdownHost().
493 base::WeakPtrFactory
<RenderWidgetHostViewMac
> weak_factory_
;
495 // selected text on the renderer.
496 std::string selected_text_
;
498 // The window used for popup widgets.
499 base::scoped_nsobject
<NSWindow
> popup_window_
;
501 // The fullscreen window used for pepper flash.
502 base::scoped_nsobject
<NSWindow
> pepper_fullscreen_window_
;
503 base::scoped_nsobject
<FullscreenWindowManager
> fullscreen_window_manager_
;
504 // Our parent host view, if this is fullscreen. NULL otherwise.
505 RenderWidgetHostViewMac
* fullscreen_parent_host_view_
;
507 // Display link for getting vsync info.
508 scoped_refptr
<DisplayLinkMac
> display_link_
;
510 // The current VSync timebase and interval. This is zero until the first call
511 // to SendVSyncParametersToRenderer(), and refreshed regularly thereafter.
512 base::TimeTicks vsync_timebase_
;
513 base::TimeDelta vsync_interval_
;
515 // The current composition character range and its bounds.
516 gfx::Range composition_range_
;
517 std::vector
<gfx::Rect
> composition_bounds_
;
519 // The current caret bounds.
520 gfx::Rect caret_rect_
;
522 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewMac
);
525 } // namespace content
527 #endif // CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_MAC_H_