summaryrefslogtreecommitdiffstats
path: root/webkit/port
diff options
context:
space:
mode:
authorjcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-07 21:35:03 +0000
committerjcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-07 21:35:03 +0000
commit0ebf38756f3a68b30fe0d8e9336dbfafda52b5d5 (patch)
treea9ce0236b330fab3f39124c52fa0c1f184eb3965 /webkit/port
parent5e91242859811aef980a929253e6c33eb2cfec6e (diff)
downloadchromium_src-0ebf38756f3a68b30fe0d8e9336dbfafda52b5d5.zip
chromium_src-0ebf38756f3a68b30fe0d8e9336dbfafda52b5d5.tar.gz
chromium_src-0ebf38756f3a68b30fe0d8e9336dbfafda52b5d5.tar.bz2
Landing this again as I cannot reproduce the perf regression locally.
Will investigate on the bot. TBR=nsylvain Review URL: http://codereview.chromium.org/9700 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@5018 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/port')
-rw-r--r--webkit/port/page/chromium/ChromeClientChromium.h2
-rw-r--r--webkit/port/platform/chromium/PopupMenuChromium.cpp133
-rw-r--r--webkit/port/platform/chromium/PopupMenuChromium.h82
3 files changed, 142 insertions, 75 deletions
diff --git a/webkit/port/page/chromium/ChromeClientChromium.h b/webkit/port/page/chromium/ChromeClientChromium.h
index 5813770..783b5b5 100644
--- a/webkit/port/page/chromium/ChromeClientChromium.h
+++ b/webkit/port/page/chromium/ChromeClientChromium.h
@@ -26,7 +26,7 @@ namespace WebCore {
// Notifies the client of a new popup widget. The client should place
// and size the widget with the given bounds, relative to the screen.
- virtual void popupOpened(FramelessScrollView* popupView, const IntRect& bounds) = 0;
+ virtual void popupOpened(FramelessScrollView* popupView, const IntRect& bounds, bool focus_on_show) = 0;
};
}
diff --git a/webkit/port/platform/chromium/PopupMenuChromium.cpp b/webkit/port/platform/chromium/PopupMenuChromium.cpp
index d30df68..ae9f164 100644
--- a/webkit/port/platform/chromium/PopupMenuChromium.cpp
+++ b/webkit/port/platform/chromium/PopupMenuChromium.cpp
@@ -36,9 +36,9 @@
#include "ChromeClientChromium.h"
#include "Document.h"
#include "Font.h"
-#include "Frame.h"
#include "FrameView.h"
#include "FontSelector.h"
+#include "Frame.h"
#include "FramelessScrollView.h"
#include "FramelessScrollViewClient.h"
#include "GraphicsContext.h"
@@ -57,6 +57,8 @@
#include "Widget.h"
#pragma warning(pop)
+#include "webkit/port/platform/chromium/PopupMenuChromium.h"
+
using namespace WTF;
using namespace Unicode;
@@ -72,51 +74,6 @@ static const int kMaxHeight = 500;
static const int kBorderSize = 1;
static const TimeStamp kTypeAheadTimeoutMs = 1000;
-class PopupListBox;
-
-// TODO(darin): Our FramelessScrollView classes need to implement HostWindow!
-
-// This class holds a PopupListBox. Its sole purpose is to be able to draw
-// a border around its child. All its paint/event handling is just forwarded
-// to the child listBox (with the appropriate transforms).
-class PopupContainer : public FramelessScrollView, public RefCounted<PopupContainer> {
-public:
- static PassRefPtr<PopupContainer> create(PopupMenuClient* client);
-
- // FramelessScrollView
- virtual void paint(GraphicsContext* gc, const IntRect& rect);
- virtual void hide();
- virtual bool handleMouseDownEvent(const PlatformMouseEvent& event);
- virtual bool handleMouseMoveEvent(const PlatformMouseEvent& event);
- virtual bool handleMouseReleaseEvent(const PlatformMouseEvent& event);
- virtual bool handleWheelEvent(const PlatformWheelEvent& event);
- virtual bool handleKeyEvent(const PlatformKeyboardEvent& event);
-
- // PopupContainer methods
-
- // Show the popup
- void showPopup(FrameView* view);
-
- // Hide the popup. Do not call this directly: use client->hidePopup().
- void hidePopup();
-
- // Compute size of widget and children.
- void layout();
-
- PopupListBox* listBox() const { return m_listBox.get(); }
-
-private:
- friend class RefCounted<PopupContainer>;
-
- PopupContainer(PopupMenuClient* client);
- ~PopupContainer();
-
- // Paint the border.
- void paintBorder(GraphicsContext* gc, const IntRect& rect);
-
- RefPtr<PopupListBox> m_listBox;
-};
-
// This class uses WebCore code to paint and handle events for a drop-down list
// box ("combobox" on Windows).
class PopupListBox : public FramelessScrollView, public RefCounted<PopupListBox> {
@@ -170,6 +127,9 @@ public:
// Compute size of widget and children.
void layout();
+ // Returns whether the popup wants to process events for the passed key.
+ bool isInterestedInEventForKey(int key_code);
+
private:
friend class PopupContainer;
friend class RefCounted<PopupListBox>;
@@ -327,13 +287,15 @@ static PlatformWheelEvent constructRelativeWheelEvent(const PlatformWheelEvent&
// PopupContainer implementation
// static
-PassRefPtr<PopupContainer> PopupContainer::create(PopupMenuClient* client)
+PassRefPtr<PopupContainer> PopupContainer::create(PopupMenuClient* client,
+ bool focusOnShow)
{
- return adoptRef(new PopupContainer(client));
+ return adoptRef(new PopupContainer(client, focusOnShow));
}
-PopupContainer::PopupContainer(PopupMenuClient* client)
- : m_listBox(new PopupListBox(client))
+PopupContainer::PopupContainer(PopupMenuClient* client, bool focusOnShow)
+ : m_listBox(new PopupListBox(client)),
+ m_focusOnShow(focusOnShow)
{
// FrameViews are created with a refcount of 1 so it needs releasing after we
// assign it to a RefPtr.
@@ -367,7 +329,7 @@ void PopupContainer::showPopup(FrameView* view)
if (widgetRect.bottom() > static_cast<int>(screen.bottom()))
widgetRect.move(0, -(widgetRect.height() + selectHeight));
- chromeClient->popupOpened(this, widgetRect);
+ chromeClient->popupOpened(this, widgetRect, m_focusOnShow);
}
// Must get called after we have a client and containingWindow.
@@ -474,6 +436,33 @@ void PopupContainer::paintBorder(GraphicsContext* gc, const IntRect& rect)
gc->drawRect(IntRect(tx + width() - kBorderSize, ty, kBorderSize, height()));
}
+bool PopupContainer::isInterestedInEventForKey(int key_code) {
+ return m_listBox->isInterestedInEventForKey(key_code);
+}
+
+void PopupContainer::show(const IntRect& r, FrameView* v, int index) {
+ // The rect is the size of the select box. It's usually larger than we need.
+ // subtract border size so that usually the container will be displayed
+ // exactly the same width as the select box.
+ listBox()->setBaseWidth(max(r.width() - kBorderSize * 2, 0));
+
+ listBox()->updateFromElement();
+
+ // We set the selected item in updateFromElement(), and disregard the
+ // index passed into this function (same as Webkit's PopupMenuWin.cpp)
+ // TODO(ericroman): make sure this is correct, and add an assertion.
+ // DCHECK(popupWindow(popup)->listBox()->selectedIndex() == index);
+
+ // Convert point to main window coords.
+ IntPoint location = v->contentsToWindow(r.location());
+
+ // Move it below the select widget.
+ location.move(0, r.height());
+
+ IntRect popupRect(location, r.size());
+ setFrameRect(popupRect);
+ showPopup(v);
+}
///////////////////////////////////////////////////////////////////////////////
// PopupListBox implementation
@@ -548,6 +537,23 @@ bool PopupListBox::handleWheelEvent(const PlatformWheelEvent& event)
return true;
}
+// Should be kept in sync with handleKeyEvent().
+bool PopupListBox::isInterestedInEventForKey(int key_code) {
+ switch (key_code) {
+ case VKEY_ESCAPE:
+ case VKEY_RETURN:
+ case VKEY_UP:
+ case VKEY_DOWN:
+ case VKEY_PRIOR:
+ case VKEY_NEXT:
+ case VKEY_HOME:
+ case VKEY_END:
+ return true;
+ default:
+ return false;
+ }
+}
+
bool PopupListBox::handleKeyEvent(const PlatformKeyboardEvent& event)
{
if (event.type() == PlatformKeyboardEvent::KeyUp)
@@ -1036,29 +1042,8 @@ PopupMenu::~PopupMenu()
void PopupMenu::show(const IntRect& r, FrameView* v, int index)
{
- p.m_popup = PopupContainer::create(client());
-
- // The rect is the size of the select box. It's usually larger than we need.
- // subtract border size so that usually the container will be displayed
- // exactly the same width as the select box.
- p.m_popup->listBox()->setBaseWidth(max(r.width() - kBorderSize * 2, 0));
-
- updateFromElement();
-
- // We set the selected item in updateFromElement(), and disregard the
- // index passed into this function (same as Webkit's PopupMenuWin.cpp)
- // TODO(ericroman): make sure this is correct, and add an assertion.
- // DCHECK(popupWindow(m_popup)->listBox()->selectedIndex() == index);
-
- // Convert point to main window coords.
- IntPoint location = v->contentsToWindow(r.location());
-
- // Move it below the select widget.
- location.move(0, r.height());
-
- IntRect popupRect(location, r.size());
- p.m_popup->setFrameRect(popupRect);
- p.m_popup->showPopup(v);
+ p.m_popup = PopupContainer::create(client(), true);
+ p.m_popup->show(r, v, index);
}
void PopupMenu::hide()
diff --git a/webkit/port/platform/chromium/PopupMenuChromium.h b/webkit/port/platform/chromium/PopupMenuChromium.h
index e69de29..d419468 100644
--- a/webkit/port/platform/chromium/PopupMenuChromium.h
+++ b/webkit/port/platform/chromium/PopupMenuChromium.h
@@ -0,0 +1,82 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PopupMenuChromium_h
+#define PopupMenuChromium_h
+
+#pragma warning(push, 0)
+#include "PopupMenuClient.h"
+
+#include "FramelessScrollView.h"
+#include "IntRect.h"
+#pragma warning(pop)
+
+
+namespace WebCore {
+
+class PopupListBox;
+
+// TODO(darin): Our FramelessScrollView classes need to implement HostWindow!
+
+// This class holds a PopupListBox (see cpp file). Its sole purpose is to be
+// able to draw a border around its child. All its paint/event handling is just
+// forwarded to the child listBox (with the appropriate transforms).
+// NOTE: this class is exposed so it can be instantiated direcly for the
+// autofill popup. We cannot use the Popup class directly in that case as the
+// autofill popup should not be focused when shown and we want to forward the
+// key events to it (through handleKeyEvent).
+
+class PopupContainer : public FramelessScrollView, public RefCounted<PopupContainer> {
+public:
+ static PassRefPtr<PopupContainer> create(PopupMenuClient* client,
+ bool focusOnShow);
+
+ // Whether a key event should be sent to this popup.
+ virtual bool isInterestedInEventForKey(int key_code);
+
+ // FramelessScrollView
+ virtual void paint(GraphicsContext* gc, const IntRect& rect);
+ virtual void hide();
+ virtual bool handleMouseDownEvent(const PlatformMouseEvent& event);
+ virtual bool handleMouseMoveEvent(const PlatformMouseEvent& event);
+ virtual bool handleMouseReleaseEvent(const PlatformMouseEvent& event);
+ virtual bool handleWheelEvent(const PlatformWheelEvent& event);
+ virtual bool handleKeyEvent(const PlatformKeyboardEvent& event);
+
+ // PopupContainer methods
+
+ // Show the popup
+ void showPopup(FrameView* view);
+
+ // Show the popup in the specified rect for the specified frame.
+ // Note: this code was somehow arbitrarily factored-out of the Popup class
+ // so WebViewImpl can create a PopupContainer.
+ void show(const IntRect& r, FrameView* v, int index);
+
+ // Hide the popup. Do not call this directly: use client->hidePopup().
+ void hidePopup();
+
+ // Compute size of widget and children.
+ void layout();
+
+ PopupListBox* listBox() const { return m_listBox.get(); }
+
+private:
+ friend class WTF::RefCounted<PopupContainer>;
+
+ PopupContainer(PopupMenuClient* client, bool focusOnShow);
+ ~PopupContainer();
+
+ // Paint the border.
+ void paintBorder(GraphicsContext* gc, const IntRect& rect);
+
+ RefPtr<PopupListBox> m_listBox;
+
+ // Whether the window showing this popup should be focused when shown.
+ bool m_focusOnShow;
+};
+
+}
+
+#endif // PopupMenuChromium_h