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