diff options
author | jcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-07 21:35:03 +0000 |
---|---|---|
committer | jcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-07 21:35:03 +0000 |
commit | 0ebf38756f3a68b30fe0d8e9336dbfafda52b5d5 (patch) | |
tree | a9ce0236b330fab3f39124c52fa0c1f184eb3965 /webkit/port | |
parent | 5e91242859811aef980a929253e6c33eb2cfec6e (diff) | |
download | chromium_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.h | 2 | ||||
-rw-r--r-- | webkit/port/platform/chromium/PopupMenuChromium.cpp | 133 | ||||
-rw-r--r-- | webkit/port/platform/chromium/PopupMenuChromium.h | 82 |
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 |