| Index: chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.cc
|
| diff --git a/chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.cc b/chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.cc
|
| index bebb0b835784ac37c4eedcfc40e509fcdfd73318..ed1f84a20708654b80bdc23e00aa4d833440537e 100644
|
| --- a/chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.cc
|
| +++ b/chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.cc
|
| @@ -4,10 +4,14 @@
|
|
|
| #include "autofill_popup_view_gtk.h"
|
|
|
| +#include <gdk/gdkkeysyms.h>
|
| +
|
| #include "base/logging.h"
|
| #include "base/utf_string_conversions.h"
|
| #include "chrome/browser/autofill/autofill_external_delegate.h"
|
| #include "chrome/browser/ui/gtk/gtk_util.h"
|
| +#include "content/public/browser/render_view_host.h"
|
| +#include "content/public/browser/web_contents.h"
|
| #include "ui/base/gtk/gtk_compat.h"
|
| #include "ui/base/gtk/gtk_hig_constants.h"
|
| #include "ui/base/gtk/gtk_windowing.h"
|
| @@ -43,7 +47,8 @@ AutofillPopupViewGtk::AutofillPopupViewGtk(
|
| GtkWidget* parent)
|
| : AutofillPopupView(web_contents, external_delegate),
|
| parent_(parent),
|
| - window_(gtk_window_new(GTK_WINDOW_POPUP)) {
|
| + window_(gtk_window_new(GTK_WINDOW_POPUP)),
|
| + render_view_host_(web_contents->GetRenderViewHost()) {
|
| CHECK(parent != NULL);
|
| gtk_window_set_resizable(GTK_WINDOW(window_), FALSE);
|
| gtk_widget_set_app_paintable(window_, TRUE);
|
| @@ -74,21 +79,11 @@ AutofillPopupViewGtk::~AutofillPopupViewGtk() {
|
| }
|
|
|
| void AutofillPopupViewGtk::ShowInternal() {
|
| - // Find out the maximum bounds required by the popup.
|
| - // TODO(csharp): Once the icon is also displayed it will affect the required
|
| - // size so it will need to be included in the calculation.
|
| - int popup_width = element_bounds().width();
|
| - DCHECK_EQ(autofill_values().size(), autofill_labels().size());
|
| - for (size_t i = 0; i < autofill_values().size(); ++i) {
|
| - popup_width = std::max(popup_width,
|
| - font_.GetStringWidth(autofill_values()[i]) +
|
| - kMiddlePadding +
|
| - font_.GetStringWidth(autofill_labels()[i]));
|
| - }
|
| -
|
| gint origin_x, origin_y;
|
| gdk_window_get_origin(gtk_widget_get_window(parent_), &origin_x, &origin_y);
|
|
|
| + int popup_width = GetPopupRequiredWidth();
|
| +
|
| // Move the popup to appear right below the text field it is using.
|
| bounds_.SetRect(
|
| origin_x + element_bounds().x(),
|
| @@ -103,6 +98,8 @@ void AutofillPopupViewGtk::ShowInternal() {
|
| popup_width,
|
| row_height_ * autofill_values().size());
|
|
|
| + render_view_host_->AddKeyboardListener(this);
|
| +
|
| gtk_widget_show(window_);
|
|
|
| GtkWidget* toplevel = gtk_widget_get_toplevel(parent_);
|
| @@ -111,6 +108,8 @@ void AutofillPopupViewGtk::ShowInternal() {
|
| }
|
|
|
| void AutofillPopupViewGtk::HideInternal() {
|
| + render_view_host_->RemoveKeyboardListener(this);
|
| +
|
| gtk_widget_hide(window_);
|
| }
|
|
|
| @@ -127,13 +126,9 @@ gboolean AutofillPopupViewGtk::HandleButtonRelease(GtkWidget* widget,
|
| if (event->button != 1)
|
| return FALSE;
|
|
|
| - size_t line = LineFromY(event->y);
|
| - DCHECK_LT(line, autofill_values().size());
|
| + DCHECK_EQ(selected_line(), LineFromY(event->y));
|
|
|
| - external_delegate()->DidAcceptAutofillSuggestions(
|
| - autofill_values()[line],
|
| - autofill_unique_ids()[line],
|
| - line);
|
| + AcceptSelectedLine();
|
|
|
| return TRUE;
|
| }
|
| @@ -224,6 +219,34 @@ gboolean AutofillPopupViewGtk::HandleMotion(GtkWidget* widget,
|
| return TRUE;
|
| }
|
|
|
| +bool AutofillPopupViewGtk::HandleKeyPressEvent(GdkEventKey* event) {
|
| + switch (event->keyval) {
|
| + case GDK_Up:
|
| + SelectPreviousLine();
|
| + return true;
|
| + case GDK_Down:
|
| + SelectNextLine();
|
| + return true;
|
| + case GDK_Page_Up:
|
| + SetSelectedLine(0);
|
| + return true;
|
| + case GDK_Page_Down:
|
| + SetSelectedLine(autofill_values().size() - 1);
|
| + return true;
|
| + case GDK_Escape:
|
| + Hide();
|
| + return true;
|
| + case GDK_Delete:
|
| + case GDK_KP_Delete:
|
| + return (event->state == GDK_SHIFT_MASK) && RemoveSelectedLine();
|
| + case GDK_Return:
|
| + case GDK_KP_Enter:
|
| + return AcceptSelectedLine();
|
| + }
|
| +
|
| + return false;
|
| +}
|
| +
|
| void AutofillPopupViewGtk::SetupLayout(const gfx::Rect& window_rect,
|
| const GdkColor& text_color) {
|
| int allocated_content_width = window_rect.width();
|
| @@ -242,6 +265,21 @@ void AutofillPopupViewGtk::SetupLayout(const gfx::Rect& window_rect,
|
| pango_attr_list_unref(attrs);
|
| }
|
|
|
| +int AutofillPopupViewGtk::GetPopupRequiredWidth() {
|
| + // TODO(csharp): Once the icon is also displayed it will affect the required
|
| + // size so it will need to be included in the calculation.
|
| + int popup_width = element_bounds().width();
|
| + DCHECK_EQ(autofill_values().size(), autofill_labels().size());
|
| + for (size_t i = 0; i < autofill_values().size(); ++i) {
|
| + popup_width = std::max(popup_width,
|
| + font_.GetStringWidth(autofill_values()[i]) +
|
| + kMiddlePadding +
|
| + font_.GetStringWidth(autofill_labels()[i]));
|
| + }
|
| +
|
| + return popup_width;
|
| +}
|
| +
|
| int AutofillPopupViewGtk::LineFromY(int y) {
|
| return y / row_height_;
|
| }
|
|
|