summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorrsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-02 15:46:01 +0000
committerrsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-02 15:46:01 +0000
commitd4cff27a73a9dc6caa6b37a8b28ef72ecc35fa0d (patch)
tree22759b5ed8332e11983609a93432dd47e9a65a79 /content
parentc5b003c0bbadd824f84421390945f685f0fc9cd1 (diff)
downloadchromium_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.cc2
-rw-r--r--content/browser/renderer_host/render_view_host.cc5
-rw-r--r--content/browser/renderer_host/render_view_host.h6
-rw-r--r--content/browser/renderer_host/render_widget_host.cc7
-rw-r--r--content/browser/renderer_host/render_widget_host.h5
-rw-r--r--content/browser/renderer_host/render_widget_host_view.h7
-rw-r--r--content/common/common_param_traits.cc19
-rw-r--r--content/common/common_param_traits.h12
-rw-r--r--content/common/font_descriptor_mac.h3
-rw-r--r--content/common/font_descriptor_mac.mm7
-rw-r--r--content/common/font_descriptor_mac_unittest.mm8
-rw-r--r--content/common/view_messages.h11
-rw-r--r--content/content_common.gypi1
-rw-r--r--content/renderer/render_view.cc26
-rw-r--r--content/renderer/render_widget.cc45
-rw-r--r--content/renderer/render_widget_fullscreen_pepper.cc4
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;
}