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