diff options
Diffstat (limited to 'chrome/browser')
7 files changed, 87 insertions, 3 deletions
diff --git a/chrome/browser/renderer_host/render_widget_host.cc b/chrome/browser/renderer_host/render_widget_host.cc index 64fb609..9e07de7 100644 --- a/chrome/browser/renderer_host/render_widget_host.cc +++ b/chrome/browser/renderer_host/render_widget_host.cc @@ -114,6 +114,7 @@ IPC_DEFINE_MESSAGE_MAP(RenderWidgetHost) IPC_MESSAGE_HANDLER(ViewHostMsg_Blur, OnMsgBlur) IPC_MESSAGE_HANDLER(ViewHostMsg_SetCursor, OnMsgSetCursor) IPC_MESSAGE_HANDLER(ViewHostMsg_ImeUpdateStatus, OnMsgImeUpdateStatus) + IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_ShowPopup, OnMsgShowPopup(msg)) IPC_MESSAGE_UNHANDLED_ERROR() IPC_END_MESSAGE_MAP() @@ -662,6 +663,23 @@ void RenderWidgetHost::OnMsgImeUpdateStatus(int control, } } +void RenderWidgetHost::OnMsgShowPopup(const IPC::Message& message) { +#if defined(OS_MACOSX) + void* iter = NULL; + ViewHostMsg_ShowPopup_Params validated_params; + if (!IPC::ParamTraits<ViewHostMsg_ShowPopup_Params>::Read(&message, &iter, + &validated_params)) + return; + + view_->ShowPopupWithItems(validated_params.bounds, + validated_params.item_height, + validated_params.selected_item, + validated_params.popup_items); +#else // OS_WIN || OS_LINUX + NOTREACHED(); +#endif +} + void RenderWidgetHost::PaintBackingStoreRect(TransportDIB* bitmap, const gfx::Rect& bitmap_rect, const gfx::Size& view_size) { diff --git a/chrome/browser/renderer_host/render_widget_host.h b/chrome/browser/renderer_host/render_widget_host.h index ad81ad8..0e93a84 100644 --- a/chrome/browser/renderer_host/render_widget_host.h +++ b/chrome/browser/renderer_host/render_widget_host.h @@ -318,6 +318,7 @@ class RenderWidgetHost : public IPC::Channel::Listener { // Using int instead of ViewHostMsg_ImeControl for control's type to avoid // having to bring in render_messages.h in a header file. void OnMsgImeUpdateStatus(int control, const gfx::Rect& caret_rect); + void OnMsgShowPopup(const IPC::Message& message); // Paints the given bitmap to the current backing store at the given location. void PaintBackingStoreRect(TransportDIB* dib, diff --git a/chrome/browser/renderer_host/render_widget_host_view.h b/chrome/browser/renderer_host/render_widget_host_view.h index beec90e..7053150 100644 --- a/chrome/browser/renderer_host/render_widget_host_view.h +++ b/chrome/browser/renderer_host/render_widget_host_view.h @@ -7,8 +7,9 @@ #include "base/gfx/native_widget_types.h" #include "base/shared_memory.h" -#include "webkit/glue/webplugin.h" #include "skia/include/SkBitmap.h" +#include "webkit/glue/webplugin.h" +#include "webkit/glue/webwidget_delegate.h" namespace gfx { class Rect; @@ -136,6 +137,14 @@ class RenderWidgetHostView { // Allocate a backing store for this view virtual BackingStore* AllocBackingStore(const gfx::Size& size) = 0; +#if defined(OS_MACOSX) + // Display a native control popup menu for WebKit. + virtual void ShowPopupWithItems(gfx::Rect bounds, + int item_height, + int selected_item, + const std::vector<WebMenuItem>& items) = 0; +#endif + void set_activatable(bool activatable) { activatable_ = activatable; } @@ -151,7 +160,7 @@ class RenderWidgetHostView { protected: // Interface class only, do not construct. RenderWidgetHostView() : activatable_(true) {} - + // Whether the window can be activated. Autocomplete popup windows for example // cannot be activated. Default is true. bool activatable_; diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.h b/chrome/browser/renderer_host/render_widget_host_view_mac.h index 4c1e266..e04b822 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_mac.h +++ b/chrome/browser/renderer_host/render_widget_host_view_mac.h @@ -82,9 +82,15 @@ class RenderWidgetHostViewMac : public RenderWidgetHostView { virtual void Destroy(); virtual void SetTooltipText(const std::wstring& tooltip_text); virtual BackingStore* AllocBackingStore(const gfx::Size& size); + virtual void ShowPopupWithItems(gfx::Rect bounds, + int item_height, + int selected_item, + const std::vector<WebMenuItem>& items); void KillSelf(); + void set_parent_view(BaseView* parent_view) { parent_view_ = parent_view; } + // These member variables should be private, but the associated ObjC class // needs access to them and can't be made a friend. @@ -131,6 +137,9 @@ class RenderWidgetHostViewMac : public RenderWidgetHostView { // Factory used to safely scope delayed calls to ShutdownHost(). ScopedRunnableMethodFactory<RenderWidgetHostViewMac> shutdown_factory_; + // Used for positioning a popup menu. + BaseView* parent_view_; + DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewMac); }; diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.mm b/chrome/browser/renderer_host/render_widget_host_view_mac.mm index bfe0bfc..9e6b88f 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_mac.mm +++ b/chrome/browser/renderer_host/render_widget_host_view_mac.mm @@ -14,6 +14,7 @@ #include "skia/ext/platform_canvas.h" #include "third_party/WebKit/WebKit/chromium/public/mac/WebInputEventFactory.h" #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" +#include "webkit/glue/webmenurunner_mac.h" using WebKit::WebInputEventFactory; using WebKit::WebMouseEvent; @@ -46,7 +47,8 @@ RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) about_to_validate_and_paint_(false), is_loading_(false), is_hidden_(false), - shutdown_factory_(this) { + shutdown_factory_(this), + parent_view_(NULL) { cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc] initWithRenderWidgetHostViewMac:this] autorelease]; render_widget_host_->set_view(this); @@ -267,6 +269,42 @@ BackingStore* RenderWidgetHostViewMac::AllocBackingStore( return new BackingStore(size); } +// Display a popup menu for WebKit using Cocoa widgets. +void RenderWidgetHostViewMac::ShowPopupWithItems( + gfx::Rect bounds, + int item_height, + int selected_item, + const std::vector<WebMenuItem>& items) { + NSRect view_rect = [cocoa_view_ bounds]; + NSRect position = NSMakeRect(bounds.x(), bounds.y() - bounds.height(), + bounds.width(), bounds.height()); + + // Display the menu. + WebMenuRunner* menu_runner = + [[[WebMenuRunner alloc] initWithItems:items] autorelease]; + + [menu_runner runMenuInView:parent_view_ + withBounds:position + initialIndex:selected_item]; + + int window_num = [[parent_view_ window] windowNumber]; + NSEvent* event = CreateEventForMenuAction([menu_runner menuItemWasChosen], + window_num, item_height, + [menu_runner indexOfSelectedItem], + position, view_rect); + + if ([menu_runner menuItemWasChosen]) { + // Simulate a menu selection event. + const WebMouseEvent& mouse_event = + WebInputEventFactory::mouseEvent(event, cocoa_view_); + render_widget_host_->ForwardMouseEvent(mouse_event); + } else { + // Simulate a menu dismiss event. + NativeWebKeyboardEvent keyboard_event(event); + render_widget_host_->ForwardKeyboardEvent(keyboard_event); + } +} + void RenderWidgetHostViewMac::KillSelf() { if (shutdown_factory_.empty()) { [cocoa_view_ setHidden:YES]; diff --git a/chrome/browser/renderer_host/test_render_view_host.h b/chrome/browser/renderer_host/test_render_view_host.h index 5f67ec1..0e93526 100644 --- a/chrome/browser/renderer_host/test_render_view_host.h +++ b/chrome/browser/renderer_host/test_render_view_host.h @@ -72,6 +72,12 @@ class TestRenderWidgetHostView : public RenderWidgetHostView { virtual void PrepareToDestroy() {} virtual void SetTooltipText(const std::wstring& tooltip_text) {} virtual BackingStore* AllocBackingStore(const gfx::Size& size); +#if defined(OS_MACOSX) + virtual void ShowPopupWithItems(gfx::Rect bounds, + int item_height, + int selected_item, + const std::vector<WebMenuItem>& items) {} +#endif bool is_showing() const { return is_showing_; } diff --git a/chrome/browser/tab_contents/tab_contents_view_mac.mm b/chrome/browser/tab_contents/tab_contents_view_mac.mm index 2f08d70..3d894c8 100644 --- a/chrome/browser/tab_contents/tab_contents_view_mac.mm +++ b/chrome/browser/tab_contents/tab_contents_view_mac.mm @@ -148,6 +148,9 @@ RenderWidgetHostView* TabContentsViewMac::CreateNewWidgetInternal( static_cast<RenderWidgetHostViewMac*>(widget_view); [widget_view_mac->native_view() retain]; + // |widget_view_mac| needs to know how to position itself in our view. + widget_view_mac->set_parent_view(cocoa_view_); + return widget_view; } |