Index: chrome/browser/ui/gtk/omnibox/omnibox_popup_view_gtk.cc |
diff --git a/chrome/browser/ui/gtk/omnibox/omnibox_popup_view_gtk.cc b/chrome/browser/ui/gtk/omnibox/omnibox_popup_view_gtk.cc |
index 23ab592f21028d2cebd792d253dace6104bddc8c..9f4961f837aa9eb2613dc93a3268267e3a1bc983 100644 |
--- a/chrome/browser/ui/gtk/omnibox/omnibox_popup_view_gtk.cc |
+++ b/chrome/browser/ui/gtk/omnibox/omnibox_popup_view_gtk.cc |
@@ -98,15 +98,6 @@ gfx::Rect GetWindowRect(GdkWindow* window) { |
return gfx::Rect(width, height); |
} |
-// Return a Rect for the space for a result line. This excludes the border, |
-// but includes the padding. This is the area that is colored for a selection. |
-gfx::Rect GetRectForLine(size_t line, int width) { |
- return gfx::Rect(kBorderThickness, |
- (line * kHeightPerResult) + kBorderThickness, |
- width - (kBorderThickness * 2), |
- kHeightPerResult); |
-} |
- |
// TODO(deanm): Find some better home for this, and make it more efficient. |
size_t GetUTF8Offset(const string16& text, size_t text_offset) { |
return UTF16ToUTF8(text.substr(0, text_offset)).length(); |
@@ -170,6 +161,7 @@ GdkColor SelectedURLColor(GdkColor foreground, GdkColor background) { |
} |
} // namespace |
+// static |
void OmniboxPopupViewGtk::SetupLayoutForMatch( |
PangoLayout* layout, |
const string16& text, |
@@ -268,15 +260,22 @@ OmniboxPopupViewGtk::OmniboxPopupViewGtk(const gfx::Font& font, |
OmniboxEditModel* edit_model, |
GtkWidget* location_bar) |
: signal_registrar_(new ui::GtkSignalRegistrar), |
- model_(new OmniboxPopupModel(this, edit_model)), |
omnibox_view_(omnibox_view), |
location_bar_(location_bar), |
window_(gtk_window_new(GTK_WINDOW_POPUP)), |
layout_(NULL), |
- theme_service_(GtkThemeService::GetFrom(edit_model->profile())), |
+ theme_service_(NULL), |
font_(font.DeriveFont(kEditFontAdjust)), |
ignore_mouse_drag_(false), |
opened_(false) { |
+ // edit_model may be NULL in unit tests. |
+ if (edit_model) { |
+ model_.reset(new OmniboxPopupModel(this, edit_model)); |
+ theme_service_ = GtkThemeService::GetFrom(edit_model->profile()); |
+ } |
+} |
+ |
+void OmniboxPopupViewGtk::Init() { |
gtk_widget_set_can_focus(window_, FALSE); |
// Don't allow the window to be resized. This also forces the window to |
// shrink down to the size of its child contents. |
@@ -334,8 +333,11 @@ OmniboxPopupViewGtk::~OmniboxPopupViewGtk() { |
// This is because the model destructor can call back into us, and we need |
// to make sure everything is still valid when it does. |
model_.reset(); |
- g_object_unref(layout_); |
- gtk_widget_destroy(window_); |
+ // layout_ may be NULL in unit tests. |
+ if (layout_) { |
+ g_object_unref(layout_); |
+ gtk_widget_destroy(window_); |
+ } |
} |
bool OmniboxPopupViewGtk::IsOpen() const { |
@@ -352,13 +354,14 @@ void OmniboxPopupViewGtk::InvalidateLine(size_t line) { |
} |
void OmniboxPopupViewGtk::UpdatePopupAppearance() { |
- const AutocompleteResult& result = model_->result(); |
- if (result.empty()) { |
+ const AutocompleteResult& result = GetResult(); |
+ const size_t hidden_matches = GetHiddenMatchCount(); |
+ if (result.size() <= hidden_matches) { |
Hide(); |
return; |
} |
- Show(result.size()); |
+ Show(result.size() - hidden_matches); |
gtk_widget_queue_draw(window_); |
} |
@@ -468,7 +471,7 @@ void OmniboxPopupViewGtk::StackWindow() { |
size_t OmniboxPopupViewGtk::LineFromY(int y) { |
size_t line = std::max(y - kBorderThickness, 0) / kHeightPerResult; |
- return std::min(line, model_->result().size() - 1); |
+ return std::min(line + GetHiddenMatchCount(), GetResult().size() - 1); |
} |
void OmniboxPopupViewGtk::AcceptLine(size_t line, |
@@ -476,7 +479,7 @@ void OmniboxPopupViewGtk::AcceptLine(size_t line, |
// OpenMatch() may close the popup, which will clear the result set and, by |
// extension, |match| and its contents. So copy the relevant match out to |
// make sure it stays alive until the call completes. |
- AutocompleteMatch match = model_->result().match_at(line); |
+ AutocompleteMatch match = GetResult().match_at(line); |
omnibox_view_->OpenMatch(match, disposition, GURL(), line); |
} |
@@ -526,7 +529,7 @@ void OmniboxPopupViewGtk::GetVisibleMatchForInput( |
size_t index, |
const AutocompleteMatch** match, |
bool* is_selected_keyword) { |
- const AutocompleteResult& result = model_->result(); |
+ const AutocompleteResult& result = GetResult(); |
if (result.match_at(index).associated_keyword.get() && |
model_->selected_line() == index && |
@@ -540,6 +543,22 @@ void OmniboxPopupViewGtk::GetVisibleMatchForInput( |
*is_selected_keyword = false; |
} |
+gfx::Rect OmniboxPopupViewGtk::GetRectForLine(size_t line, int width) { |
+ size_t visible_line = line - GetHiddenMatchCount(); |
+ return gfx::Rect(kBorderThickness, |
+ (visible_line * kHeightPerResult) + kBorderThickness, |
+ width - (kBorderThickness * 2), |
+ kHeightPerResult); |
+} |
+ |
+size_t OmniboxPopupViewGtk::GetHiddenMatchCount() { |
+ return GetResult().ShouldHideTopMatch() ? 1 : 0; |
+} |
+ |
+const AutocompleteResult& OmniboxPopupViewGtk::GetResult() const { |
Evan Stade
2013/08/15 01:05:12
make the definition order match the declaration or
Jered
2013/08/15 16:08:49
Done.
|
+ return model_->result(); |
+} |
+ |
gboolean OmniboxPopupViewGtk::HandleMotion(GtkWidget* widget, |
GdkEventMotion* event) { |
// TODO(deanm): Windows has a bunch of complicated logic here. |
@@ -590,7 +609,7 @@ gboolean OmniboxPopupViewGtk::HandleButtonRelease(GtkWidget* widget, |
gboolean OmniboxPopupViewGtk::HandleExpose(GtkWidget* widget, |
GdkEventExpose* event) { |
bool ltr = !base::i18n::IsRTL(); |
- const AutocompleteResult& result = model_->result(); |
+ const AutocompleteResult& result = GetResult(); |
gfx::Rect window_rect = GetWindowRect(event->window); |
gfx::Rect damage_rect = gfx::Rect(event->area); |
@@ -617,7 +636,7 @@ gboolean OmniboxPopupViewGtk::HandleExpose(GtkWidget* widget, |
pango_layout_set_height(layout_, kHeightPerResult * PANGO_SCALE); |
- for (size_t i = 0; i < result.size(); ++i) { |
+ for (size_t i = GetHiddenMatchCount(); i < result.size(); ++i) { |
gfx::Rect line_rect = GetRectForLine(i, window_rect.width()); |
// Only repaint and layout damaged lines. |
if (!line_rect.Intersects(damage_rect)) |