Implement IME state per window.

BUG=http://code.google.com/p/ibus/issues/detail?id=1568
TEST=Disable global engine with ibus-setup.

Review URL: https://codereview.appspot.com/12957046
This commit is contained in:
fujiwarat 2013-08-28 13:10:46 +09:00
Родитель b4bb7c2d10
Коммит 47fbb13019
8 изменённых файлов: 442 добавлений и 172 удалений

Просмотреть файл

@ -826,7 +826,8 @@ _context_focus_out_cb (BusInputContext *context,
/**
* _context_destroy_cb:
*
* A callback function to be called when the "destroy" signal is sent to the context.
* A callback function to be called when the "destroy" signal is sent to the
* context.
*/
static void
_context_destroy_cb (BusInputContext *context,
@ -835,9 +836,12 @@ _context_destroy_cb (BusInputContext *context,
g_assert (BUS_IS_IBUS_IMPL (ibus));
g_assert (BUS_IS_INPUT_CONTEXT (context));
if (context == ibus->focused_context) {
if (context == ibus->focused_context)
bus_ibus_impl_set_focused_context (ibus, NULL);
}
if (ibus->panel &&
bus_input_context_get_capabilities (context) & IBUS_CAP_FOCUS)
bus_panel_proxy_destroy_context (ibus->panel, context);
ibus->contexts = g_list_remove (ibus->contexts, context);
g_object_unref (context);

Просмотреть файл

@ -1,8 +1,8 @@
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/* vim:set et sts=4: */
/* ibus - The Input Bus
* Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
* Copyright (C) 2008-2010 Red Hat, Inc.
* Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
* Copyright (C) 2008-2013 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -694,3 +694,23 @@ bus_panel_proxy_focus_out (BusPanelProxy *panel,
panel->focused_context = NULL;
}
void
bus_panel_proxy_destroy_context (BusPanelProxy *panel,
BusInputContext *context)
{
const gchar *path;
g_assert (BUS_IS_PANEL_PROXY (panel));
g_assert (BUS_IS_INPUT_CONTEXT (context));
g_object_ref_sink (context);
path = ibus_service_get_object_path ((IBusService *)context);
g_dbus_proxy_call ((GDBusProxy *)panel,
"DestroyContext",
g_variant_new ("(o)", path),
G_DBUS_CALL_FLAGS_NONE,
-1, NULL, NULL, NULL);
g_object_unref (context);
}

Просмотреть файл

@ -1,8 +1,8 @@
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/* vim:set et sts=4: */
/* ibus - The Input Bus
* Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
* Copyright (C) 2008-2010 Red Hat, Inc.
* Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
* Copyright (C) 2008-2013 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -36,62 +36,79 @@
#define BUS_PANEL_PROXY(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), BUS_TYPE_PANEL_PROXY, BusPanelProxy))
#define BUS_PANEL_PROXY_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), BUS_TYPE_PANEL_PROXY, BusPanelProxyClass))
(G_TYPE_CHECK_CLASS_CAST ((klass), \
BUS_TYPE_PANEL_PROXY, \
BusPanelProxyClass))
#define BUS_IS_PANEL_PROXY(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), BUS_TYPE_PANEL_PROXY))
#define BUS_IS_PANEL_PROXY_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), BUS_TYPE_PANEL_PROXY))
#define BUS_PANEL_PROXY_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), BUS_TYPE_PANEL_PROXY, BusPanelProxyClass))
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
BUS_TYPE_PANEL_PROXY, \
BusPanelProxyClass))
G_BEGIN_DECLS
typedef struct _BusPanelProxy BusPanelProxy;
typedef struct _BusPanelProxyClass BusPanelProxyClass;
GType bus_panel_proxy_get_type (void);
BusPanelProxy *bus_panel_proxy_new (BusConnection *connection);
GType bus_panel_proxy_get_type (void);
BusPanelProxy *bus_panel_proxy_new (BusConnection *connection);
/* functions that invoke D-Bus methods of the panel component. */
void bus_panel_proxy_focus_in (BusPanelProxy *panel,
BusInputContext *context);
void bus_panel_proxy_focus_out (BusPanelProxy *panel,
BusInputContext *context);
void bus_panel_proxy_focus_in (BusPanelProxy *panel,
BusInputContext *context);
void bus_panel_proxy_focus_out (BusPanelProxy *panel,
BusInputContext *context);
void bus_panel_proxy_destroy_context
(BusPanelProxy *panel,
BusInputContext *context);
void bus_panel_proxy_set_cursor_location
(BusPanelProxy *panel,
gint32 x,
gint32 y,
gint32 w,
gint32 h);
void bus_panel_proxy_update_preedit_text(BusPanelProxy *panel,
IBusText *text,
guint cursor_pos,
gboolean visible);
void bus_panel_proxy_show_preedit_text (BusPanelProxy *panel);
void bus_panel_proxy_hide_preedit_text (BusPanelProxy *panel);
(BusPanelProxy *panel,
gint32 x,
gint32 y,
gint32 w,
gint32 h);
void bus_panel_proxy_update_preedit_text
(BusPanelProxy *panel,
IBusText *text,
guint cursor_pos,
gboolean visible);
void bus_panel_proxy_show_preedit_text
(BusPanelProxy *panel);
void bus_panel_proxy_hide_preedit_text
(BusPanelProxy *panel);
void bus_panel_proxy_update_auxiliary_text
(BusPanelProxy *panel,
IBusText *text,
gboolean visible);
void bus_panel_proxy_show_auxiliary_text(BusPanelProxy *panel);
void bus_panel_proxy_hide_auxiliary_text(BusPanelProxy *panel);
void bus_panel_proxy_update_lookup_table(BusPanelProxy *panel,
IBusLookupTable *table,
gboolean visible);
void bus_panel_proxy_show_lookup_table (BusPanelProxy *panel);
void bus_panel_proxy_hide_lookup_table (BusPanelProxy *panel);
(BusPanelProxy *panel,
IBusText *text,
gboolean visible);
void bus_panel_proxy_show_auxiliary_text
(BusPanelProxy *panel);
void bus_panel_proxy_hide_auxiliary_text
(BusPanelProxy *panel);
void bus_panel_proxy_update_lookup_table
(BusPanelProxy *panel,
IBusLookupTable *table,
gboolean visible);
void bus_panel_proxy_show_lookup_table
(BusPanelProxy *panel);
void bus_panel_proxy_hide_lookup_table
(BusPanelProxy *panel);
void bus_panel_proxy_page_up_lookup_table
(BusPanelProxy *panel);
(BusPanelProxy *panel);
void bus_panel_proxy_page_down_lookup_table
(BusPanelProxy *panel);
(BusPanelProxy *panel);
void bus_panel_proxy_cursor_up_lookup_table
(BusPanelProxy *panel);
(BusPanelProxy *panel);
void bus_panel_proxy_cursor_down_lookup_table
(BusPanelProxy *panel);
void bus_panel_proxy_register_properties(BusPanelProxy *panel,
IBusPropList *prop_list);
void bus_panel_proxy_update_property (BusPanelProxy *panel,
IBusProperty *prop);
(BusPanelProxy *panel);
void bus_panel_proxy_register_properties
(BusPanelProxy *panel,
IBusPropList *prop_list);
void bus_panel_proxy_update_property
(BusPanelProxy *panel,
IBusProperty *prop);
G_END_DECLS
#endif

Просмотреть файл

@ -282,7 +282,7 @@
<applyto>/desktop/ibus/general/use_global_engine</applyto>
<owner>ibus</owner>
<type>bool</type>
<default>false</default>
<default>true</default>
<locale name="C">
<short>Use global input method</short>
<long>Share the same input method among all applications</long>

Просмотреть файл

@ -1001,7 +1001,7 @@ You may use up/down buttons to change it.&lt;/i&gt;&lt;/small&gt;</property>
</child>
<child>
<object class="GtkFrame" id="frame5">
<property name="no_show_all">True</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>

Просмотреть файл

@ -1,8 +1,8 @@
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/* vim:set et sts=4: */
/* ibus - The Input Bus
* Copyright (c) 2009, Google Inc. All rights reserved.
* Copyright (C) 2010 Peng Huang <shawn.p.huang@gmail.com>
* Copyright (c) 2009-2013 Google Inc. All rights reserved.
* Copyright (C) 2010-2013 Peng Huang <shawn.p.huang@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -48,6 +48,7 @@ enum {
SHOW_PREEDIT_TEXT,
START_SETUP,
STATE_CHANGED,
DESTROY_CONTEXT,
LAST_SIGNAL,
};
@ -58,62 +59,80 @@ enum {
static guint panel_signals[LAST_SIGNAL] = { 0 };
/* functions prototype */
static void ibus_panel_service_set_property (IBusPanelService *panel,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void ibus_panel_service_get_property (IBusPanelService *panel,
guint prop_id,
GValue *value,
GParamSpec *pspec);
static void ibus_panel_service_real_destroy (IBusPanelService *panel);
static void ibus_panel_service_service_method_call (IBusService *service,
GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *method_name,
GVariant *parameters,
GDBusMethodInvocation *invocation);
static GVariant *ibus_panel_service_service_get_property (IBusService *service,
GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *property_name,
GError **error);
static gboolean ibus_panel_service_service_set_property (IBusService *service,
GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *property_name,
GVariant *value,
GError **error);
static void ibus_panel_service_not_implemented (IBusPanelService *panel);
static void ibus_panel_service_focus_in (IBusPanelService *panel,
const gchar *input_context_path);
static void ibus_panel_service_focus_out (IBusPanelService *panel,
const gchar *input_context_path);
static void ibus_panel_service_register_properties (IBusPanelService *panel,
IBusPropList *prop_list);
static void ibus_panel_service_set_cursor_location (IBusPanelService *panel,
gint x,
gint y,
gint w,
gint h);
static void ibus_panel_service_update_auxiliary_text (IBusPanelService *panel,
IBusText *text,
gboolean visible);
static void ibus_panel_service_update_lookup_table (IBusPanelService *panel,
IBusLookupTable *lookup_table,
gboolean visible);
static void ibus_panel_service_update_preedit_text (IBusPanelService *panel,
IBusText *text,
guint cursor_pos,
gboolean visible);
static void ibus_panel_service_update_property (IBusPanelService *panel,
IBusProperty *prop);
static void ibus_panel_service_set_property
(IBusPanelService *panel,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void ibus_panel_service_get_property
(IBusPanelService *panel,
guint prop_id,
GValue *value,
GParamSpec *pspec);
static void ibus_panel_service_real_destroy
(IBusPanelService *panel);
static void ibus_panel_service_service_method_call
(IBusService *service,
GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *method_name,
GVariant *parameters,
GDBusMethodInvocation *invocation);
static GVariant *ibus_panel_service_service_get_property
(IBusService *service,
GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *property_name,
GError **error);
static gboolean ibus_panel_service_service_set_property
(IBusService *service,
GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *property_name,
GVariant *value,
GError **error);
static void ibus_panel_service_not_implemented
(IBusPanelService *panel);
static void ibus_panel_service_focus_in
(IBusPanelService *panel,
const gchar *input_context_path);
static void ibus_panel_service_focus_out
(IBusPanelService *panel,
const gchar *input_context_path);
static void ibus_panel_service_destroy_context
(IBusPanelService *panel,
const gchar *input_context_path);
static void ibus_panel_service_register_properties
(IBusPanelService *panel,
IBusPropList *prop_list);
static void ibus_panel_service_set_cursor_location
(IBusPanelService *panel,
gint x,
gint y,
gint w,
gint h);
static void ibus_panel_service_update_auxiliary_text
(IBusPanelService *panel,
IBusText *text,
gboolean visible);
static void ibus_panel_service_update_lookup_table
(IBusPanelService *panel,
IBusLookupTable *lookup_table,
gboolean visible);
static void ibus_panel_service_update_preedit_text
(IBusPanelService *panel,
IBusText *text,
guint cursor_pos,
gboolean visible);
static void ibus_panel_service_update_property
(IBusPanelService *panel,
IBusProperty *prop);
G_DEFINE_TYPE (IBusPanelService, ibus_panel_service, IBUS_TYPE_SERVICE)
@ -156,6 +175,9 @@ static const gchar introspection_xml[] =
" <method name='FocusOut'>"
" <arg direction='in' type='o' name='ic' />"
" </method>"
" <method name='DestroyContext'>"
" <arg direction='in' type='o' name='ic' />"
" </method>"
" <method name='SetCursorLocation'>"
" <arg direction='in' type='i' name='x' />"
" <arg direction='in' type='i' name='y' />"
@ -194,21 +216,30 @@ static void
ibus_panel_service_class_init (IBusPanelServiceClass *class)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
ibus_panel_service_parent_class = IBUS_SERVICE_CLASS (g_type_class_peek_parent (class));
ibus_panel_service_parent_class =
IBUS_SERVICE_CLASS (g_type_class_peek_parent (class));
gobject_class->set_property = (GObjectSetPropertyFunc) ibus_panel_service_set_property;
gobject_class->get_property = (GObjectGetPropertyFunc) ibus_panel_service_get_property;
gobject_class->set_property =
(GObjectSetPropertyFunc) ibus_panel_service_set_property;
gobject_class->get_property =
(GObjectGetPropertyFunc) ibus_panel_service_get_property;
IBUS_OBJECT_CLASS (gobject_class)->destroy = (IBusObjectDestroyFunc) ibus_panel_service_real_destroy;
IBUS_OBJECT_CLASS (gobject_class)->destroy =
(IBusObjectDestroyFunc) ibus_panel_service_real_destroy;
IBUS_SERVICE_CLASS (class)->service_method_call = ibus_panel_service_service_method_call;
IBUS_SERVICE_CLASS (class)->service_get_property = ibus_panel_service_service_get_property;
IBUS_SERVICE_CLASS (class)->service_set_property = ibus_panel_service_service_set_property;
IBUS_SERVICE_CLASS (class)->service_method_call =
ibus_panel_service_service_method_call;
IBUS_SERVICE_CLASS (class)->service_get_property =
ibus_panel_service_service_get_property;
IBUS_SERVICE_CLASS (class)->service_set_property =
ibus_panel_service_service_set_property;
ibus_service_class_add_interfaces (IBUS_SERVICE_CLASS (class), introspection_xml);
ibus_service_class_add_interfaces (IBUS_SERVICE_CLASS (class),
introspection_xml);
class->focus_in = ibus_panel_service_focus_in;
class->focus_out = ibus_panel_service_focus_out;
class->destroy_context = ibus_panel_service_destroy_context;
class->register_properties = ibus_panel_service_register_properties;
class->set_cursor_location = ibus_panel_service_set_cursor_location;
class->update_lookup_table = ibus_panel_service_update_lookup_table;
@ -240,9 +271,11 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class)
* @visible: Whether the update is visible.
*
* Emitted when the client application get the update-preedit-text.
* Implement the member function update_preedit_text() in extended class to receive this signal.
* Implement the member function update_preedit_text() in extended class
* to receive this signal.
*
* <note><para>Argument @user_data is ignored in this function.</para></note>
* <note><para>Argument @user_data is ignored in this function.</para>
* </note>
*/
panel_signals[UPDATE_PREEDIT_TEXT] =
g_signal_new (I_("update-preedit-text"),
@ -263,9 +296,11 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class)
* @visible: Whether the update is visible.
*
* Emitted when the client application get the update-auxiliary-text.
* Implement the member function update_auxiliary_text() in extended class to receive this signal.
* Implement the member function update_auxiliary_text() in extended class
* to receive this signal.
*
* <note><para>Argument @user_data is ignored in this function.</para></note>
* <note><para>Argument @user_data is ignored in this function.</para>
* </note>
*/
panel_signals[UPDATE_AUXILIARY_TEXT] =
g_signal_new (I_("update-auxiliary-text"),
@ -285,9 +320,11 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class)
* @visible: Whether the update is visible.
*
* Emitted when the client application get the update-lookup-table.
* Implement the member function update_lookup_table() in extended class to receive this signal.
* Implement the member function update_lookup_table() in extended class
* to receive this signal.
*
* <note><para>Argument @user_data is ignored in this function.</para></note>
* <note><para>Argument @user_data is ignored in this function.</para>
* </note>
*/
panel_signals[UPDATE_LOOKUP_TABLE] =
g_signal_new (I_("update-lookup-table"),
@ -306,9 +343,11 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class)
* @input_context_path: Object path of InputContext.
*
* Emitted when the client application get the focus-in.
* Implement the member function focus_in() in extended class to receive this signal.
* Implement the member function focus_in() in extended class to receive
* this signal.
*
* <note><para>Argument @user_data is ignored in this function.</para></note>
* <note><para>Argument @user_data is ignored in this function.</para>
* </note>
*/
panel_signals[FOCUS_IN] =
g_signal_new (I_("focus-in"),
@ -326,9 +365,11 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class)
* @input_context_path: Object path of InputContext.
*
* Emitted when the client application get the focus-out.
* Implement the member function focus_out() in extended class to receive this signal.
* Implement the member function focus_out() in extended class to receive
* this signal.
*
* <note><para>Argument @user_data is ignored in this function.</para></note>
* <note><para>Argument @user_data is ignored in this function.</para>
* </note>
*/
panel_signals[FOCUS_OUT] =
g_signal_new (I_("focus-out"),
@ -346,9 +387,11 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class)
* @prop_list: An IBusPropList that contains properties.
*
* Emitted when the client application get the register-properties.
* Implement the member function register_properties() in extended class to receive this signal.
* Implement the member function register_properties() in extended class
* to receive this signal.
*
* <note><para>Argument @user_data is ignored in this function.</para></note>
* <note><para>Argument @user_data is ignored in this function.</para>
* </note>
*/
panel_signals[REGISTER_PROPERTIES] =
g_signal_new (I_("register-properties"),
@ -366,9 +409,11 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class)
* @prop: The IBusProperty to be updated.
*
* Emitted when the client application get the update-property.
* Implement the member function update_property() in extended class to receive this signal.
* Implement the member function update_property() in extended class to
* receive this signal.
*
* <note><para>Argument @user_data is ignored in this function.</para></note>
* <note><para>Argument @user_data is ignored in this function.</para>
* </note>
*/
panel_signals[UPDATE_PROPERTY] =
g_signal_new (I_("update-property"),
@ -389,9 +434,11 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class)
* @h: Height of the cursor.
*
* Emitted when the client application get the set-cursor-location.
* Implement the member function set_cursor_location() in extended class to receive this signal.
* Implement the member function set_cursor_location() in extended class
* to receive this signal.
*
* <note><para>Argument @user_data is ignored in this function.</para></note>
* <note><para>Argument @user_data is ignored in this function.</para>
* </note>
*/
panel_signals[SET_CURSOR_LOCATION] =
g_signal_new (I_("set-cursor-location"),
@ -411,9 +458,11 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class)
* IBusPanelService::cursor-up-lookup-table:
*
* Emitted when the client application get the cursor-up-lookup-table.
* Implement the member function cursor_up_lookup_table() in extended class to receive this signal.
* Implement the member function cursor_up_lookup_table() in extended
* class to receive this signal.
*
* <note><para>Argument @user_data is ignored in this function.</para></note>
* <note><para>Argument @user_data is ignored in this function.</para>
* </note>
*/
panel_signals[CURSOR_UP_LOOKUP_TABLE] =
g_signal_new (I_("cursor-up-lookup-table"),
@ -428,9 +477,11 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class)
* IBusPanelService::cursor-down-lookup-table:
*
* Emitted when the client application get the cursor-down-lookup-table.
* Implement the member function cursor_down_lookup_table() in extended class to receive this signal.
* Implement the member function cursor_down_lookup_table() in extended
* class to receive this signal.
*
* <note><para>Argument @user_data is ignored in this function.</para></note>
* <note><para>Argument @user_data is ignored in this function.</para>
* </note>
*/
panel_signals[CURSOR_DOWN_LOOKUP_TABLE] =
g_signal_new (I_("cursor-down-lookup-table"),
@ -445,9 +496,11 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class)
* IBusPanelService::hide-auxiliary-text:
*
* Emitted when the client application get the hide-auxiliary-text.
* Implement the member function hide_auxiliary_text() in extended class to receive this signal.
* Implement the member function hide_auxiliary_text() in extended class
* to receive this signal.
*
* <note><para>Argument @user_data is ignored in this function.</para></note>
* <note><para>Argument @user_data is ignored in this function.</para>
* </note>
*/
panel_signals[HIDE_AUXILIARY_TEXT] =
g_signal_new (I_("hide-auxiliary-text"),
@ -462,9 +515,11 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class)
* IBusPanelService::hide-language-bar:
*
* Emitted when the client application get the hide-language-bar.
* Implement the member function hide_language_bar() in extended class to receive this signal.
* Implement the member function hide_language_bar() in extended class to
* receive this signal.
*
* <note><para>Argument @user_data is ignored in this function.</para></note>
* <note><para>Argument @user_data is ignored in this function.</para>
* </note>
*/
panel_signals[HIDE_LANGUAGE_BAR] =
g_signal_new (I_("hide-language-bar"),
@ -479,9 +534,11 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class)
* IBusPanelService::hide-lookup-table:
*
* Emitted when the client application get the hide-lookup-table.
* Implement the member function hide_lookup_table() in extended class to receive this signal.
* Implement the member function hide_lookup_table() in extended class to
* receive this signal.
*
* <note><para>Argument @user_data is ignored in this function.</para></note>
* <note><para>Argument @user_data is ignored in this function.</para>
* </note>
*/
panel_signals[HIDE_LOOKUP_TABLE] =
g_signal_new (I_("hide-lookup-table"),
@ -496,9 +553,11 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class)
* IBusPanelService::hide-preedit-text:
*
* Emitted when the client application get the hide-preedit-text.
* Implement the member function hide_preedit_text() in extended class to receive this signal.
* Implement the member function hide_preedit_text() in extended class to
* receive this signal.
*
* <note><para>Argument @user_data is ignored in this function.</para></note>
* <note><para>Argument @user_data is ignored in this function.</para>
* </note>
*/
panel_signals[HIDE_PREEDIT_TEXT] =
g_signal_new (I_("hide-preedit-text"),
@ -513,9 +572,11 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class)
* IBusPanelService::page-up-lookup-table:
*
* Emitted when the client application get the page-up-lookup-table.
* Implement the member function page_up_lookup_table() in extended class to receive this signal.
* Implement the member function page_up_lookup_table() in extended class
* to receive this signal.
*
* <note><para>Argument @user_data is ignored in this function.</para></note>
* <note><para>Argument @user_data is ignored in this function.</para>
* </note>
*/
panel_signals[PAGE_UP_LOOKUP_TABLE] =
g_signal_new (I_("page-up-lookup-table"),
@ -530,9 +591,11 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class)
* IBusPanelService::page-down-lookup-table:
*
* Emitted when the client application get the page-down-lookup-table.
* Implement the member function page_down_lookup_table() in extended class to receive this signal.
* Implement the member function page_down_lookup_table() in extended
* class to receive this signal.
*
* <note><para>Argument @user_data is ignored in this function.</para></note>
* <note><para>Argument @user_data is ignored in this function.</para>
* </note>
*/
panel_signals[PAGE_DOWN_LOOKUP_TABLE] =
g_signal_new (I_("page-down-lookup-table"),
@ -547,9 +610,11 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class)
* IBusPanelService::reset:
*
* Emitted when the client application get the reset.
* Implement the member function reset() in extended class to receive this signal.
* Implement the member function reset() in extended class to receive this
* signal.
*
* <note><para>Argument @user_data is ignored in this function.</para></note>
* <note><para>Argument @user_data is ignored in this function.</para>
* </note>
*/
panel_signals[RESET] =
g_signal_new (I_("reset"),
@ -564,9 +629,11 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class)
* IBusPanelService::show-auxiliary-text:
*
* Emitted when the client application get the show-auxiliary-text.
* Implement the member function show_auxiliary_text() in extended class to receive this signal.
* Implement the member function show_auxiliary_text() in extended class
* to receive this signal.
*
* <note><para>Argument @user_data is ignored in this function.</para></note>
* <note><para>Argument @user_data is ignored in this function.</para>
* </note>
*/
panel_signals[SHOW_AUXILIARY_TEXT] =
g_signal_new (I_("show-auxiliary-text"),
@ -581,9 +648,11 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class)
* IBusPanelService::show-language-bar:
*
* Emitted when the client application get the show-language-bar.
* Implement the member function show_language_bar() in extended class to receive this signal.
* Implement the member function show_language_bar() in extended class to
* receive this signal.
*
* <note><para>Argument @user_data is ignored in this function.</para></note>
* <note><para>Argument @user_data is ignored in this function.</para>
* </note>
*/
panel_signals[SHOW_LANGUAGE_BAR] =
g_signal_new (I_("show-language-bar"),
@ -598,9 +667,11 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class)
* IBusPanelService::show-lookup-table:
*
* Emitted when the client application get the show-lookup-table.
* Implement the member function show_lookup_table() in extended class to receive this signal.
* Implement the member function show_lookup_table() in extended class to
* receive this signal.
*
* <note><para>Argument @user_data is ignored in this function.</para></note>
* <note><para>Argument @user_data is ignored in this function.</para>
* </note>
*/
panel_signals[SHOW_LOOKUP_TABLE] =
g_signal_new (I_("show-lookup-table"),
@ -615,9 +686,11 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class)
* IBusPanelService::show-preedit-text:
*
* Emitted when the client application get the show-preedit-text.
* Implement the member function show_preedit_text() in extended class to receive this signal.
* Implement the member function show_preedit_text() in extended class to
* receive this signal.
*
* <note><para>Argument @user_data is ignored in this function.</para></note>
* <note><para>Argument @user_data is ignored in this function.</para>
* </note>
*/
panel_signals[SHOW_PREEDIT_TEXT] =
g_signal_new (I_("show-preedit-text"),
@ -632,9 +705,11 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class)
* IBusPanelService::start-setup:
*
* Emitted when the client application get the start-setup.
* Implement the member function start_setup() in extended class to receive this signal.
* Implement the member function start_setup() in extended class to
* receive this signal.
*
* <note><para>Argument @user_data is ignored in this function.</para></note>
* <note><para>Argument @user_data is ignored in this function.</para>
* </note>
*/
panel_signals[START_SETUP] =
g_signal_new (I_("start-setup"),
@ -649,9 +724,11 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class)
* IBusPanelService::state-changed:
*
* Emitted when the client application get the state-changed.
* Implement the member function state_changed() in extended class to receive this signal.
* Implement the member function state_changed() in extended class to
* receive this signal.
*
* <note><para>Argument @user_data is ignored in this function.</para></note>
* <note><para>Argument @user_data is ignored in this function.</para>
* </note>
*/
panel_signals[STATE_CHANGED] =
g_signal_new (I_("state-changed"),
@ -661,6 +738,28 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class)
NULL, NULL,
_ibus_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* IBusPanelService::destroy-context:
* @input_context_path: Object path of InputContext.
*
* Emitted when the client application destroys.
* Implement the member function destroy_context() in extended class to
* receive this signal.
*
* <note><para>Argument @user_data is ignored in this function.</para>
* </note>
*/
panel_signals[DESTROY_CONTEXT] =
g_signal_new (I_("destroy-context"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (IBusPanelServiceClass, destroy_context),
NULL, NULL,
_ibus_marshal_VOID__STRING,
G_TYPE_NONE,
1,
G_TYPE_STRING);
}
static void
@ -790,6 +889,14 @@ ibus_panel_service_service_method_call (IBusService *service,
return;
}
if (g_strcmp0 (method_name, "DestroyContext") == 0) {
const gchar *path;
g_variant_get (parameters, "(&o)", &path);
g_signal_emit (panel, panel_signals[DESTROY_CONTEXT], 0, path);
g_dbus_method_invocation_return_value (invocation, NULL);
return;
}
if (g_strcmp0 (method_name, "RegisterProperties") == 0) {
GVariant *variant = g_variant_get_child_value (parameters, 0);
IBusPropList *prop_list = IBUS_PROP_LIST (ibus_serializable_deserialize (variant));
@ -917,6 +1024,13 @@ ibus_panel_service_focus_out (IBusPanelService *panel,
ibus_panel_service_not_implemented(panel);
}
static void
ibus_panel_service_destroy_context (IBusPanelService *panel,
const gchar *input_context_path)
{
ibus_panel_service_not_implemented(panel);
}
static void
ibus_panel_service_register_properties (IBusPanelService *panel,
IBusPropList *prop_list)

Просмотреть файл

@ -1,7 +1,7 @@
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/* vim:set et sts=4: */
/* ibus - The Input Bus
* Copyright (c) 2009, Google Inc. All rights reserved.
* Copyright (c) 2009-2013 Google Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -76,9 +76,11 @@ struct _IBusPanelServiceClass {
/* class members */
void (* focus_in) (IBusPanelService *panel,
const gchar *input_context_path);
const gchar
*input_context_path);
void (* focus_out) (IBusPanelService *panel,
const gchar *input_context_path);
const gchar
*input_context_path);
void (* register_properties) (IBusPanelService *panel,
IBusPropList *prop_list);
void (* set_cursor_location) (IBusPanelService *panel,
@ -93,7 +95,7 @@ struct _IBusPanelServiceClass {
IBusLookupTable *lookup_table,
gboolean visible);
void (* update_preedit_text) (IBusPanelService *panel,
IBusText *text,
IBusText *text,
guint cursor_pos,
gboolean visible);
void (* update_property) (IBusPanelService *panel,
@ -113,10 +115,13 @@ struct _IBusPanelServiceClass {
void (* show_preedit_text) (IBusPanelService *panel);
void (* start_setup) (IBusPanelService *panel);
void (* state_changed) (IBusPanelService *panel);
void (* destroy_context) (IBusPanelService *panel,
const gchar
*input_context_path);
/*< private >*/
/* padding */
gpointer pdummy[8]; // We can add 8 pointers without breaking the ABI.
gpointer pdummy[7]; // We can add 8 pointers without breaking the ABI.
};
GType ibus_panel_service_get_type (void);

Просмотреть файл

@ -2,7 +2,7 @@
*
* ibus - The Input Bus
*
* Copyright(c) 2011 Peng Huang <shawn.p.huang@gmail.com>
* Copyright(c) 2011-2013 Peng Huang <shawn.p.huang@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -43,8 +43,14 @@ class Panel : IBus.PanelService {
private Gtk.Menu m_ime_menu;
private Gtk.Menu m_sys_menu;
private IBus.EngineDesc[] m_engines = {};
private GLib.HashTable<string, IBus.EngineDesc> m_engine_contexts =
new GLib.HashTable<string, IBus.EngineDesc>(GLib.str_hash,
GLib.str_equal);
private string m_current_context_path = "";
private bool m_use_global_engine = true;
private CandidatePanel m_candidate_panel;
private Switcher m_switcher;
private bool m_switcher_is_running = false;
private PropertyManager m_property_manager;
private GLib.Pid m_setup_pid = 0;
private Gtk.AboutDialog m_about_dialog;
@ -120,6 +126,10 @@ class Panel : IBus.PanelService {
set_embed_preedit_text();
});
m_settings_general.changed["use-global-engine"].connect((key) => {
set_use_global_engine();
});
m_settings_hotkey.changed["triggers"].connect((key) => {
unbind_switch_shortcut();
bind_switch_shortcut();
@ -290,6 +300,11 @@ class Panel : IBus.PanelService {
m_bus.set_ibus_property("EmbedPreeditText", variant);
}
private void set_use_global_engine() {
m_use_global_engine =
m_settings_general.get_boolean("use-global-engine");
}
private int compare_versions(string version1, string version2) {
string[] version1_list = version1.split(".");
string[] version2_list = version2.split(".");
@ -376,6 +391,7 @@ class Panel : IBus.PanelService {
// Update m_use_system_keyboard_layout before update_engines()
// is called.
set_use_system_keyboard_layout();
set_use_global_engine();
update_engines(m_settings_general.get_strv("preload-engines"),
m_settings_general.get_strv("engines-order"));
unbind_switch_shortcut();
@ -432,6 +448,31 @@ class Panel : IBus.PanelService {
}
}
private void engine_contexts_insert(IBus.EngineDesc engine) {
if (m_use_global_engine)
return;
if (m_engine_contexts.size() >= 200) {
warning ("Contexts by windows are too much counted!");
m_engine_contexts.remove_all();
}
m_engine_contexts.replace(m_current_context_path, engine);
}
private void set_engine(IBus.EngineDesc engine) {
if (!m_bus.set_global_engine(engine.get_name())) {
warning("Switch engine to %s failed.", engine.get_name());
return;
}
// set xkb layout
if (!m_use_system_keyboard_layout)
exec_setxkbmap(engine);
engine_contexts_insert(engine);
}
private void switch_engine(int i, bool force = false) {
GLib.assert(i >= 0 && i < m_engines.length);
@ -441,14 +482,7 @@ class Panel : IBus.PanelService {
IBus.EngineDesc engine = m_engines[i];
if (!m_bus.set_global_engine(engine.get_name())) {
warning("Switch engine to %s failed.", engine.get_name());
return;
}
// set xkb layout
if (!m_use_system_keyboard_layout) {
exec_setxkbmap(engine);
}
set_engine(engine);
}
private void handle_engine_switch(Gdk.Event event, bool revert) {
@ -471,7 +505,20 @@ class Panel : IBus.PanelService {
if (pressed && m_switcher_delay_time >= 0) {
int i = revert ? m_engines.length - 1 : 1;
/* The flag of m_switcher_is_running avoids the following problem:
*
* When an IME is chosen on m_switcher, focus_in() is called
* for the root window. If an engine is set in focus_in()
* during running m_switcher when m_use_global_engine is false,
* state_changed() is also called and m_engines[] is modified
* in state_changed() and m_switcher.run() returns the index
* for m_engines[] but m_engines[] was modified by state_changed()
* and the index is not correct. */
m_switcher_is_running = true;
i = m_switcher.run(keyval, modifiers, event, m_engines, i);
m_switcher_is_running = false;
if (i < 0) {
debug("switch cancelled");
} else {
@ -686,9 +733,68 @@ class Panel : IBus.PanelService {
}
public override void focus_in(string input_context_path) {
if (m_use_global_engine)
return;
/* Do not change the order of m_engines during running switcher. */
if (m_switcher_is_running)
return;
m_current_context_path = input_context_path;
var engine = m_engine_contexts[m_current_context_path];
if (engine == null) {
/* If engine == null, need to call set_engine(m_engines[0])
* here and update m_engine_contexts[] to avoid the
* following problem:
*
* If context1 is focused and does not set an engine and
* return here, the current engine1 is used for context1.
* When context2 is focused and switch engine1 to engine2,
* the current engine becomes engine2.
* And when context1 is focused again, context1 still
* does not set an engine and return here,
* engine2 is used for context2 instead of engine1. */
engine = m_engines.length > 0 ? m_engines[0] : null;
if (engine == null)
return;
} else {
bool in_engines = false;
foreach (var e in m_engines) {
if (engine.get_name() == e.get_name()) {
in_engines = true;
break;
}
}
/* The engine is deleted by ibus-setup before focus_in()
* is called. */
if (!in_engines)
return;
}
set_engine(engine);
}
public override void focus_out(string input_context_path) {
if (m_use_global_engine)
return;
/* Do not change the order of m_engines during running switcher. */
if (m_switcher_is_running)
return;
m_current_context_path = "";
}
public override void destroy_context(string input_context_path) {
if (m_use_global_engine)
return;
m_engine_contexts.remove(input_context_path);
}
public override void register_properties(IBus.PropList props) {
@ -731,6 +837,10 @@ class Panel : IBus.PanelService {
}
public override void state_changed() {
/* Do not change the order of m_engines during running switcher. */
if (m_switcher_is_running)
return;
var icon_name = "ibus-keyboard";
var engine = m_bus.get_global_engine();