fa84570a1fbf5daa61320b5fccd4b671b75a9a13
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / render_widget_host_view_mac.h
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.
4
5 #ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_MAC_H_
6 #define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_MAC_H_
7
8 #import <Cocoa/Cocoa.h>
9 #include <IOSurface/IOSurfaceAPI.h>
10 #include <list>
11 #include <map>
12 #include <string>
13 #include <utility>
14 #include <vector>
15
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/compositor/io_surface_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"
35
36 struct ViewHostMsg_TextInputState_Params;
37
38 namespace content {
39 class BrowserCompositorviewMac;
40 class RenderWidgetHostViewMac;
41 class RenderWidgetHostViewMacEditCommandHelper;
42 class WebContents;
43 }
44
45 namespace ui {
46 class Compositor;
47 class Layer;
48 }
49
50 @class FullscreenWindowManager;
51 @protocol RenderWidgetHostViewMacDelegate;
52 @class ToolTip;
53
54 @protocol RenderWidgetHostViewMacOwner
55 - (content::RenderWidgetHostViewMac*)renderWidgetHostViewMac;
56 @end
57
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,
65                 NSTextInputClient> {
66  @private
67   scoped_ptr<content::RenderWidgetHostViewMac> renderWidgetHostView_;
68   // This ivar is the cocoa delegate of the NSResponder.
69   base::scoped_nsobject<NSObject<RenderWidgetHostViewMacDelegate>>
70       responderDelegate_;
71   BOOL canBeKeyView_;
72   BOOL takesFocusOnlyOnMouseDown_;
73   BOOL closeOnDeactivate_;
74   scoped_ptr<content::RenderWidgetHostViewMacEditCommandHelper>
75       editCommand_helper_;
76
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_;
82
83   // Is YES if there was a mouse-down as yet unbalanced with a mouse-up.
84   BOOL hasOpenMouseDown_;
85
86   NSWindow* lastWindow_;  // weak
87
88   // The cursor for the page. This is passed up from the renderer.
89   base::scoped_nsobject<NSCursor> currentCursor_;
90
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
95   // directly.
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.
101
102   // Represents the input-method attributes supported by this object.
103   base::scoped_nsobject<NSArray> validAttributesForMarkedText_;
104
105   // Indicates if we are currently handling a key down event.
106   BOOL handlingKeyDown_;
107
108   // Indicates if there is any marked text.
109   BOOL hasMarkedText_;
110
111   // Indicates if unmarkText is called or not when handling a keyboard
112   // event.
113   BOOL unmarkTextCalled_;
114
115   // The range of current marked text inside the whole content of the DOM node
116   // being edited.
117   // TODO(suzhe): This is currently a fake value, as we do not support accessing
118   // the whole content yet.
119   NSRange markedRange_;
120
121   // The selected range, cached from a message sent by the renderer.
122   NSRange selectedRange_;
123
124   // Text to be inserted which was generated by handling a key down event.
125   base::string16 textToBeInserted_;
126
127   // Marked text which was generated by handling a key down event.
128   base::string16 markedText_;
129
130   // Underline information of the |markedText_|.
131   std::vector<blink::WebCompositionUnderline> underlines_;
132
133   // Indicates if doCommandBySelector method receives any edit command when
134   // handling a key down event.
135   BOOL hasEditCommands_;
136
137   // Contains edit commands received by the -doCommandBySelector: method when
138   // handling a key down event, not including inserting commands, eg. insertTab,
139   // etc.
140   content::EditCommands editCommands_;
141
142   // The plugin that currently has focus (-1 if no plugin has focus).
143   int focusedPluginIdentifier_;
144
145   // Whether or not plugin IME is currently enabled active.
146   BOOL pluginImeActive_;
147
148   // Whether the previous mouse event was ignored due to hitTest check.
149   BOOL mouseEventWasIgnored_;
150
151   // Event monitor for scroll wheel end event.
152   id endWheelMonitor_;
153
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
157   // key down event.
158   BOOL suppressNextEscapeKeyUp_;
159 }
160
161 @property(nonatomic, readonly) NSRange selectedRange;
162 @property(nonatomic, readonly) BOOL suppressNextEscapeKeyUp;
163
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;
184 @end
185
186 namespace content {
187 class RenderWidgetHostImpl;
188
189 ///////////////////////////////////////////////////////////////////////////////
190 // RenderWidgetHostViewMac
191 //
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.
197 //
198 //  Comment excerpted from render_widget_host.h:
199 //
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."
203 //
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,
209       public IPC::Sender,
210       public gfx::DisplayObserver {
211  public:
212   // The view will associate itself with the given widget. The native view must
213   // be hooked up immediately to the view hierarchy, or else when it is
214   // deleted it will delete this out from under the caller.
215   explicit RenderWidgetHostViewMac(RenderWidgetHost* widget);
216   virtual ~RenderWidgetHostViewMac();
217
218   RenderWidgetHostViewCocoa* cocoa_view() const { return cocoa_view_; }
219
220   // |delegate| is used to separate out the logic from the NSResponder delegate.
221   // |delegate| is retained by this class.
222   // |delegate| should be set at most once.
223   CONTENT_EXPORT void SetDelegate(
224     NSObject<RenderWidgetHostViewMacDelegate>* delegate);
225   void SetAllowPauseForResizeOrRepaint(bool allow);
226
227   // RenderWidgetHostView implementation.
228   virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
229   virtual void InitAsChild(gfx::NativeView parent_view) OVERRIDE;
230   virtual RenderWidgetHost* GetRenderWidgetHost() const OVERRIDE;
231   virtual void SetSize(const gfx::Size& size) OVERRIDE;
232   virtual void SetBounds(const gfx::Rect& rect) OVERRIDE;
233   virtual gfx::Vector2dF GetLastScrollOffset() const 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;
254
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 RenderWidgetHostGone() OVERRIDE;
277   virtual void Destroy() OVERRIDE;
278   virtual void SetTooltipText(const base::string16& tooltip_text) OVERRIDE;
279   virtual void SelectionChanged(const base::string16& text,
280                                 size_t offset,
281                                 const gfx::Range& range) OVERRIDE;
282   virtual void SelectionBoundsChanged(
283       const ViewHostMsg_SelectionBounds_Params& params) OVERRIDE;
284   virtual void CopyFromCompositingSurface(
285       const gfx::Rect& src_subrect,
286       const gfx::Size& dst_size,
287       const base::Callback<void(bool, const SkBitmap&)>& callback,
288       SkColorType color_type) OVERRIDE;
289   virtual void CopyFromCompositingSurfaceToVideoFrame(
290       const gfx::Rect& src_subrect,
291       const scoped_refptr<media::VideoFrame>& target,
292       const base::Callback<void(bool)>& callback) OVERRIDE;
293   virtual bool CanCopyToVideoFrame() const OVERRIDE;
294   virtual bool CanSubscribeFrame() const OVERRIDE;
295   virtual void BeginFrameSubscription(
296       scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) OVERRIDE;
297   virtual void EndFrameSubscription() OVERRIDE;
298   virtual void OnSwapCompositorFrame(
299       uint32 output_surface_id, scoped_ptr<cc::CompositorFrame> frame) OVERRIDE;
300   virtual void AcceleratedSurfaceInitialized(int host_id,
301                                              int route_id) OVERRIDE;
302   virtual BrowserAccessibilityManager* CreateBrowserAccessibilityManager(
303       BrowserAccessibilityDelegate* delegate) OVERRIDE;
304   virtual gfx::Point AccessibilityOriginInScreen(const gfx::Rect& bounds)
305       OVERRIDE;
306   virtual void AccessibilityShowMenu(const gfx::Point& point) OVERRIDE;
307   virtual bool PostProcessEventForPluginIme(
308       const NativeWebKeyboardEvent& event) OVERRIDE;
309
310   virtual void AcceleratedSurfaceBuffersSwapped(
311       const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
312       int gpu_host_id) OVERRIDE;
313   virtual void AcceleratedSurfacePostSubBuffer(
314       const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
315       int gpu_host_id) OVERRIDE;
316   virtual void AcceleratedSurfaceSuspend() OVERRIDE;
317   virtual void AcceleratedSurfaceRelease() OVERRIDE;
318   virtual bool HasAcceleratedSurface(const gfx::Size& desired_size) OVERRIDE;
319   virtual void GetScreenInfo(blink::WebScreenInfo* results) OVERRIDE;
320   virtual gfx::Rect GetBoundsInRootWindow() OVERRIDE;
321   virtual gfx::GLSurfaceHandle GetCompositingSurface() OVERRIDE;
322
323   virtual bool LockMouse() OVERRIDE;
324   virtual void UnlockMouse() OVERRIDE;
325   virtual void WheelEventAck(const blink::WebMouseWheelEvent& event,
326                              InputEventAckState ack_result) OVERRIDE;
327
328   // IPC::Sender implementation.
329   virtual bool Send(IPC::Message* message) OVERRIDE;
330
331   virtual SkColorType PreferredReadbackFormat() OVERRIDE;
332
333   // gfx::DisplayObserver implementation.
334   virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE;
335   virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE;
336   virtual void OnDisplayMetricsChanged(const gfx::Display& display,
337                                        uint32_t metrics) OVERRIDE;
338
339   // Forwards the mouse event to the renderer.
340   void ForwardMouseEvent(const blink::WebMouseEvent& event);
341
342   void KillSelf();
343
344   void SetTextInputActive(bool active);
345
346   // Sends completed plugin IME notification and text back to the renderer.
347   void PluginImeCompositionCompleted(const base::string16& text, int plugin_id);
348
349   const std::string& selected_text() const { return selected_text_; }
350
351   // Returns true and stores first rectangle for character range if the
352   // requested |range| is already cached, otherwise returns false.
353   // Exposed for testing.
354   CONTENT_EXPORT bool GetCachedFirstRectForCharacterRange(
355       NSRange range, NSRect* rect, NSRange* actual_range);
356
357   // Returns true if there is line break in |range| and stores line breaking
358   // point to |line_breaking_point|. The |line_break_point| is valid only if
359   // this function returns true.
360   bool GetLineBreakIndex(const std::vector<gfx::Rect>& bounds,
361                          const gfx::Range& range,
362                          size_t* line_break_point);
363
364   // Returns composition character boundary rectangle. The |range| is
365   // composition based range. Also stores |actual_range| which is corresponding
366   // to actually used range for returned rectangle.
367   gfx::Rect GetFirstRectForCompositionRange(const gfx::Range& range,
368                                             gfx::Range* actual_range);
369
370   // Converts from given whole character range to composition oriented range. If
371   // the conversion failed, return gfx::Range::InvalidRange.
372   gfx::Range ConvertCharacterRangeToCompositionRange(
373       const gfx::Range& request_range);
374
375   WebContents* GetWebContents();
376
377   // These member variables should be private, but the associated ObjC class
378   // needs access to them and can't be made a friend.
379
380   // The associated Model.  Can be NULL if Destroy() is called when
381   // someone (other than superview) has retained |cocoa_view_|.
382   RenderWidgetHostImpl* render_widget_host_;
383
384   // Current text input type.
385   ui::TextInputType text_input_type_;
386   bool can_compose_inline_;
387
388   // The background CoreAnimation layer which is hosted by |cocoa_view_|.
389   base::scoped_nsobject<CALayer> background_layer_;
390
391   // Delegated frame management and compositior.
392   scoped_ptr<DelegatedFrameHost> delegated_frame_host_;
393   scoped_ptr<ui::Layer> root_layer_;
394
395   // Container for the NSView drawn by the browser compositor.
396   scoped_ptr<BrowserCompositorViewMac> browser_compositor_view_;
397
398   // Placeholder that is allocated while browser_compositor_view_ is NULL,
399   // indicating that a BrowserCompositorViewMac may be allocated. This is to
400   // help in recycling the internals of BrowserCompositorViewMac.
401   scoped_ptr<BrowserCompositorViewPlaceholderMac>
402       browser_compositor_view_placeholder_;
403
404   NSWindow* pepper_fullscreen_window() const {
405     return pepper_fullscreen_window_;
406   }
407
408   CONTENT_EXPORT void release_pepper_fullscreen_window_for_testing();
409
410   RenderWidgetHostViewMac* fullscreen_parent_host_view() const {
411     return fullscreen_parent_host_view_;
412   }
413
414   int window_number() const;
415
416   // The scale factor for the screen that the view is currently on.
417   float ViewScaleFactor() const;
418
419   // Update the scale factor for the backing store and for any CALayers.
420   void UpdateBackingStoreScaleFactor();
421
422   // Ensure that the display link is associated with the correct display.
423   void UpdateDisplayLink();
424
425   void PauseForPendingResizeOrRepaintsAndDraw();
426
427   // DelegatedFrameHostClient implementation.
428   virtual ui::Compositor* GetCompositor() const OVERRIDE;
429   virtual ui::Layer* GetLayer() OVERRIDE;
430   virtual RenderWidgetHostImpl* GetHost() OVERRIDE;
431   virtual bool IsVisible() OVERRIDE;
432   virtual scoped_ptr<ResizeLock> CreateResizeLock(
433       bool defer_compositor_lock) OVERRIDE;
434   virtual gfx::Size DesiredFrameSize() OVERRIDE;
435   virtual float CurrentDeviceScaleFactor() OVERRIDE;
436   virtual gfx::Size ConvertViewSizeToPixel(const gfx::Size& size) OVERRIDE;
437   virtual DelegatedFrameHost* GetDelegatedFrameHost() const OVERRIDE;
438
439   // BrowserCompositorViewMacClient implementation.
440   virtual bool BrowserCompositorViewShouldAckImmediately() const OVERRIDE;
441   virtual void BrowserCompositorViewFrameSwapped(
442       const std::vector<ui::LatencyInfo>& latency_info) OVERRIDE;
443   virtual NSView* BrowserCompositorSuperview() OVERRIDE;
444   virtual ui::Layer* BrowserCompositorRootLayer() OVERRIDE;
445
446  private:
447   friend class RenderWidgetHostViewMacTest;
448
449   // Returns whether this render view is a popup (autocomplete window).
450   bool IsPopup() const;
451
452   // Shuts down the render_widget_host_.  This is a separate function so we can
453   // invoke it from the message loop.
454   void ShutdownHost();
455
456   // Tear down all components of the browser compositor in an order that will
457   // ensure no dangling references.
458   void ShutdownBrowserCompositor();
459
460   void EnsureBrowserCompositorView();
461   void DestroyBrowserCompositorView();
462
463   // IPC message handlers.
464   void OnPluginFocusChanged(bool focused, int plugin_id);
465   void OnStartPluginIme();
466   void OnGetRenderedTextCompleted(const std::string& text);
467
468   // Send updated vsync parameters to the renderer.
469   void SendVSyncParametersToRenderer();
470
471   // Dispatches a TTS session.
472   void SpeakText(const std::string& text);
473
474   // The associated view. This is weak and is inserted into the view hierarchy
475   // to own this RenderWidgetHostViewMac object. Set to nil at the start of the
476   // destructor.
477   RenderWidgetHostViewCocoa* cocoa_view_;
478
479   // Indicates if the page is loading.
480   bool is_loading_;
481
482   // Whether it's allowed to pause waiting for a new frame.
483   bool allow_pause_for_resize_or_repaint_;
484
485   // The last scroll offset of the view.
486   gfx::Vector2dF last_scroll_offset_;
487
488   // The text to be shown in the tooltip, supplied by the renderer.
489   base::string16 tooltip_text_;
490
491   // Factory used to safely scope delayed calls to ShutdownHost().
492   base::WeakPtrFactory<RenderWidgetHostViewMac> weak_factory_;
493
494   // selected text on the renderer.
495   std::string selected_text_;
496
497   // The window used for popup widgets.
498   base::scoped_nsobject<NSWindow> popup_window_;
499
500   // The fullscreen window used for pepper flash.
501   base::scoped_nsobject<NSWindow> pepper_fullscreen_window_;
502   base::scoped_nsobject<FullscreenWindowManager> fullscreen_window_manager_;
503   // Our parent host view, if this is fullscreen.  NULL otherwise.
504   RenderWidgetHostViewMac* fullscreen_parent_host_view_;
505
506   // Display link for getting vsync info.
507   scoped_refptr<DisplayLinkMac> display_link_;
508
509   // The current VSync timebase and interval. This is zero until the first call
510   // to SendVSyncParametersToRenderer(), and refreshed regularly thereafter.
511   base::TimeTicks vsync_timebase_;
512   base::TimeDelta vsync_interval_;
513
514   // The current composition character range and its bounds.
515   gfx::Range composition_range_;
516   std::vector<gfx::Rect> composition_bounds_;
517
518   // The current caret bounds.
519   gfx::Rect caret_rect_;
520
521   DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewMac);
522 };
523
524 }  // namespace content
525
526 #endif  // CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_MAC_H_