Commit dbc37da0 authored by nona@chromium.org's avatar nona@chromium.org

Support mozc suggest window on ChromeOS.

Ordinal IME shows candidate window under the cursor, but Mozc should show
"suggest window"(same view but different location) and it's location is sent
by mozc-engine.

BUG=chromium-os:21356
TEST=manually confirmed it works fine and no conflict with other CJK engine.


Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=112452

Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=112965

Review URL: http://codereview.chromium.org/8505051

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@113158 0039d316-1c4b-4281-b951-d872f2087c98
parent b9403ef2
......@@ -296,7 +296,10 @@ deps = {
(Var("googlecode_url") % "libyuv") + "/trunk@64",
"src/third_party/mozc/session":
(Var("googlecode_url") % "mozc") + "/trunk/src/session@58",
(Var("googlecode_url") % "mozc") + "/trunk/src/session@83",
"src/third_party/mozc/chrome/chromeos/renderer":
(Var("googlecode_url") % "mozc") + "/trunk/src/chrome/chromeos/renderer@83",
"src/third_party/smhasher/src":
(Var("googlecode_url") % "smhasher") + "/trunk@136",
......
......@@ -833,7 +833,8 @@ CandidateWindowView::CandidateWindowView(views::Widget* parent_frame)
footer_area_(NULL),
previous_shortcut_column_width_(0),
previous_candidate_column_width_(0),
previous_annotation_column_width_(0) {
previous_annotation_column_width_(0),
is_suggestion_window_location_available_(false) {
}
CandidateWindowView::~CandidateWindowView() {
......@@ -935,6 +936,24 @@ void CandidateWindowView::ShowLookupTable() {
bool CandidateWindowView::ShouldUpdateCandidateViews(
const InputMethodLookupTable& old_table,
const InputMethodLookupTable& new_table) {
// Check if mozc lookup table location is changed.
if (old_table.mozc_candidates.has_window_location() ||
new_table.mozc_candidates.has_window_location()) {
if (!old_table.mozc_candidates.IsInitialized() ||
!new_table.mozc_candidates.IsInitialized()) {
return true;
}
std::string old_serialized_msg;
std::string new_serialized_msg;
old_table.mozc_candidates.SerializeToString(&old_serialized_msg);
new_table.mozc_candidates.SerializeToString(&new_serialized_msg);
return old_serialized_msg != new_serialized_msg;
}
// Check if most table contents are identical.
if (old_table.page_size == new_table.page_size &&
old_table.orientation == new_table.orientation &&
......@@ -959,6 +978,24 @@ void CandidateWindowView::UpdateCandidates(
// Initialize candidate views if necessary.
MaybeInitializeCandidateViews(new_lookup_table);
// Store mozc specific window location.
if (new_lookup_table.mozc_candidates.has_window_location() &&
new_lookup_table.mozc_candidates.window_location() ==
mozc::commands::Candidates::COMPOSITION) {
DCHECK(new_lookup_table.mozc_candidates.has_composition_rectangle());
suggestion_window_location_.set_x(
new_lookup_table.mozc_candidates.composition_rectangle().x());
suggestion_window_location_.set_y(
new_lookup_table.mozc_candidates.composition_rectangle().y());
suggestion_window_location_.set_width(
new_lookup_table.mozc_candidates.composition_rectangle().width());
suggestion_window_location_.set_height(
new_lookup_table.mozc_candidates.composition_rectangle().height());
is_suggestion_window_location_available_ = true;
} else {
is_suggestion_window_location_available_ = false;
}
// Compute the index of the current page.
const int current_page_index = ComputePageIndex(new_lookup_table);
if (current_page_index < 0) {
......@@ -1183,8 +1220,16 @@ void CandidateWindowView::CommitCandidate() {
}
void CandidateWindowView::ResizeAndMoveParentFrame() {
const int x = cursor_location_.x();
const int y = cursor_location_.y();
// If rendering operation comes from mozc-engine, uses mozc specific location,
// otherwise lookup table is shown under the cursor.
const int x = is_suggestion_window_location_available_ ?
suggestion_window_location_.x() : cursor_location_.x();
// To avoid lookup-table overlapping, uses maximum y-position of mozc specific
// location and cursor location, because mozc-engine does not consider about
// multi-line composition.
const int y = is_suggestion_window_location_available_ ?
std::max(suggestion_window_location_.y(), cursor_location_.y()) :
cursor_location_.y();
const int height = cursor_location_.height();
const int horizontal_offset = GetHorizontalOffset();
......
......@@ -177,6 +177,16 @@ class CandidateWindowView : public views::View {
// The last cursor location.
gfx::Rect cursor_location_;
// This location is used by suggestion window rendering which is mostly used
// by ibus-mozc. The suggestion window should be aligned with the composition
// text as opposed to the cursor. In case of ibus-mozc, suggestion window
// location is calculated by engine and it carried by update_lookup_table
// signal as additional information. This value is available when
// is_suggestion_window_available is true.
gfx::Rect suggestion_window_location_;
bool is_suggestion_window_location_available_;
DISALLOW_COPY_AND_ASSIGN(CandidateWindowView);
};
......
// Copyright (c) 2011 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.
// TODO(nona): Add unittests for UpdateCandidates.
#include "chrome/browser/chromeos/input_method/candidate_window_view.h"
#include <string>
#include "testing/gtest/include/gtest/gtest.h"
namespace chromeos {
namespace input_method {
namespace {
void ClearInputMethodLookupTable(InputMethodLookupTable* table) {
table->visible = false;
table->cursor_absolute_index = 0;
table->page_size = 10;
table->candidates.clear();
table->orientation = InputMethodLookupTable::kVertical;
table->labels.clear();
table->annotations.clear();
table->mozc_candidates.Clear();
}
void InitializeMozcCandidates(InputMethodLookupTable* table) {
table->mozc_candidates.Clear();
table->mozc_candidates.set_position(0);
table->mozc_candidates.set_size(0);
}
void SetCaretRectIntoMozcCandidates(
InputMethodLookupTable* table,
mozc::commands::Candidates::CandidateWindowLocation location,
int x,
int y,
int width,
int height) {
table->mozc_candidates.set_window_location(location);
mozc::commands::Rectangle *rect =
table->mozc_candidates.mutable_composition_rectangle();
rect->set_x(x);
rect->set_y(y);
rect->set_width(width);
rect->set_height(height);
}
void AppendCandidateIntoMozcCandidates(InputMethodLookupTable* table,
std::string value) {
mozc::commands::Candidates::Candidate *candidate =
table->mozc_candidates.add_candidate();
int current_entry_count = table->mozc_candidates.candidate_size();
candidate->set_index(current_entry_count);
candidate->set_value(value);
candidate->set_id(current_entry_count);
candidate->set_information_id(current_entry_count);
}
} // namespace
TEST(CandidateWindowViewTest, ShouldUpdateCandidateViewsTest) {
// This test verifies the process of judging update lookup-table or not.
// This judgement is handled by ShouldUpdateCandidateViews, which returns true
......@@ -28,6 +82,9 @@ TEST(CandidateWindowViewTest, ShouldUpdateCandidateViewsTest) {
InputMethodLookupTable old_table;
InputMethodLookupTable new_table;
ClearInputMethodLookupTable(&old_table);
ClearInputMethodLookupTable(&new_table);
old_table.visible = true;
old_table.cursor_absolute_index = 0;
old_table.page_size = 1;
......@@ -119,5 +176,160 @@ TEST(CandidateWindowViewTest, ShouldUpdateCandidateViewsTest) {
new_table));
}
TEST(CandidateWindowViewTest, MozcSuggestWindowShouldUpdateTest) {
// ShouldUpdateCandidateViews method should also judge with consideration of
// the mozc specific candidate information. Following tests verify them.
const char* kSampleCandidate1 = "Sample Candidate 1";
const char* kSampleCandidate2 = "Sample Candidate 2";
const int kCaretPositionX1 = 10;
const int kCaretPositionY1 = 20;
const int kCaretPositionWidth1 = 30;
const int kCaretPositionHeight1 = 40;
const int kCaretPositionX2 = 15;
const int kCaretPositionY2 = 25;
const int kCaretPositionWidth2 = 35;
const int kCaretPositionHeight2 = 45;
InputMethodLookupTable old_table;
InputMethodLookupTable new_table;
// State chagne from using non-mozc candidate to mozc candidate.
ClearInputMethodLookupTable(&old_table);
ClearInputMethodLookupTable(&new_table);
old_table.candidates.push_back(kSampleCandidate1);
InitializeMozcCandidates(&new_table);
AppendCandidateIntoMozcCandidates(&new_table, kSampleCandidate1);
SetCaretRectIntoMozcCandidates(&new_table,
mozc::commands::Candidates::COMPOSITION,
kCaretPositionX1,
kCaretPositionY1,
kCaretPositionWidth1,
kCaretPositionHeight1);
EXPECT_TRUE(CandidateWindowView::ShouldUpdateCandidateViews(old_table,
new_table));
// State change from using mozc candidate to non-mozc candidate
ClearInputMethodLookupTable(&old_table);
ClearInputMethodLookupTable(&new_table);
InitializeMozcCandidates(&old_table);
AppendCandidateIntoMozcCandidates(&old_table, kSampleCandidate1);
SetCaretRectIntoMozcCandidates(&old_table,
mozc::commands::Candidates::COMPOSITION,
kCaretPositionX1,
kCaretPositionY1,
kCaretPositionWidth1,
kCaretPositionHeight1);
new_table.candidates.push_back(kSampleCandidate1);
EXPECT_TRUE(CandidateWindowView::ShouldUpdateCandidateViews(old_table,
new_table));
// State change from using mozc candidate to mozc candidate
// No change
ClearInputMethodLookupTable(&old_table);
ClearInputMethodLookupTable(&new_table);
InitializeMozcCandidates(&old_table);
AppendCandidateIntoMozcCandidates(&old_table, kSampleCandidate1);
SetCaretRectIntoMozcCandidates(&old_table,
mozc::commands::Candidates::COMPOSITION,
kCaretPositionX1,
kCaretPositionY1,
kCaretPositionWidth1,
kCaretPositionHeight1);
InitializeMozcCandidates(&new_table);
AppendCandidateIntoMozcCandidates(&new_table, kSampleCandidate1);
SetCaretRectIntoMozcCandidates(&new_table,
mozc::commands::Candidates::COMPOSITION,
kCaretPositionX1,
kCaretPositionY1,
kCaretPositionWidth1,
kCaretPositionHeight1);
EXPECT_FALSE(CandidateWindowView::ShouldUpdateCandidateViews(old_table,
new_table));
// Position change only
ClearInputMethodLookupTable(&old_table);
ClearInputMethodLookupTable(&new_table);
InitializeMozcCandidates(&old_table);
AppendCandidateIntoMozcCandidates(&old_table, kSampleCandidate1);
SetCaretRectIntoMozcCandidates(&old_table,
mozc::commands::Candidates::COMPOSITION,
kCaretPositionX1,
kCaretPositionY1,
kCaretPositionWidth1,
kCaretPositionHeight1);
InitializeMozcCandidates(&new_table);
AppendCandidateIntoMozcCandidates(&new_table, kSampleCandidate1);
SetCaretRectIntoMozcCandidates(&new_table,
mozc::commands::Candidates::COMPOSITION,
kCaretPositionX2,
kCaretPositionY2,
kCaretPositionWidth2,
kCaretPositionHeight2);
EXPECT_TRUE(CandidateWindowView::ShouldUpdateCandidateViews(old_table,
new_table));
// Candidate contents only
ClearInputMethodLookupTable(&old_table);
ClearInputMethodLookupTable(&new_table);
InitializeMozcCandidates(&old_table);
AppendCandidateIntoMozcCandidates(&old_table, kSampleCandidate1);
SetCaretRectIntoMozcCandidates(&old_table,
mozc::commands::Candidates::COMPOSITION,
kCaretPositionX1,
kCaretPositionY1,
kCaretPositionWidth1,
kCaretPositionHeight1);
InitializeMozcCandidates(&new_table);
AppendCandidateIntoMozcCandidates(&new_table, kSampleCandidate2);
SetCaretRectIntoMozcCandidates(&new_table,
mozc::commands::Candidates::COMPOSITION,
kCaretPositionX1,
kCaretPositionY1,
kCaretPositionWidth1,
kCaretPositionHeight1);
EXPECT_TRUE(CandidateWindowView::ShouldUpdateCandidateViews(old_table,
new_table));
// Both candidate and position
ClearInputMethodLookupTable(&old_table);
ClearInputMethodLookupTable(&new_table);
InitializeMozcCandidates(&old_table);
AppendCandidateIntoMozcCandidates(&old_table, kSampleCandidate1);
SetCaretRectIntoMozcCandidates(&old_table,
mozc::commands::Candidates::COMPOSITION,
kCaretPositionX1,
kCaretPositionY1,
kCaretPositionWidth1,
kCaretPositionHeight1);
InitializeMozcCandidates(&new_table);
AppendCandidateIntoMozcCandidates(&new_table, kSampleCandidate2);
SetCaretRectIntoMozcCandidates(&new_table,
mozc::commands::Candidates::COMPOSITION,
kCaretPositionX2,
kCaretPositionY2,
kCaretPositionWidth2,
kCaretPositionHeight2);
EXPECT_TRUE(CandidateWindowView::ShouldUpdateCandidateViews(old_table,
new_table));
}
} // namespace input_method
} // namespace chromeos
......@@ -11,7 +11,7 @@
#include <sstream>
#include "base/logging.h"
#include "base/string_util.h"
#include "third_party/mozc/session/commands.pb.h"
#include "third_party/mozc/session/candidates_lite.pb.h"
namespace chromeos {
namespace input_method {
......
......@@ -15,7 +15,7 @@
#include "base/basictypes.h"
#include "base/observer_list.h"
#include "third_party/mozc/session/commands.pb.h"
#include "third_party/mozc/session/candidates_lite.pb.h"
namespace chromeos {
namespace input_method {
......
......@@ -37,88 +37,5 @@
],
},
},
{
'target_name': 'litify_mozc_proto_files',
'type': 'none',
'actions': [
{
'action_name': 'litify_config_proto',
'inputs': [
'../../../../third_party/mozc/session/config.proto',
],
'outputs': [
'<(input_method_out_dir)/mozc/session/config.proto',
],
'action': [
'python',
'litify_proto_file.py',
'../../../../third_party/mozc/session/config.proto',
'<(input_method_out_dir)/mozc/session/config.proto',
],
},
{
'action_name': 'litify_commands_proto',
'inputs': [
'../../../../third_party/mozc/session/commands.proto',
],
'outputs': [
'<(input_method_out_dir)/mozc/session/commands.proto',
],
'action': [
'python',
'litify_proto_file.py',
'../../../../third_party/mozc/session/commands.proto',
'<(input_method_out_dir)/mozc/session/commands.proto',
],
},
],
},
{
# Protobuf compiler / generator for the mozc inputmethod commands
# protocol buffer.
'target_name': 'mozc_commands_proto',
'type': 'static_library',
'sources': [
'<(input_method_out_dir)/mozc/session/config.proto',
'<(input_method_out_dir)/mozc/session/commands.proto',
],
'rules': [
{
'rule_name': 'genproto',
'extension': 'proto',
'inputs': [
'<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)protoc<(EXECUTABLE_SUFFIX)',
],
'outputs': [
'<(protoc_out_dir)/third_party/mozc/session/<(RULE_INPUT_ROOT).pb.h',
'<(protoc_out_dir)/third_party/mozc/session/<(RULE_INPUT_ROOT).pb.cc',
],
'action': [
'<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)protoc<(EXECUTABLE_SUFFIX)',
'--proto_path=<(input_method_out_dir)/mozc',
'<(input_method_out_dir)/mozc/session/<(RULE_INPUT_ROOT)<(RULE_INPUT_EXT)',
'--cpp_out=<(protoc_out_dir)/third_party/mozc',
],
'message': 'Generating C++ code from <(RULE_INPUT_PATH)',
'process_outputs_as_sources': 1,
},
],
'dependencies': [
'litify_mozc_proto_files',
'../../../../third_party/protobuf/protobuf.gyp:protobuf_lite',
'../../../../third_party/protobuf/protobuf.gyp:protoc#host',
],
'include_dirs': [
'<(protoc_out_dir)/third_party/mozc',
],
'direct_dependent_settings': {
'include_dirs': [
'<(protoc_out_dir)/third_party/mozc',
]
},
'export_dependent_settings': [
'../../../../third_party/protobuf/protobuf.gyp:protobuf_lite',
],
},
]
}
#!/usr/bin/env python
# Copyright (c) 2011 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.
"""Litify a .proto file.
This program add a line
"option optimize_for = LITE_RUNTIME;"
to the input .proto file.
Run it like:
litify_proto_file.py input.proto output.proto
"""
import fileinput
import sys
def main(argv):
if len(argv) != 3:
print 'Usage: litify_proto_file.py [input] [output]'
return 1
output_file = open(sys.argv[2], 'w')
for line in fileinput.input(sys.argv[1]):
output_file.write(line)
output_file.write("\noption optimize_for = LITE_RUNTIME;\n")
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv))
......@@ -4096,8 +4096,8 @@
'dependencies': [
'../build/linux/system.gyp:dbus-glib',
'../third_party/libevent/libevent.gyp:libevent',
'../third_party/mozc/chrome/chromeos/renderer/chromeos_renderer.gyp:mozc_candidates_proto',
'browser/chromeos/input_method/input_method.gyp:gencode',
'browser/chromeos/input_method/input_method.gyp:mozc_commands_proto',
],
'sources!': [
'browser/background/background_mode_manager_gtk.cc',
......
......@@ -2173,7 +2173,7 @@
['toolkit_uses_gtk == 1 or chromeos==1 or (OS=="linux" and use_aura==1)', {
'dependencies': [
'../build/linux/system.gyp:ssl',
'browser/chromeos/input_method/input_method.gyp:mozc_commands_proto',
'../third_party/mozc/chrome/chromeos/renderer/chromeos_renderer.gyp:mozc_candidates_proto',
],
}],
['use_gnome_keyring == 0', {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment