Index: chrome/browser/chromeos/input_method/ibus_ui_controller.cc |
diff --git a/chrome/browser/chromeos/input_method/ibus_ui_controller.cc b/chrome/browser/chromeos/input_method/ibus_ui_controller.cc |
index 1b70a0aa31f151cedfc79213481cbf3752e2b99d..dce2aa316794d03b2c4c13c562e24cbe378ea687 100644 |
--- a/chrome/browser/chromeos/input_method/ibus_ui_controller.cc |
+++ b/chrome/browser/chromeos/input_method/ibus_ui_controller.cc |
@@ -1,13 +1,10 @@ |
// Copyright (c) 2012 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): Remvoe IBusUiController |
#include "chrome/browser/chromeos/input_method/ibus_ui_controller.h" |
-#if defined(HAVE_IBUS) |
-#include <ibus.h> |
-#endif |
- |
#include <sstream> |
#include "ash/shell.h" |
@@ -17,6 +14,8 @@ |
#include "chrome/browser/chromeos/input_method/input_method_descriptor.h" |
#include "chrome/browser/chromeos/input_method/input_method_manager.h" |
#include "chrome/browser/chromeos/input_method/input_method_util.h" |
+#include "chromeos/dbus/dbus_thread_manager.h" |
+#include "chromeos/dbus/ibus/ibus_lookup_table.h" |
#include "ui/aura/client/aura_constants.h" |
#include "ui/aura/root_window.h" |
#include "ui/base/ime/input_method_ibus.h" |
@@ -25,18 +24,59 @@ namespace chromeos { |
namespace input_method { |
namespace { |
-bool IsActive(const std::string& input_method_id, |
- const InputMethodDescriptors* descriptors) { |
- for (size_t i = 0; i < descriptors->size(); ++i) { |
- if (descriptors->at(i).id() == input_method_id) { |
- return true; |
- } |
- } |
- return false; |
+// Returns pointer of IBusPanelService. This function returns NULL if it is not |
+// ready. |
+ibus::IBusPanelService* GetIBusPanelService() { |
+ return DBusThreadManager::Get()->GetIBusPanelService(); |
+} |
+ |
+// Returns a ui::InputMethodIBus object which is associated with the root |
+// window. Returns NULL if the Ash shell has already been destructed. |
+static ui::InputMethodIBus* GetChromeInputMethod() { |
+ if (!ash::Shell::HasInstance()) |
+ return NULL; |
+ aura::Window* root_window = ash::Shell::GetPrimaryRootWindow(); |
+ if (!root_window) |
+ return NULL; |
+ return static_cast<ui::InputMethodIBus*>(root_window->GetProperty( |
+ aura::client::kRootWindowInputMethodKey)); |
} |
} // namespace |
+// A class for customizing the behavior of ui::InputMethodIBus for Chrome OS. |
+class IBusChromeOSClientImpl : public ui::internal::IBusClient { |
+ public: |
+ explicit IBusChromeOSClientImpl(IBusUiController* ui) : ui_(ui) {} |
+ |
+ // ui::IBusClient override. |
+ virtual InputMethodType GetInputMethodType() OVERRIDE { |
+ InputMethodManager* manager = InputMethodManager::GetInstance(); |
+ DCHECK(manager); |
+ return InputMethodUtil::IsKeyboardLayout( |
+ manager->GetCurrentInputMethod().id()) ? |
+ INPUT_METHOD_XKB_LAYOUT : INPUT_METHOD_NORMAL; |
+ } |
+ |
+ virtual void SetCursorLocation(const gfx::Rect& cursor_location, |
+ const gfx::Rect& composition_head) OVERRIDE { |
+ if (!ui_) |
+ return; |
+ // We don't have to call ibus_input_context_set_cursor_location() on |
+ // Chrome OS because the candidate window for IBus is integrated with |
+ // Chrome. |
+ ui_->SetCursorLocation(cursor_location, composition_head); |
+ } |
+ |
+ void set_ui(IBusUiController* ui) { |
+ ui_ = ui; |
+ } |
+ |
+ private: |
+ IBusUiController* ui_; |
+ DISALLOW_COPY_AND_ASSIGN(IBusChromeOSClientImpl); |
+}; |
+ |
InputMethodLookupTable::InputMethodLookupTable() |
: visible(false), |
cursor_absolute_index(0), |
@@ -64,682 +104,137 @@ std::string InputMethodLookupTable::ToString() const { |
return stream.str(); |
} |
-#if defined(HAVE_IBUS) |
- |
-// Returns an string representation of |table| for debugging. |
-std::string IBusLookupTableToString(IBusLookupTable* table) { |
- std::stringstream stream; |
- stream << "page_size: " << table->page_size << "\n"; |
- stream << "cursor_pos: " << table->cursor_pos << "\n"; |
- stream << "cursor_visible: " << table->cursor_visible << "\n"; |
- stream << "round: " << table->round << "\n"; |
- stream << "orientation: " << table->orientation << "\n"; |
- stream << "candidates:"; |
- for (int i = 0; ; i++) { |
- IBusText *text = ibus_lookup_table_get_candidate(table, i); |
- if (!text) { |
- break; |
- } |
- stream << " " << text->text; |
- } |
- return stream.str(); |
-} |
- |
// The real implementation of the IBusUiController. |
-class IBusUiControllerImpl : public IBusUiController { |
- public: |
- IBusUiControllerImpl() |
- : ibus_(NULL), |
- ibus_panel_service_(NULL) { |
- ui::InputMethodIBus* input_method = GetChromeInputMethod(); |
- DCHECK(input_method); |
- input_method->set_ibus_client(scoped_ptr<ui::internal::IBusClient>( |
- new IBusChromeOSClientImpl(this)).Pass()); |
- } |
- |
- ~IBusUiControllerImpl() { |
- ui::InputMethodIBus* input_method = GetChromeInputMethod(); |
- if (input_method) { |
- ui::internal::IBusClient* client = input_method->ibus_client(); |
- // We assume that no objects other than |this| set an IBus client. |
- DCHECK(client); |
- static_cast<IBusChromeOSClientImpl*>(client)->set_ui(NULL); |
- } |
- // ibus_panel_service_ depends on ibus_, thus unref it first. |
- if (ibus_panel_service_) { |
- DisconnectPanelServiceSignals(); |
- g_object_unref(ibus_panel_service_); |
- } |
- if (ibus_) { |
- DisconnectIBusSignals(); |
- g_object_unref(ibus_); |
- } |
- } |
- |
- // Creates IBusBus object if it's not created yet, and tries to connect to |
- // ibus-daemon. Returns true if IBusBus is successfully connected to the |
- // daemon. |
- bool ConnectToIBus() { |
- if (ibus_) { |
- return true; |
- } |
- ibus_init(); |
- ibus_ = ibus_bus_new(); |
- CHECK(ibus_) << "ibus_bus_new() failed. Out of memory?"; |
- |
- bool result = false; |
- // Check the IBus connection status. |
- if (ibus_bus_is_connected(ibus_)) { |
- DVLOG(1) << "ibus_bus_is_connected(). IBus connection is ready."; |
- FOR_EACH_OBSERVER(Observer, observers_, OnConnectionChange(true)); |
- result = true; |
- } |
- |
- // Start listening the gobject signals regardless of the bus connection |
- // status. |
- ConnectIBusSignals(); |
- return result; |
- } |
- |
- // Creates IBusPanelService object if |ibus_| is already connected. |
- bool MaybeRestorePanelService() { |
- if (!ibus_ || !ibus_bus_is_connected(ibus_)) { |
- return false; |
- } |
- |
- if (ibus_panel_service_) { |
- DVLOG(1) << "IBusPanelService is already available. Remove it first."; |
- g_object_set_data(G_OBJECT(ibus_), kPanelObjectKey, NULL); |
- g_object_unref(ibus_panel_service_); |
- ibus_panel_service_ = NULL; |
- } |
- |
- // Create an IBusPanelService object. |
- GDBusConnection* ibus_connection = ibus_bus_get_connection(ibus_); |
- if (!ibus_connection) { |
- DVLOG(1) << "ibus_bus_get_connection() failed"; |
- return false; |
- } |
- ibus_panel_service_ = ibus_panel_service_new(ibus_connection); |
- if (!ibus_panel_service_) { |
- DVLOG(1) << "ibus_chromeos_panel_service_new() failed"; |
- return false; |
- } |
- ConnectPanelServiceSignals(); |
- g_object_set_data(G_OBJECT(ibus_), kPanelObjectKey, ibus_panel_service_); |
- DVLOG(1) << "IBusPanelService object is successfully (re-)created."; |
- |
- // Request the well-known name *asynchronously*. |
- ibus_bus_request_name_async(ibus_, |
- IBUS_SERVICE_PANEL, |
- 0 /* flags */, |
- -1 /* timeout */, |
- NULL /* cancellable */, |
- RequestNameCallback, |
- g_object_ref(ibus_)); |
- return true; |
- } |
- |
- // IBusUiController override. |
- virtual void NotifyCandidateClicked(int index, |
- int button, |
- int flags) OVERRIDE { |
- if (!ibus_ || !ibus_bus_is_connected(ibus_)) { |
- DVLOG(1) << "NotifyCandidateClicked: bus is not connected."; |
- return; |
- } |
- if (!ibus_panel_service_) { |
- DVLOG(1) << "NotifyCandidateClicked: panel service is not available."; |
- return; |
- } |
- |
- /* Send a D-Bus signal to ibus-daemon *asynchronously*. */ |
- ibus_panel_service_candidate_clicked(ibus_panel_service_, |
- index, |
- button, |
- flags); |
- } |
- |
- // IBusUiController override. |
- virtual void NotifyCursorUp() OVERRIDE { |
- if (!ibus_ || !ibus_bus_is_connected(ibus_)) { |
- DVLOG(1) << "NotifyCursorUp: bus is not connected."; |
- return; |
- } |
- if (!ibus_panel_service_) { |
- DVLOG(1) << "NotifyCursorUp: panel service is not available."; |
- return; |
- } |
- |
- /* Send a D-Bus signal to ibus-daemon *asynchronously*. */ |
- ibus_panel_service_cursor_up(ibus_panel_service_); |
- } |
- |
- // IBusUiController override. |
- virtual void NotifyCursorDown() OVERRIDE { |
- if (!ibus_ || !ibus_bus_is_connected(ibus_)) { |
- DVLOG(1) << "NotifyCursorDown: bus is not connected."; |
- return; |
- } |
- if (!ibus_panel_service_) { |
- DVLOG(1) << "NotifyCursorDown: panel service is not available."; |
- return; |
- } |
- /* Send a D-Bus signal to ibus-daemon *asynchronously*. */ |
- ibus_panel_service_cursor_down(ibus_panel_service_); |
- } |
- |
- // IBusUiController override. |
- virtual void NotifyPageUp() OVERRIDE { |
- if (!ibus_ || !ibus_bus_is_connected(ibus_)) { |
- DVLOG(1) << "NotifyPageUp: bus is not connected."; |
- return; |
- } |
- if (!ibus_panel_service_) { |
- DVLOG(1) << "NotifyPageUp: panel service is not available."; |
- return; |
- } |
- |
- /* Send a D-Bus signal to ibus-daemon *asynchronously*. */ |
- ibus_panel_service_page_up(ibus_panel_service_); |
- } |
- |
- // IBusUiController override. |
- virtual void NotifyPageDown() OVERRIDE { |
- if (!ibus_ || !ibus_bus_is_connected(ibus_)) { |
- DVLOG(1) << "NotifyPageDown: bus is not connected."; |
- return; |
- } |
- if (!ibus_panel_service_) { |
- DVLOG(1) << "NotifyPageDown: panel service is not available."; |
- return; |
- } |
- |
- /* Send a D-Bus signal to ibus-daemon *asynchronously*. */ |
- ibus_panel_service_page_down(ibus_panel_service_); |
- } |
- |
- // IBusUiController override. |
- virtual void Connect() OVERRIDE { |
- // It's totally fine if ConnectToIBus() fails here, as we'll get |
- // "connected" gobject signal once the connection becomes ready. |
- if (ConnectToIBus()) |
- MaybeRestorePanelService(); |
- } |
- |
- // IBusUiController override. |
- virtual void AddObserver(Observer* observer) OVERRIDE { |
- observers_.AddObserver(observer); |
- } |
- |
- // IBusUiController override. |
- virtual void RemoveObserver(Observer* observer) OVERRIDE { |
- observers_.RemoveObserver(observer); |
- } |
- |
- private: |
- // A class for customizing the behavior of ui::InputMethodIBus for Chrome OS. |
- class IBusChromeOSClientImpl : public ui::internal::IBusClient { |
- public: |
- explicit IBusChromeOSClientImpl(IBusUiControllerImpl* ui) |
- : ui_(ui) { |
- } |
- |
- // ui::IBusClient override. |
- virtual InputMethodType GetInputMethodType() OVERRIDE { |
- const std::string current_input_method_id = GetCurrentInputMethodId(); |
- return InputMethodUtil::IsKeyboardLayout(current_input_method_id) ? |
- INPUT_METHOD_XKB_LAYOUT : INPUT_METHOD_NORMAL; |
- } |
- |
- virtual void SetCursorLocation(const gfx::Rect& cursor_location, |
- const gfx::Rect& composition_head) OVERRIDE { |
- if (!ui_) |
- return; |
- // We don't have to call ibus_input_context_set_cursor_location() on |
- // Chrome OS because the candidate window for IBus is integrated with |
- // Chrome. |
- ui_->SetCursorLocation(NULL, cursor_location, composition_head); |
- } |
- |
- void set_ui(IBusUiControllerImpl* ui) { |
- ui_ = ui; |
- } |
- |
- private: |
- std::string GetCurrentInputMethodId() { |
- InputMethodManager* manager = InputMethodManager::GetInstance(); |
- return manager->GetCurrentInputMethod().id(); |
- } |
- |
- IBusUiControllerImpl* ui_; |
- }; |
- |
- // Returns a ui::InputMethodIBus object which is associated with the root |
- // window. Returns NULL if the Ash shell has already been destructed. |
- static ui::InputMethodIBus* GetChromeInputMethod() { |
- if (!ash::Shell::HasInstance()) |
- return NULL; |
- aura::Window* root_window = ash::Shell::GetPrimaryRootWindow(); |
- if (!root_window) |
- return NULL; |
- return static_cast<ui::InputMethodIBus*>(root_window->GetProperty( |
- aura::client::kRootWindowInputMethodKey)); |
- } |
- |
- // Functions that end with Thunk are used to deal with glib callbacks. |
- // |
- // Note that we cannot use CHROMEG_CALLBACK_0() here as we'll define |
- // IBusBusConnected() inline. If we are to define the function outside |
- // of the class definition, we should use CHROMEG_CALLBACK_0() here. |
- // |
- // CHROMEG_CALLBACK_0(Impl, |
- // void, IBusBusConnected, IBusBus*); |
- static void IBusBusConnectedThunk(IBusBus* sender, gpointer userdata) { |
- return reinterpret_cast<IBusUiControllerImpl*>(userdata) |
- ->IBusBusConnected(sender); |
- } |
- static void IBusBusDisconnectedThunk(IBusBus* sender, gpointer userdata) { |
- return reinterpret_cast<IBusUiControllerImpl*>(userdata) |
- ->IBusBusDisconnected(sender); |
- } |
- static void HideAuxiliaryTextThunk(IBusPanelService* sender, |
- gpointer userdata) { |
- return reinterpret_cast<IBusUiControllerImpl*>(userdata) |
- ->HideAuxiliaryText(sender); |
- } |
- static void HideLookupTableThunk(IBusPanelService* sender, |
- gpointer userdata) { |
- return reinterpret_cast<IBusUiControllerImpl*>(userdata) |
- ->HideLookupTable(sender); |
- } |
- static void UpdateAuxiliaryTextThunk(IBusPanelService* sender, |
- IBusText* text, gboolean visible, |
- gpointer userdata) { |
- return reinterpret_cast<IBusUiControllerImpl*>(userdata) |
- ->UpdateAuxiliaryText(sender, text, visible); |
- } |
- static void SetCursorLocationThunk(IBusPanelService* sender, |
- gint x, gint y, gint width, gint height, |
- gpointer userdata) { |
- return reinterpret_cast<IBusUiControllerImpl*>(userdata) |
- ->SetCursorLocation(sender, gfx::Rect(x, y, width, height), |
- gfx::Rect()); |
- } |
- static void UpdateLookupTableThunk(IBusPanelService* sender, |
- IBusLookupTable* table, gboolean visible, |
- gpointer userdata) { |
- return reinterpret_cast<IBusUiControllerImpl*>(userdata) |
- ->UpdateLookupTable(sender, table, visible); |
- } |
- static void UpdatePreeditTextThunk(IBusPanelService* sender, |
- IBusText* text, |
- guint cursor_pos, |
- gboolean visible, |
- gpointer userdata) { |
- return reinterpret_cast<IBusUiControllerImpl*>(userdata) |
- ->UpdatePreeditText(sender, text, cursor_pos, visible); |
- } |
- static void HidePreeditTextThunk(IBusPanelService* sender, |
- gpointer userdata) { |
- return reinterpret_cast<IBusUiControllerImpl*>(userdata) |
- ->HidePreeditText(sender); |
- } |
- |
- |
- // Installs gobject signal handlers to |ibus_|. |
- void ConnectIBusSignals() { |
- if (!ibus_) { |
- return; |
- } |
- g_signal_connect(ibus_, |
- "connected", |
- G_CALLBACK(IBusBusConnectedThunk), |
- this); |
- g_signal_connect(ibus_, |
- "disconnected", |
- G_CALLBACK(IBusBusDisconnectedThunk), |
- this); |
- } |
- |
- // Removes gobject signal handlers from |ibus_|. |
- void DisconnectIBusSignals() { |
- if (!ibus_) { |
- return; |
- } |
- g_signal_handlers_disconnect_by_func( |
- ibus_, |
- reinterpret_cast<gpointer>(G_CALLBACK(IBusBusConnectedThunk)), |
- this); |
- g_signal_handlers_disconnect_by_func( |
- ibus_, |
- reinterpret_cast<gpointer>(G_CALLBACK(IBusBusDisconnectedThunk)), |
- this); |
- } |
- |
- // Installs gobject signal handlers to |ibus_panel_service_|. |
- void ConnectPanelServiceSignals() { |
- if (!ibus_panel_service_) { |
- return; |
- } |
- g_signal_connect(ibus_panel_service_, |
- "hide-auxiliary-text", |
- G_CALLBACK(HideAuxiliaryTextThunk), |
- this); |
- g_signal_connect(ibus_panel_service_, |
- "hide-lookup-table", |
- G_CALLBACK(HideLookupTableThunk), |
- this); |
- g_signal_connect(ibus_panel_service_, |
- "update-auxiliary-text", |
- G_CALLBACK(UpdateAuxiliaryTextThunk), |
- this); |
- g_signal_connect(ibus_panel_service_, |
- "set-cursor-location", |
- G_CALLBACK(SetCursorLocationThunk), |
- this); |
- g_signal_connect(ibus_panel_service_, |
- "update-lookup-table", |
- G_CALLBACK(UpdateLookupTableThunk), |
- this); |
- g_signal_connect(ibus_panel_service_, |
- "update-preedit-text", |
- G_CALLBACK(UpdatePreeditTextThunk), |
- this); |
- g_signal_connect(ibus_panel_service_, |
- "hide-preedit-text", |
- G_CALLBACK(HidePreeditTextThunk), |
- this); |
- } |
- |
- // Removes gobject signal handlers from |ibus_panel_service_|. |
- void DisconnectPanelServiceSignals() { |
- if (!ibus_panel_service_) { |
- return; |
- } |
- g_signal_handlers_disconnect_by_func( |
- ibus_panel_service_, |
- reinterpret_cast<gpointer>(HideAuxiliaryTextThunk), |
- this); |
- g_signal_handlers_disconnect_by_func( |
- ibus_panel_service_, |
- reinterpret_cast<gpointer>(HideLookupTableThunk), |
- this); |
- g_signal_handlers_disconnect_by_func( |
- ibus_panel_service_, |
- reinterpret_cast<gpointer>(UpdateAuxiliaryTextThunk), |
- this); |
- g_signal_handlers_disconnect_by_func( |
- ibus_panel_service_, |
- reinterpret_cast<gpointer>(SetCursorLocationThunk), |
- this); |
- g_signal_handlers_disconnect_by_func( |
- ibus_panel_service_, |
- reinterpret_cast<gpointer>(UpdateLookupTableThunk), |
- this); |
- g_signal_handlers_disconnect_by_func( |
- ibus_panel_service_, |
- reinterpret_cast<gpointer>(UpdatePreeditTextThunk), |
- this); |
- g_signal_handlers_disconnect_by_func( |
- ibus_panel_service_, |
- reinterpret_cast<gpointer>(HidePreeditTextThunk), |
- this); |
- } |
- |
- // Handles "connected" signal from ibus-daemon. |
- void IBusBusConnected(IBusBus* bus) { |
- DVLOG(1) << "IBus connection is recovered."; |
- if (!MaybeRestorePanelService()) { |
- DVLOG(1) << "MaybeRestorePanelService() failed"; |
- return; |
- } |
+IBusUiController::IBusUiController() { |
+ ui::InputMethodIBus* input_method = GetChromeInputMethod(); |
+ DCHECK(input_method); |
+ input_method->set_ibus_client(scoped_ptr<ui::internal::IBusClient>( |
+ new IBusChromeOSClientImpl(this)).Pass()); |
+} |
- FOR_EACH_OBSERVER(Observer, observers_, OnConnectionChange(true)); |
+IBusUiController::~IBusUiController() { |
+ ui::InputMethodIBus* input_method = GetChromeInputMethod(); |
+ if (input_method) { |
+ ui::internal::IBusClient* client = input_method->ibus_client(); |
+ // We assume that no objects other than |this| set an IBus client. |
+ DCHECK(client); |
+ static_cast<IBusChromeOSClientImpl*>(client)->set_ui(NULL); |
} |
+} |
- // Handles "disconnected" signal from ibus-daemon. Releases the |
- // |ibus_panel_service_| object since the connection the service has will be |
- // destroyed soon. |
- void IBusBusDisconnected(IBusBus* bus) { |
- DVLOG(1) << "IBus connection is terminated."; |
- if (ibus_panel_service_) { |
- DisconnectPanelServiceSignals(); |
- // Since the connection being disconnected is currently mutex-locked, |
- // we can't unref the panel service object directly here. Because when the |
- // service object is deleted, the connection, which the service also has, |
- // will be locked again. To avoid deadlock, we use g_idle_add instead. |
- g_object_set_data(G_OBJECT(ibus_), kPanelObjectKey, NULL); |
- g_idle_add(ReleasePanelService, ibus_panel_service_); |
- ibus_panel_service_ = NULL; |
- } |
- |
- FOR_EACH_OBSERVER(Observer, observers_, OnConnectionChange(false)); |
+void IBusUiController::NotifyCandidateClicked(int index, int button, |
+ int flags) { |
+ ibus::IBusPanelService* service = GetIBusPanelService(); |
+ if (service) { |
+ service->CandidateClicked( |
+ index, |
+ static_cast<ibus::IBusMouseButton>(button), |
+ flags); |
} |
+} |
- // Releases |ibus_panel_service_|. See the comment above. |
- static gboolean ReleasePanelService(gpointer user_data) { |
- g_return_val_if_fail(IBUS_IS_PANEL_SERVICE(user_data), FALSE); |
- g_object_unref(user_data); |
- return FALSE; // stop the idle timer. |
- } |
+void IBusUiController::NotifyCursorUp() { |
+ ibus::IBusPanelService* service = GetIBusPanelService(); |
+ if (service) |
+ service->CursorUp(); |
+} |
- // Handles IBusPanelService's |HideAuxiliaryText| method call. |
- void HideAuxiliaryText(IBusPanelService* panel) { |
- FOR_EACH_OBSERVER(Observer, observers_, OnHideAuxiliaryText()); |
- } |
+void IBusUiController::NotifyCursorDown() { |
+ ibus::IBusPanelService* service = GetIBusPanelService(); |
+ if (service) |
+ service->CursorDown(); |
+} |
- // Handles IBusPanelService's |HideLookupTable| method call. |
- void HideLookupTable(IBusPanelService *panel) { |
- FOR_EACH_OBSERVER(Observer, observers_, OnHideLookupTable()); |
- } |
+void IBusUiController::NotifyPageUp() { |
+ ibus::IBusPanelService* service = GetIBusPanelService(); |
+ if (service) |
+ service->PageUp(); |
+} |
- // Handles IBusPanelService's |UpdateAuxiliaryText| method call. |
- void UpdateAuxiliaryText(IBusPanelService* panel, |
- IBusText* text, |
- gboolean visible) { |
- g_return_if_fail(text); |
- g_return_if_fail(text->text); |
- // Convert IBusText to a std::string. IBusText is an attributed text, |
- const std::string simple_text = text->text; |
- FOR_EACH_OBSERVER(Observer, observers_, |
- OnUpdateAuxiliaryText(simple_text, visible == TRUE)); |
- } |
+void IBusUiController::NotifyPageDown() { |
+ ibus::IBusPanelService* service = GetIBusPanelService(); |
+ if (service) |
+ service->PageDown(); |
+} |
- // Handles IBusPanelService's |SetCursorLocation| method call. |
- void SetCursorLocation(IBusPanelService *panel, |
- const gfx::Rect& cursor_location, |
- const gfx::Rect& composition_head) { |
- // Note: |panel| might be NULL. See IBusChromeOSClientImpl above. |
- FOR_EACH_OBSERVER(Observer, observers_, |
- OnSetCursorLocation(cursor_location, composition_head)); |
- } |
+void IBusUiController::AddObserver(Observer* observer) { |
+ observers_.AddObserver(observer); |
+} |
- // Handles IBusPanelService's |UpdatePreeditText| method call. |
- void UpdatePreeditText(IBusPanelService *panel, |
- IBusText *text, |
- guint cursor_pos, |
- gboolean visible) { |
- FOR_EACH_OBSERVER(Observer, observers_, |
- OnUpdatePreeditText(text->text, cursor_pos, visible)); |
- } |
+void IBusUiController::RemoveObserver(Observer* observer) { |
+ observers_.RemoveObserver(observer); |
+} |
- // Handles IBusPanelService's |UpdatePreeditText| method call. |
- void HidePreeditText(IBusPanelService *panel) { |
- FOR_EACH_OBSERVER(Observer, observers_, OnHidePreeditText()); |
- } |
+void IBusUiController::HideAuxiliaryText() { |
+ FOR_EACH_OBSERVER(Observer, observers_, OnHideAuxiliaryText()); |
+} |
- // Handles IBusPanelService's |UpdateLookupTable| method call. |
- void UpdateLookupTable(IBusPanelService *panel, |
- IBusLookupTable *table, |
- gboolean visible) { |
- g_return_if_fail(table); |
- |
- InputMethodLookupTable lookup_table; |
- lookup_table.visible = (visible == TRUE); |
- |
- // Copy the orientation information. |
- const gint orientation = ibus_lookup_table_get_orientation(table); |
- if (orientation == IBUS_ORIENTATION_VERTICAL) { |
- lookup_table.orientation = InputMethodLookupTable::kVertical; |
- } else if (orientation == IBUS_ORIENTATION_HORIZONTAL) { |
- lookup_table.orientation = InputMethodLookupTable::kHorizontal; |
- } |
- |
- // The function ibus_serializable_get_attachment had been changed |
- // to use GVariant by the commit |
- // https://github.com/ibus/ibus/commit/ac9dfac13cef34288440a2ecdf067cd827fb2f8f |
- GVariant* variant = ibus_serializable_get_attachment( |
- IBUS_SERIALIZABLE(table), "show_window_at_composition"); |
- if (variant) |
- lookup_table.show_at_composition_head = !!g_variant_get_boolean(variant); |
- else |
- lookup_table.show_at_composition_head = false; |
- |
- // Copy candidates and annotations to |lookup_table|. |
- for (int i = 0; ; i++) { |
- IBusText *text = ibus_lookup_table_get_candidate(table, i); |
- if (!text) |
- break; |
- lookup_table.candidates.push_back(text->text); |
- |
- IBusText *label = ibus_lookup_table_get_label(table, i); |
- if (label) |
- lookup_table.labels.push_back(label->text); |
- |
- GVariant* annotation_variant = |
- ibus_serializable_get_attachment(IBUS_SERIALIZABLE(text), |
- "annotation"); |
- lookup_table.annotations.push_back(""); |
- if (annotation_variant) { |
- const gchar* annotation = |
- g_variant_get_string(annotation_variant, NULL); |
- if (annotation) |
- lookup_table.annotations[i] = annotation; |
- } |
- |
- GVariant* description_title_variant = |
- ibus_serializable_get_attachment(IBUS_SERIALIZABLE(text), |
- "description_title"); |
- InputMethodLookupTable::Description description; |
- if (description_title_variant) { |
- const gchar* description_title = |
- g_variant_get_string(description_title_variant, NULL); |
- if (description_title) |
- description.title = description_title; |
- |
- } |
- |
- GVariant* description_body_variant = |
- ibus_serializable_get_attachment(IBUS_SERIALIZABLE(text), |
- "description_body"); |
- if (description_body_variant) { |
- const gchar* description_body = |
- g_variant_get_string(description_body_variant, NULL); |
- if (description_body) |
- description.body = description_body; |
- } |
- lookup_table.descriptions.push_back(description); |
- } |
- DCHECK_EQ(lookup_table.candidates.size(), |
- lookup_table.annotations.size()); |
- |
- lookup_table.cursor_absolute_index = |
- ibus_lookup_table_get_cursor_pos(table); |
- lookup_table.page_size = ibus_lookup_table_get_page_size(table); |
- // Ensure that the page_size is non-zero to avoid div-by-zero error. |
- if (lookup_table.page_size <= 0) { |
- DVLOG(1) << "Invalid page size: " << lookup_table.page_size; |
- lookup_table.page_size = 1; |
- } |
- |
- FOR_EACH_OBSERVER(Observer, observers_, |
- OnUpdateLookupTable(lookup_table)); |
- } |
+void IBusUiController::HideLookupTable() { |
+ FOR_EACH_OBSERVER(Observer, observers_, OnHideLookupTable()); |
+} |
- // A callback function that will be called when ibus_bus_request_name_async() |
- // request is finished. |
- static void RequestNameCallback(GObject* source_object, |
- GAsyncResult* res, |
- gpointer user_data) { |
- IBusBus* bus = IBUS_BUS(user_data); |
- g_return_if_fail(bus); |
- |
- GError* error = NULL; |
- const guint service_id = |
- ibus_bus_request_name_async_finish(bus, res, &error); |
- |
- if (!service_id) { |
- std::string message = "(unknown error)"; |
- if (error && error->message) { |
- message = error->message; |
- } |
- DVLOG(1) << "Failed to register the panel service: " << message; |
- } else { |
- DVLOG(1) << "The panel service is registered: ID=" << service_id; |
- } |
- |
- if (error) { |
- g_error_free(error); |
- } |
- g_object_unref(bus); |
- } |
+void IBusUiController::UpdateAuxiliaryText(const std::string& text, |
+ bool visible) { |
+ FOR_EACH_OBSERVER(Observer, observers_, |
+ OnUpdateAuxiliaryText(text, visible)); |
+} |
- IBusBus* ibus_; |
- IBusPanelService* ibus_panel_service_; |
- ObserverList<Observer> observers_; |
-}; |
-#endif // defined(HAVE_IBUS) |
- |
-// The stub implementation is used if IBus is not present. |
-// |
-// Note that this class is intentionally built even if HAVE_IBUS is |
-// defined so that we can easily tell build breakage when we change the |
-// IBusUiControllerImpl but forget to update the stub implementation. |
-class IBusUiControllerStubImpl : public IBusUiController { |
- public: |
- IBusUiControllerStubImpl() { |
- } |
+void IBusUiController::SetCursorLocation(const gfx::Rect& cursor_location, |
+ const gfx::Rect& composition_head) { |
+ FOR_EACH_OBSERVER(Observer, observers_, |
+ OnSetCursorLocation(cursor_location, composition_head)); |
+} |
- virtual void Connect() { |
- } |
+void IBusUiController::UpdatePreeditText(const std::string& text, |
+ uint32 cursor_pos, |
+ bool visible) { |
+ FOR_EACH_OBSERVER(Observer, observers_, |
+ OnUpdatePreeditText(text, cursor_pos, visible)); |
+} |
- virtual void AddObserver(Observer* observer) { |
- } |
+void IBusUiController::HidePreeditText() { |
+ FOR_EACH_OBSERVER(Observer, observers_, OnHidePreeditText()); |
+} |
- virtual void RemoveObserver(Observer* observer) { |
- } |
+void IBusUiController::UpdateLookupTable(const ibus::IBusLookupTable& table, |
+ bool visible) { |
+ // TODO(nona): Use ibus::IBusLookupTable instead. |
+ InputMethodLookupTable lookup_table; |
+ lookup_table.visible = visible; |
- virtual void NotifyCandidateClicked(int index, int button, int flags) { |
+ // Copy the orientation information. |
+ if (table.orientation() == |
+ ibus::IBusLookupTable::IBUS_LOOKUP_TABLE_ORIENTATION_VERTICAL) { |
+ lookup_table.orientation = InputMethodLookupTable::kVertical; |
+ } else { |
+ lookup_table.orientation = InputMethodLookupTable::kHorizontal; |
} |
- virtual void NotifyCursorUp() { |
- } |
+ lookup_table.show_at_composition_head = table.show_window_at_composition(); |
- virtual void NotifyCursorDown() { |
- } |
+ // Copy candidates and annotations to |lookup_table|. |
+ for (size_t i = 0; i < table.candidates().size(); ++i) { |
+ const ibus::IBusLookupTable::Entry& entry = table.candidates()[i]; |
+ lookup_table.candidates.push_back(entry.value); |
+ lookup_table.labels.push_back(entry.label); |
+ lookup_table.annotations.push_back(entry.annotation); |
- virtual void NotifyPageUp() { |
+ InputMethodLookupTable::Description description; |
+ description.title = entry.description_title; |
+ description.body = entry.description_body; |
+ lookup_table.descriptions.push_back(description); |
} |
- virtual void NotifyPageDown() { |
+ lookup_table.cursor_absolute_index = table.cursor_position(); |
+ lookup_table.page_size = table.page_size(); |
+ // Ensure that the page_size is non-zero to avoid div-by-zero error. |
+ if (lookup_table.page_size <= 0) { |
+ DVLOG(1) << "Invalid page size: " << lookup_table.page_size; |
+ lookup_table.page_size = 1; |
} |
-}; |
- |
-IBusUiController* IBusUiController::Create() { |
-#if defined(HAVE_IBUS) |
- return new IBusUiControllerImpl; |
-#else |
- return new IBusUiControllerStubImpl; |
-#endif |
-} |
- |
-IBusUiController::~IBusUiController() { |
-} |
-bool IsActiveForTesting(const std::string& input_method_id, |
- const InputMethodDescriptors* descriptors) { |
- return IsActive(input_method_id, descriptors); |
+ FOR_EACH_OBSERVER(Observer, observers_, |
+ OnUpdateLookupTable(lookup_table)); |
} |
} // namespace input_method |