| Index: ui/ui_controls/ui_controls_gtk.cc | 
| diff --git a/ui/ui_controls/ui_controls_gtk.cc b/ui/ui_controls/ui_controls_gtk.cc | 
| index c0e22df30d5687f32d68df7a5cf6bf1a92ac7561..9fd3359c6f58f9d12b1ff6aee5addc4b8390586e 100644 | 
| --- a/ui/ui_controls/ui_controls_gtk.cc | 
| +++ b/ui/ui_controls/ui_controls_gtk.cc | 
| @@ -94,156 +94,175 @@ void FakeAMouseMotionEvent(gint x, gint y) { | 
|  | 
| namespace ui_controls { | 
|  | 
| -bool SendKeyPress(gfx::NativeWindow window, | 
| -                  ui::KeyboardCode key, | 
| -                  bool control, | 
| -                  bool shift, | 
| -                  bool alt, | 
| -                  bool command) { | 
| -  DCHECK(!command);  // No command key on Linux | 
| -  GdkWindow* event_window = NULL; | 
| -  GtkWidget* grab_widget = gtk_grab_get_current(); | 
| -  if (grab_widget) { | 
| -    // If there is a grab, send all events to the grabbed widget. | 
| -    event_window = gtk_widget_get_window(grab_widget); | 
| -  } else if (window) { | 
| -    event_window = gtk_widget_get_window(GTK_WIDGET(window)); | 
| -  } else { | 
| -    // No target was specified. Send the events to the active toplevel. | 
| -    GList* windows = gtk_window_list_toplevels(); | 
| -    for (GList* element = windows; element; element = g_list_next(element)) { | 
| -      GtkWindow* this_window = GTK_WINDOW(element->data); | 
| -      if (gtk_window_is_active(this_window)) { | 
| -        event_window = gtk_widget_get_window(GTK_WIDGET(this_window)); | 
| -        break; | 
| +namespace { | 
| + | 
| +class UIControlsGtk : public UIControls { | 
| + public: | 
| +  UIControlsGtk() {} | 
| +  virtual ~UIControlsGtk() {} | 
| + | 
| +  bool SendKeyPress(gfx::NativeWindow window, | 
| +                    ui::KeyboardCode key, | 
| +                    bool control, | 
| +                    bool shift, | 
| +                    bool alt, | 
| +                    bool command) OVERRIDE { | 
| +    DCHECK(!command);  // No command key on Linux | 
| +    GdkWindow* event_window = NULL; | 
| +    GtkWidget* grab_widget = gtk_grab_get_current(); | 
| +    if (grab_widget) { | 
| +      // If there is a grab, send all events to the grabbed widget. | 
| +      event_window = gtk_widget_get_window(grab_widget); | 
| +    } else if (window) { | 
| +      event_window = gtk_widget_get_window(GTK_WIDGET(window)); | 
| +    } else { | 
| +      // No target was specified. Send the events to the active toplevel. | 
| +      GList* windows = gtk_window_list_toplevels(); | 
| +      for (GList* element = windows; element; element = g_list_next(element)) { | 
| +        GtkWindow* this_window = GTK_WINDOW(element->data); | 
| +        if (gtk_window_is_active(this_window)) { | 
| +          event_window = gtk_widget_get_window(GTK_WIDGET(this_window)); | 
| +          break; | 
| +        } | 
| } | 
| +      g_list_free(windows); | 
| +    } | 
| +    if (!event_window) { | 
| +      NOTREACHED() << "Window not specified and none is active"; | 
| +      return false; | 
| } | 
| -    g_list_free(windows); | 
| -  } | 
| -  if (!event_window) { | 
| -    NOTREACHED() << "Window not specified and none is active"; | 
| -    return false; | 
| -  } | 
|  | 
| -  std::vector<GdkEvent*> events; | 
| -  ui::SynthesizeKeyPressEvents(event_window, key, control, shift, alt, &events); | 
| -  for (std::vector<GdkEvent*>::iterator iter = events.begin(); | 
| -       iter != events.end(); ++iter) { | 
| -    gdk_event_put(*iter); | 
| -    // gdk_event_put appends a copy of the event. | 
| -    gdk_event_free(*iter); | 
| -  } | 
| +    std::vector<GdkEvent*> events; | 
| +    ui::SynthesizeKeyPressEvents( | 
| +        event_window, key, control, shift, alt, &events); | 
| +    for (std::vector<GdkEvent*>::iterator iter = events.begin(); | 
| +        iter != events.end(); ++iter) { | 
| +      gdk_event_put(*iter); | 
| +      // gdk_event_put appends a copy of the event. | 
| +      gdk_event_free(*iter); | 
| +    } | 
|  | 
| -  return true; | 
| -} | 
| +    return true; | 
| +  } | 
|  | 
| -bool SendKeyPressNotifyWhenDone(gfx::NativeWindow window, | 
| -                                ui::KeyboardCode key, | 
| -                                bool control, | 
| -                                bool shift, | 
| -                                bool alt, | 
| -                                bool command, | 
| -                                const base::Closure& task) { | 
| -  DCHECK(!command);  // No command key on Linux | 
| -  int release_count = 1; | 
| -  if (control) | 
| -    release_count++; | 
| -  if (shift) | 
| -    release_count++; | 
| -  if (alt) | 
| -    release_count++; | 
| -  // This object will delete itself after running |task|. | 
| -  new EventWaiter(task, GDK_KEY_RELEASE, release_count); | 
| -  return SendKeyPress(window, key, control, shift, alt, command); | 
| -} | 
| +  bool SendKeyPressNotifyWhenDone(gfx::NativeWindow window, | 
| +                                  ui::KeyboardCode key, | 
| +                                  bool control, | 
| +                                  bool shift, | 
| +                                  bool alt, | 
| +                                  bool command, | 
| +                                  const base::Closure& task) OVERRIDE { | 
| +    DCHECK(!command);  // No command key on Linux | 
| +    int release_count = 1; | 
| +    if (control) | 
| +      release_count++; | 
| +    if (shift) | 
| +      release_count++; | 
| +    if (alt) | 
| +      release_count++; | 
| +    // This object will delete itself after running |task|. | 
| +    new EventWaiter(task, GDK_KEY_RELEASE, release_count); | 
| +    return SendKeyPress(window, key, control, shift, alt, command); | 
| +  } | 
|  | 
| -bool SendMouseMove(long x, long y) { | 
| -  gdk_display_warp_pointer(gdk_display_get_default(), gdk_screen_get_default(), | 
| -                           x, y); | 
| -  // Sometimes gdk_display_warp_pointer fails to send back any indication of | 
| -  // the move, even though it succesfully moves the server cursor. We fake it in | 
| -  // order to get drags to work. | 
| -  FakeAMouseMotionEvent(x, y); | 
| -  return true; | 
| -} | 
| +  bool SendMouseMove(long x, long y) OVERRIDE { | 
| +    gdk_display_warp_pointer( | 
| +        gdk_display_get_default(), gdk_screen_get_default(), x, y); | 
| +    // Sometimes gdk_display_warp_pointer fails to send back any indication of | 
| +    // the move, even though it succesfully moves the server cursor. We fake | 
| +    // it in order to get drags to work. | 
| +    FakeAMouseMotionEvent(x, y); | 
| +    return true; | 
| +  } | 
|  | 
| -bool SendMouseMoveNotifyWhenDone(long x, long y, const base::Closure& task) { | 
| -  bool rv = SendMouseMove(x, y); | 
| -  new EventWaiter(task, GDK_MOTION_NOTIFY, 1); | 
| -  return rv; | 
| -} | 
| +  bool SendMouseMoveNotifyWhenDone( | 
| +      long x, long y, const base::Closure& task) OVERRIDE { | 
| +    bool rv = SendMouseMove(x, y); | 
| +    new EventWaiter(task, GDK_MOTION_NOTIFY, 1); | 
| +    return rv; | 
| +  } | 
|  | 
| -bool SendMouseEvents(MouseButton type, int state) { | 
| -  GdkEvent* event = gdk_event_new(GDK_BUTTON_PRESS); | 
| +  bool SendMouseEvents(MouseButton type, int state) OVERRIDE { | 
| +    GdkEvent* event = gdk_event_new(GDK_BUTTON_PRESS); | 
| + | 
| +    event->button.send_event = false; | 
| +    event->button.time = XTimeNow(); | 
| + | 
| +    gint x, y; | 
| +    GtkWidget* grab_widget = gtk_grab_get_current(); | 
| +    if (grab_widget) { | 
| +      // If there is a grab, we need to target all events at it regardless of | 
| +      // what widget the mouse is over. | 
| +      event->button.window = gtk_widget_get_window(grab_widget); | 
| +      gdk_window_get_pointer(event->button.window, &x, &y, NULL); | 
| +    } else { | 
| +      event->button.window = gdk_window_at_pointer(&x, &y); | 
| +      CHECK(event->button.window); | 
| +    } | 
|  | 
| -  event->button.send_event = false; | 
| -  event->button.time = XTimeNow(); | 
| +    g_object_ref(event->button.window); | 
| +    event->button.x = x; | 
| +    event->button.y = y; | 
| +    gint origin_x, origin_y; | 
| +    gdk_window_get_origin(event->button.window, &origin_x, &origin_y); | 
| +    event->button.x_root = x + origin_x; | 
| +    event->button.y_root = y + origin_y; | 
| + | 
| +    event->button.axes = NULL; | 
| +    GdkModifierType modifier; | 
| +    gdk_window_get_pointer(event->button.window, NULL, NULL, &modifier); | 
| +    event->button.state = modifier; | 
| +    event->button.button = type == LEFT ? 1 : (type == MIDDLE ? 2 : 3); | 
| +    event->button.device = gdk_device_get_core_pointer(); | 
| + | 
| +    event->button.type = GDK_BUTTON_PRESS; | 
| +    if (state & DOWN) | 
| +      gdk_event_put(event); | 
| + | 
| +    // Also send a release event. | 
| +    GdkEvent* release_event = gdk_event_copy(event); | 
| +    release_event->button.type = GDK_BUTTON_RELEASE; | 
| +    release_event->button.time++; | 
| +    if (state & UP) | 
| +      gdk_event_put(release_event); | 
| + | 
| +    gdk_event_free(event); | 
| +    gdk_event_free(release_event); | 
|  | 
| -  gint x, y; | 
| -  GtkWidget* grab_widget = gtk_grab_get_current(); | 
| -  if (grab_widget) { | 
| -    // If there is a grab, we need to target all events at it regardless of | 
| -    // what widget the mouse is over. | 
| -    event->button.window = gtk_widget_get_window(grab_widget); | 
| -    gdk_window_get_pointer(event->button.window, &x, &y, NULL); | 
| -  } else { | 
| -    event->button.window = gdk_window_at_pointer(&x, &y); | 
| -    CHECK(event->button.window); | 
| +    return false; | 
| } | 
|  | 
| -  g_object_ref(event->button.window); | 
| -  event->button.x = x; | 
| -  event->button.y = y; | 
| -  gint origin_x, origin_y; | 
| -  gdk_window_get_origin(event->button.window, &origin_x, &origin_y); | 
| -  event->button.x_root = x + origin_x; | 
| -  event->button.y_root = y + origin_y; | 
| - | 
| -  event->button.axes = NULL; | 
| -  GdkModifierType modifier; | 
| -  gdk_window_get_pointer(event->button.window, NULL, NULL, &modifier); | 
| -  event->button.state = modifier; | 
| -  event->button.button = type == LEFT ? 1 : (type == MIDDLE ? 2 : 3); | 
| -  event->button.device = gdk_device_get_core_pointer(); | 
| - | 
| -  event->button.type = GDK_BUTTON_PRESS; | 
| -  if (state & DOWN) | 
| -    gdk_event_put(event); | 
| - | 
| -  // Also send a release event. | 
| -  GdkEvent* release_event = gdk_event_copy(event); | 
| -  release_event->button.type = GDK_BUTTON_RELEASE; | 
| -  release_event->button.time++; | 
| -  if (state & UP) | 
| -    gdk_event_put(release_event); | 
| +  bool SendMouseEventsNotifyWhenDone(MouseButton type, | 
| +                                    int state, | 
| +                                    const base::Closure& task) OVERRIDE { | 
| +    bool rv = SendMouseEvents(type, state); | 
| +    GdkEventType wait_type; | 
| +    if (state & UP) { | 
| +      wait_type = GDK_BUTTON_RELEASE; | 
| +    } else { | 
| +      if (type == LEFT) | 
| +        wait_type = GDK_BUTTON_PRESS; | 
| +      else if (type == MIDDLE) | 
| +        wait_type = GDK_2BUTTON_PRESS; | 
| +      else | 
| +        wait_type = GDK_3BUTTON_PRESS; | 
| +    } | 
| +    new EventWaiter(task, wait_type, 1); | 
| +    return rv; | 
| +  } | 
|  | 
| -  gdk_event_free(event); | 
| -  gdk_event_free(release_event); | 
| +  bool SendMouseClick(MouseButton type) { | 
| +    return SendMouseEvents(type, UP | DOWN); | 
| +  } | 
|  | 
| -  return false; | 
| -} | 
| + private: | 
| +  DISALLOW_COPY_AND_ASSIGN(UIControlsGtk); | 
| +}; | 
|  | 
| -bool SendMouseEventsNotifyWhenDone(MouseButton type, | 
| -                                   int state, | 
| -                                   const base::Closure& task) { | 
| -  bool rv = SendMouseEvents(type, state); | 
| -  GdkEventType wait_type; | 
| -  if (state & UP) { | 
| -    wait_type = GDK_BUTTON_RELEASE; | 
| -  } else { | 
| -    if (type == LEFT) | 
| -      wait_type = GDK_BUTTON_PRESS; | 
| -    else if (type == MIDDLE) | 
| -      wait_type = GDK_2BUTTON_PRESS; | 
| -    else | 
| -      wait_type = GDK_3BUTTON_PRESS; | 
| -  } | 
| -  new EventWaiter(task, wait_type, 1); | 
| -  return rv; | 
| -} | 
| +}  // namespace | 
|  | 
| -bool SendMouseClick(MouseButton type) { | 
| -  return SendMouseEvents(type, UP | DOWN); | 
| +UIControls* CreateNativeUIControls() { | 
| +  return new UIControlsGtk; | 
| } | 
|  | 
| }  // namespace ui_controls | 
|  |