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