diff options
author | rsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-02 15:46:01 +0000 |
---|---|---|
committer | rsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-02 15:46:01 +0000 |
commit | d4cff27a73a9dc6caa6b37a8b28ef72ecc35fa0d (patch) | |
tree | 22759b5ed8332e11983609a93432dd47e9a65a79 /content | |
parent | c5b003c0bbadd824f84421390945f685f0fc9cd1 (diff) | |
download | chromium_src-d4cff27a73a9dc6caa6b37a8b28ef72ecc35fa0d.zip chromium_src-d4cff27a73a9dc6caa6b37a8b28ef72ecc35fa0d.tar.gz chromium_src-d4cff27a73a9dc6caa6b37a8b28ef72ecc35fa0d.tar.bz2 |
[Mac] Implement the system dictionary popup by implementing NSTextInput methods.
This is a two-sided patch; the Chromium side is plumbing to marshall data from
the renderer to the system APIs.
Note that just hitting Cmd+Ctrl+D usually does not bring up the popup. I think
this may be an Apple bug, but I have not yet found a work-around.
BUG=17951,37715,47141
TEST=Hold Cmd+Ctrl+D on a web page and mouse around. The dictionary popup should follow the mouse and show the definition of the current word.
TEST=In a text area, the dictionary popup should work only if the text area has focus.
R=avi,suzhe,jam
Review URL: http://codereview.chromium.org/6289009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@83723 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r-- | content/browser/renderer_host/render_message_filter.cc | 2 | ||||
-rw-r--r-- | content/browser/renderer_host/render_view_host.cc | 5 | ||||
-rw-r--r-- | content/browser/renderer_host/render_view_host.h | 6 | ||||
-rw-r--r-- | content/browser/renderer_host/render_widget_host.cc | 7 | ||||
-rw-r--r-- | content/browser/renderer_host/render_widget_host.h | 5 | ||||
-rw-r--r-- | content/browser/renderer_host/render_widget_host_view.h | 7 | ||||
-rw-r--r-- | content/common/common_param_traits.cc | 19 | ||||
-rw-r--r-- | content/common/common_param_traits.h | 12 | ||||
-rw-r--r-- | content/common/font_descriptor_mac.h | 3 | ||||
-rw-r--r-- | content/common/font_descriptor_mac.mm | 7 | ||||
-rw-r--r-- | content/common/font_descriptor_mac_unittest.mm | 8 | ||||
-rw-r--r-- | content/common/view_messages.h | 11 | ||||
-rw-r--r-- | content/content_common.gypi | 1 | ||||
-rw-r--r-- | content/renderer/render_view.cc | 26 | ||||
-rw-r--r-- | content/renderer/render_widget.cc | 45 | ||||
-rw-r--r-- | content/renderer/render_widget_fullscreen_pepper.cc | 4 |
16 files changed, 138 insertions, 30 deletions
diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc index 16a20be..1cc7ec9 100644 --- a/content/browser/renderer_host/render_message_filter.cc +++ b/content/browser/renderer_host/render_message_filter.cc @@ -558,7 +558,7 @@ void RenderMessageFilter::OnLoadFont(const FontDescriptor& font, base::SharedMemoryHandle* handle) { base::SharedMemory font_data; uint32 font_data_size = 0; - bool ok = FontLoader::LoadFontIntoBuffer(font.nsFont(), &font_data, + bool ok = FontLoader::LoadFontIntoBuffer(font.ToNSFont(), &font_data, &font_data_size); if (!ok || font_data_size == 0) { LOG(ERROR) << "Couldn't load font data for " << font.font_name << diff --git a/content/browser/renderer_host/render_view_host.cc b/content/browser/renderer_host/render_view_host.cc index 98bcbf8..da09850 100644 --- a/content/browser/renderer_host/render_view_host.cc +++ b/content/browser/renderer_host/render_view_host.cc @@ -1080,9 +1080,10 @@ void RenderViewHost::OnMsgSetTooltipText( view()->SetTooltipText(UTF16ToWide(wrapped_tooltip_text)); } -void RenderViewHost::OnMsgSelectionChanged(const std::string& text) { +void RenderViewHost::OnMsgSelectionChanged(const std::string& text, + const ui::Range& range) { if (view()) - view()->SelectionChanged(text); + view()->SelectionChanged(text, range); } void RenderViewHost::OnMsgRunJavaScriptMessage( diff --git a/content/browser/renderer_host/render_view_host.h b/content/browser/renderer_host/render_view_host.h index 14ecddd..2936218 100644 --- a/content/browser/renderer_host/render_view_host.h +++ b/content/browser/renderer_host/render_view_host.h @@ -52,6 +52,10 @@ namespace gfx { class Point; } // namespace gfx +namespace ui { +class Range; +} // namespace ui + namespace webkit_glue { struct CustomContextMenuContext; struct WebAccessibility; @@ -496,7 +500,7 @@ class RenderViewHost : public RenderWidgetHost { const std::string& target); void OnMsgSetTooltipText(const std::wstring& tooltip_text, WebKit::WebTextDirection text_direction_hint); - void OnMsgSelectionChanged(const std::string& text); + void OnMsgSelectionChanged(const std::string& text, const ui::Range& range); void OnMsgPasteFromSelectionClipboard(); void OnMsgRunJavaScriptMessage(const std::wstring& message, const std::wstring& default_prompt, diff --git a/content/browser/renderer_host/render_widget_host.cc b/content/browser/renderer_host/render_widget_host.cc index 77db54b..339b310 100644 --- a/content/browser/renderer_host/render_widget_host.cc +++ b/content/browser/renderer_host/render_widget_host.cc @@ -174,6 +174,8 @@ bool RenderWidgetHost::OnMessageReceived(const IPC::Message &msg) { IPC_MESSAGE_HANDLER(ViewHostMsg_SetCursor, OnMsgSetCursor) IPC_MESSAGE_HANDLER(ViewHostMsg_ImeUpdateTextInputState, OnMsgImeUpdateTextInputState) + IPC_MESSAGE_HANDLER(ViewHostMsg_ImeCompositionRangeChanged, + OnMsgImeCompositionRangeChanged) IPC_MESSAGE_HANDLER(ViewHostMsg_ImeCancelComposition, OnMsgImeCancelComposition) IPC_MESSAGE_HANDLER(ViewHostMsg_DidActivateAcceleratedCompositing, @@ -1029,6 +1031,11 @@ void RenderWidgetHost::OnMsgImeUpdateTextInputState( view_->ImeUpdateTextInputState(type, caret_rect); } +void RenderWidgetHost::OnMsgImeCompositionRangeChanged(const ui::Range& range) { + if (view_) + view_->ImeCompositionRangeChanged(range); +} + void RenderWidgetHost::OnMsgImeCancelComposition() { if (view_) view_->ImeCancelComposition(); diff --git a/content/browser/renderer_host/render_widget_host.h b/content/browser/renderer_host/render_widget_host.h index d110436..13aa909 100644 --- a/content/browser/renderer_host/render_widget_host.h +++ b/content/browser/renderer_host/render_widget_host.h @@ -31,6 +31,10 @@ namespace gfx { class Rect; } +namespace ui { +class Range; +} + namespace WebKit { class WebInputEvent; class WebMouseEvent; @@ -475,6 +479,7 @@ class RenderWidgetHost : public IPC::Channel::Listener, void OnMsgSetCursor(const WebCursor& cursor); void OnMsgImeUpdateTextInputState(WebKit::WebTextInputType type, const gfx::Rect& caret_rect); + void OnMsgImeCompositionRangeChanged(const ui::Range& range); void OnMsgImeCancelComposition(); void OnMsgDidActivateAcceleratedCompositing(bool activated); diff --git a/content/browser/renderer_host/render_widget_host_view.h b/content/browser/renderer_host/render_widget_host_view.h index 76c1db4..f443d1c 100644 --- a/content/browser/renderer_host/render_widget_host_view.h +++ b/content/browser/renderer_host/render_widget_host_view.h @@ -18,6 +18,7 @@ #include "third_party/skia/include/core/SkColor.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupType.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebTextInputType.h" +#include "ui/base/range/range.h" #include "ui/gfx/native_widget_types.h" #include "ui/gfx/rect.h" #include "ui/gfx/surface/transport_dib.h" @@ -139,6 +140,9 @@ class RenderWidgetHostView { // Cancel the ongoing composition of the input method attached to the view. virtual void ImeCancelComposition() = 0; + // Updates the range of the marked text in an IME composition. + virtual void ImeCompositionRangeChanged(const ui::Range& range) {} + // Informs the view that a portion of the widget's backing store was scrolled // and/or painted. The view should ensure this gets copied to the screen. // @@ -176,7 +180,8 @@ class RenderWidgetHostView { virtual void SetTooltipText(const std::wstring& tooltip_text) = 0; // Notifies the View that the renderer text selection has changed. - virtual void SelectionChanged(const std::string& text) {} + virtual void SelectionChanged(const std::string& text, + const ui::Range& range) {} // Tells the View whether the context menu is showing. This is used on Linux // to suppress updates to webkit focus for the duration of the show. diff --git a/content/common/common_param_traits.cc b/content/common/common_param_traits.cc index 1e0ffd0..5e31003 100644 --- a/content/common/common_param_traits.cc +++ b/content/common/common_param_traits.cc @@ -9,6 +9,7 @@ #include "net/base/upload_data.h" #include "net/http/http_response_headers.h" #include "third_party/skia/include/core/SkBitmap.h" +#include "ui/base/range/range.h" #include "ui/gfx/rect.h" namespace { @@ -501,6 +502,24 @@ void ParamTraits<gfx::Rect>::Log(const gfx::Rect& p, std::string* l) { p.width(), p.height())); } +void ParamTraits<ui::Range>::Write(Message* m, const ui::Range& r) { + m->WriteSize(r.start()); + m->WriteSize(r.end()); +} + +bool ParamTraits<ui::Range>::Read(const Message* m, void** iter, ui::Range* r) { + size_t start, end; + if (!m->ReadSize(iter, &start) || !m->ReadSize(iter, &end)) + return false; + r->set_start(start); + r->set_end(end); + return true; +} + +void ParamTraits<ui::Range>::Log(const ui::Range& r, std::string* l) { + l->append(base::StringPrintf("(%"PRIuS", %"PRIuS")", r.start(), r.end())); +} + void ParamTraits<SkBitmap>::Write(Message* m, const SkBitmap& p) { size_t fixed_size = sizeof(SkBitmap_Data); SkBitmap_Data bmp_data; diff --git a/content/common/common_param_traits.h b/content/common/common_param_traits.h index ae102cb..41e0326 100644 --- a/content/common/common_param_traits.h +++ b/content/common/common_param_traits.h @@ -38,6 +38,10 @@ class HostPortPair; class UploadData; } +namespace ui { +class Range; +} + namespace IPC { template <> @@ -165,6 +169,14 @@ struct ParamTraits<gfx::NativeWindow> { } }; +template <> +struct ParamTraits<ui::Range> { + typedef ui::Range param_type; + static void Write(Message* m, const param_type& p); + static bool Read(const Message* m, void** iter, param_type* r); + static void Log(const param_type& p, std::string* l); +}; + #if defined(OS_WIN) template<> struct ParamTraits<TransportDIB::Id> { diff --git a/content/common/font_descriptor_mac.h b/content/common/font_descriptor_mac.h index 91bb338..c3ac5a8 100644 --- a/content/common/font_descriptor_mac.h +++ b/content/common/font_descriptor_mac.h @@ -17,11 +17,12 @@ class NSFont; // Container to allow serializing an NSFont over IPC. struct FontDescriptor { explicit FontDescriptor(NSFont* font); + FontDescriptor(string16 name, float size); FontDescriptor() : font_point_size(0) {} // Return an autoreleased NSFont corresponding to the font description. - NSFont* nsFont() const; + NSFont* ToNSFont() const; // Name of the font. string16 font_name; diff --git a/content/common/font_descriptor_mac.mm b/content/common/font_descriptor_mac.mm index 90c7986..c8e3112 100644 --- a/content/common/font_descriptor_mac.mm +++ b/content/common/font_descriptor_mac.mm @@ -13,7 +13,12 @@ FontDescriptor::FontDescriptor(NSFont* font) { font_point_size = [font pointSize]; } -NSFont* FontDescriptor::nsFont() const { +FontDescriptor::FontDescriptor(string16 name, float size) { + font_name = name; + font_point_size = size; +} + +NSFont* FontDescriptor::ToNSFont() const { NSString* font_name_ns = base::SysUTF16ToNSString(font_name); NSFont* font = [NSFont fontWithName:font_name_ns size:font_point_size]; return font; diff --git a/content/common/font_descriptor_mac_unittest.mm b/content/common/font_descriptor_mac_unittest.mm index d4a74d1..f8fdfc8 100644 --- a/content/common/font_descriptor_mac_unittest.mm +++ b/content/common/font_descriptor_mac_unittest.mm @@ -72,7 +72,7 @@ NSFont* MakeNSFont(const std::string& font_name, float font_point_size) { FontDescriptor desc; desc.font_name = UTF8ToUTF16(font_name); desc.font_point_size = font_point_size; - return desc.nsFont(); + return desc.ToNSFont(); } // Verify that serialization and deserialization of fonts with various styles @@ -81,12 +81,12 @@ TEST_F(FontSerializationTest, StyledFonts) { NSFont* plain_font = [NSFont systemFontOfSize:12.0]; ASSERT_TRUE(plain_font != nil); FontDescriptor desc_plain(plain_font); - EXPECT_TRUE(CompareFonts(plain_font, desc_plain.nsFont())); + EXPECT_TRUE(CompareFonts(plain_font, desc_plain.ToNSFont())); NSFont* bold_font = [NSFont boldSystemFontOfSize:30.0]; ASSERT_TRUE(bold_font != nil); FontDescriptor desc_bold(bold_font); - EXPECT_TRUE(CompareFonts(bold_font, desc_bold.nsFont())); + EXPECT_TRUE(CompareFonts(bold_font, desc_bold.ToNSFont())); NSFont* italic_bold_font = [[NSFontManager sharedFontManager] @@ -96,7 +96,7 @@ TEST_F(FontSerializationTest, StyledFonts) { size:18.0]; ASSERT_TRUE(italic_bold_font != nil); FontDescriptor desc_italic_bold(italic_bold_font); - EXPECT_TRUE(CompareFonts(italic_bold_font, desc_italic_bold.nsFont())); + EXPECT_TRUE(CompareFonts(italic_bold_font, desc_italic_bold.ToNSFont())); } // Test that FontDescriptor doesn't crash when used with bad parameters. diff --git a/content/common/view_messages.h b/content/common/view_messages.h index 55a118c..ea324b7 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h @@ -25,6 +25,7 @@ #include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupType.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebTextInputType.h" +#include "ui/base/range/range.h" #include "ui/gfx/rect.h" #include "webkit/glue/context_menu.h" #include "webkit/glue/password_form.h" @@ -1676,8 +1677,9 @@ IPC_MESSAGE_ROUTED2(ViewHostMsg_SetTooltipText, WebKit::WebTextDirection /* text direction hint */) // Notification that the text selection has changed. -IPC_MESSAGE_ROUTED1(ViewHostMsg_SelectionChanged, - std::string /* currently selected text */) +IPC_MESSAGE_ROUTED2(ViewHostMsg_SelectionChanged, + std::string /* currently selected text */, + ui::Range /* selection range */) // Asks the browser to display the file chooser. The result is returned in a // ViewHost_RunFileChooserResponse message. @@ -1709,6 +1711,11 @@ IPC_MESSAGE_ROUTED2(ViewHostMsg_ImeUpdateTextInputState, WebKit::WebTextInputType, /* text_input_type */ gfx::Rect /* caret_rect */) + +// Message sent when the IME text composition range changes. +IPC_MESSAGE_ROUTED1(ViewHostMsg_ImeCompositionRangeChanged, + ui::Range /* composition range */) + // Required for cancelling an ongoing input method composition. IPC_MESSAGE_ROUTED0(ViewHostMsg_ImeCancelComposition) diff --git a/content/content_common.gypi b/content/content_common.gypi index 998641c..24ef258 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi @@ -15,6 +15,7 @@ '../third_party/npapi/npapi.gyp:npapi', '../third_party/WebKit/Source/WebKit/chromium/WebKit.gyp:webkit', '../ui/gfx/gl/gl.gyp:gl', + '../ui/ui.gyp:ui_base', '../webkit/support/webkit_support.gyp:appcache', '../webkit/support/webkit_support.gyp:blob', '../webkit/support/webkit_support.gyp:database', diff --git a/content/renderer/render_view.cc b/content/renderer/render_view.cc index 19bbaac..eafbd1d 100644 --- a/content/renderer/render_view.cc +++ b/content/renderer/render_view.cc @@ -1423,25 +1423,27 @@ void RenderView::didChangeSelection(bool is_empty_selection) { #if defined(OS_POSIX) if (!handling_input_event_) return; - // TODO(estade): investigate incremental updates to the selection so that we - // don't send the entire selection over IPC every time. - if (!is_empty_selection) { + + if (is_empty_selection) { + last_selection_.clear(); + } else { // Sometimes we get repeated didChangeSelection calls from webkit when // the selection hasn't actually changed. We don't want to report these // because it will cause us to continually claim the X clipboard. - const std::string& this_selection = - webview()->focusedFrame()->selectionAsText().utf8(); + WebFrame* frame = webview()->focusedFrame(); + const std::string& this_selection = frame->selectionAsText().utf8(); if (this_selection == last_selection_) return; - - Send(new ViewHostMsg_SelectionChanged(routing_id_, - this_selection)); last_selection_ = this_selection; - } else { - last_selection_.clear(); - Send(new ViewHostMsg_SelectionChanged(routing_id_, - last_selection_)); } + + ui::Range range(ui::Range::InvalidRange()); + size_t location, length; + if (webview()->caretOrSelectionRange(&location, &length)) { + range.set_start(location); + range.set_end(location + length); + } + Send(new ViewHostMsg_SelectionChanged(routing_id_, last_selection_, range)); #endif // defined(OS_POSIX) } diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 26f3f99..6b190b3 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc @@ -22,6 +22,7 @@ #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupMenu.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupMenuInfo.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebRange.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h" @@ -48,6 +49,7 @@ using WebKit::WebNavigationPolicy; using WebKit::WebPopupMenu; using WebKit::WebPopupMenuInfo; using WebKit::WebPopupType; +using WebKit::WebRange; using WebKit::WebRect; using WebKit::WebScreenInfo; using WebKit::WebSize; @@ -886,19 +888,51 @@ void RenderWidget::OnImeSetComposition( int selection_start, int selection_end) { if (!webwidget_) return; - if (!webwidget_->setComposition( + if (webwidget_->setComposition( text, WebVector<WebCompositionUnderline>(underlines), selection_start, selection_end)) { + // Setting the IME composition was successful. Send the new composition + // range to the browser. + ui::Range range(ui::Range::InvalidRange()); + size_t location, length; + if (webwidget_->compositionRange(&location, &length)) { + range.set_start(location); + range.set_end(location + length); + } + // The IME was cancelled via the Esc key, so just send back the caret. + else if (webwidget_->caretOrSelectionRange(&location, &length)) { + range.set_start(location); + range.set_end(location + length); + } + Send(new ViewHostMsg_ImeCompositionRangeChanged(routing_id(), range)); + } else { // If we failed to set the composition text, then we need to let the browser // process to cancel the input method's ongoing composition session, to make // sure we are in a consistent state. Send(new ViewHostMsg_ImeCancelComposition(routing_id())); + + // Send an updated IME range with just the caret range. + ui::Range range(ui::Range::InvalidRange()); + size_t location, length; + if (webwidget_->caretOrSelectionRange(&location, &length)) { + range.set_start(location); + range.set_end(location + length); + } + Send(new ViewHostMsg_ImeCompositionRangeChanged(routing_id(), range)); } } void RenderWidget::OnImeConfirmComposition(const string16& text) { if (webwidget_) webwidget_->confirmComposition(text); + // Send an updated IME range with just the caret range. + ui::Range range(ui::Range::InvalidRange()); + size_t location, length; + if (webwidget_->caretOrSelectionRange(&location, &length)) { + range.set_start(location); + range.set_end(location + length); + } + Send(new ViewHostMsg_ImeCompositionRangeChanged(routing_id(), range)); } // This message causes the renderer to render an image of the @@ -1090,6 +1124,15 @@ void RenderWidget::resetInputMethod() { if (webwidget_->confirmComposition()) Send(new ViewHostMsg_ImeCancelComposition(routing_id())); } + + // Send an updated IME range with the current caret rect. + ui::Range range(ui::Range::InvalidRange()); + size_t location, length; + if (webwidget_->caretOrSelectionRange(&location, &length)) { + range.set_start(location); + range.set_end(location + length); + } + Send(new ViewHostMsg_ImeCompositionRangeChanged(routing_id(), range)); } void RenderWidget::SchedulePluginMove( diff --git a/content/renderer/render_widget_fullscreen_pepper.cc b/content/renderer/render_widget_fullscreen_pepper.cc index d2ab734..ae8aeb7 100644 --- a/content/renderer/render_widget_fullscreen_pepper.cc +++ b/content/renderer/render_widget_fullscreen_pepper.cc @@ -161,10 +161,6 @@ class PepperWidget : public WebWidget { return false; } - virtual bool selectionRange(size_t *location, size_t *length) { - return false; - } - virtual bool caretOrSelectionRange(size_t* location, size_t* length) { return false; } |