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_GTK_H_ 6 #define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_GTK_H_ 7 8 #include <gdk/gdk.h> 9 10 #include <string> 11 #include <vector> 12 13 #include "base/memory/scoped_ptr.h" 14 #include "base/time/time.h" 15 #include "content/browser/accessibility/browser_accessibility_manager.h" 16 #include "content/browser/renderer_host/gtk_plugin_container_manager.h" 17 #include "content/browser/renderer_host/render_widget_host_view_base.h" 18 #include "content/common/content_export.h" 19 #include "ipc/ipc_sender.h" 20 #include "ui/base/gtk/gtk_signal.h" 21 #include "ui/base/gtk/gtk_signal_registrar.h" 22 #include "ui/base/gtk/owned_widget_gtk.h" 23 #include "ui/base/x/active_window_watcher_x_observer.h" 24 #include "ui/gfx/native_widget_types.h" 25 #include "ui/gfx/point.h" 26 #include "ui/gfx/rect.h" 27 #include "webkit/common/cursors/webcursor.h" 28 29 typedef struct _GtkClipboard GtkClipboard; 30 typedef struct _GtkSelectionData GtkSelectionData; 31 32 namespace content { 33 class GtkIMContextWrapper; 34 class GtkKeyBindingsHandler; 35 class RenderWidgetHost; 36 class RenderWidgetHostImpl; 37 struct NativeWebKeyboardEvent; 38 39 // ----------------------------------------------------------------------------- 40 // See comments in render_widget_host_view.h about this class and its members. 41 // ----------------------------------------------------------------------------- 42 class CONTENT_EXPORT RenderWidgetHostViewGtk 43 : public RenderWidgetHostViewBase, 44 public BrowserAccessibilityDelegate, 45 public ui::ActiveWindowWatcherXObserver, 46 public IPC::Sender { 47 public: 48 virtual ~RenderWidgetHostViewGtk(); 49 50 // RenderWidgetHostView implementation. 51 virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE; 52 virtual void InitAsChild(gfx::NativeView parent_view) OVERRIDE; 53 virtual RenderWidgetHost* GetRenderWidgetHost() const OVERRIDE; 54 virtual void SetSize(const gfx::Size& size) OVERRIDE; 55 virtual void SetBounds(const gfx::Rect& rect) OVERRIDE; 56 virtual gfx::NativeView GetNativeView() const OVERRIDE; 57 virtual gfx::NativeViewId GetNativeViewId() const OVERRIDE; 58 virtual gfx::NativeViewAccessible GetNativeViewAccessible() OVERRIDE; 59 virtual bool HasFocus() const OVERRIDE; 60 virtual bool IsSurfaceAvailableForCopy() const OVERRIDE; 61 virtual void Show() OVERRIDE; 62 virtual void Hide() OVERRIDE; 63 virtual bool IsShowing() OVERRIDE; 64 virtual gfx::Rect GetViewBounds() const OVERRIDE; 65 virtual GdkEventButton* GetLastMouseDown() OVERRIDE; 66 virtual gfx::NativeView BuildInputMethodsGtkMenu() OVERRIDE; 67 virtual void SetBackground(const SkBitmap& background) OVERRIDE; 68 69 // RenderWidgetHostViewPort implementation. 70 virtual void InitAsPopup(RenderWidgetHostView* parent_host_view, 71 const gfx::Rect& pos) OVERRIDE; 72 virtual void InitAsFullscreen( 73 RenderWidgetHostView* reference_host_view) OVERRIDE; 74 virtual void WasShown() OVERRIDE; 75 virtual void WasHidden() OVERRIDE; 76 virtual void MovePluginWindows( 77 const gfx::Vector2d& scroll_offset, 78 const std::vector<WebPluginGeometry>& moves) OVERRIDE; 79 virtual void Focus() OVERRIDE; 80 virtual void Blur() OVERRIDE; 81 virtual void UpdateCursor(const WebCursor& cursor) OVERRIDE; 82 virtual void SetIsLoading(bool is_loading) OVERRIDE; 83 virtual void TextInputTypeChanged(ui::TextInputType type, 84 ui::TextInputMode input_mode, 85 bool can_compose_inline) OVERRIDE; 86 virtual void ImeCancelComposition() OVERRIDE; 87 virtual void DidUpdateBackingStore( 88 const gfx::Rect& scroll_rect, 89 const gfx::Vector2d& scroll_delta, 90 const std::vector<gfx::Rect>& copy_rects, 91 const ui::LatencyInfo& latency_info) OVERRIDE; 92 virtual void RenderProcessGone(base::TerminationStatus status, 93 int error_code) OVERRIDE; 94 virtual void Destroy() OVERRIDE; 95 virtual void WillDestroyRenderWidget(RenderWidgetHost* rwh) {} 96 virtual void SetTooltipText(const base::string16& tooltip_text) OVERRIDE; 97 virtual void SelectionChanged(const base::string16& text, 98 size_t offset, 99 const gfx::Range& range) OVERRIDE; 100 virtual void SelectionBoundsChanged( 101 const ViewHostMsg_SelectionBounds_Params& params) OVERRIDE; 102 virtual void ScrollOffsetChanged() OVERRIDE; 103 virtual BackingStore* AllocBackingStore(const gfx::Size& size) OVERRIDE; 104 virtual void CopyFromCompositingSurface( 105 const gfx::Rect& src_subrect, 106 const gfx::Size& dst_size, 107 const base::Callback<void(bool, const SkBitmap&)>& callback) OVERRIDE; 108 virtual void CopyFromCompositingSurfaceToVideoFrame( 109 const gfx::Rect& src_subrect, 110 const scoped_refptr<media::VideoFrame>& target, 111 const base::Callback<void(bool)>& callback) OVERRIDE; 112 virtual bool CanCopyToVideoFrame() const OVERRIDE; 113 virtual void OnAcceleratedCompositingStateChange() OVERRIDE; 114 virtual void AcceleratedSurfaceInitialized(int host_id, 115 int route_id) OVERRIDE; 116 virtual void AcceleratedSurfaceBuffersSwapped( 117 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, 118 int gpu_host_id) OVERRIDE; 119 virtual void AcceleratedSurfacePostSubBuffer( 120 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params, 121 int gpu_host_id) OVERRIDE; 122 virtual void AcceleratedSurfaceSuspend() OVERRIDE; 123 virtual void AcceleratedSurfaceRelease() OVERRIDE; 124 virtual bool HasAcceleratedSurface(const gfx::Size& desired_size) OVERRIDE; 125 virtual void SetHasHorizontalScrollbar( 126 bool has_horizontal_scrollbar) OVERRIDE; 127 virtual void SetScrollOffsetPinning( 128 bool is_pinned_to_left, bool is_pinned_to_right) OVERRIDE; 129 virtual void GetScreenInfo(blink::WebScreenInfo* results) OVERRIDE; 130 virtual gfx::Rect GetBoundsInRootWindow() OVERRIDE; 131 virtual gfx::GLSurfaceHandle GetCompositingSurface() OVERRIDE; 132 virtual void ResizeCompositingSurface(const gfx::Size&) OVERRIDE; 133 virtual bool LockMouse() OVERRIDE; 134 virtual void UnlockMouse() OVERRIDE; 135 virtual void OnAccessibilityEvents( 136 const std::vector<AccessibilityHostMsg_EventParams>& params) 137 OVERRIDE; 138 139 // ActiveWindowWatcherXObserver implementation. 140 virtual void ActiveWindowChanged(GdkWindow* active_window) OVERRIDE; 141 142 // IPC::Sender implementation: 143 virtual bool Send(IPC::Message* message) OVERRIDE; 144 145 // If the widget is aligned with an edge of the monitor its on and the user 146 // attempts to drag past that edge we track the number of times it has 147 // occurred, so that we can force the widget to scroll when it otherwise 148 // would be unable to. 149 void ModifyEventForEdgeDragging(GtkWidget* widget, GdkEventMotion* event); 150 151 // Mouse events always provide a movementX/Y which needs to be computed. 152 // Also, mouse lock requires knowledge of last unlocked cursor coordinates. 153 // State is stored on the host view to do this, and the mouse event modified. 154 void ModifyEventMovementAndCoords(blink::WebMouseEvent* event); 155 156 void Paint(const gfx::Rect&); 157 158 // Called by GtkIMContextWrapper to forward a keyboard event to renderer. 159 // On Linux (not ChromeOS): 160 // Before calling RenderWidgetHost::ForwardKeyboardEvent(), this method 161 // calls GtkKeyBindingsHandler::Match() against the event and send matched 162 // edit commands to renderer by calling 163 // RenderWidgetHost::ForwardEditCommandsForNextKeyEvent(). 164 void ForwardKeyboardEvent(const NativeWebKeyboardEvent& event); 165 166 bool RetrieveSurrounding(std::string* text, size_t* cursor_index); 167 168 // BrowserAccessibilityDelegate implementation. 169 virtual void SetAccessibilityFocus(int acc_obj_id) OVERRIDE; 170 virtual void AccessibilityDoDefaultAction(int acc_obj_id) OVERRIDE; 171 virtual void AccessibilityScrollToMakeVisible( 172 int acc_obj_id, gfx::Rect subfocus) OVERRIDE; 173 virtual void AccessibilityScrollToPoint( 174 int acc_obj_id, gfx::Point point) OVERRIDE; 175 virtual void AccessibilitySetTextSelection( 176 int acc_obj_id, int start_offset, int end_offset) OVERRIDE; 177 virtual gfx::Point GetLastTouchEventLocation() const OVERRIDE; 178 virtual void FatalAccessibilityTreeError() OVERRIDE; 179 180 // Get the root of the AtkObject* tree for accessibility. 181 AtkObject* GetAccessible(); 182 183 protected: 184 friend class RenderWidgetHostView; 185 186 // Should construct only via RenderWidgetHostView::CreateViewForWidget. 187 explicit RenderWidgetHostViewGtk(RenderWidgetHost* widget); 188 189 private: 190 friend class RenderWidgetHostViewGtkWidget; 191 192 CHROMEGTK_CALLBACK_0(RenderWidgetHostViewGtk, 193 void, 194 OnDestroy); 195 196 // Returns whether the widget needs an input grab (GTK+ and X) to work 197 // properly. 198 bool NeedsInputGrab(); 199 200 // Returns whether this render view is a popup (<select> dropdown or 201 // autocomplete window). 202 bool IsPopup() const; 203 204 // Do initialization needed by all InitAs*() methods. 205 void DoSharedInit(); 206 207 // Do initialization needed just by InitAsPopup() and InitAsFullscreen(). 208 // We move and resize |window| to |bounds| and show it and its contents. 209 void DoPopupOrFullscreenInit(GtkWindow* window, const gfx::Rect& bounds); 210 211 // Update the display cursor for the render view. 212 void ShowCurrentCursor(); 213 214 void set_last_mouse_down(GdkEventButton* event); 215 216 // Cause the next query for the widget center to recompute the cached value. 217 void MarkCachedWidgetCenterStale(); 218 219 void OnCreatePluginContainer(gfx::PluginWindowHandle id); 220 void OnDestroyPluginContainer(gfx::PluginWindowHandle id); 221 222 gfx::Point GetWidgetCenter(); 223 224 // The model object. 225 RenderWidgetHostImpl* host_; 226 227 // The native UI widget. 228 ui::OwnedWidgetGtk view_; 229 230 // This is true when we are currently painting and thus should handle extra 231 // paint requests by expanding the invalid rect rather than actually 232 // painting. 233 bool about_to_validate_and_paint_; 234 235 // This is the rectangle which we'll paint. 236 gfx::Rect invalid_rect_; 237 238 // Whether we are currently loading. 239 bool is_loading_; 240 241 // The cursor for the page. This is passed up from the renderer. 242 WebCursor current_cursor_; 243 244 // The time at which this view started displaying white pixels as a result of 245 // not having anything to paint (empty backing store from renderer). This 246 // value returns true for is_null() if we are not recording whiteout times. 247 base::TimeTicks whiteout_start_time_; 248 249 // The time it took after this view was selected for it to be fully painted. 250 base::TimeTicks web_contents_switch_paint_time_; 251 252 // The native view of our parent widget. Used only for popups. 253 GtkWidget* parent_; 254 255 // We ignore the first mouse release on popups so the popup will remain open. 256 bool is_popup_first_mouse_release_; 257 258 // Whether or not this widget's input context was focused before being 259 // shadowed by another widget. Used in OnGrabNotify() handler to track the 260 // focused state correctly. 261 bool was_imcontext_focused_before_grab_; 262 263 // True if we are responsible for creating an X grab. This will only be used 264 // for <select> dropdowns. It should be true for most such cases, but false 265 // for extension popups. 266 bool do_x_grab_; 267 268 // Is the widget fullscreen? 269 bool is_fullscreen_; 270 271 // Has the window ever been marked active? Only valid for fullscreen or 272 // popup windows. 273 bool made_active_; 274 275 // Used to record the last position of the mouse. 276 // While the mouse is locked, they store the last known position just as mouse 277 // lock was entered. 278 // Relative to the upper-left corner of the view. 279 gfx::Point unlocked_mouse_position_; 280 // Relative to the upper-left corner of the screen. 281 gfx::Point unlocked_global_mouse_position_; 282 // Last hidden cursor position. Relative to screen. 283 gfx::Point global_mouse_position_; 284 // Indicates when mouse motion is valid after the widget has moved. 285 bool mouse_has_been_warped_to_new_center_; 286 // Indicates the cursor has been warped to the unlocked position, 287 // but a move event has not yet been received for it there. 288 bool mouse_is_being_warped_to_unlocked_position_; 289 290 // For full-screen windows we have a OnDestroy handler that we need to remove, 291 // so we keep it ID here. 292 unsigned long destroy_handler_id_; 293 294 // A convenience wrapper object for GtkIMContext; 295 scoped_ptr<GtkIMContextWrapper> im_context_; 296 297 // A convenience object for handling editor key bindings defined in gtk 298 // keyboard theme. 299 scoped_ptr<GtkKeyBindingsHandler> key_bindings_handler_; 300 301 // Helper class that lets us allocate plugin containers and move them. 302 GtkPluginContainerManager plugin_container_manager_; 303 304 // The size that we want the renderer to be. We keep this in a separate 305 // variable because resizing in GTK+ is async. 306 gfx::Size requested_size_; 307 308 // The latest reported center of the widget, use GetWidgetCenter() to access. 309 gfx::Point widget_center_; 310 // If the window moves the widget_center will not be valid until we recompute. 311 bool widget_center_valid_; 312 313 // The number of times the user has dragged against horizontal edge of the 314 // monitor (if the widget is aligned with that edge). Negative values 315 // indicate the left edge, positive the right. 316 int dragged_at_horizontal_edge_; 317 318 // The number of times the user has dragged against vertical edge of the 319 // monitor (if the widget is aligned with that edge). Negative values 320 // indicate the top edge, positive the bottom. 321 int dragged_at_vertical_edge_; 322 323 gfx::PluginWindowHandle compositing_surface_; 324 325 // The event for the last mouse down we handled. We need this for context 326 // menus and drags. 327 GdkEventButton* last_mouse_down_; 328 329 // Instance of accessibility information for the root of the AtkObject 330 // tree representation of the WebKit render tree. 331 scoped_ptr<BrowserAccessibilityManager> browser_accessibility_manager_; 332 333 ui::GtkSignalRegistrar signals_; 334 335 ui::LatencyInfo software_latency_info_; 336 }; 337 338 } // namespace content 339 340 #endif // CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_GTK_H_ 341