Home | History | Annotate | Download | only in renderer_host
      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 
    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);
    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 
    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