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