This source file includes following definitions.
- GetMozSpinningCursor
- MovedToPoint
- GetAccessible
- CreateNewWidget
- OnExposeEvent
- OnRealize
- OnConfigureEvent
- OnSizeAllocate
- OnKeyPressReleaseEvent
- OnFocusIn
- OnFocusOut
- OnGrabNotify
- OnButtonPressReleaseEvent
- OnMouseMoveEvent
- OnCrossingEvent
- OnClientEvent
- GetPendingScrollDelta
- OnMouseScrollEvent
- last_mouse_down_
- OnMessageReceived
- InitAsChild
- InitAsPopup
- InitAsFullscreen
- GetRenderWidgetHost
- WasShown
- WasHidden
- SetSize
- SetBounds
- GetNativeView
- GetNativeViewId
- GetNativeViewAccessible
- MovePluginWindows
- Focus
- Blur
- HasFocus
- ActiveWindowChanged
- Send
- IsSurfaceAvailableForCopy
- Show
- Hide
- IsShowing
- GetViewBounds
- UpdateCursor
- SetIsLoading
- TextInputTypeChanged
- ImeCancelComposition
- DidUpdateBackingStore
- RenderProcessGone
- Destroy
- SetTooltipText
- SelectionChanged
- SelectionBoundsChanged
- ScrollOffsetChanged
- GetLastMouseDown
- BuildInputMethodsGtkMenu
- OnDestroy
- NeedsInputGrab
- IsPopup
- DoSharedInit
- DoPopupOrFullscreenInit
- AllocBackingStore
- CopyFromCompositingSurface
- CopyFromCompositingSurfaceToVideoFrame
- CanCopyToVideoFrame
- AcceleratedSurfaceInitialized
- AcceleratedSurfaceBuffersSwapped
- AcceleratedSurfacePostSubBuffer
- AcceleratedSurfaceSuspend
- AcceleratedSurfaceRelease
- HasAcceleratedSurface
- SetBackground
- ModifyEventForEdgeDragging
- Paint
- ShowCurrentCursor
- SetHasHorizontalScrollbar
- SetScrollOffsetPinning
- OnAcceleratedCompositingStateChange
- GetScreenInfo
- GetBoundsInRootWindow
- GetCompositingSurface
- ResizeCompositingSurface
- LockMouse
- UnlockMouse
- ForwardKeyboardEvent
- RetrieveSurrounding
- set_last_mouse_down
- MarkCachedWidgetCenterStale
- GetWidgetCenter
- ModifyEventMovementAndCoords
- CreateViewForWidget
- GetDefaultScreenInfo
- SetAccessibilityFocus
- AccessibilityDoDefaultAction
- AccessibilityScrollToMakeVisible
- AccessibilityScrollToPoint
- AccessibilitySetTextSelection
- GetLastTouchEventLocation
- FatalAccessibilityTreeError
- CreateBrowserAccessibilityManagerIfNeeded
- GetAccessible
- OnCreatePluginContainer
- OnDestroyPluginContainer
- PreferredReadbackFormat
#include "content/browser/renderer_host/render_widget_host_view_gtk.h"
#include <cairo/cairo.h>
#include <gdk/gdk.h>
#include <gdk/gdkkeysyms.h>
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
#include <algorithm>
#include <string>
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/debug/trace_event.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_offset_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "content/browser/accessibility/browser_accessibility_gtk.h"
#include "content/browser/accessibility/browser_accessibility_manager_gtk.h"
#include "content/browser/renderer_host/backing_store_gtk.h"
#include "content/browser/renderer_host/gtk_im_context_wrapper.h"
#include "content/browser/renderer_host/gtk_key_bindings_handler.h"
#include "content/browser/renderer_host/gtk_window_utils.h"
#include "content/browser/renderer_host/input/web_input_event_builders_gtk.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/common/cursors/webcursor_gtk_data.h"
#include "content/common/gpu/gpu_messages.h"
#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
#include "content/common/webplugin_geometry.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/common/content_switches.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/WebKit/public/platform/WebScreenInfo.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h"
#include "ui/base/x/active_window_watcher_x.h"
#include "ui/base/x/x11_util.h"
#include "ui/gfx/gtk_compat.h"
#include "ui/gfx/gtk_native_view_id_manager.h"
#include "ui/gfx/gtk_preserve_window.h"
#include "ui/gfx/text_elider.h"
using blink::WebMouseWheelEvent;
using blink::WebScreenInfo;
namespace content {
namespace {
const int kMaxWindowWidth = 10000;
const int kMaxWindowHeight = 10000;
const GdkColor kBGColor =
#if defined(NDEBUG)
{ 0, 0xff * 257, 0xff * 257, 0xff * 257 };
#else
{ 0, 0x00 * 257, 0xff * 257, 0x00 * 257 };
#endif
GdkCursor* GetMozSpinningCursor() {
static GdkCursor* moz_spinning_cursor = NULL;
if (!moz_spinning_cursor) {
const GdkColor fg = { 0, 0, 0, 0 };
const GdkColor bg = { 65535, 65535, 65535, 65535 };
GdkPixmap* source = gdk_bitmap_create_from_data(
NULL, reinterpret_cast<const gchar*>(moz_spinning_bits), 32, 32);
GdkPixmap* mask = gdk_bitmap_create_from_data(
NULL, reinterpret_cast<const gchar*>(moz_spinning_mask_bits), 32, 32);
moz_spinning_cursor =
gdk_cursor_new_from_pixmap(source, mask, &fg, &bg, 2, 2);
g_object_unref(source);
g_object_unref(mask);
}
return moz_spinning_cursor;
}
bool MovedToPoint(const blink::WebMouseEvent& mouse_event,
const gfx::Point& center) {
return mouse_event.globalX == center.x() &&
mouse_event.globalY == center.y();
}
}
class RenderWidgetHostViewGtkWidget {
public:
static AtkObject* GetAccessible(void* userdata) {
return (static_cast<RenderWidgetHostViewGtk*>(userdata))->
GetAccessible();
}
static GtkWidget* CreateNewWidget(RenderWidgetHostViewGtk* host_view) {
GtkWidget* widget = gtk_preserve_window_new();
gtk_widget_set_name(widget, "chrome-render-widget-host-view");
gtk_widget_set_double_buffered(widget, FALSE);
gtk_widget_set_redraw_on_allocate(widget, FALSE);
gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, &kBGColor);
gtk_widget_set_size_request(widget, 0, 0);
gtk_widget_add_events(widget, GDK_EXPOSURE_MASK |
GDK_STRUCTURE_MASK |
GDK_POINTER_MOTION_MASK |
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_KEY_PRESS_MASK |
GDK_KEY_RELEASE_MASK |
GDK_FOCUS_CHANGE_MASK |
GDK_ENTER_NOTIFY_MASK |
GDK_LEAVE_NOTIFY_MASK);
gtk_widget_set_can_focus(widget, TRUE);
g_signal_connect(widget, "expose-event",
G_CALLBACK(OnExposeEvent), host_view);
g_signal_connect(widget, "realize",
G_CALLBACK(OnRealize), host_view);
g_signal_connect(widget, "configure-event",
G_CALLBACK(OnConfigureEvent), host_view);
g_signal_connect(widget, "size-allocate",
G_CALLBACK(OnSizeAllocate), host_view);
g_signal_connect(widget, "key-press-event",
G_CALLBACK(OnKeyPressReleaseEvent), host_view);
g_signal_connect(widget, "key-release-event",
G_CALLBACK(OnKeyPressReleaseEvent), host_view);
g_signal_connect(widget, "focus-in-event",
G_CALLBACK(OnFocusIn), host_view);
g_signal_connect(widget, "focus-out-event",
G_CALLBACK(OnFocusOut), host_view);
g_signal_connect(widget, "grab-notify",
G_CALLBACK(OnGrabNotify), host_view);
g_signal_connect(widget, "button-press-event",
G_CALLBACK(OnButtonPressReleaseEvent), host_view);
g_signal_connect(widget, "button-release-event",
G_CALLBACK(OnButtonPressReleaseEvent), host_view);
g_signal_connect(widget, "motion-notify-event",
G_CALLBACK(OnMouseMoveEvent), host_view);
g_signal_connect(widget, "enter-notify-event",
G_CALLBACK(OnCrossingEvent), host_view);
g_signal_connect(widget, "leave-notify-event",
G_CALLBACK(OnCrossingEvent), host_view);
g_signal_connect(widget, "client-event",
G_CALLBACK(OnClientEvent), host_view);
g_signal_connect_after(widget, "scroll-event",
G_CALLBACK(OnMouseScrollEvent), host_view);
gtk_preserve_window_set_accessible_factory(
GTK_PRESERVE_WINDOW(widget), GetAccessible, host_view);
return widget;
}
private:
static gboolean OnExposeEvent(GtkWidget* widget,
GdkEventExpose* expose,
RenderWidgetHostViewGtk* host_view) {
if (host_view->host_->is_hidden())
return FALSE;
const gfx::Rect damage_rect(expose->area);
host_view->Paint(damage_rect);
return FALSE;
}
static gboolean OnRealize(GtkWidget* widget,
RenderWidgetHostViewGtk* host_view) {
host_view->signals_.Connect(gtk_widget_get_toplevel(widget),
"configure-event",
G_CALLBACK(OnConfigureEvent), host_view);
return FALSE;
}
static gboolean OnConfigureEvent(GtkWidget* widget,
GdkEventConfigure* event,
RenderWidgetHostViewGtk* host_view) {
host_view->MarkCachedWidgetCenterStale();
host_view->UpdateScreenInfo(host_view->GetNativeView());
return FALSE;
}
static gboolean OnSizeAllocate(GtkWidget* widget,
GdkRectangle* allocation,
RenderWidgetHostViewGtk* host_view) {
if (!host_view->IsPopup() && !host_view->is_fullscreen_)
host_view->SetSize(gfx::Size(allocation->width, allocation->height));
return FALSE;
}
static gboolean OnKeyPressReleaseEvent(GtkWidget* widget,
GdkEventKey* event,
RenderWidgetHostViewGtk* host_view) {
TRACE_EVENT0("browser",
"RenderWidgetHostViewGtkWidget::OnKeyPressReleaseEvent");
bool should_close_on_escape =
(host_view->IsPopup() && host_view->NeedsInputGrab()) ||
host_view->is_fullscreen_;
if (should_close_on_escape && GDK_Escape == event->keyval) {
host_view->host_->Shutdown();
} else {
host_view->im_context_->ProcessKeyEvent(event);
}
return TRUE;
}
static gboolean OnFocusIn(GtkWidget* widget,
GdkEventFocus* focus,
RenderWidgetHostViewGtk* host_view) {
host_view->ShowCurrentCursor();
RenderWidgetHostImpl* host =
RenderWidgetHostImpl::From(host_view->GetRenderWidgetHost());
host->GotFocus();
host->SetActive(true);
host_view->im_context_->OnFocusIn();
return TRUE;
}
static gboolean OnFocusOut(GtkWidget* widget,
GdkEventFocus* focus,
RenderWidgetHostViewGtk* host_view) {
gdk_window_set_cursor(gtk_widget_get_window(widget), NULL);
if (!host_view->IsShowingContextMenu()) {
RenderWidgetHostImpl* host =
RenderWidgetHostImpl::From(host_view->GetRenderWidgetHost());
host->SetActive(false);
host->Blur();
}
host_view->was_imcontext_focused_before_grab_ = false;
host_view->im_context_->OnFocusOut();
host_view->set_last_mouse_down(NULL);
return TRUE;
}
static void OnGrabNotify(GtkWidget* widget, gboolean was_grabbed,
RenderWidgetHostViewGtk* host_view) {
if (was_grabbed) {
if (host_view->was_imcontext_focused_before_grab_)
host_view->im_context_->OnFocusIn();
} else {
host_view->was_imcontext_focused_before_grab_ =
host_view->im_context_->is_focused();
if (host_view->was_imcontext_focused_before_grab_) {
gdk_window_set_cursor(gtk_widget_get_window(widget), NULL);
host_view->im_context_->OnFocusOut();
}
}
}
static gboolean OnButtonPressReleaseEvent(
GtkWidget* widget,
GdkEventButton* event,
RenderWidgetHostViewGtk* host_view) {
TRACE_EVENT0("browser",
"RenderWidgetHostViewGtkWidget::OnButtonPressReleaseEvent");
if (event->type != GDK_BUTTON_RELEASE)
host_view->set_last_mouse_down(event);
if (!(event->button == 1 || event->button == 2 || event->button == 3))
return FALSE;
if (event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS)
return FALSE;
if (!gtk_widget_is_focus(widget))
host_view->host_->OnPointerEventActivate();
if (event->type != GDK_BUTTON_RELEASE)
host_view->im_context_->ConfirmComposition();
GtkWidget* event_widget = gtk_get_event_widget(
reinterpret_cast<GdkEvent*>(event));
if (event_widget != widget) {
int x = 0;
int y = 0;
gtk_widget_get_pointer(widget, &x, &y);
GtkAllocation allocation;
gtk_widget_get_allocation(widget, &allocation);
bool click_in_popup = x >= 0 && y >= 0 && x < allocation.width &&
y < allocation.height;
if (event->type != GDK_BUTTON_RELEASE && host_view->IsPopup() &&
!host_view->is_popup_first_mouse_release_ && !click_in_popup) {
host_view->host_->Shutdown();
return FALSE;
}
event->x = x;
event->y = y;
}
if (event->type == GDK_BUTTON_PRESS && !gtk_widget_has_focus(widget))
gtk_widget_grab_focus(widget);
host_view->is_popup_first_mouse_release_ = false;
RenderWidgetHostImpl* widget_host =
RenderWidgetHostImpl::From(host_view->GetRenderWidgetHost());
if (widget_host)
widget_host->ForwardMouseEvent(WebMouseEventBuilder::Build(event));
return FALSE;
}
static gboolean OnMouseMoveEvent(GtkWidget* widget,
GdkEventMotion* event,
RenderWidgetHostViewGtk* host_view) {
TRACE_EVENT0("browser",
"RenderWidgetHostViewGtkWidget::OnMouseMoveEvent");
GtkWidget* event_widget = gtk_get_event_widget(
reinterpret_cast<GdkEvent*>(event));
if (event_widget != widget) {
int x = 0;
int y = 0;
gtk_widget_get_pointer(widget, &x, &y);
event->x = x;
event->y = y;
}
host_view->ModifyEventForEdgeDragging(widget, event);
blink::WebMouseEvent mouse_event = WebMouseEventBuilder::Build(event);
if (host_view->mouse_locked_) {
gfx::Point center = host_view->GetWidgetCenter();
bool moved_to_center = MovedToPoint(mouse_event, center);
if (moved_to_center)
host_view->mouse_has_been_warped_to_new_center_ = true;
host_view->ModifyEventMovementAndCoords(&mouse_event);
if (!moved_to_center &&
(mouse_event.movementX || mouse_event.movementY)) {
GdkDisplay* display = gtk_widget_get_display(widget);
GdkScreen* screen = gtk_widget_get_screen(widget);
gdk_display_warp_pointer(display, screen, center.x(), center.y());
if (host_view->mouse_has_been_warped_to_new_center_)
RenderWidgetHostImpl::From(
host_view->GetRenderWidgetHost())->ForwardMouseEvent(mouse_event);
}
} else {
host_view->ModifyEventMovementAndCoords(&mouse_event);
if (!host_view->mouse_is_being_warped_to_unlocked_position_) {
RenderWidgetHostImpl::From(
host_view->GetRenderWidgetHost())->ForwardMouseEvent(mouse_event);
}
}
return FALSE;
}
static gboolean OnCrossingEvent(GtkWidget* widget,
GdkEventCrossing* event,
RenderWidgetHostViewGtk* host_view) {
TRACE_EVENT0("browser",
"RenderWidgetHostViewGtkWidget::OnCrossingEvent");
const int any_button_mask =
GDK_BUTTON1_MASK |
GDK_BUTTON2_MASK |
GDK_BUTTON3_MASK |
GDK_BUTTON4_MASK |
GDK_BUTTON5_MASK;
if (!(event->state & any_button_mask)) {
blink::WebMouseEvent mouse_event = WebMouseEventBuilder::Build(event);
host_view->ModifyEventMovementAndCoords(&mouse_event);
mouse_event.movementX = 0;
mouse_event.movementY = 0;
RenderWidgetHostImpl::From(
host_view->GetRenderWidgetHost())->ForwardMouseEvent(mouse_event);
}
return FALSE;
}
static gboolean OnClientEvent(GtkWidget* widget,
GdkEventClient* event,
RenderWidgetHostViewGtk* host_view) {
VLOG(1) << "client event type: " << event->message_type
<< " data_format: " << event->data_format
<< " data: " << event->data.l;
return TRUE;
}
static int GetPendingScrollDelta(bool vert, guint current_event_state) {
int num_clicks = 0;
GdkEvent* event;
bool event_coalesced = true;
while ((event = gdk_event_get()) && event_coalesced) {
event_coalesced = false;
if (event->type == GDK_SCROLL) {
GdkEventScroll scroll = event->scroll;
if (scroll.state & GDK_SHIFT_MASK) {
if (scroll.direction == GDK_SCROLL_UP)
scroll.direction = GDK_SCROLL_LEFT;
else if (scroll.direction == GDK_SCROLL_DOWN)
scroll.direction = GDK_SCROLL_RIGHT;
}
if (vert) {
if (scroll.direction == GDK_SCROLL_UP ||
scroll.direction == GDK_SCROLL_DOWN) {
if (scroll.state == current_event_state) {
num_clicks += (scroll.direction == GDK_SCROLL_UP ? 1 : -1);
gdk_event_free(event);
event_coalesced = true;
}
}
} else {
if (scroll.direction == GDK_SCROLL_LEFT ||
scroll.direction == GDK_SCROLL_RIGHT) {
if (scroll.state == current_event_state) {
num_clicks += (scroll.direction == GDK_SCROLL_LEFT ? 1 : -1);
gdk_event_free(event);
event_coalesced = true;
}
}
}
}
}
if (event) {
gdk_event_put(event);
gdk_event_free(event);
}
return num_clicks * WebMouseWheelEventBuilder::ScrollbarPixelsPerTick();
}
static gboolean OnMouseScrollEvent(GtkWidget* widget,
GdkEventScroll* event,
RenderWidgetHostViewGtk* host_view) {
TRACE_EVENT0("browser",
"RenderWidgetHostViewGtkWidget::OnMouseScrollEvent");
if (event->state & GDK_SHIFT_MASK) {
if (event->direction == GDK_SCROLL_UP)
event->direction = GDK_SCROLL_LEFT;
else if (event->direction == GDK_SCROLL_DOWN)
event->direction = GDK_SCROLL_RIGHT;
}
WebMouseWheelEvent web_event = WebMouseWheelEventBuilder::Build(event);
const float pixelsPerTick =
WebMouseWheelEventBuilder::ScrollbarPixelsPerTick();
if (event->direction == GDK_SCROLL_UP ||
event->direction == GDK_SCROLL_DOWN) {
if (event->direction == GDK_SCROLL_UP)
web_event.deltaY = pixelsPerTick;
else
web_event.deltaY = -pixelsPerTick;
web_event.deltaY += GetPendingScrollDelta(true, event->state);
} else {
if (event->direction == GDK_SCROLL_LEFT)
web_event.deltaX = pixelsPerTick;
else
web_event.deltaX = -pixelsPerTick;
web_event.deltaX += GetPendingScrollDelta(false, event->state);
}
RenderWidgetHostImpl::From(
host_view->GetRenderWidgetHost())->ForwardWheelEvent(web_event);
return FALSE;
}
DISALLOW_IMPLICIT_CONSTRUCTORS(RenderWidgetHostViewGtkWidget);
};
RenderWidgetHostViewGtk::RenderWidgetHostViewGtk(RenderWidgetHost* widget_host)
: host_(RenderWidgetHostImpl::From(widget_host)),
about_to_validate_and_paint_(false),
is_loading_(false),
parent_(NULL),
is_popup_first_mouse_release_(true),
was_imcontext_focused_before_grab_(false),
do_x_grab_(false),
is_fullscreen_(false),
made_active_(false),
mouse_is_being_warped_to_unlocked_position_(false),
destroy_handler_id_(0),
dragged_at_horizontal_edge_(0),
dragged_at_vertical_edge_(0),
compositing_surface_(gfx::kNullPluginWindow),
last_mouse_down_(NULL) {
host_->SetView(this);
}
RenderWidgetHostViewGtk::~RenderWidgetHostViewGtk() {
UnlockMouse();
set_last_mouse_down(NULL);
view_.Destroy();
}
bool RenderWidgetHostViewGtk::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewGtk, message)
IPC_MESSAGE_HANDLER(ViewHostMsg_CreatePluginContainer,
OnCreatePluginContainer)
IPC_MESSAGE_HANDLER(ViewHostMsg_DestroyPluginContainer,
OnDestroyPluginContainer)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void RenderWidgetHostViewGtk::InitAsChild(
gfx::NativeView parent_view) {
DoSharedInit();
gtk_widget_show(view_.get());
}
void RenderWidgetHostViewGtk::InitAsPopup(
RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) {
DCHECK(IsPopup());
DoSharedInit();
parent_ = parent_host_view->GetNativeView();
GtkWindow* window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_POPUP));
gtk_container_add(GTK_CONTAINER(window), view_.get());
DoPopupOrFullscreenInit(window, pos);
if (NeedsInputGrab()) {
GtkWidget* toplevel = gtk_widget_get_toplevel(parent_);
if (toplevel &&
GTK_WIDGET_TOPLEVEL(toplevel) &&
GTK_IS_WINDOW(toplevel)) {
gtk_window_group_add_window(
gtk_window_get_group(GTK_WINDOW(toplevel)), window);
}
gtk_grab_add(view_.get());
do_x_grab_ = !gdk_pointer_is_grabbed();
if (do_x_grab_) {
GdkWindow* grab_window = gtk_widget_get_window(parent_);
if (!grab_window || !gdk_window_is_viewable(grab_window))
grab_window = gtk_widget_get_window(view_.get());
gdk_pointer_grab(
grab_window,
TRUE,
static_cast<GdkEventMask>(GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK),
NULL,
NULL,
GDK_CURRENT_TIME);
gdk_keyboard_grab(grab_window, TRUE, GDK_CURRENT_TIME);
}
}
}
void RenderWidgetHostViewGtk::InitAsFullscreen(
RenderWidgetHostView* reference_host_view) {
DCHECK(reference_host_view);
DoSharedInit();
is_fullscreen_ = true;
GtkWindow* window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
gtk_window_set_decorated(window, FALSE);
destroy_handler_id_ = g_signal_connect(GTK_WIDGET(window),
"destroy",
G_CALLBACK(OnDestroyThunk),
this);
gtk_container_add(GTK_CONTAINER(window), view_.get());
GdkScreen* screen = gtk_window_get_screen(window);
GdkWindow* ref_gdk_window = gtk_widget_get_window(
reference_host_view->GetNativeView());
gfx::Rect bounds;
if (ref_gdk_window) {
const int monitor_id = gdk_screen_get_monitor_at_window(screen,
ref_gdk_window);
GdkRectangle monitor_rect;
gdk_screen_get_monitor_geometry(screen, monitor_id, &monitor_rect);
bounds = gfx::Rect(monitor_rect);
} else {
bounds = gfx::Rect(
0, 0, gdk_screen_get_width(screen), gdk_screen_get_height(screen));
}
gtk_window_move(window, bounds.x(), bounds.y());
gtk_window_resize(window, bounds.width(), bounds.height());
gtk_window_fullscreen(window);
DoPopupOrFullscreenInit(window, bounds);
}
RenderWidgetHost* RenderWidgetHostViewGtk::GetRenderWidgetHost() const {
return host_;
}
void RenderWidgetHostViewGtk::WasShown() {
if (!host_ || !host_->is_hidden())
return;
if (web_contents_switch_paint_time_.is_null())
web_contents_switch_paint_time_ = base::TimeTicks::Now();
host_->WasShown();
}
void RenderWidgetHostViewGtk::WasHidden() {
if (!host_ || host_->is_hidden())
return;
host_->WasHidden();
web_contents_switch_paint_time_ = base::TimeTicks();
}
void RenderWidgetHostViewGtk::SetSize(const gfx::Size& size) {
int width = std::min(size.width(), kMaxWindowWidth);
int height = std::min(size.height(), kMaxWindowHeight);
if (IsPopup()) {
gtk_widget_set_size_request(view_.get(), width, height);
}
if (requested_size_.width() != width ||
requested_size_.height() != height) {
requested_size_ = gfx::Size(width, height);
host_->SendScreenRects();
host_->WasResized();
}
}
void RenderWidgetHostViewGtk::SetBounds(const gfx::Rect& rect) {
if (IsPopup()) {
gtk_window_move(GTK_WINDOW(gtk_widget_get_toplevel(view_.get())),
rect.x(), rect.y());
}
SetSize(rect.size());
}
gfx::NativeView RenderWidgetHostViewGtk::GetNativeView() const {
return view_.get();
}
gfx::NativeViewId RenderWidgetHostViewGtk::GetNativeViewId() const {
return GtkNativeViewManager::GetInstance()->GetIdForWidget(view_.get());
}
gfx::NativeViewAccessible RenderWidgetHostViewGtk::GetNativeViewAccessible() {
NOTIMPLEMENTED();
return NULL;
}
void RenderWidgetHostViewGtk::MovePluginWindows(
const gfx::Vector2d& scroll_offset,
const std::vector<WebPluginGeometry>& moves) {
for (size_t i = 0; i < moves.size(); ++i) {
plugin_container_manager_.MovePluginContainer(moves[i]);
}
}
void RenderWidgetHostViewGtk::Focus() {
gtk_widget_grab_focus(view_.get());
}
void RenderWidgetHostViewGtk::Blur() {
host_->Blur();
}
bool RenderWidgetHostViewGtk::HasFocus() const {
return gtk_widget_has_focus(view_.get());
}
void RenderWidgetHostViewGtk::ActiveWindowChanged(GdkWindow* window) {
GdkWindow* our_window = gtk_widget_get_parent_window(view_.get());
if (our_window == window)
made_active_ = true;
if (is_fullscreen_ && our_window != window && made_active_)
host_->Shutdown();
}
bool RenderWidgetHostViewGtk::Send(IPC::Message* message) {
return host_->Send(message);
}
bool RenderWidgetHostViewGtk::IsSurfaceAvailableForCopy() const {
return true;
}
void RenderWidgetHostViewGtk::Show() {
gtk_widget_show(view_.get());
WasShown();
}
void RenderWidgetHostViewGtk::Hide() {
gtk_widget_hide(view_.get());
WasHidden();
}
bool RenderWidgetHostViewGtk::IsShowing() {
return gtk_widget_get_visible(view_.get());
}
gfx::Rect RenderWidgetHostViewGtk::GetViewBounds() const {
GdkWindow* gdk_window = gtk_widget_get_window(view_.get());
if (!gdk_window)
return gfx::Rect(requested_size_);
GdkRectangle window_rect;
gdk_window_get_origin(gdk_window, &window_rect.x, &window_rect.y);
return gfx::Rect(window_rect.x, window_rect.y,
requested_size_.width(), requested_size_.height());
}
void RenderWidgetHostViewGtk::UpdateCursor(const WebCursor& cursor) {
if (current_cursor_.GetCursorType() != GDK_CURSOR_IS_PIXMAP &&
current_cursor_.GetCursorType() == cursor.GetCursorType()) {
return;
}
current_cursor_ = cursor;
ShowCurrentCursor();
}
void RenderWidgetHostViewGtk::SetIsLoading(bool is_loading) {
is_loading_ = is_loading;
if (current_cursor_.GetCursorType() == GDK_LAST_CURSOR)
ShowCurrentCursor();
}
void RenderWidgetHostViewGtk::TextInputTypeChanged(
ui::TextInputType type,
ui::TextInputMode input_mode,
bool can_compose_inline) {
im_context_->UpdateInputMethodState(type, can_compose_inline);
}
void RenderWidgetHostViewGtk::ImeCancelComposition() {
im_context_->CancelComposition();
}
void RenderWidgetHostViewGtk::DidUpdateBackingStore(
const gfx::Rect& scroll_rect,
const gfx::Vector2d& scroll_delta,
const std::vector<gfx::Rect>& copy_rects,
const std::vector<ui::LatencyInfo>& latency_info) {
TRACE_EVENT0("ui::gtk", "RenderWidgetHostViewGtk::DidUpdateBackingStore");
for (size_t i = 0; i < latency_info.size(); i++)
software_latency_info_.push_back(latency_info[i]);
if (host_->is_hidden())
return;
if (about_to_validate_and_paint_)
invalid_rect_.Union(scroll_rect);
else
Paint(scroll_rect);
for (size_t i = 0; i < copy_rects.size(); ++i) {
gfx::Rect rect = gfx::SubtractRects(copy_rects[i], scroll_rect);
if (rect.IsEmpty())
continue;
if (about_to_validate_and_paint_)
invalid_rect_.Union(rect);
else
Paint(rect);
}
}
void RenderWidgetHostViewGtk::RenderProcessGone(base::TerminationStatus status,
int error_code) {
Destroy();
plugin_container_manager_.set_host_widget(NULL);
}
void RenderWidgetHostViewGtk::Destroy() {
if (compositing_surface_ != gfx::kNullPluginWindow) {
GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance();
manager->ReleasePermanentXID(compositing_surface_);
}
if (do_x_grab_) {
GdkDisplay* display = gtk_widget_get_display(parent_);
gdk_display_pointer_ungrab(display, GDK_CURRENT_TIME);
gdk_display_keyboard_ungrab(display, GDK_CURRENT_TIME);
}
if (view_.get()) {
if (IsPopup() || is_fullscreen_) {
GtkWidget* window = gtk_widget_get_parent(view_.get());
ui::ActiveWindowWatcherX::RemoveObserver(this);
if (is_fullscreen_)
g_signal_handler_disconnect(window, destroy_handler_id_);
gtk_widget_destroy(window);
}
gtk_widget_destroy(view_.get());
}
host_ = NULL;
base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
}
void RenderWidgetHostViewGtk::SetTooltipText(
const base::string16& tooltip_text) {
const int kMaxTooltipLength = 8 << 10;
const base::string16 clamped_tooltip =
gfx::TruncateString(tooltip_text, kMaxTooltipLength);
if (clamped_tooltip.empty()) {
gtk_widget_set_has_tooltip(view_.get(), FALSE);
} else {
gtk_widget_set_tooltip_text(view_.get(),
base::UTF16ToUTF8(clamped_tooltip).c_str());
}
}
void RenderWidgetHostViewGtk::SelectionChanged(const base::string16& text,
size_t offset,
const gfx::Range& range) {
RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
if (text.empty() || range.is_empty())
return;
size_t pos = range.GetMin() - offset;
size_t n = range.length();
DCHECK(pos + n <= text.length()) << "The text can not fully cover range.";
if (pos >= text.length()) {
NOTREACHED() << "The text can not cover range.";
return;
}
ui::ScopedClipboardWriter clipboard_writer(
ui::Clipboard::GetForCurrentThread(),
ui::CLIPBOARD_TYPE_SELECTION);
clipboard_writer.WriteText(text.substr(pos, n));
}
void RenderWidgetHostViewGtk::SelectionBoundsChanged(
const ViewHostMsg_SelectionBounds_Params& params) {
im_context_->UpdateCaretBounds(
gfx::UnionRects(params.anchor_rect, params.focus_rect));
}
void RenderWidgetHostViewGtk::ScrollOffsetChanged() {
}
GdkEventButton* RenderWidgetHostViewGtk::GetLastMouseDown() {
return last_mouse_down_;
}
gfx::NativeView RenderWidgetHostViewGtk::BuildInputMethodsGtkMenu() {
return im_context_->BuildInputMethodsGtkMenu();
}
void RenderWidgetHostViewGtk::OnDestroy(GtkWidget* widget) {
DCHECK(is_fullscreen_);
host_->Shutdown();
}
bool RenderWidgetHostViewGtk::NeedsInputGrab() {
return popup_type_ == blink::WebPopupTypeSelect;
}
bool RenderWidgetHostViewGtk::IsPopup() const {
return popup_type_ != blink::WebPopupTypeNone;
}
void RenderWidgetHostViewGtk::DoSharedInit() {
view_.Own(RenderWidgetHostViewGtkWidget::CreateNewWidget(this));
im_context_.reset(new GtkIMContextWrapper(this));
plugin_container_manager_.set_host_widget(view_.get());
key_bindings_handler_.reset(new GtkKeyBindingsHandler(view_.get()));
}
void RenderWidgetHostViewGtk::DoPopupOrFullscreenInit(GtkWindow* window,
const gfx::Rect& bounds) {
requested_size_.SetSize(std::min(bounds.width(), kMaxWindowWidth),
std::min(bounds.height(), kMaxWindowHeight));
host_->WasResized();
ui::ActiveWindowWatcherX::AddObserver(this);
if (!is_fullscreen_) {
gtk_widget_set_size_request(
view_.get(), requested_size_.width(), requested_size_.height());
gtk_window_set_resizable(window, FALSE);
gtk_window_set_default_size(window, -1, -1);
gtk_window_move(window, bounds.x(), bounds.y());
}
gtk_widget_show_all(GTK_WIDGET(window));
}
BackingStore* RenderWidgetHostViewGtk::AllocBackingStore(
const gfx::Size& size) {
gint depth = gdk_visual_get_depth(gtk_widget_get_visual(view_.get()));
return new BackingStoreGtk(host_, size,
ui::GetVisualFromGtkWidget(view_.get()),
depth);
}
void RenderWidgetHostViewGtk::CopyFromCompositingSurface(
const gfx::Rect& src_subrect,
const gfx::Size& ,
const base::Callback<void(bool, const SkBitmap&)>& callback,
SkBitmap::Config config) {
if (config != SkBitmap::kARGB_8888_Config) {
NOTIMPLEMENTED();
callback.Run(false, SkBitmap());
}
GetRenderWidgetHost()->GetSnapshotFromRenderer(src_subrect, callback);
}
void RenderWidgetHostViewGtk::CopyFromCompositingSurfaceToVideoFrame(
const gfx::Rect& src_subrect,
const scoped_refptr<media::VideoFrame>& target,
const base::Callback<void(bool)>& callback) {
NOTIMPLEMENTED();
callback.Run(false);
}
bool RenderWidgetHostViewGtk::CanCopyToVideoFrame() const {
return false;
}
void RenderWidgetHostViewGtk::AcceleratedSurfaceInitialized(int host_id,
int route_id) {
}
void RenderWidgetHostViewGtk::AcceleratedSurfaceBuffersSwapped(
const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
int gpu_host_id) {
AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
ack_params.sync_point = 0;
RenderWidgetHostImpl::AcknowledgeBufferPresent(
params.route_id, gpu_host_id, ack_params);
RenderWidgetHostImpl::CompositorFrameDrawn(params.latency_info);
}
void RenderWidgetHostViewGtk::AcceleratedSurfacePostSubBuffer(
const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
int gpu_host_id) {
AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
ack_params.sync_point = 0;
RenderWidgetHostImpl::AcknowledgeBufferPresent(
params.route_id, gpu_host_id, ack_params);
RenderWidgetHostImpl::CompositorFrameDrawn(params.latency_info);
}
void RenderWidgetHostViewGtk::AcceleratedSurfaceSuspend() {
}
void RenderWidgetHostViewGtk::AcceleratedSurfaceRelease() {
}
bool RenderWidgetHostViewGtk::HasAcceleratedSurface(
const gfx::Size& desired_size) {
return false;
}
void RenderWidgetHostViewGtk::SetBackground(const SkBitmap& background) {
RenderWidgetHostViewBase::SetBackground(background);
Send(new ViewMsg_SetBackground(host_->GetRoutingID(), background));
}
void RenderWidgetHostViewGtk::ModifyEventForEdgeDragging(
GtkWidget* widget, GdkEventMotion* event) {
int new_dragged_at_horizontal_edge = 0;
int new_dragged_at_vertical_edge = 0;
CR_DEFINE_STATIC_LOCAL(gfx::Size, drag_monitor_size, ());
if (event->state & GDK_BUTTON1_MASK) {
if (drag_monitor_size.IsEmpty()) {
GdkScreen* screen = gtk_widget_get_screen(widget);
int monitor =
gdk_screen_get_monitor_at_point(screen, event->x_root, event->y_root);
GdkRectangle geometry;
gdk_screen_get_monitor_geometry(screen, monitor, &geometry);
drag_monitor_size.SetSize(geometry.width, geometry.height);
}
GtkAllocation allocation;
gtk_widget_get_allocation(widget, &allocation);
if (event->x == 0 && event->x_root == 0) {
new_dragged_at_horizontal_edge = dragged_at_horizontal_edge_ - 1;
} else if (allocation.width - 1 == static_cast<gint>(event->x) &&
drag_monitor_size.width() - 1 == static_cast<gint>(event->x_root)) {
new_dragged_at_horizontal_edge = dragged_at_horizontal_edge_ + 1;
}
if (event->y == 0 && event->y_root == 0) {
new_dragged_at_vertical_edge = dragged_at_vertical_edge_ - 1;
} else if (allocation.height - 1 == static_cast<gint>(event->y) &&
drag_monitor_size.height() - 1 == static_cast<gint>(event->y_root)) {
new_dragged_at_vertical_edge = dragged_at_vertical_edge_ + 1;
}
event->x_root += new_dragged_at_horizontal_edge;
event->x += new_dragged_at_horizontal_edge;
event->y_root += new_dragged_at_vertical_edge;
event->y += new_dragged_at_vertical_edge;
} else {
drag_monitor_size.SetSize(0, 0);
}
dragged_at_horizontal_edge_ = new_dragged_at_horizontal_edge;
dragged_at_vertical_edge_ = new_dragged_at_vertical_edge;
}
void RenderWidgetHostViewGtk::Paint(const gfx::Rect& damage_rect) {
TRACE_EVENT0("ui::gtk", "RenderWidgetHostViewGtk::Paint");
RenderWidgetHostImpl* render_widget_host =
RenderWidgetHostImpl::From(GetRenderWidgetHost());
if (render_widget_host->is_accelerated_compositing_active()) {
host_->ScheduleComposite();
return;
}
GdkWindow* window = gtk_widget_get_window(view_.get());
DCHECK(!about_to_validate_and_paint_);
invalid_rect_ = damage_rect;
about_to_validate_and_paint_ = true;
bool force_create = !host_->empty();
BackingStoreGtk* backing_store = static_cast<BackingStoreGtk*>(
host_->GetBackingStore(force_create));
about_to_validate_and_paint_ = false;
gfx::Rect paint_rect = gfx::Rect(0, 0, kMaxWindowWidth, kMaxWindowHeight);
paint_rect.Intersect(invalid_rect_);
if (backing_store) {
if (window) {
backing_store->XShowRect(gfx::Point(0, 0),
paint_rect, ui::GetX11WindowFromGtkWidget(view_.get()));
}
if (!whiteout_start_time_.is_null()) {
base::TimeDelta whiteout_duration = base::TimeTicks::Now() -
whiteout_start_time_;
UMA_HISTOGRAM_TIMES("MPArch.RWHH_WhiteoutDuration", whiteout_duration);
whiteout_start_time_ = base::TimeTicks();
}
if (!web_contents_switch_paint_time_.is_null()) {
base::TimeDelta web_contents_switch_paint_duration =
base::TimeTicks::Now() - web_contents_switch_paint_time_;
UMA_HISTOGRAM_TIMES("MPArch.RWH_TabSwitchPaintDuration",
web_contents_switch_paint_duration);
web_contents_switch_paint_time_ = base::TimeTicks();
}
for (size_t i = 0; i < software_latency_info_.size(); i++) {
software_latency_info_[i].AddLatencyNumber(
ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, 0);
render_widget_host->FrameSwapped(software_latency_info_[i]);
}
software_latency_info_.clear();
} else {
if (window)
gdk_window_clear(window);
if (whiteout_start_time_.is_null())
whiteout_start_time_ = base::TimeTicks::Now();
}
}
void RenderWidgetHostViewGtk::ShowCurrentCursor() {
if (!gtk_widget_get_window(view_.get()))
return;
GdkCursor* gdk_cursor;
if (current_cursor_.GetCursorType() == GDK_LAST_CURSOR) {
gdk_cursor = is_loading_ ? GetMozSpinningCursor() : NULL;
} else {
gdk_cursor = current_cursor_.GetNativeCursor();
}
gdk_window_set_cursor(gtk_widget_get_window(view_.get()), gdk_cursor);
}
void RenderWidgetHostViewGtk::SetHasHorizontalScrollbar(
bool has_horizontal_scrollbar) {
}
void RenderWidgetHostViewGtk::SetScrollOffsetPinning(
bool is_pinned_to_left, bool is_pinned_to_right) {
}
void RenderWidgetHostViewGtk::OnAcceleratedCompositingStateChange() {
bool activated = host_->is_accelerated_compositing_active();
GtkPreserveWindow* widget = reinterpret_cast<GtkPreserveWindow*>(view_.get());
gtk_preserve_window_delegate_resize(widget, activated);
}
void RenderWidgetHostViewGtk::GetScreenInfo(WebScreenInfo* results) {
GdkWindow* gdk_window = gtk_widget_get_window(view_.get());
if (!gdk_window) {
GdkDisplay* display = gdk_display_get_default();
gdk_window = gdk_display_get_default_group(display);
}
if (!gdk_window)
return;
GetScreenInfoFromNativeWindow(gdk_window, results);
}
gfx::Rect RenderWidgetHostViewGtk::GetBoundsInRootWindow() {
GtkWidget* toplevel = gtk_widget_get_toplevel(view_.get());
if (!toplevel)
return GetViewBounds();
GdkRectangle frame_extents;
GdkWindow* gdk_window = gtk_widget_get_window(toplevel);
if (!gdk_window)
return GetViewBounds();
gdk_window_get_frame_extents(gdk_window, &frame_extents);
return gfx::Rect(frame_extents.x, frame_extents.y,
frame_extents.width, frame_extents.height);
}
gfx::GLSurfaceHandle RenderWidgetHostViewGtk::GetCompositingSurface() {
if (compositing_surface_ == gfx::kNullPluginWindow) {
GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance();
gfx::NativeViewId view_id = GetNativeViewId();
if (!manager->GetPermanentXIDForId(&compositing_surface_, view_id)) {
DLOG(ERROR) << "Can't find XID for view id " << view_id;
}
}
return gfx::GLSurfaceHandle(compositing_surface_, gfx::NATIVE_TRANSPORT);
}
void RenderWidgetHostViewGtk::ResizeCompositingSurface(const gfx::Size& size) {
GtkWidget* widget = view_.get();
GdkWindow* window = gtk_widget_get_window(widget);
if (window) {
Display* display = GDK_WINDOW_XDISPLAY(window);
gdk_window_resize(window, size.width(), size.height());
XSync(display, False);
}
}
bool RenderWidgetHostViewGtk::LockMouse() {
if (mouse_locked_)
return true;
mouse_locked_ = true;
GtkWidget* current_grab_window = gtk_grab_get_current();
if (current_grab_window) {
gtk_grab_remove(current_grab_window);
LOG(WARNING) << "Locking Mouse with gdk_pointer_grab, "
<< "but had to steal grab from another window";
}
GtkWidget* widget = view_.get();
GdkWindow* window = gtk_widget_get_window(widget);
GdkCursor* cursor = gdk_cursor_new(GDK_BLANK_CURSOR);
GdkGrabStatus grab_status =
gdk_pointer_grab(window,
FALSE,
static_cast<GdkEventMask>(
GDK_POINTER_MOTION_MASK |
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK),
window,
cursor,
GDK_CURRENT_TIME);
if (grab_status != GDK_GRAB_SUCCESS) {
LOG(WARNING) << "Failed to grab pointer for LockMouse. "
<< "gdk_pointer_grab returned: " << grab_status;
mouse_locked_ = false;
return false;
}
SetTooltipText(base::string16());
MarkCachedWidgetCenterStale();
mouse_is_being_warped_to_unlocked_position_ = false;
return true;
}
void RenderWidgetHostViewGtk::UnlockMouse() {
if (!mouse_locked_)
return;
mouse_locked_ = false;
GtkWidget* widget = view_.get();
GdkDisplay* display = gtk_widget_get_display(widget);
GdkScreen* screen = gtk_widget_get_screen(widget);
gdk_display_pointer_ungrab(display, GDK_CURRENT_TIME);
gdk_display_warp_pointer(display, screen,
unlocked_global_mouse_position_.x(),
unlocked_global_mouse_position_.y());
mouse_is_being_warped_to_unlocked_position_ = true;
if (host_)
host_->LostMouseLock();
}
void RenderWidgetHostViewGtk::ForwardKeyboardEvent(
const NativeWebKeyboardEvent& event) {
if (!host_)
return;
EditCommands edit_commands;
if (!event.skip_in_browser &&
key_bindings_handler_->Match(event, &edit_commands)) {
Send(new InputMsg_SetEditCommandsForNextKeyEvent(
host_->GetRoutingID(), edit_commands));
NativeWebKeyboardEvent copy_event(event);
copy_event.match_edit_command = true;
host_->ForwardKeyboardEvent(copy_event);
return;
}
host_->ForwardKeyboardEvent(event);
}
bool RenderWidgetHostViewGtk::RetrieveSurrounding(std::string* text,
size_t* cursor_index) {
if (!selection_range_.IsValid())
return false;
size_t offset = selection_range_.GetMin() - selection_text_offset_;
DCHECK(offset <= selection_text_.length());
if (offset == selection_text_.length()) {
*text = base::UTF16ToUTF8(selection_text_);
*cursor_index = text->length();
return true;
}
*text = base::UTF16ToUTF8AndAdjustOffset(
base::StringPiece16(selection_text_), &offset);
if (offset == base::string16::npos) {
NOTREACHED() << "Invalid offset in UTF16 string.";
return false;
}
*cursor_index = offset;
return true;
}
void RenderWidgetHostViewGtk::set_last_mouse_down(GdkEventButton* event) {
GdkEventButton* temp = NULL;
if (event) {
temp = reinterpret_cast<GdkEventButton*>(
gdk_event_copy(reinterpret_cast<GdkEvent*>(event)));
}
if (last_mouse_down_)
gdk_event_free(reinterpret_cast<GdkEvent*>(last_mouse_down_));
last_mouse_down_ = temp;
}
void RenderWidgetHostViewGtk::MarkCachedWidgetCenterStale() {
widget_center_valid_ = false;
mouse_has_been_warped_to_new_center_ = false;
}
gfx::Point RenderWidgetHostViewGtk::GetWidgetCenter() {
if (widget_center_valid_)
return widget_center_;
GdkWindow* window = gtk_widget_get_window(view_.get());
gint window_x = 0;
gint window_y = 0;
gdk_window_get_origin(window, &window_x, &window_y);
gint window_w = gdk_window_get_width(window);
gint window_h = gdk_window_get_height(window);
widget_center_.SetPoint(window_x + window_w / 2,
window_y + window_h / 2);
widget_center_valid_ = true;
return widget_center_;
}
void RenderWidgetHostViewGtk::ModifyEventMovementAndCoords(
blink::WebMouseEvent* event) {
event->movementX = event->globalX - global_mouse_position_.x();
event->movementY = event->globalY - global_mouse_position_.y();
if (mouse_is_being_warped_to_unlocked_position_) {
event->movementX = 0;
event->movementY = 0;
if (MovedToPoint(*event, unlocked_global_mouse_position_))
mouse_is_being_warped_to_unlocked_position_ = false;
}
global_mouse_position_.SetPoint(event->globalX, event->globalY);
if (mouse_locked_) {
event->x = unlocked_mouse_position_.x();
event->y = unlocked_mouse_position_.y();
event->windowX = unlocked_mouse_position_.x();
event->windowY = unlocked_mouse_position_.y();
event->globalX = unlocked_global_mouse_position_.x();
event->globalY = unlocked_global_mouse_position_.y();
} else if (!mouse_is_being_warped_to_unlocked_position_) {
unlocked_mouse_position_.SetPoint(event->windowX, event->windowY);
unlocked_global_mouse_position_.SetPoint(event->globalX, event->globalY);
}
}
RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget(
RenderWidgetHost* widget) {
return new RenderWidgetHostViewGtk(widget);
}
void RenderWidgetHostViewPort::GetDefaultScreenInfo(WebScreenInfo* results) {
GdkWindow* gdk_window =
gdk_display_get_default_group(gdk_display_get_default());
GetScreenInfoFromNativeWindow(gdk_window, results);
}
void RenderWidgetHostViewGtk::SetAccessibilityFocus(int acc_obj_id) {
if (!host_)
return;
host_->AccessibilitySetFocus(acc_obj_id);
}
void RenderWidgetHostViewGtk::AccessibilityDoDefaultAction(int acc_obj_id) {
if (!host_)
return;
host_->AccessibilityDoDefaultAction(acc_obj_id);
}
void RenderWidgetHostViewGtk::AccessibilityScrollToMakeVisible(
int acc_obj_id, gfx::Rect subfocus) {
if (!host_)
return;
host_->AccessibilityScrollToMakeVisible(acc_obj_id, subfocus);
}
void RenderWidgetHostViewGtk::AccessibilityScrollToPoint(
int acc_obj_id, gfx::Point point) {
if (!host_)
return;
host_->AccessibilityScrollToPoint(acc_obj_id, point);
}
void RenderWidgetHostViewGtk::AccessibilitySetTextSelection(
int acc_obj_id, int start_offset, int end_offset) {
if (!host_)
return;
host_->AccessibilitySetTextSelection(acc_obj_id, start_offset, end_offset);
}
gfx::Point RenderWidgetHostViewGtk::GetLastTouchEventLocation() const {
return gfx::Point();
}
void RenderWidgetHostViewGtk::FatalAccessibilityTreeError() {
if (host_) {
host_->FatalAccessibilityTreeError();
SetBrowserAccessibilityManager(NULL);
} else {
CHECK(FALSE);
}
}
void RenderWidgetHostViewGtk::CreateBrowserAccessibilityManagerIfNeeded() {
if (!GetBrowserAccessibilityManager()) {
GtkWidget* parent = gtk_widget_get_parent(view_.get());
SetBrowserAccessibilityManager(
new BrowserAccessibilityManagerGtk(
parent,
BrowserAccessibilityManagerGtk::GetEmptyDocument(),
this));
}
}
AtkObject* RenderWidgetHostViewGtk::GetAccessible() {
if (!GetBrowserAccessibilityManager()) {
GtkWidget* parent = gtk_widget_get_parent(view_.get());
SetBrowserAccessibilityManager(
new BrowserAccessibilityManagerGtk(
parent,
BrowserAccessibilityManagerGtk::GetEmptyDocument(),
this));
}
BrowserAccessibilityGtk* root =
GetBrowserAccessibilityManager()->GetRoot()->ToBrowserAccessibilityGtk();
atk_object_set_role(root->GetAtkObject(), ATK_ROLE_HTML_CONTAINER);
return root->GetAtkObject();
}
void RenderWidgetHostViewGtk::OnCreatePluginContainer(
gfx::PluginWindowHandle id) {
plugin_container_manager_.CreatePluginContainer(id);
}
void RenderWidgetHostViewGtk::OnDestroyPluginContainer(
gfx::PluginWindowHandle id) {
plugin_container_manager_.DestroyPluginContainer(id);
}
SkBitmap::Config RenderWidgetHostViewGtk::PreferredReadbackFormat() {
return SkBitmap::kARGB_8888_Config;
}
}