summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/render_widget_host.cc4
-rw-r--r--chrome/browser/render_widget_host_view_win.cc5
-rw-r--r--webkit/glue/editor_client_impl.cc7
-rw-r--r--webkit/glue/webview_impl.cc55
-rw-r--r--webkit/port/platform/chromium/PopupMenuChromium.cpp5
-rw-r--r--webkit/port/platform/chromium/PopupMenuChromium.h3
6 files changed, 59 insertions, 20 deletions
diff --git a/chrome/browser/render_widget_host.cc b/chrome/browser/render_widget_host.cc
index 41fd233..90aac3c 100644
--- a/chrome/browser/render_widget_host.cc
+++ b/chrome/browser/render_widget_host.cc
@@ -340,8 +340,8 @@ void RenderWidgetHost::OnMsgClose() {
}
void RenderWidgetHost::OnMsgRequestMove(const gfx::Rect& pos) {
- // Don't allow renderer widgets to move themselves by default. Maybe this
- // policy will change if we add more types of widgets.
+ // Note that we ignore the position.
+ view_->SetSize(pos.size());
}
void RenderWidgetHost::OnMsgPaintRect(
diff --git a/chrome/browser/render_widget_host_view_win.cc b/chrome/browser/render_widget_host_view_win.cc
index d530e5d..d927868 100644
--- a/chrome/browser/render_widget_host_view_win.cc
+++ b/chrome/browser/render_widget_host_view_win.cc
@@ -131,9 +131,10 @@ void RenderWidgetHostViewWin::SetSize(const gfx::Size& size) {
if (is_hidden_)
return;
+ // No SWP_NOREDRAW as autofill popups can resize and the underneath window
+ // should redraw in that case.
UINT swp_flags = SWP_NOSENDCHANGING | SWP_NOOWNERZORDER | SWP_NOCOPYBITS |
- SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE |
- SWP_DEFERERASE;
+ SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_DEFERERASE;
SetWindowPos(NULL, 0, 0, size.width(), size.height(), swp_flags);
render_widget_host_->WasResized();
EnsureTooltip();
diff --git a/webkit/glue/editor_client_impl.cc b/webkit/glue/editor_client_impl.cc
index e1b3e1e..4daa74d 100644
--- a/webkit/glue/editor_client_impl.cc
+++ b/webkit/glue/editor_client_impl.cc
@@ -644,6 +644,9 @@ void EditorClientImpl::textFieldDidEndEditing(WebCore::Element*) {
// Cancel any pending DoAutofill calls.
autofill_factory_.RevokeAll();
+
+ // Hide any showing popup.
+ web_view_->HideAutoCompletePopup();
}
void EditorClientImpl::textDidChangeInTextField(WebCore::Element* element) {
@@ -687,8 +690,10 @@ void EditorClientImpl::DoAutofill(WebCore::HTMLInputElement* input_element,
bool caret_at_end =
input_element->selectionStart() == input_element->selectionEnd() &&
input_element->selectionEnd() == static_cast<int>(value.length());
- if (value.empty() || !caret_at_end)
+ if (value.empty() || !caret_at_end) {
+ web_view_->HideAutoCompletePopup();
return;
+ }
// First let's see if there is a password listener for that element.
WebFrameImpl* webframe =
diff --git a/webkit/glue/webview_impl.cc b/webkit/glue/webview_impl.cc
index c04b649..540b654 100644
--- a/webkit/glue/webview_impl.cc
+++ b/webkit/glue/webview_impl.cc
@@ -132,10 +132,7 @@ class AutocompletePopupMenuClient
: text_field_(text_field),
selected_index_(default_suggestion_index),
webview_(webview) {
- for (std::vector<std::wstring>::const_iterator iter = suggestions.begin();
- iter != suggestions.end(); ++iter) {
- suggestions_.push_back(webkit_glue::StdWStringToString(*iter));
- }
+ SetSuggestions(suggestions);
}
virtual ~AutocompletePopupMenuClient() {
}
@@ -233,6 +230,21 @@ class AutocompletePopupMenuClient
return widget.release();
}
+ void SetSuggestions(const std::vector<std::wstring>& suggestions) {
+ suggestions_.clear();
+ for (std::vector<std::wstring>::const_iterator iter = suggestions.begin();
+ iter != suggestions.end(); ++iter) {
+ suggestions_.push_back(webkit_glue::StdWStringToString(*iter));
+ }
+ // Try to preserve selection if possible.
+ if (selected_index_ >= static_cast<int>(suggestions.size()))
+ selected_index_ = -1;
+ }
+
+ WebCore::HTMLInputElement* text_field() const {
+ return text_field_.get();
+ }
+
private:
RefPtr<WebCore::HTMLInputElement> text_field_;
std::vector<WebCore::String> suggestions_;
@@ -431,10 +443,6 @@ bool WebViewImpl::KeyEvent(const WebKeyboardEvent& event) {
}
}
- // A new key being pressed should hide the popup.
- if (event.type == WebInputEvent::KEY_DOWN)
- HideAutoCompletePopup();
-
Frame* frame = GetFocusedWebCoreFrame();
if (!frame)
return false;
@@ -1449,15 +1457,19 @@ void WebViewImpl::AutofillSuggestionsForNode(
int64 node_id,
const std::vector<std::wstring>& suggestions,
int default_suggestion_index) {
- if (!page_.get() || suggestions.empty())
+ if (!page_.get() || suggestions.empty()) {
+ HideAutoCompletePopup();
return;
+ }
DCHECK(default_suggestion_index < static_cast<int>(suggestions.size()));
if (RefPtr<Frame> focused = page_->focusController()->focusedFrame()) {
RefPtr<Document> document = focused->document();
- if (!document.get())
+ if (!document.get()) {
+ HideAutoCompletePopup();
return;
+ }
RefPtr<Node> focused_node = document->focusedNode();
// If the node for which we queried the autofill suggestions is not the
@@ -1465,8 +1477,10 @@ void WebViewImpl::AutofillSuggestionsForNode(
// TODO(jcampan): also check the carret is at the end and that the text has
// not changed.
if (!focused_node.get() ||
- reinterpret_cast<int64>(focused_node.get()) != node_id)
+ reinterpret_cast<int64>(focused_node.get()) != node_id) {
+ HideAutoCompletePopup();
return;
+ }
if (!focused_node->hasTagName(WebCore::HTMLNames::inputTag)) {
NOTREACHED();
@@ -1475,10 +1489,8 @@ void WebViewImpl::AutofillSuggestionsForNode(
WebCore::HTMLInputElement* input_elem =
static_cast<WebCore::HTMLInputElement*>(focused_node.get());
- // Hide any current autocomplete popup.
- HideAutoCompletePopup();
-
- if (suggestions.size() > 0) {
+ if (!autocomplete_popup_client_.get() ||
+ autocomplete_popup_client_->text_field() != input_elem) {
autocomplete_popup_client_ =
adoptRef(new AutocompletePopupMenuClient(this, input_elem,
suggestions,
@@ -1492,6 +1504,19 @@ void WebViewImpl::AutofillSuggestionsForNode(
autocomplete_popup_->setAcceptOnAbandon(false);
autocomplete_popup_->show(focused_node->getRect(),
page_->mainFrame()->view(), 0);
+ } else {
+ // There is already a popup, reuse it.
+ autocomplete_popup_client_->SetSuggestions(suggestions);
+ IntRect old_bounds = autocomplete_popup_->boundsRect();
+ autocomplete_popup_->refresh();
+ IntRect new_bounds = autocomplete_popup_->boundsRect();
+ // Let's resize the backing window if necessary.
+ if (old_bounds != new_bounds) {
+ WebWidgetImpl* web_widget =
+ static_cast<WebWidgetImpl*>(autocomplete_popup_->client());
+ web_widget->delegate()->SetWindowRect(
+ web_widget, webkit_glue::FromIntRect(new_bounds));
+ }
}
}
}
diff --git a/webkit/port/platform/chromium/PopupMenuChromium.cpp b/webkit/port/platform/chromium/PopupMenuChromium.cpp
index c85b1e2..82696cf 100644
--- a/webkit/port/platform/chromium/PopupMenuChromium.cpp
+++ b/webkit/port/platform/chromium/PopupMenuChromium.cpp
@@ -494,6 +494,11 @@ void PopupContainer::setAcceptOnAbandon(bool value) {
listBox()->setAcceptOnAbandon(value);
}
+void PopupContainer::refresh() {
+ listBox()->updateFromElement();
+ layout();
+}
+
///////////////////////////////////////////////////////////////////////////////
// PopupListBox implementation
diff --git a/webkit/port/platform/chromium/PopupMenuChromium.h b/webkit/port/platform/chromium/PopupMenuChromium.h
index 49b2a75..c8c7098 100644
--- a/webkit/port/platform/chromium/PopupMenuChromium.h
+++ b/webkit/port/platform/chromium/PopupMenuChromium.h
@@ -79,6 +79,9 @@ public:
PopupListBox* listBox() const { return m_listBox.get(); }
+ // Refresh the popup values from the PopupMenuClient.
+ void refresh();
+
private:
friend class WTF::RefCounted<PopupContainer>;