• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_MAC_H_
6 #define CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_MAC_H_
7 #pragma once
8 
9 #import <Cocoa/Cocoa.h>
10 
11 #include "base/memory/scoped_nsobject.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/task.h"
14 #include "base/time.h"
15 #include "chrome/browser/accessibility/browser_accessibility_delegate_mac.h"
16 #include "chrome/browser/accessibility/browser_accessibility_manager.h"
17 #include "chrome/browser/ui/cocoa/base_view.h"
18 #include "content/browser/renderer_host/accelerated_surface_container_manager_mac.h"
19 #include "content/browser/renderer_host/render_widget_host_view.h"
20 #include "content/common/edit_command.h"
21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCompositionUnderline.h"
22 #include "webkit/glue/webcursor.h"
23 
24 @class AcceleratedPluginView;
25 class RenderWidgetHostViewMac;
26 class RWHVMEditCommandHelper;
27 @class ToolTip;
28 
29 @protocol RenderWidgetHostViewMacOwner
30 - (RenderWidgetHostViewMac*)renderWidgetHostViewMac;
31 @end
32 
33 // This is the view that lives in the Cocoa view hierarchy. In Windows-land,
34 // RenderWidgetHostViewWin is both the view and the delegate. We split the roles
35 // but that means that the view needs to own the delegate and will dispose of it
36 // when it's removed from the view system.
37 // See http://crbug.com/47890 for why we don't use NSTextInputClient yet.
38 @interface RenderWidgetHostViewCocoa
39     : BaseView <RenderWidgetHostViewMacOwner,
40                 NSTextInput,
41                 NSChangeSpelling,
42                 BrowserAccessibilityDelegateCocoa> {
43  @private
44   scoped_ptr<RenderWidgetHostViewMac> renderWidgetHostView_;
45   BOOL canBeKeyView_;
46   BOOL takesFocusOnlyOnMouseDown_;
47   BOOL closeOnDeactivate_;
48   scoped_ptr<RWHVMEditCommandHelper> editCommand_helper_;
49 
50   // These are part of the magic tooltip code from WebKit's WebHTMLView:
51   id trackingRectOwner_;              // (not retained)
52   void *trackingRectUserData_;
53   NSTrackingRectTag lastToolTipTag_;
54   scoped_nsobject<NSString> toolTip_;
55 
56   // Is YES if there was a mouse-down as yet unbalanced with a mouse-up.
57   BOOL hasOpenMouseDown_;
58 
59   NSWindow* lastWindow_;  // weak
60 
61   // Variables used by our implementaion of the NSTextInput protocol.
62   // An input method of Mac calls the methods of this protocol not only to
63   // notify an application of its status, but also to retrieve the status of
64   // the application. That is, an application cannot control an input method
65   // directly.
66   // This object keeps the status of a composition of the renderer and returns
67   // it when an input method asks for it.
68   // We need to implement Objective-C methods for the NSTextInput protocol. On
69   // the other hand, we need to implement a C++ method for an IPC-message
70   // handler which receives input-method events from the renderer.
71 
72   // Represents the input-method attributes supported by this object.
73   scoped_nsobject<NSArray> validAttributesForMarkedText_;
74 
75   // Represents the cursor position in this view coordinate.
76   // The renderer sends the cursor position through an IPC message.
77   // We save the latest cursor position here and return it when an input
78   // methods needs it.
79   NSRect caretRect_;
80 
81   // Indicates if we are currently handling a key down event.
82   BOOL handlingKeyDown_;
83 
84   // Indicates if there is any marked text.
85   BOOL hasMarkedText_;
86 
87   // Indicates if unmarkText is called or not when handling a keyboard
88   // event.
89   BOOL unmarkTextCalled_;
90 
91   // The range of current marked text inside the whole content of the DOM node
92   // being edited.
93   // TODO(suzhe): This is currently a fake value, as we do not support accessing
94   // the whole content yet.
95   NSRange markedRange_;
96 
97   // The selected range inside current marked text.
98   // TODO(suzhe): Currently it's only valid when there is any marked text.
99   // In the future, we may need to support accessing the whole content of the
100   // DOM node being edited, then this should be the selected range inside the
101   // DOM node.
102   NSRange selectedRange_;
103 
104   // Text to be inserted which was generated by handling a key down event.
105   string16 textToBeInserted_;
106 
107   // Marked text which was generated by handling a key down event.
108   string16 markedText_;
109 
110   // Underline information of the |markedText_|.
111   std::vector<WebKit::WebCompositionUnderline> underlines_;
112 
113   // Indicates if doCommandBySelector method receives any edit command when
114   // handling a key down event.
115   BOOL hasEditCommands_;
116 
117   // Contains edit commands received by the -doCommandBySelector: method when
118   // handling a key down event, not including inserting commands, eg. insertTab,
119   // etc.
120   EditCommands editCommands_;
121 
122   // The plugin that currently has focus (-1 if no plugin has focus).
123   int focusedPluginIdentifier_;
124 
125   // Whether or not plugin IME is currently enabled active.
126   BOOL pluginImeActive_;
127 
128   // Whether the previous mouse event was ignored due to hitTest check.
129   BOOL mouseEventWasIgnored_;
130 }
131 
132 @property(assign, nonatomic) NSRect caretRect;
133 
134 - (void)setCanBeKeyView:(BOOL)can;
135 - (void)setTakesFocusOnlyOnMouseDown:(BOOL)b;
136 - (void)setCloseOnDeactivate:(BOOL)b;
137 - (void)setToolTipAtMousePoint:(NSString *)string;
138 // Set frame, then notify the RenderWidgetHost that the frame has been changed,
139 // but do it in a separate task, using |performSelector:withObject:afterDelay:|.
140 // This stops the flickering issue in http://crbug.com/31970
141 - (void)setFrameWithDeferredUpdate:(NSRect)frame;
142 // Notify the RenderWidgetHost that the frame was updated so it can resize
143 // its contents.
144 - (void)renderWidgetHostWasResized;
145 // Cancel ongoing composition (abandon the marked text).
146 - (void)cancelComposition;
147 // Confirm ongoing composition.
148 - (void)confirmComposition;
149 // Enables or disables plugin IME.
150 - (void)setPluginImeActive:(BOOL)active;
151 // Updates the current plugin focus state.
152 - (void)pluginFocusChanged:(BOOL)focused forPlugin:(int)pluginId;
153 // Evaluates the event in the context of plugin IME, if plugin IME is enabled.
154 // Returns YES if the event was handled.
155 - (BOOL)postProcessEventForPluginIme:(NSEvent*)event;
156 
157 @end
158 
159 ///////////////////////////////////////////////////////////////////////////////
160 // RenderWidgetHostViewMac
161 //
162 //  An object representing the "View" of a rendered web page. This object is
163 //  responsible for displaying the content of the web page, and integrating with
164 //  the Cocoa view system. It is the implementation of the RenderWidgetHostView
165 //  that the cross-platform RenderWidgetHost object uses
166 //  to display the data.
167 //
168 //  Comment excerpted from render_widget_host.h:
169 //
170 //    "The lifetime of the RenderWidgetHost* is tied to the render process.
171 //     If the render process dies, the RenderWidgetHost* goes away and all
172 //     references to it must become NULL."
173 //
174 class RenderWidgetHostViewMac : public RenderWidgetHostView {
175  public:
176   // The view will associate itself with the given widget. The native view must
177   // be hooked up immediately to the view hierarchy, or else when it is
178   // deleted it will delete this out from under the caller.
179   explicit RenderWidgetHostViewMac(RenderWidgetHost* widget);
180   virtual ~RenderWidgetHostViewMac();
181 
native_view()182   RenderWidgetHostViewCocoa* native_view() const { return cocoa_view_; }
183 
184   // Implementation of RenderWidgetHostView:
185   virtual void InitAsPopup(RenderWidgetHostView* parent_host_view,
186                            const gfx::Rect& pos);
187   virtual void InitAsFullscreen();
188   virtual RenderWidgetHost* GetRenderWidgetHost() const;
189   virtual void DidBecomeSelected();
190   virtual void WasHidden();
191   virtual void SetSize(const gfx::Size& size);
192   virtual void SetBounds(const gfx::Rect& rect);
193   virtual gfx::NativeView GetNativeView();
194   virtual void MovePluginWindows(
195       const std::vector<webkit::npapi::WebPluginGeometry>& moves);
196   virtual void Focus();
197   virtual void Blur();
198   virtual bool HasFocus();
199   virtual void Show();
200   virtual void Hide();
201   virtual bool IsShowing();
202   virtual gfx::Rect GetViewBounds() const;
203   virtual void UpdateCursor(const WebCursor& cursor);
204   virtual void SetIsLoading(bool is_loading);
205   virtual void ImeUpdateTextInputState(WebKit::WebTextInputType state,
206                                        const gfx::Rect& caret_rect);
207   virtual void ImeCancelComposition();
208   virtual void DidUpdateBackingStore(
209       const gfx::Rect& scroll_rect, int scroll_dx, int scroll_dy,
210       const std::vector<gfx::Rect>& copy_rects);
211   virtual void RenderViewGone(base::TerminationStatus status,
212                               int error_code);
WillDestroyRenderWidget(RenderWidgetHost * rwh)213   virtual void WillDestroyRenderWidget(RenderWidgetHost* rwh) {};
214   virtual void Destroy();
215   virtual void SetTooltipText(const std::wstring& tooltip_text);
216   virtual void SelectionChanged(const std::string& text);
217   virtual BackingStore* AllocBackingStore(const gfx::Size& size);
218   virtual void SetTakesFocusOnlyOnMouseDown(bool flag);
219   // See comment in RenderWidgetHostView!
220   virtual gfx::Rect GetViewCocoaBounds() const;
221   virtual gfx::Rect GetRootWindowRect();
222   virtual void SetActive(bool active);
223   virtual void SetWindowVisibility(bool visible);
224   virtual void WindowFrameChanged();
225   virtual void SetBackground(const SkBitmap& background);
226   virtual bool ContainsNativeView(gfx::NativeView native_view) const;
227 
228   virtual void OnAccessibilityNotifications(
229       const std::vector<ViewHostMsg_AccessibilityNotification_Params>& params);
230 
231   virtual void PluginFocusChanged(bool focused, int plugin_id);
232   virtual void StartPluginIme();
233   virtual bool PostProcessEventForPluginIme(
234       const NativeWebKeyboardEvent& event);
235 
236   // Methods associated with GPU-accelerated plug-in instances and the
237   // accelerated compositor.
238   virtual gfx::PluginWindowHandle AllocateFakePluginWindowHandle(bool opaque,
239                                                                  bool root);
240   virtual void DestroyFakePluginWindowHandle(gfx::PluginWindowHandle window);
241 
242   // Exposed for testing.
243   AcceleratedPluginView* ViewForPluginWindowHandle(
244       gfx::PluginWindowHandle window);
245 
246   // Helper to do the actual cleanup after a plugin handle has been destroyed.
247   // Required because DestroyFakePluginWindowHandle() isn't always called for
248   // all handles (it's e.g. not called on navigation, when the RWHVMac gets
249   // destroyed anyway).
250   void DeallocFakePluginWindowHandle(gfx::PluginWindowHandle window);
251 
252   virtual void AcceleratedSurfaceSetIOSurface(gfx::PluginWindowHandle window,
253                                               int32 width,
254                                               int32 height,
255                                               uint64 io_surface_identifier);
256   virtual void AcceleratedSurfaceSetTransportDIB(
257       gfx::PluginWindowHandle window,
258       int32 width,
259       int32 height,
260       TransportDIB::Handle transport_dib);
261   virtual void AcceleratedSurfaceBuffersSwapped(
262       gfx::PluginWindowHandle window,
263       uint64 surface_id,
264       int renderer_id,
265       int32 route_id,
266       int gpu_host_id,
267       uint64 swap_buffers_count);
268   virtual void GpuRenderingStateDidChange();
269 
270   virtual gfx::PluginWindowHandle GetCompositingSurface();
271 
272   void DrawAcceleratedSurfaceInstance(
273       CGLContextObj context,
274       gfx::PluginWindowHandle plugin_handle,
275       NSSize size);
276   // Forces the textures associated with any accelerated plugin instances
277   // to be reloaded.
278   void ForceTextureReload();
279 
280   virtual void SetVisuallyDeemphasized(const SkColor* color, bool animate);
281 
282   void KillSelf();
283 
284   void SetTextInputActive(bool active);
285 
286   // Sends completed plugin IME notification and text back to the renderer.
287   void PluginImeCompositionCompleted(const string16& text, int plugin_id);
288 
selected_text()289   const std::string& selected_text() const { return selected_text_; }
290 
291   void UpdateRootGpuViewVisibility(bool show_gpu_widget);
292 
293   // When rendering transitions from gpu to software, the gpu widget can't be
294   // hidden until the software backing store has been updated. This method
295   // checks if the GPU view needs to be hidden and hides it if necessary. It
296   // should be called after the software backing store has been painted to.
297   void HandleDelayedGpuViewHiding();
298 
299   // This is called from the display link thread, and provides the GPU
300   // process a notion of how quickly the browser is able to keep up with it.
301   void AcknowledgeSwapBuffers(int renderer_id,
302                               int32 route_id,
303                               int gpu_host_id,
304                               uint64 swap_buffers_count);
305 
306   // These member variables should be private, but the associated ObjC class
307   // needs access to them and can't be made a friend.
308 
309   // The associated Model.  Can be NULL if Destroy() is called when
310   // someone (other than superview) has retained |cocoa_view_|.
311   RenderWidgetHost* render_widget_host_;
312 
313   // This is true when we are currently painting and thus should handle extra
314   // paint requests by expanding the invalid rect rather than actually painting.
315   bool about_to_validate_and_paint_;
316 
317   scoped_ptr<BrowserAccessibilityManager> browser_accessibility_manager_;
318 
319   // This is true when we have already scheduled a call to
320   // |-callSetNeedsDisplayInRect:| but it has not been fulfilled yet.  Used to
321   // prevent us from scheduling multiple calls.
322   bool call_set_needs_display_in_rect_pending_;
323 
324   // The invalid rect that needs to be painted by callSetNeedsDisplayInRect.
325   // This value is only meaningful when
326   // |call_set_needs_display_in_rect_pending_| is true.
327   NSRect invalid_rect_;
328 
329   // The time at which this view started displaying white pixels as a result of
330   // not having anything to paint (empty backing store from renderer). This
331   // value returns true for is_null() if we are not recording whiteout times.
332   base::TimeTicks whiteout_start_time_;
333 
334   // The time it took after this view was selected for it to be fully painted.
335   base::TimeTicks tab_switch_paint_time_;
336 
337   // Current text input type.
338   WebKit::WebTextInputType text_input_type_;
339 
340   typedef std::map<gfx::PluginWindowHandle, AcceleratedPluginView*>
341       PluginViewMap;
342   PluginViewMap plugin_views_;  // Weak values.
343 
344   // Helper class for managing instances of accelerated plug-ins.
345   AcceleratedSurfaceContainerManagerMac plugin_container_manager_;
346 
347  private:
348   // Returns whether this render view is a popup (autocomplete window).
349   bool IsPopup() const;
350 
351   // Updates the display cursor to the current cursor if the cursor is over this
352   // render view.
353   void UpdateCursorIfOverSelf();
354 
355   // Shuts down the render_widget_host_.  This is a separate function so we can
356   // invoke it from the message loop.
357   void ShutdownHost();
358 
359   // Used to determine whether or not to enable accessibility.
360   bool IsVoiceOverRunning();
361 
362   // The associated view. This is weak and is inserted into the view hierarchy
363   // to own this RenderWidgetHostViewMac object.
364   RenderWidgetHostViewCocoa* cocoa_view_;
365 
366   // The cursor for the page. This is passed up from the renderer.
367   WebCursor current_cursor_;
368 
369   // Indicates if the page is loading.
370   bool is_loading_;
371 
372   // true if the View is not visible.
373   bool is_hidden_;
374 
375   // The text to be shown in the tooltip, supplied by the renderer.
376   std::wstring tooltip_text_;
377 
378   // Factory used to safely scope delayed calls to ShutdownHost().
379   ScopedRunnableMethodFactory<RenderWidgetHostViewMac> shutdown_factory_;
380 
381   // selected text on the renderer.
382   std::string selected_text_;
383 
384   // When rendering transitions from gpu to software, the gpu widget can't be
385   // hidden until the software backing store has been updated. This variable is
386   // set when the gpu widget needs to be hidden once a paint is completed.
387   bool needs_gpu_visibility_update_after_repaint_;
388 
389   gfx::PluginWindowHandle compositing_surface_;
390 
391   DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewMac);
392 };
393 
394 #endif  // CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_MAC_H_
395