15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/render_widget_host_view_gtk.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cairo/cairo.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gdk/gdk.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gdk/gdkkeysyms.h>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gdk/gdkx.h>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gtk/gtk.h>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
209ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/utf_offset_string_conversions.h"
24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/accessibility/browser_accessibility_gtk.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/accessibility/browser_accessibility_manager_gtk.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/backing_store_gtk.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/gtk_im_context_wrapper.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/gtk_key_bindings_handler.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/gtk_window_utils.h"
32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "content/browser/renderer_host/input/web_input_event_builders_gtk.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/render_view_host_delegate.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/render_view_host_impl.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_messages.h"
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/common/input_messages.h"
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/common/view_messages.h"
38ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/common/webplugin_geometry.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/native_web_keyboard_event.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_switches.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "skia/ext/platform_canvas.h"
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "third_party/WebKit/public/platform/WebScreenInfo.h"
437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebInputEvent.h"
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/clipboard/scoped_clipboard_writer.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/x/active_window_watcher_x.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/x/x11_util.h"
4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/gfx/gtk_compat.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/gtk_native_view_id_manager.h"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/gtk_preserve_window.h"
5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/gfx/text_elider.h"
51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/common/cursors/webcursor_gtk_data.h"
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebMouseWheelEvent;
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebScreenInfo;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Paint rects on Linux are bounded by the maximum size of a shared memory
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// region. By default that's 32MB, but many distros increase it significantly
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (i.e. to 256MB).
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We fetch the maximum value from /proc/sys/kernel/shmmax at runtime and, if
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// we exceed that, then we limit the height of the paint rect in the renderer.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These constants are here to ensure that, in the event that we exceed it, we
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// end up with something a little more square. Previously we had 4000x4000, but
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// people's monitor setups are actually exceeding that these days.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxWindowWidth = 10000;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxWindowHeight = 10000;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GdkColor kBGColor =
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(NDEBUG)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 0, 0xff * 257, 0xff * 257, 0xff * 257 };
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 0, 0x00 * 257, 0xff * 257, 0x00 * 257 };
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the spinning cursor used for loading state.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GdkCursor* GetMozSpinningCursor() {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static GdkCursor* moz_spinning_cursor = NULL;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!moz_spinning_cursor) {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GdkColor fg = { 0, 0, 0, 0 };
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GdkColor bg = { 65535, 65535, 65535, 65535 };
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GdkPixmap* source = gdk_bitmap_create_from_data(
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NULL, reinterpret_cast<const gchar*>(moz_spinning_bits), 32, 32);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GdkPixmap* mask = gdk_bitmap_create_from_data(
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NULL, reinterpret_cast<const gchar*>(moz_spinning_mask_bits), 32, 32);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moz_spinning_cursor =
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        gdk_cursor_new_from_pixmap(source, mask, &fg, &bg, 2, 2);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_object_unref(source);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_object_unref(mask);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return moz_spinning_cursor;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool MovedToPoint(const blink::WebMouseEvent& mouse_event,
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   const gfx::Point& center) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return mouse_event.globalX == center.x() &&
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         mouse_event.globalY == center.y();
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class is a simple convenience wrapper for Gtk functions. It has only
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static methods.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RenderWidgetHostViewGtkWidget {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static AtkObject* GetAccessible(void* userdata) {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (static_cast<RenderWidgetHostViewGtk*>(userdata))->
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetAccessible();
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static GtkWidget* CreateNewWidget(RenderWidgetHostViewGtk* host_view) {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GtkWidget* widget = gtk_preserve_window_new();
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gtk_widget_set_name(widget, "chrome-render-widget-host-view");
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We manually double-buffer in Paint() because Paint() may or may not be
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // called in repsonse to an "expose-event" signal.
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gtk_widget_set_double_buffered(widget, FALSE);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gtk_widget_set_redraw_on_allocate(widget, FALSE);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, &kBGColor);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Allow the browser window to be resized freely.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gtk_widget_set_size_request(widget, 0, 0);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gtk_widget_add_events(widget, GDK_EXPOSURE_MASK |
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  GDK_STRUCTURE_MASK |
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  GDK_POINTER_MOTION_MASK |
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  GDK_BUTTON_PRESS_MASK |
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  GDK_BUTTON_RELEASE_MASK |
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  GDK_KEY_PRESS_MASK |
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  GDK_KEY_RELEASE_MASK |
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  GDK_FOCUS_CHANGE_MASK |
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  GDK_ENTER_NOTIFY_MASK |
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  GDK_LEAVE_NOTIFY_MASK);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gtk_widget_set_can_focus(widget, TRUE);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_signal_connect(widget, "expose-event",
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     G_CALLBACK(OnExposeEvent), host_view);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_signal_connect(widget, "realize",
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     G_CALLBACK(OnRealize), host_view);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_signal_connect(widget, "configure-event",
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     G_CALLBACK(OnConfigureEvent), host_view);
1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    g_signal_connect(widget, "size-allocate",
1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                     G_CALLBACK(OnSizeAllocate), host_view);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_signal_connect(widget, "key-press-event",
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     G_CALLBACK(OnKeyPressReleaseEvent), host_view);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_signal_connect(widget, "key-release-event",
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     G_CALLBACK(OnKeyPressReleaseEvent), host_view);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_signal_connect(widget, "focus-in-event",
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     G_CALLBACK(OnFocusIn), host_view);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_signal_connect(widget, "focus-out-event",
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     G_CALLBACK(OnFocusOut), host_view);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_signal_connect(widget, "grab-notify",
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     G_CALLBACK(OnGrabNotify), host_view);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_signal_connect(widget, "button-press-event",
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     G_CALLBACK(OnButtonPressReleaseEvent), host_view);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_signal_connect(widget, "button-release-event",
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     G_CALLBACK(OnButtonPressReleaseEvent), host_view);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_signal_connect(widget, "motion-notify-event",
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     G_CALLBACK(OnMouseMoveEvent), host_view);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_signal_connect(widget, "enter-notify-event",
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     G_CALLBACK(OnCrossingEvent), host_view);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_signal_connect(widget, "leave-notify-event",
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     G_CALLBACK(OnCrossingEvent), host_view);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_signal_connect(widget, "client-event",
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     G_CALLBACK(OnClientEvent), host_view);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Connect after so that we are called after the handler installed by the
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // WebContentsView which handles zoom events.
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_signal_connect_after(widget, "scroll-event",
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           G_CALLBACK(OnMouseScrollEvent), host_view);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Route calls to get_accessible to the view.
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gtk_preserve_window_set_accessible_factory(
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GTK_PRESERVE_WINDOW(widget), GetAccessible, host_view);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return widget;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static gboolean OnExposeEvent(GtkWidget* widget,
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                GdkEventExpose* expose,
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                RenderWidgetHostViewGtk* host_view) {
1858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (host_view->host_->is_hidden())
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return FALSE;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect damage_rect(expose->area);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_view->Paint(damage_rect);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return FALSE;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static gboolean OnRealize(GtkWidget* widget,
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            RenderWidgetHostViewGtk* host_view) {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Use GtkSignalRegistrar to register events on a widget we don't
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // control the lifetime of, auto disconnecting at our end of our life.
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_view->signals_.Connect(gtk_widget_get_toplevel(widget),
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                "configure-event",
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                G_CALLBACK(OnConfigureEvent), host_view);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return FALSE;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static gboolean OnConfigureEvent(GtkWidget* widget,
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   GdkEventConfigure* event,
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   RenderWidgetHostViewGtk* host_view) {
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_view->MarkCachedWidgetCenterStale();
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_view->UpdateScreenInfo(host_view->GetNativeView());
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return FALSE;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  static gboolean OnSizeAllocate(GtkWidget* widget,
2114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 GdkRectangle* allocation,
2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 RenderWidgetHostViewGtk* host_view) {
2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (!host_view->IsPopup() && !host_view->is_fullscreen_)
2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      host_view->SetSize(gfx::Size(allocation->width, allocation->height));
2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return FALSE;
2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static gboolean OnKeyPressReleaseEvent(GtkWidget* widget,
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         GdkEventKey* event,
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         RenderWidgetHostViewGtk* host_view) {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TRACE_EVENT0("browser",
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 "RenderWidgetHostViewGtkWidget::OnKeyPressReleaseEvent");
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Force popups or fullscreen windows to close on Escape so they won't keep
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the keyboard grabbed or be stuck onscreen if the renderer is hanging.
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool should_close_on_escape =
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (host_view->IsPopup() && host_view->NeedsInputGrab()) ||
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        host_view->is_fullscreen_;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (should_close_on_escape && GDK_Escape == event->keyval) {
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      host_view->host_->Shutdown();
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Send key event to input method.
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      host_view->im_context_->ProcessKeyEvent(event);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We return TRUE because we did handle the event. If it turns out webkit
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // can't handle the event, we'll deal with it in
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // RenderView::UnhandledKeyboardEvent().
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TRUE;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static gboolean OnFocusIn(GtkWidget* widget,
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            GdkEventFocus* focus,
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            RenderWidgetHostViewGtk* host_view) {
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_view->ShowCurrentCursor();
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderWidgetHostImpl* host =
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        RenderWidgetHostImpl::From(host_view->GetRenderWidgetHost());
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host->GotFocus();
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host->SetActive(true);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The only way to enable a GtkIMContext object is to call its focus in
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // handler.
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_view->im_context_->OnFocusIn();
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TRUE;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static gboolean OnFocusOut(GtkWidget* widget,
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             GdkEventFocus* focus,
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             RenderWidgetHostViewGtk* host_view) {
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Whenever we lose focus, set the cursor back to that of our parent window,
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // which should be the default arrow.
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gdk_window_set_cursor(gtk_widget_get_window(widget), NULL);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If we are showing a context menu, maintain the illusion that webkit has
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // focus.
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!host_view->IsShowingContextMenu()) {
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RenderWidgetHostImpl* host =
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          RenderWidgetHostImpl::From(host_view->GetRenderWidgetHost());
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      host->SetActive(false);
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      host->Blur();
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Prevents us from stealing input context focus in OnGrabNotify() handler.
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_view->was_imcontext_focused_before_grab_ = false;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Disable the GtkIMContext object.
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_view->im_context_->OnFocusOut();
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_view->set_last_mouse_down(NULL);
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TRUE;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when we are shadowed or unshadowed by a keyboard grab (which will
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // occur for activatable popups, such as dropdown menus). Popup windows do not
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // take focus, so we never get a focus out or focus in event when they are
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // shown, and must rely on this signal instead.
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void OnGrabNotify(GtkWidget* widget, gboolean was_grabbed,
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           RenderWidgetHostViewGtk* host_view) {
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (was_grabbed) {
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (host_view->was_imcontext_focused_before_grab_)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        host_view->im_context_->OnFocusIn();
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      host_view->was_imcontext_focused_before_grab_ =
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          host_view->im_context_->is_focused();
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (host_view->was_imcontext_focused_before_grab_) {
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        gdk_window_set_cursor(gtk_widget_get_window(widget), NULL);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        host_view->im_context_->OnFocusOut();
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static gboolean OnButtonPressReleaseEvent(
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GtkWidget* widget,
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GdkEventButton* event,
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RenderWidgetHostViewGtk* host_view) {
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TRACE_EVENT0("browser",
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 "RenderWidgetHostViewGtkWidget::OnButtonPressReleaseEvent");
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event->type != GDK_BUTTON_RELEASE)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      host_view->set_last_mouse_down(event);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!(event->button == 1 || event->button == 2 || event->button == 3))
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return FALSE;  // We do not forward any other buttons to the renderer.
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return FALSE;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If we don't have focus already, this mouse click will focus us.
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!gtk_widget_is_focus(widget))
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      host_view->host_->OnPointerEventActivate();
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Confirm existing composition text on mouse click events, to make sure
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the input caret won't be moved with an ongoing composition session.
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event->type != GDK_BUTTON_RELEASE)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      host_view->im_context_->ConfirmComposition();
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We want to translate the coordinates of events that do not originate
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // from this widget to be relative to the top left of the widget.
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GtkWidget* event_widget = gtk_get_event_widget(
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        reinterpret_cast<GdkEvent*>(event));
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event_widget != widget) {
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int x = 0;
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int y = 0;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gtk_widget_get_pointer(widget, &x, &y);
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // If the mouse event happens outside our popup, force the popup to
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // close.  We do this so a hung renderer doesn't prevent us from
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // releasing the x pointer grab.
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GtkAllocation allocation;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gtk_widget_get_allocation(widget, &allocation);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool click_in_popup = x >= 0 && y >= 0 && x < allocation.width &&
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          y < allocation.height;
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Only Shutdown on mouse downs. Mouse ups can occur outside the render
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // view if the user drags for DnD or while using the scrollbar on a select
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // dropdown. Don't shutdown if we are not a popup.
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (event->type != GDK_BUTTON_RELEASE && host_view->IsPopup() &&
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          !host_view->is_popup_first_mouse_release_ && !click_in_popup) {
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        host_view->host_->Shutdown();
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return FALSE;
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      event->x = x;
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      event->y = y;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(evanm): why is this necessary here but not in test shell?
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This logic is the same as GtkButton.
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event->type == GDK_BUTTON_PRESS && !gtk_widget_has_focus(widget))
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gtk_widget_grab_focus(widget);
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_view->is_popup_first_mouse_release_ = false;
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderWidgetHostImpl* widget_host =
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        RenderWidgetHostImpl::From(host_view->GetRenderWidgetHost());
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (widget_host)
362d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      widget_host->ForwardMouseEvent(WebMouseEventBuilder::Build(event));
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Although we did handle the mouse event, we need to let other handlers
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // run (in particular the one installed by WebContentsViewGtk).
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return FALSE;
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static gboolean OnMouseMoveEvent(GtkWidget* widget,
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   GdkEventMotion* event,
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   RenderWidgetHostViewGtk* host_view) {
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TRACE_EVENT0("browser",
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 "RenderWidgetHostViewGtkWidget::OnMouseMoveEvent");
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We want to translate the coordinates of events that do not originate
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // from this widget to be relative to the top left of the widget.
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GtkWidget* event_widget = gtk_get_event_widget(
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        reinterpret_cast<GdkEvent*>(event));
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event_widget != widget) {
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int x = 0;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int y = 0;
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gtk_widget_get_pointer(widget, &x, &y);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      event->x = x;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      event->y = y;
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_view->ModifyEventForEdgeDragging(widget, event);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    blink::WebMouseEvent mouse_event = WebMouseEventBuilder::Build(event);
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (host_view->mouse_locked_) {
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Point center = host_view->GetWidgetCenter();
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bool moved_to_center = MovedToPoint(mouse_event, center);
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (moved_to_center)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        host_view->mouse_has_been_warped_to_new_center_ = true;
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      host_view->ModifyEventMovementAndCoords(&mouse_event);
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!moved_to_center &&
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          (mouse_event.movementX || mouse_event.movementY)) {
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GdkDisplay* display = gtk_widget_get_display(widget);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GdkScreen* screen = gtk_widget_get_screen(widget);
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        gdk_display_warp_pointer(display, screen, center.x(), center.y());
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (host_view->mouse_has_been_warped_to_new_center_)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          RenderWidgetHostImpl::From(
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              host_view->GetRenderWidgetHost())->ForwardMouseEvent(mouse_event);
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {  // Mouse is not locked.
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      host_view->ModifyEventMovementAndCoords(&mouse_event);
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Do not send mouse events while the mouse cursor is being warped back
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // to the unlocked location.
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!host_view->mouse_is_being_warped_to_unlocked_position_) {
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        RenderWidgetHostImpl::From(
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            host_view->GetRenderWidgetHost())->ForwardMouseEvent(mouse_event);
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return FALSE;
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static gboolean OnCrossingEvent(GtkWidget* widget,
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  GdkEventCrossing* event,
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  RenderWidgetHostViewGtk* host_view) {
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TRACE_EVENT0("browser",
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 "RenderWidgetHostViewGtkWidget::OnCrossingEvent");
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int any_button_mask =
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GDK_BUTTON1_MASK |
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GDK_BUTTON2_MASK |
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GDK_BUTTON3_MASK |
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GDK_BUTTON4_MASK |
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GDK_BUTTON5_MASK;
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Only forward crossing events if the mouse button is not down.
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (When the mouse button is down, the proper events are already being
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // sent by ButtonPressReleaseEvent and MouseMoveEvent, above, and if we
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // additionally send this crossing event with the state indicating the
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // button is down, it causes problems with drag and drop in WebKit.)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!(event->state & any_button_mask)) {
438f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      blink::WebMouseEvent mouse_event = WebMouseEventBuilder::Build(event);
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      host_view->ModifyEventMovementAndCoords(&mouse_event);
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // When crossing out and back into a render view the movement values
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // must represent the instantaneous movement of the mouse, not the jump
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // from the exit to re-entry point.
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_event.movementX = 0;
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_event.movementY = 0;
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RenderWidgetHostImpl::From(
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          host_view->GetRenderWidgetHost())->ForwardMouseEvent(mouse_event);
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return FALSE;
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static gboolean OnClientEvent(GtkWidget* widget,
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                GdkEventClient* event,
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                RenderWidgetHostViewGtk* host_view) {
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VLOG(1) << "client event type: " << event->message_type
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            << " data_format: " << event->data_format
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            << " data: " << event->data.l;
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TRUE;
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return the net up / down (or left / right) distance represented by events
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in the  events will be removed from the queue. We only look at the top of
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // queue...any other type of event will cause us not to look farther.
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If there is a change to the set of modifier keys or scroll axis
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in the events we will stop looking as well.
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static int GetPendingScrollDelta(bool vert, guint current_event_state) {
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int num_clicks = 0;
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GdkEvent* event;
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool event_coalesced = true;
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while ((event = gdk_event_get()) && event_coalesced) {
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      event_coalesced = false;
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (event->type == GDK_SCROLL) {
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GdkEventScroll scroll = event->scroll;
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (scroll.state & GDK_SHIFT_MASK) {
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if (scroll.direction == GDK_SCROLL_UP)
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            scroll.direction = GDK_SCROLL_LEFT;
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          else if (scroll.direction == GDK_SCROLL_DOWN)
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            scroll.direction = GDK_SCROLL_RIGHT;
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (vert) {
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if (scroll.direction == GDK_SCROLL_UP ||
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              scroll.direction == GDK_SCROLL_DOWN) {
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (scroll.state == current_event_state) {
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              num_clicks += (scroll.direction == GDK_SCROLL_UP ? 1 : -1);
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              gdk_event_free(event);
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              event_coalesced = true;
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if (scroll.direction == GDK_SCROLL_LEFT ||
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              scroll.direction == GDK_SCROLL_RIGHT) {
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (scroll.state == current_event_state) {
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              num_clicks += (scroll.direction == GDK_SCROLL_LEFT ? 1 : -1);
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              gdk_event_free(event);
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              event_coalesced = true;
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If we have an event left we put it back on the queue.
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event) {
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gdk_event_put(event);
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gdk_event_free(event);
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
506d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return num_clicks * WebMouseWheelEventBuilder::ScrollbarPixelsPerTick();
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static gboolean OnMouseScrollEvent(GtkWidget* widget,
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     GdkEventScroll* event,
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     RenderWidgetHostViewGtk* host_view) {
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TRACE_EVENT0("browser",
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 "RenderWidgetHostViewGtkWidget::OnMouseScrollEvent");
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If the user is holding shift, translate it into a horizontal scroll. We
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // don't care what other modifiers the user may be holding (zooming is
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // handled at the WebContentsView level).
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event->state & GDK_SHIFT_MASK) {
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (event->direction == GDK_SCROLL_UP)
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        event->direction = GDK_SCROLL_LEFT;
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else if (event->direction == GDK_SCROLL_DOWN)
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        event->direction = GDK_SCROLL_RIGHT;
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
524d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    WebMouseWheelEvent web_event = WebMouseWheelEventBuilder::Build(event);
525d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const float pixelsPerTick =
526d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        WebMouseWheelEventBuilder::ScrollbarPixelsPerTick();
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We  peek ahead at the top of the queue to look for additional pending
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // scroll events.
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event->direction == GDK_SCROLL_UP ||
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        event->direction == GDK_SCROLL_DOWN) {
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (event->direction == GDK_SCROLL_UP)
532d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        web_event.deltaY = pixelsPerTick;
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else
534d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        web_event.deltaY = -pixelsPerTick;
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_event.deltaY += GetPendingScrollDelta(true, event->state);
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (event->direction == GDK_SCROLL_LEFT)
538d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        web_event.deltaX = pixelsPerTick;
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else
540d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        web_event.deltaX = -pixelsPerTick;
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_event.deltaX += GetPendingScrollDelta(false, event->state);
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderWidgetHostImpl::From(
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        host_view->GetRenderWidgetHost())->ForwardWheelEvent(web_event);
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return FALSE;
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_IMPLICIT_CONSTRUCTORS(RenderWidgetHostViewGtkWidget);
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RenderWidgetHostViewGtk::RenderWidgetHostViewGtk(RenderWidgetHost* widget_host)
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : host_(RenderWidgetHostImpl::From(widget_host)),
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      about_to_validate_and_paint_(false),
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_loading_(false),
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      parent_(NULL),
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_popup_first_mouse_release_(true),
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      was_imcontext_focused_before_grab_(false),
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      do_x_grab_(false),
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_fullscreen_(false),
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      made_active_(false),
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      mouse_is_being_warped_to_unlocked_position_(false),
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      destroy_handler_id_(0),
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dragged_at_horizontal_edge_(0),
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dragged_at_vertical_edge_(0),
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      compositing_surface_(gfx::kNullPluginWindow),
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_mouse_down_(NULL) {
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_->SetView(this);
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RenderWidgetHostViewGtk::~RenderWidgetHostViewGtk() {
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UnlockMouse();
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set_last_mouse_down(NULL);
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view_.Destroy();
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool RenderWidgetHostViewGtk::OnMessageReceived(const IPC::Message& message) {
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool handled = true;
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewGtk, message)
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ViewHostMsg_CreatePluginContainer,
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        OnCreatePluginContainer)
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ViewHostMsg_DestroyPluginContainer,
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        OnDestroyPluginContainer)
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  IPC_END_MESSAGE_MAP()
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return handled;
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::InitAsChild(
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::NativeView parent_view) {
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoSharedInit();
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_widget_show(view_.get());
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::InitAsPopup(
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) {
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we aren't a popup, then |window| will be leaked.
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsPopup());
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoSharedInit();
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent_ = parent_host_view->GetNativeView();
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GtkWindow* window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_POPUP));
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_container_add(GTK_CONTAINER(window), view_.get());
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoPopupOrFullscreenInit(window, pos);
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Grab all input for the app. If a click lands outside the bounds of the
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // popup, WebKit will notice and destroy us. The underlying X window needs to
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be created and mapped by the above code before we can grab the input
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // devices.
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (NeedsInputGrab()) {
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If our parent is in a widget hierarchy that ends with a window, add
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ourselves to the same window group to make sure that our GTK grab
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // covers it.
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GtkWidget* toplevel = gtk_widget_get_toplevel(parent_);
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (toplevel &&
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GTK_WIDGET_TOPLEVEL(toplevel) &&
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GTK_IS_WINDOW(toplevel)) {
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gtk_window_group_add_window(
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          gtk_window_get_group(GTK_WINDOW(toplevel)), window);
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Install an application-level GTK grab to make sure that we receive all of
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the app's input.
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gtk_grab_add(view_.get());
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We need to install an X grab as well. However if the app already has an X
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // grab (as in the case of extension popup), an app grab will suffice.
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    do_x_grab_ = !gdk_pointer_is_grabbed();
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (do_x_grab_) {
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Install the grab on behalf our parent window if it and all of its
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // ancestors are mapped; otherwise, just use ourselves (maybe we're being
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // shown on behalf of an inactive tab).
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GdkWindow* grab_window = gtk_widget_get_window(parent_);
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!grab_window || !gdk_window_is_viewable(grab_window))
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        grab_window = gtk_widget_get_window(view_.get());
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gdk_pointer_grab(
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          grab_window,
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          TRUE,  // Only events outside of the window are reported with
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 // respect to |parent_->window|.
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          static_cast<GdkEventMask>(GDK_BUTTON_PRESS_MASK |
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK),
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          NULL,
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          NULL,
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          GDK_CURRENT_TIME);
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We grab keyboard events too so things like alt+tab are eaten.
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gdk_keyboard_grab(grab_window, TRUE, GDK_CURRENT_TIME);
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::InitAsFullscreen(
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderWidgetHostView* reference_host_view) {
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(reference_host_view);
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoSharedInit();
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_fullscreen_ = true;
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GtkWindow* window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_window_set_decorated(window, FALSE);
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  destroy_handler_id_ = g_signal_connect(GTK_WIDGET(window),
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         "destroy",
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         G_CALLBACK(OnDestroyThunk),
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         this);
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_container_add(GTK_CONTAINER(window), view_.get());
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Try to move and resize the window to cover the screen in case the window
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // manager doesn't support _NET_WM_STATE_FULLSCREEN.
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkScreen* screen = gtk_window_get_screen(window);
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkWindow* ref_gdk_window = gtk_widget_get_window(
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reference_host_view->GetNativeView());
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect bounds;
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ref_gdk_window) {
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int monitor_id = gdk_screen_get_monitor_at_window(screen,
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                            ref_gdk_window);
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GdkRectangle monitor_rect;
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gdk_screen_get_monitor_geometry(screen, monitor_id, &monitor_rect);
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bounds = gfx::Rect(monitor_rect);
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bounds = gfx::Rect(
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        0, 0, gdk_screen_get_width(screen), gdk_screen_get_height(screen));
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_window_move(window, bounds.x(), bounds.y());
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_window_resize(window, bounds.width(), bounds.height());
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_window_fullscreen(window);
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoPopupOrFullscreenInit(window, bounds);
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RenderWidgetHost* RenderWidgetHostViewGtk::GetRenderWidgetHost() const {
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return host_;
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::WasShown() {
6938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!host_ || !host_->is_hidden())
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (web_contents_switch_paint_time_.is_null())
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_contents_switch_paint_time_ = base::TimeTicks::Now();
69868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_->WasShown();
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::WasHidden() {
7038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!host_ || host_->is_hidden())
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we have a renderer, then inform it that we are being hidden so it can
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // reduce its resource utilization.
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_->WasHidden();
709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  web_contents_switch_paint_time_ = base::TimeTicks();
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::SetSize(const gfx::Size& size) {
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int width = std::min(size.width(), kMaxWindowWidth);
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int height = std::min(size.height(), kMaxWindowHeight);
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsPopup()) {
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We're a popup, honor the size request.
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gtk_widget_set_size_request(view_.get(), width, height);
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Update the size of the RWH.
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (requested_size_.width() != width ||
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      requested_size_.height() != height) {
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    requested_size_ = gfx::Size(width, height);
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    host_->SendScreenRects();
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_->WasResized();
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::SetBounds(const gfx::Rect& rect) {
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is called when webkit has sent us a Move message.
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsPopup()) {
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gtk_window_move(GTK_WINDOW(gtk_widget_get_toplevel(view_.get())),
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    rect.x(), rect.y());
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetSize(rect.size());
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::NativeView RenderWidgetHostViewGtk::GetNativeView() const {
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return view_.get();
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::NativeViewId RenderWidgetHostViewGtk::GetNativeViewId() const {
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GtkNativeViewManager::GetInstance()->GetIdForWidget(view_.get());
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::NativeViewAccessible RenderWidgetHostViewGtk::GetNativeViewAccessible() {
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTIMPLEMENTED();
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::MovePluginWindows(
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Vector2d& scroll_offset,
755ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    const std::vector<WebPluginGeometry>& moves) {
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < moves.size(); ++i) {
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    plugin_container_manager_.MovePluginContainer(moves[i]);
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::Focus() {
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_widget_grab_focus(view_.get());
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::Blur() {
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(estade): We should be clearing native focus as well, but I know of no
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // way to do that without focusing another widget.
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_->Blur();
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RenderWidgetHostViewGtk::HasFocus() const {
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return gtk_widget_has_focus(view_.get());
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::ActiveWindowChanged(GdkWindow* window) {
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkWindow* our_window = gtk_widget_get_parent_window(view_.get());
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (our_window == window)
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    made_active_ = true;
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the window was previously active, but isn't active anymore, shut it
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // down.
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_fullscreen_ && our_window != window && made_active_)
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_->Shutdown();
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool RenderWidgetHostViewGtk::Send(IPC::Message* message) {
7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return host_->Send(message);
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RenderWidgetHostViewGtk::IsSurfaceAvailableForCopy() const {
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::Show() {
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_widget_show(view_.get());
79768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  WasShown();
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::Hide() {
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_widget_hide(view_.get());
80268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  WasHidden();
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RenderWidgetHostViewGtk::IsShowing() {
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gtk_widget_get_visible(view_.get());
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect RenderWidgetHostViewGtk::GetViewBounds() const {
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkWindow* gdk_window = gtk_widget_get_window(view_.get());
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!gdk_window)
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return gfx::Rect(requested_size_);
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkRectangle window_rect;
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gdk_window_get_origin(gdk_window, &window_rect.x, &window_rect.y);
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Rect(window_rect.x, window_rect.y,
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   requested_size_.width(), requested_size_.height());
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::UpdateCursor(const WebCursor& cursor) {
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Optimize the common case, where the cursor hasn't changed.
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // However, we can switch between different pixmaps, so only on the
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // non-pixmap branch.
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (current_cursor_.GetCursorType() != GDK_CURSOR_IS_PIXMAP &&
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      current_cursor_.GetCursorType() == cursor.GetCursorType()) {
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  current_cursor_ = cursor;
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShowCurrentCursor();
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::SetIsLoading(bool is_loading) {
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_loading_ = is_loading;
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Only call ShowCurrentCursor() when it will actually change the cursor.
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (current_cursor_.GetCursorType() == GDK_LAST_CURSOR)
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ShowCurrentCursor();
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid RenderWidgetHostViewGtk::TextInputTypeChanged(
8407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    ui::TextInputType type,
84158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ui::TextInputMode input_mode,
84258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool can_compose_inline) {
8437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  im_context_->UpdateInputMethodState(type, can_compose_inline);
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::ImeCancelComposition() {
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  im_context_->CancelComposition();
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::DidUpdateBackingStore(
8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Rect& scroll_rect,
8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Vector2d& scroll_delta,
853868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const std::vector<gfx::Rect>& copy_rects,
854868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const ui::LatencyInfo& latency_info) {
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT0("ui::gtk", "RenderWidgetHostViewGtk::DidUpdateBackingStore");
856868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  software_latency_info_.MergeWith(latency_info);
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (host_->is_hidden())
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(darin): Implement the equivalent of Win32's ScrollWindowEX.  Can that
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be done using XCopyArea?  Perhaps similar to
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // BackingStore::ScrollBackingStore?
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (about_to_validate_and_paint_)
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    invalid_rect_.Union(scroll_rect);
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Paint(scroll_rect);
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < copy_rects.size(); ++i) {
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Avoid double painting.  NOTE: This is only relevant given the call to
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Paint(scroll_rect) above.
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Rect rect = gfx::SubtractRects(copy_rects[i], scroll_rect);
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rect.IsEmpty())
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (about_to_validate_and_paint_)
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      invalid_rect_.Union(rect);
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Paint(rect);
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid RenderWidgetHostViewGtk::RenderProcessGone(base::TerminationStatus status,
8847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                                int error_code) {
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Destroy();
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  plugin_container_manager_.set_host_widget(NULL);
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::Destroy() {
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (compositing_surface_ != gfx::kNullPluginWindow) {
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance();
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    manager->ReleasePermanentXID(compositing_surface_);
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (do_x_grab_) {
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Undo the X grab.
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GdkDisplay* display = gtk_widget_get_display(parent_);
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gdk_display_pointer_ungrab(display, GDK_CURRENT_TIME);
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gdk_display_keyboard_ungrab(display, GDK_CURRENT_TIME);
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (view_.get()) {
9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If this is a popup or fullscreen widget, then we need to destroy the
9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // window that we created to hold it.
9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsPopup() || is_fullscreen_) {
9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GtkWidget* window = gtk_widget_get_parent(view_.get());
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui::ActiveWindowWatcherX::RemoveObserver(this);
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Disconnect the destroy handler so that we don't try to shutdown twice.
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (is_fullscreen_)
9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        g_signal_handler_disconnect(window, destroy_handler_id_);
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gtk_widget_destroy(window);
9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Remove |view_| from all containers now, so nothing else can hold a
9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // reference to |view_|'s widget except possibly a gtk signal handler if
9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // this code is currently executing within the context of a gtk signal
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // handler.  Note that |view_| is still alive after this call.  It will be
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // deallocated in the destructor.
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // See http://crbug.com/11847 for details.
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gtk_widget_destroy(view_.get());
9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The RenderWidgetHost's destruction led here, so don't call it.
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_ = NULL;
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
932a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void RenderWidgetHostViewGtk::SetTooltipText(
933a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& tooltip_text) {
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Maximum number of characters we allow in a tooltip.
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kMaxTooltipLength = 8 << 10;
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clamp the tooltip length to kMaxTooltipLength so that we don't
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // accidentally DOS the user with a mega tooltip (since GTK doesn't do
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this itself).
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // I filed https://bugzilla.gnome.org/show_bug.cgi?id=604641 upstream.
940a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const base::string16 clamped_tooltip =
94158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      gfx::TruncateString(tooltip_text, kMaxTooltipLength);
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (clamped_tooltip.empty()) {
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gtk_widget_set_has_tooltip(view_.get(), FALSE);
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gtk_widget_set_tooltip_text(view_.get(),
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                UTF16ToUTF8(clamped_tooltip).c_str());
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
951a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void RenderWidgetHostViewGtk::SelectionChanged(const base::string16& text,
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               size_t offset,
95358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                               const gfx::Range& range) {
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (text.empty() || range.is_empty())
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = range.GetMin() - offset;
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t n = range.length();
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(pos + n <= text.length()) << "The text can not fully cover range.";
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (pos >= text.length()) {
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "The text can not cover range.";
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Set the CLIPBOARD_TYPE SELECTION to the ui::Clipboard.
9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::ScopedClipboardWriter clipboard_writer(
9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui::Clipboard::GetForCurrentThread(),
9704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::CLIPBOARD_TYPE_SELECTION);
9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  clipboard_writer.WriteText(text.substr(pos, n));
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::SelectionBoundsChanged(
9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ViewHostMsg_SelectionBounds_Params& params) {
9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  im_context_->UpdateCaretBounds(
9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::UnionRects(params.anchor_rect, params.focus_rect));
9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RenderWidgetHostViewGtk::ScrollOffsetChanged() {
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GdkEventButton* RenderWidgetHostViewGtk::GetLastMouseDown() {
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return last_mouse_down_;
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::NativeView RenderWidgetHostViewGtk::BuildInputMethodsGtkMenu() {
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return im_context_->BuildInputMethodsGtkMenu();
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::OnDestroy(GtkWidget* widget) {
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(is_fullscreen_);
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_->Shutdown();
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RenderWidgetHostViewGtk::NeedsInputGrab() {
997f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return popup_type_ == blink::WebPopupTypeSelect;
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RenderWidgetHostViewGtk::IsPopup() const {
1001f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return popup_type_ != blink::WebPopupTypeNone;
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::DoSharedInit() {
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view_.Own(RenderWidgetHostViewGtkWidget::CreateNewWidget(this));
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  im_context_.reset(new GtkIMContextWrapper(this));
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  plugin_container_manager_.set_host_widget(view_.get());
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  key_bindings_handler_.reset(new GtkKeyBindingsHandler(view_.get()));
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::DoPopupOrFullscreenInit(GtkWindow* window,
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                      const gfx::Rect& bounds) {
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requested_size_.SetSize(std::min(bounds.width(), kMaxWindowWidth),
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          std::min(bounds.height(), kMaxWindowHeight));
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_->WasResized();
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::ActiveWindowWatcherX::AddObserver(this);
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Don't set the size when we're going fullscreen. This can confuse the
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // window manager into thinking we're resizing a fullscreen window and
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // therefore not fullscreen anymore.
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_fullscreen_) {
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gtk_widget_set_size_request(
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        view_.get(), requested_size_.width(), requested_size_.height());
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Don't allow the window to be resized. This also forces the window to
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // shrink down to the size of its child contents.
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gtk_window_set_resizable(window, FALSE);
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gtk_window_set_default_size(window, -1, -1);
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gtk_window_move(window, bounds.x(), bounds.y());
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_widget_show_all(GTK_WIDGET(window));
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BackingStore* RenderWidgetHostViewGtk::AllocBackingStore(
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Size& size) {
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gint depth = gdk_visual_get_depth(gtk_widget_get_visual(view_.get()));
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new BackingStoreGtk(host_, size,
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             ui::GetVisualFromGtkWidget(view_.get()),
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             depth);
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NOTE: |output| is initialized with the size of |src_subrect|, and |dst_size|
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is ignored on GTK.
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::CopyFromCompositingSurface(
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& src_subrect,
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Size& /* dst_size */,
10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Callback<void(bool, const SkBitmap&)>& callback) {
10502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Grab the snapshot from the renderer as that's the only reliable way to
10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // readback from the GPU for this platform right now.
10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetRenderWidgetHost()->GetSnapshotFromRenderer(src_subrect, callback);
10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RenderWidgetHostViewGtk::CopyFromCompositingSurfaceToVideoFrame(
10562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const gfx::Rect& src_subrect,
10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const scoped_refptr<media::VideoFrame>& target,
10582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const base::Callback<void(bool)>& callback) {
10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NOTIMPLEMENTED();
10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(false);
10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool RenderWidgetHostViewGtk::CanCopyToVideoFrame() const {
10642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1067f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void RenderWidgetHostViewGtk::AcceleratedSurfaceInitialized(int host_id,
1068f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                            int route_id) {
1069f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1070f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::AcceleratedSurfaceBuffersSwapped(
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int gpu_host_id) {
1074b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
1075b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ack_params.sync_point = 0;
1076b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  RenderWidgetHostImpl::AcknowledgeBufferPresent(
10772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      params.route_id, gpu_host_id, ack_params);
10784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RenderWidgetHostImpl::CompositorFrameDrawn(params.latency_info);
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::AcceleratedSurfacePostSubBuffer(
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int gpu_host_id) {
1084b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
1085b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ack_params.sync_point = 0;
1086b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  RenderWidgetHostImpl::AcknowledgeBufferPresent(
10872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      params.route_id, gpu_host_id, ack_params);
10884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RenderWidgetHostImpl::CompositorFrameDrawn(params.latency_info);
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::AcceleratedSurfaceSuspend() {
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RenderWidgetHostViewGtk::AcceleratedSurfaceRelease() {
10952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RenderWidgetHostViewGtk::HasAcceleratedSurface(
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const gfx::Size& desired_size) {
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(jbates) Implement this so this view can use GetBackingStore for both
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // software and GPU frames. Defaulting to false just makes GetBackingStore
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // only useable for software frames.
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::SetBackground(const SkBitmap& background) {
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderWidgetHostViewBase::SetBackground(background);
11072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Send(new ViewMsg_SetBackground(host_->GetRoutingID(), background));
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::ModifyEventForEdgeDragging(
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GtkWidget* widget, GdkEventMotion* event) {
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the widget is aligned with an edge of the monitor its on and the user
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // attempts to drag past that edge we track the number of times it has
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // occurred, so that we can force the widget to scroll when it otherwise
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // would be unable to, by modifying the (x,y) position in the drag
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // event that we forward on to webkit. If we get a move that's no longer a
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // drag or a drag indicating the user is no longer at that edge we stop
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // altering the drag events.
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int new_dragged_at_horizontal_edge = 0;
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int new_dragged_at_vertical_edge = 0;
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used for checking the edges of the monitor. We cache the values to save
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // roundtrips to the X server.
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CR_DEFINE_STATIC_LOCAL(gfx::Size, drag_monitor_size, ());
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (event->state & GDK_BUTTON1_MASK) {
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (drag_monitor_size.IsEmpty()) {
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We can safely cache the monitor size for the duration of a drag.
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GdkScreen* screen = gtk_widget_get_screen(widget);
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int monitor =
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          gdk_screen_get_monitor_at_point(screen, event->x_root, event->y_root);
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GdkRectangle geometry;
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gdk_screen_get_monitor_geometry(screen, monitor, &geometry);
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      drag_monitor_size.SetSize(geometry.width, geometry.height);
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GtkAllocation allocation;
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gtk_widget_get_allocation(widget, &allocation);
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Check X and Y independently, as the user could be dragging into a corner.
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event->x == 0 && event->x_root == 0) {
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_dragged_at_horizontal_edge = dragged_at_horizontal_edge_ - 1;
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (allocation.width - 1 == static_cast<gint>(event->x) &&
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        drag_monitor_size.width() - 1 == static_cast<gint>(event->x_root)) {
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_dragged_at_horizontal_edge = dragged_at_horizontal_edge_ + 1;
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event->y == 0 && event->y_root == 0) {
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_dragged_at_vertical_edge = dragged_at_vertical_edge_ - 1;
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (allocation.height - 1 == static_cast<gint>(event->y) &&
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        drag_monitor_size.height() - 1 == static_cast<gint>(event->y_root)) {
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_dragged_at_vertical_edge = dragged_at_vertical_edge_ + 1;
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    event->x_root += new_dragged_at_horizontal_edge;
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    event->x += new_dragged_at_horizontal_edge;
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    event->y_root += new_dragged_at_vertical_edge;
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    event->y += new_dragged_at_vertical_edge;
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Clear whenever we get a non-drag mouse move.
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    drag_monitor_size.SetSize(0, 0);
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dragged_at_horizontal_edge_ = new_dragged_at_horizontal_edge;
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dragged_at_vertical_edge_ = new_dragged_at_vertical_edge;
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::Paint(const gfx::Rect& damage_rect) {
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT0("ui::gtk", "RenderWidgetHostViewGtk::Paint");
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the GPU process is rendering directly into the View,
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // call the compositor directly.
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderWidgetHostImpl* render_widget_host =
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RenderWidgetHostImpl::From(GetRenderWidgetHost());
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (render_widget_host->is_accelerated_compositing_active()) {
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_->ScheduleComposite();
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkWindow* window = gtk_widget_get_window(view_.get());
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!about_to_validate_and_paint_);
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  invalid_rect_ = damage_rect;
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  about_to_validate_and_paint_ = true;
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the size of our canvas is (0,0), then we don't want to block here. We
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are doing one of our first paints and probably have animations going on.
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool force_create = !host_->empty();
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BackingStoreGtk* backing_store = static_cast<BackingStoreGtk*>(
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      host_->GetBackingStore(force_create));
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calling GetBackingStore maybe have changed |invalid_rect_|...
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  about_to_validate_and_paint_ = false;
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect paint_rect = gfx::Rect(0, 0, kMaxWindowWidth, kMaxWindowHeight);
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint_rect.Intersect(invalid_rect_);
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (backing_store) {
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Only render the widget if it is attached to a window; there's a short
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // period where this object isn't attached to a window but hasn't been
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Destroy()ed yet and it receives paint messages...
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (window) {
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      backing_store->XShowRect(gfx::Point(0, 0),
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          paint_rect, ui::GetX11WindowFromGtkWidget(view_.get()));
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!whiteout_start_time_.is_null()) {
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta whiteout_duration = base::TimeTicks::Now() -
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          whiteout_start_time_;
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UMA_HISTOGRAM_TIMES("MPArch.RWHH_WhiteoutDuration", whiteout_duration);
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Reset the start time to 0 so that we start recording again the next
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // time the backing store is NULL...
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      whiteout_start_time_ = base::TimeTicks();
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!web_contents_switch_paint_time_.is_null()) {
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta web_contents_switch_paint_duration =
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::TimeTicks::Now() - web_contents_switch_paint_time_;
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UMA_HISTOGRAM_TIMES("MPArch.RWH_TabSwitchPaintDuration",
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          web_contents_switch_paint_duration);
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Reset web_contents_switch_paint_time_ to 0 so future tab selections are
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // recorded.
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_contents_switch_paint_time_ = base::TimeTicks();
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    software_latency_info_.AddLatencyNumber(
12194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, 0);
1220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    render_widget_host->FrameSwapped(software_latency_info_);
1221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    software_latency_info_.Clear();
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (window)
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gdk_window_clear(window);
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (whiteout_start_time_.is_null())
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      whiteout_start_time_ = base::TimeTicks::Now();
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::ShowCurrentCursor() {
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The widget may not have a window. If that's the case, abort mission. This
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is the same issue as that explained above in Paint().
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!gtk_widget_get_window(view_.get()))
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(port): WebKit bug https://bugs.webkit.org/show_bug.cgi?id=16388 is
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that calling gdk_window_set_cursor repeatedly is expensive.  We should
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // avoid it here where possible.
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkCursor* gdk_cursor;
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (current_cursor_.GetCursorType() == GDK_LAST_CURSOR) {
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Use MOZ_CURSOR_SPINNING if we are showing the default cursor and
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the page is loading.
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gdk_cursor = is_loading_ ? GetMozSpinningCursor() : NULL;
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gdk_cursor = current_cursor_.GetNativeCursor();
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gdk_window_set_cursor(gtk_widget_get_window(view_.get()), gdk_cursor);
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::SetHasHorizontalScrollbar(
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool has_horizontal_scrollbar) {
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::SetScrollOffsetPinning(
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_pinned_to_left, bool is_pinned_to_right) {
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::OnAcceleratedCompositingStateChange() {
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool activated = host_->is_accelerated_compositing_active();
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GtkPreserveWindow* widget = reinterpret_cast<GtkPreserveWindow*>(view_.get());
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_preserve_window_delegate_resize(widget, activated);
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::GetScreenInfo(WebScreenInfo* results) {
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkWindow* gdk_window = gtk_widget_get_window(view_.get());
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!gdk_window) {
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GdkDisplay* display = gdk_display_get_default();
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gdk_window = gdk_display_get_default_group(display);
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!gdk_window)
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetScreenInfoFromNativeWindow(gdk_window, results);
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect RenderWidgetHostViewGtk::GetBoundsInRootWindow() {
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GtkWidget* toplevel = gtk_widget_get_toplevel(view_.get());
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!toplevel)
12802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return GetViewBounds();
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkRectangle frame_extents;
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkWindow* gdk_window = gtk_widget_get_window(toplevel);
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!gdk_window)
12852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return GetViewBounds();
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gdk_window_get_frame_extents(gdk_window, &frame_extents);
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Rect(frame_extents.x, frame_extents.y,
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   frame_extents.width, frame_extents.height);
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::GLSurfaceHandle RenderWidgetHostViewGtk::GetCompositingSurface() {
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (compositing_surface_ == gfx::kNullPluginWindow) {
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance();
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::NativeViewId view_id = GetNativeViewId();
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!manager->GetPermanentXIDForId(&compositing_surface_, view_id)) {
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DLOG(ERROR) << "Can't find XID for view id " << view_id;
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return gfx::GLSurfaceHandle(compositing_surface_, gfx::NATIVE_TRANSPORT);
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void RenderWidgetHostViewGtk::ResizeCompositingSurface(const gfx::Size& size) {
13054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GtkWidget* widget = view_.get();
13064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GdkWindow* window = gtk_widget_get_window(widget);
13074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (window) {
13084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    Display* display = GDK_WINDOW_XDISPLAY(window);
13094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    gdk_window_resize(window, size.width(), size.height());
13104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    XSync(display, False);
13114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
13124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
13134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RenderWidgetHostViewGtk::LockMouse() {
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouse_locked_)
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_locked_ = true;
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Release any current grab.
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GtkWidget* current_grab_window = gtk_grab_get_current();
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (current_grab_window) {
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gtk_grab_remove(current_grab_window);
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(WARNING) << "Locking Mouse with gdk_pointer_grab, "
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << "but had to steal grab from another window";
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GtkWidget* widget = view_.get();
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkWindow* window = gtk_widget_get_window(widget);
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkCursor* cursor = gdk_cursor_new(GDK_BLANK_CURSOR);
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkGrabStatus grab_status =
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gdk_pointer_grab(window,
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FALSE,  // owner_events
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       static_cast<GdkEventMask>(
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           GDK_POINTER_MOTION_MASK |
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           GDK_BUTTON_PRESS_MASK |
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           GDK_BUTTON_RELEASE_MASK),
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       window,  // confine_to
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       cursor,
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       GDK_CURRENT_TIME);
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (grab_status != GDK_GRAB_SUCCESS) {
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(WARNING) << "Failed to grab pointer for LockMouse. "
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << "gdk_pointer_grab returned: " << grab_status;
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mouse_locked_ = false;
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear the tooltip window.
1351a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SetTooltipText(base::string16());
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that the widget center location will be relevant for this mouse
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // lock session. It is updated whenever the window geometry moves
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // but may be out of date due to switching tabs.
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MarkCachedWidgetCenterStale();
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1358a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Ensure that if we were previously warping the cursor to a specific point
1359a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // that we no longer track doing so when entering lock. It should be cleared
1360a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // by the cursor moving to the warp point, and this shouldn't be necessary.
1361a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // But, this is a small effort to ensure robustness in the event a warp isn't
1362a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // completed.
1363a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  mouse_is_being_warped_to_unlocked_position_ = false;
1364a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::UnlockMouse() {
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!mouse_locked_)
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_locked_ = false;
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GtkWidget* widget = view_.get();
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkDisplay* display = gtk_widget_get_display(widget);
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkScreen* screen = gtk_widget_get_screen(widget);
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gdk_display_pointer_ungrab(display, GDK_CURRENT_TIME);
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gdk_display_warp_pointer(display, screen,
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           unlocked_global_mouse_position_.x(),
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           unlocked_global_mouse_position_.y());
13812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mouse_is_being_warped_to_unlocked_position_ = true;
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (host_)
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_->LostMouseLock();
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::ForwardKeyboardEvent(
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const NativeWebKeyboardEvent& event) {
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!host_)
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EditCommands edit_commands;
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!event.skip_in_browser &&
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      key_bindings_handler_->Match(event, &edit_commands)) {
1395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Send(new InputMsg_SetEditCommandsForNextKeyEvent(
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        host_->GetRoutingID(), edit_commands));
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NativeWebKeyboardEvent copy_event(event);
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    copy_event.match_edit_command = true;
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_->ForwardKeyboardEvent(copy_event);
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_->ForwardKeyboardEvent(event);
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RenderWidgetHostViewGtk::RetrieveSurrounding(std::string* text,
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  size_t* cursor_index) {
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!selection_range_.IsValid())
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t offset = selection_range_.GetMin() - selection_text_offset_;
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(offset <= selection_text_.length());
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (offset == selection_text_.length()) {
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *text = UTF16ToUTF8(selection_text_);
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *cursor_index = text->length();
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *text = base::UTF16ToUTF8AndAdjustOffset(
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::StringPiece16(selection_text_), &offset);
1422a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (offset == base::string16::npos) {
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "Invalid offset in UTF16 string.";
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *cursor_index = offset;
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::set_last_mouse_down(GdkEventButton* event) {
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkEventButton* temp = NULL;
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (event) {
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    temp = reinterpret_cast<GdkEventButton*>(
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        gdk_event_copy(reinterpret_cast<GdkEvent*>(event)));
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (last_mouse_down_)
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gdk_event_free(reinterpret_cast<GdkEvent*>(last_mouse_down_));
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_mouse_down_ = temp;
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::MarkCachedWidgetCenterStale() {
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget_center_valid_ = false;
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_has_been_warped_to_new_center_ = false;
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Point RenderWidgetHostViewGtk::GetWidgetCenter() {
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (widget_center_valid_)
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return widget_center_;
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkWindow* window = gtk_widget_get_window(view_.get());
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gint window_x = 0;
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gint window_y = 0;
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gdk_window_get_origin(window, &window_x, &window_y);
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gint window_w = gdk_window_get_width(window);
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gint window_h = gdk_window_get_height(window);
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget_center_.SetPoint(window_x + window_w / 2,
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          window_y + window_h / 2);
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget_center_valid_ = true;
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return widget_center_;
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::ModifyEventMovementAndCoords(
1465f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    blink::WebMouseEvent* event) {
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Movement is computed by taking the difference of the new cursor position
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and the previous. Under mouse lock the cursor will be warped back to the
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // center so that we are not limited by clipping boundaries.
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We do not measure movement as the delta from cursor to center because
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we may receive more mouse movement events before our warp has taken
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // effect.
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event->movementX = event->globalX - global_mouse_position_.x();
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event->movementY = event->globalY - global_mouse_position_.y();
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // While the cursor is being warped back to the unlocked position, suppress
14762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the movement member data.
14772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (mouse_is_being_warped_to_unlocked_position_) {
14782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event->movementX = 0;
14792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event->movementY = 0;
14802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (MovedToPoint(*event, unlocked_global_mouse_position_))
14812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      mouse_is_being_warped_to_unlocked_position_ = false;
14822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  global_mouse_position_.SetPoint(event->globalX, event->globalY);
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Under mouse lock, coordinates of mouse are locked to what they were when
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // mouse lock was entered.
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouse_locked_) {
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    event->x = unlocked_mouse_position_.x();
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    event->y = unlocked_mouse_position_.y();
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    event->windowX = unlocked_mouse_position_.x();
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    event->windowY = unlocked_mouse_position_.y();
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    event->globalX = unlocked_global_mouse_position_.x();
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    event->globalY = unlocked_global_mouse_position_.y();
1495a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  } else if (!mouse_is_being_warped_to_unlocked_position_) {
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unlocked_mouse_position_.SetPoint(event->windowX, event->windowY);
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unlocked_global_mouse_position_.SetPoint(event->globalX, event->globalY);
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RenderWidgetHostView, public:
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget(
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderWidgetHost* widget) {
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new RenderWidgetHostViewGtk(widget);
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewPort::GetDefaultScreenInfo(WebScreenInfo* results) {
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkWindow* gdk_window =
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gdk_display_get_default_group(gdk_display_get_default());
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetScreenInfoFromNativeWindow(gdk_window, results);
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::SetAccessibilityFocus(int acc_obj_id) {
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!host_)
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_->AccessibilitySetFocus(acc_obj_id);
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::AccessibilityDoDefaultAction(int acc_obj_id) {
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!host_)
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_->AccessibilityDoDefaultAction(acc_obj_id);
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::AccessibilityScrollToMakeVisible(
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int acc_obj_id, gfx::Rect subfocus) {
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!host_)
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_->AccessibilityScrollToMakeVisible(acc_obj_id, subfocus);
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::AccessibilityScrollToPoint(
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int acc_obj_id, gfx::Point point) {
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!host_)
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_->AccessibilityScrollToPoint(acc_obj_id, point);
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderWidgetHostViewGtk::AccessibilitySetTextSelection(
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int acc_obj_id, int start_offset, int end_offset) {
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!host_)
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_->AccessibilitySetTextSelection(acc_obj_id, start_offset, end_offset);
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Point RenderWidgetHostViewGtk::GetLastTouchEventLocation() const {
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Not needed on Linux.
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Point();
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RenderWidgetHostViewGtk::FatalAccessibilityTreeError() {
15612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (host_) {
15622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    host_->FatalAccessibilityTreeError();
15632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetBrowserAccessibilityManager(NULL);
15642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
15652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CHECK(FALSE);
15662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
15672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
156958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void RenderWidgetHostViewGtk::OnAccessibilityEvents(
157058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::vector<AccessibilityHostMsg_EventParams>& params) {
1571ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!GetBrowserAccessibilityManager()) {
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GtkWidget* parent = gtk_widget_get_parent(view_.get());
1573ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    SetBrowserAccessibilityManager(
15742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new BrowserAccessibilityManagerGtk(
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            parent,
15762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            BrowserAccessibilityManagerGtk::GetEmptyDocument(),
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            this));
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
157958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  GetBrowserAccessibilityManager()->OnAccessibilityEvents(params);
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AtkObject* RenderWidgetHostViewGtk::GetAccessible() {
1583ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!GetBrowserAccessibilityManager()) {
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GtkWidget* parent = gtk_widget_get_parent(view_.get());
1585ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    SetBrowserAccessibilityManager(
15862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new BrowserAccessibilityManagerGtk(
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            parent,
15882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            BrowserAccessibilityManagerGtk::GetEmptyDocument(),
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            this));
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserAccessibilityGtk* root =
1592ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      GetBrowserAccessibilityManager()->GetRoot()->ToBrowserAccessibilityGtk();
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  atk_object_set_role(root->GetAtkObject(), ATK_ROLE_HTML_CONTAINER);
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return root->GetAtkObject();
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RenderWidgetHostViewGtk::OnCreatePluginContainer(
15992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::PluginWindowHandle id) {
16002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  plugin_container_manager_.CreatePluginContainer(id);
16012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
16022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RenderWidgetHostViewGtk::OnDestroyPluginContainer(
16042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::PluginWindowHandle id) {
16052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  plugin_container_manager_.DestroyPluginContainer(id);
16062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
16072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
1609