diff -Nru fcitx-4.2.8.4/debian/changelog fcitx-4.2.8.4/debian/changelog --- fcitx-4.2.8.4/debian/changelog 2014-08-23 01:51:44.000000000 -0400 +++ fcitx-4.2.8.4/debian/changelog 2014-08-28 16:08:46.000000000 -0400 @@ -1,3 +1,12 @@ +fcitx (1:4.2.8.4-4) utopic; urgency=medium + + * debian/patches/0005-Add-CurrentIM-D-Bus-property.patch: + - Add CurrentIM D-Bus property. + * debian/patches/unity-indicator-keyboard-icons.patch: + - Use indicator-keyboard icons under Unity. + + -- William Hua Thu, 28 Aug 2014 16:07:37 -0400 + fcitx (1:4.2.8.4-3) unstable; urgency=medium * 0004-implement-set-im-by-name-if-there-is-no-focused-wind.patch: diff -Nru fcitx-4.2.8.4/debian/patches/0005-Add-CurrentIM-D-Bus-property.patch fcitx-4.2.8.4/debian/patches/0005-Add-CurrentIM-D-Bus-property.patch --- fcitx-4.2.8.4/debian/patches/0005-Add-CurrentIM-D-Bus-property.patch 1969-12-31 19:00:00.000000000 -0500 +++ fcitx-4.2.8.4/debian/patches/0005-Add-CurrentIM-D-Bus-property.patch 2014-08-28 16:06:34.000000000 -0400 @@ -0,0 +1,268 @@ +From f634890a80d36deec9293d3cc4864f568eab23aa Mon Sep 17 00:00:00 2001 +From: William Hua +Date: Thu, 28 Aug 2014 11:31:23 -0400 +Subject: [PATCH] Add CurrentIM D-Bus property. + +--- + src/frontend/ipc/ipc.c | 86 +++++++++++++++++++++++++------- + src/lib/fcitx-gclient/fcitxinputmethod.c | 71 ++++++++++++++++++++++++++ + 2 files changed, 140 insertions(+), 17 deletions(-) + +diff --git a/src/frontend/ipc/ipc.c b/src/frontend/ipc/ipc.c +index 16b3962..8db76c1 100644 +--- a/src/frontend/ipc/ipc.c ++++ b/src/frontend/ipc/ipc.c +@@ -88,13 +88,19 @@ static void IPCICReset(FcitxIPCFrontend* ipc, FcitxInputContext* ic); + static void IPCICSetCursorRect(FcitxIPCFrontend* ipc, FcitxInputContext* ic, int x, int y, int w, int h); + static int IPCProcessKey(FcitxIPCFrontend* ipc, FcitxInputContext* callic, const uint32_t originsym, const uint32_t keycode, const uint32_t originstate, uint32_t t, FcitxKeyEventType type); + static boolean IPCCheckICFromSameApplication(void* arg, FcitxInputContext* icToCheck, FcitxInputContext* ic); ++static void IPCEmitPropertiesChanged(void* arg, const char* const* properties); ++static void IPCEmitPropertyChanged(void* arg, const char* property); + static void IPCGetPropertyIMList(void* arg, DBusMessageIter* iter); + static void IPCSetPropertyIMList(void* arg, DBusMessageIter* iter); + static void IPCUpdateIMList(void* arg); ++static void IPCGetPropertyCurrentIM(void* arg, DBusMessageIter* iter); ++static void IPCSetPropertyCurrentIM(void* arg, DBusMessageIter* iter); ++static void IPCUpdateCurrentIM(void* arg); + static pid_t IPCGetPid(void* arg, FcitxInputContext* ic); + + const FcitxDBusPropertyTable propertTable[] = { + { FCITX_IM_DBUS_INTERFACE, "IMList", "a(sssb)", IPCGetPropertyIMList, IPCSetPropertyIMList }, ++ { FCITX_IM_DBUS_INTERFACE, "CurrentIM", "s", IPCGetPropertyCurrentIM, IPCSetPropertyCurrentIM }, + { NULL, NULL, NULL, NULL, NULL } + }; + +@@ -199,6 +205,9 @@ const char * im_introspection_xml = + "" + "" + "" ++ "" ++ "" ++ "" + "" + ""; + +@@ -345,6 +354,8 @@ void* IPCCreate(FcitxInstance* instance, int frontendid) + hook.arg = ipc; + hook.func = IPCUpdateIMList; + FcitxInstanceRegisterUpdateIMListHook(instance, hook); ++ hook.func = IPCUpdateCurrentIM; ++ FcitxInstanceRegisterIMChangedHook(instance, hook); + + return ipc; + } +@@ -1199,6 +1210,40 @@ boolean IPCCheckICFromSameApplication(void* arg, FcitxInputContext* icToCheck, F + return strcmp(ic2ToCheck->prgname, ic2->prgname) == 0; + } + ++void IPCEmitPropertiesChanged(void* arg, const char* const* properties) ++{ ++ if (!properties || !*properties) ++ return; ++ ++ FcitxIPCFrontend* ipc = (FcitxIPCFrontend*) arg; ++ DBusMessage* msg = dbus_message_new_signal(FCITX_IM_DBUS_PATH, // object name of the signal ++ DBUS_INTERFACE_PROPERTIES, // interface name of the signal ++ "PropertiesChanged"); // name of the signal ++ ++ DBusMessageIter args; ++ DBusMessageIter changed_properties, invalidated_properties; ++ char sinterface[] = FCITX_IM_DBUS_INTERFACE; ++ char* interface = sinterface; ++ dbus_message_iter_init_append(msg, &args); ++ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &interface); ++ ++ dbus_message_iter_open_container(&args, DBUS_TYPE_ARRAY, "{sv}", &changed_properties); ++ dbus_message_iter_close_container(&args, &changed_properties); ++ ++ dbus_message_iter_open_container(&args, DBUS_TYPE_ARRAY, "s", &invalidated_properties); ++ for (; *properties; properties++) ++ dbus_message_iter_append_basic(&invalidated_properties, DBUS_TYPE_STRING, properties); ++ dbus_message_iter_close_container(&args, &invalidated_properties); ++ ++ IPCSendSignal(ipc, NULL, msg); ++} ++ ++void IPCEmitPropertyChanged(void* arg, const char* property) ++{ ++ const char* properties[] = { property, NULL }; ++ IPCEmitPropertiesChanged(arg, properties); ++} ++ + void IPCGetPropertyIMList(void* arg, DBusMessageIter* args) + { + FcitxIPCFrontend* ipc = (FcitxIPCFrontend*) arg; +@@ -1305,28 +1350,35 @@ void IPCSetPropertyIMList(void* arg, DBusMessageIter* args) + + void IPCUpdateIMList(void* arg) + { ++ IPCEmitPropertyChanged(arg, "IMList"); ++} ++ ++void IPCGetPropertyCurrentIM(void* arg, DBusMessageIter* args) ++{ + FcitxIPCFrontend* ipc = (FcitxIPCFrontend*) arg; +- DBusMessage* msg = dbus_message_new_signal(FCITX_IM_DBUS_PATH, // object name of the signal +- DBUS_INTERFACE_PROPERTIES, // interface name of the signal +- "PropertiesChanged"); // name of the signal ++ FcitxInstance* instance = ipc->owner; ++ FcitxIM* im = FcitxInstanceGetCurrentIM(instance); ++ const char* currentIM = im && im->uniqueName ? im->uniqueName : ""; + +- DBusMessageIter args; +- DBusMessageIter changed_properties, invalidated_properties; +- char sinterface[] = FCITX_IM_DBUS_INTERFACE; +- char sproperty[] = "IMList"; +- char* interface = sinterface; +- char* property = sproperty; +- dbus_message_iter_init_append(msg, &args); +- dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &interface); ++ dbus_message_iter_append_basic(args, DBUS_TYPE_STRING, ¤tIM); ++} + +- dbus_message_iter_open_container(&args, DBUS_TYPE_ARRAY, "{sv}", &changed_properties); +- dbus_message_iter_close_container(&args, &changed_properties); ++void IPCSetPropertyCurrentIM(void* arg, DBusMessageIter* args) ++{ ++ FcitxIPCFrontend* ipc = (FcitxIPCFrontend*) arg; ++ FcitxInstance* instance = ipc->owner; ++ const char* currentIM; + +- dbus_message_iter_open_container(&args, DBUS_TYPE_ARRAY, "s", &invalidated_properties); +- dbus_message_iter_append_basic(&invalidated_properties, DBUS_TYPE_STRING, &property); +- dbus_message_iter_close_container(&args, &invalidated_properties); ++ if (dbus_message_iter_get_arg_type(args) != DBUS_TYPE_STRING) ++ return; + +- IPCSendSignal(ipc, NULL, msg); ++ dbus_message_iter_get_basic(args, ¤tIM); ++ FcitxInstanceSwitchIMByName(instance, currentIM); ++} ++ ++void IPCUpdateCurrentIM(void* arg) ++{ ++ IPCEmitPropertyChanged(arg, "CurrentIM"); + } + + pid_t IPCGetPid(void* arg, FcitxInputContext* ic) +diff --git a/src/lib/fcitx-gclient/fcitxinputmethod.c b/src/lib/fcitx-gclient/fcitxinputmethod.c +index ea6764e..2cf7896 100644 +--- a/src/lib/fcitx-gclient/fcitxinputmethod.c ++++ b/src/lib/fcitx-gclient/fcitxinputmethod.c +@@ -74,9 +74,19 @@ static const gchar introspection_xml[] = + " " + " " + " " ++ " " ++ " " ++ " " + " " + ""; + ++enum { ++ PROP_0, ++ PROP_CURRENT_IM, ++ N_PROPERTIES ++}; ++ ++static GParamSpec *properties[N_PROPERTIES]; + + enum { + IMLIST_CHANGED_SIGNAL, +@@ -252,6 +262,8 @@ fcitx_input_method_g_properties_changed(GDBusProxy *proxy, + while (g_variant_iter_next(iter, "{&sv}", &key, NULL)) { + if (g_strcmp0(key, "IMList") == 0) + g_signal_emit(user, signals[IMLIST_CHANGED_SIGNAL], 0); ++ else if (g_strcmp0(key, "CurrentIM") == 0) ++ g_object_notify_by_pspec(G_OBJECT(user), properties[PROP_CURRENT_IM]); + } + g_variant_iter_free(iter); + } +@@ -261,6 +273,8 @@ fcitx_input_method_g_properties_changed(GDBusProxy *proxy, + while (*item) { + if (g_strcmp0(*item, "IMList") == 0) + g_signal_emit(user, signals[IMLIST_CHANGED_SIGNAL], 0); ++ else if (g_strcmp0(*item, "CurrentIM") == 0) ++ g_object_notify_by_pspec(G_OBJECT(user), properties[PROP_CURRENT_IM]); + item++; + } + } +@@ -277,18 +291,75 @@ fcitx_input_method_g_signal(GDBusProxy *proxy, const gchar *sender_name, + } + + static void ++fcitx_input_method_get_property(GObject *object, ++ guint property_id, ++ GValue *value, ++ GParamSpec *pspec) ++{ ++ FcitxInputMethod *proxy = FCITX_INPUT_METHOD(object); ++ ++ switch (property_id) { ++ case PROP_CURRENT_IM: ++ g_value_take_string(value, fcitx_input_method_get_current_im(proxy)); ++ break; ++ default: ++ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); ++ } ++} ++ ++static void ++fcitx_input_method_set_property(GObject *object, ++ guint property_id, ++ const GValue *value, ++ GParamSpec *pspec) ++{ ++ FcitxInputMethod *proxy = FCITX_INPUT_METHOD(object); ++ gchar *current_im; ++ ++ switch (property_id) { ++ case PROP_CURRENT_IM: ++ current_im = g_value_dup_string(value); ++ fcitx_input_method_set_current_im(proxy, current_im); ++ g_free(current_im); ++ break; ++ default: ++ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); ++ } ++} ++ ++static void + fcitx_input_method_class_init(FcitxInputMethodClass *klass) + { + GObjectClass *gobject_class; + GDBusProxyClass *proxy_class; + + gobject_class = G_OBJECT_CLASS(klass); ++ gobject_class->get_property = fcitx_input_method_get_property; ++ gobject_class->set_property = fcitx_input_method_set_property; + gobject_class->finalize = fcitx_input_method_finalize; + + proxy_class = G_DBUS_PROXY_CLASS(klass); + proxy_class->g_signal = fcitx_input_method_g_signal; + proxy_class->g_properties_changed = fcitx_input_method_g_properties_changed; + ++ /* install properties */ ++ /** ++ * FcitxInputMethod:current-im: ++ * ++ * The current IM. ++ */ ++ properties[PROP_CURRENT_IM] = g_param_spec_string("current-im", ++ "The current IM", ++ "The current IM", ++ "", ++ G_PARAM_CONSTRUCT | ++ G_PARAM_READWRITE | ++ G_PARAM_STATIC_NAME | ++ G_PARAM_STATIC_NICK | ++ G_PARAM_STATIC_BLURB); ++ ++ g_object_class_install_properties(gobject_class, N_PROPERTIES, properties); ++ + /* install signals */ + /** + * FcitxInputMethod::imlist-changed: +-- +2.1.0 + diff -Nru fcitx-4.2.8.4/debian/patches/series fcitx-4.2.8.4/debian/patches/series --- fcitx-4.2.8.4/debian/patches/series 2014-08-23 01:49:49.000000000 -0400 +++ fcitx-4.2.8.4/debian/patches/series 2014-08-28 16:07:05.000000000 -0400 @@ -2,3 +2,5 @@ 0002-no-display-desktop.patch 0003-wait-dbus-up-to-20-times.patch 0004-implement-set-im-by-name-if-there-is-no-focused-wind.patch +0005-Add-CurrentIM-D-Bus-property.patch +unity-indicator-keyboard-icons.patch diff -Nru fcitx-4.2.8.4/debian/patches/unity-indicator-keyboard-icons.patch fcitx-4.2.8.4/debian/patches/unity-indicator-keyboard-icons.patch --- fcitx-4.2.8.4/debian/patches/unity-indicator-keyboard-icons.patch 1969-12-31 19:00:00.000000000 -0500 +++ fcitx-4.2.8.4/debian/patches/unity-indicator-keyboard-icons.patch 2014-08-28 16:06:47.000000000 -0400 @@ -0,0 +1,48 @@ +Index: fcitx-4.2.8.4/src/im/keyboard/keyboard.c +=================================================================== +--- fcitx-4.2.8.4.orig/src/im/keyboard/keyboard.c ++++ fcitx-4.2.8.4/src/im/keyboard/keyboard.c +@@ -271,15 +271,27 @@ void FcitxKeyboardLayoutCreate(FcitxKeyb + iface.ReloadConfig = NULL; + iface.OnClose = FcitxKeyboardOnClose; + ++ char *icon; ++ /* Use indicator-keyboard icons under Unity. */ ++ if (fcitx_utils_strcmp0(getenv("XDG_CURRENT_DESKTOP"), "Unity") == 0 && langCode && strlen(langCode) >= 2) { ++ fcitx_utils_alloc_cat_str(icon, "@indicator-keyboard-", langCode); ++ icon[20] = toupper(icon[20]); ++ icon[21] = tolower(icon[21]); ++ icon[22] = '\0'; ++ } else { ++ icon = strdup("kbd"); ++ } ++ + FcitxInstanceRegisterIMv2( + keyboard->owner, + layout, + uniqueName, + name, +- "kbd", ++ icon, + iface, + iPriority, + langCode); ++ free(icon); + free(uniqueName); + } + +Index: fcitx-4.2.8.4/src/ui/kimpanel/kimpanel.c +=================================================================== +--- fcitx-4.2.8.4.orig/src/ui/kimpanel/kimpanel.c ++++ fcitx-4.2.8.4/src/ui/kimpanel/kimpanel.c +@@ -218,8 +218,8 @@ FCITX_DEFINE_PLUGIN(fcitx_kimpanel_ui, u + static void SetIMMenu(FcitxIM *pim, char** prop) + { + const char *icon = ""; +- if (strncmp(pim->uniqueName, "fcitx-keyboard-", +- strlen("fcitx-keyboard-")) != 0) { ++ if (fcitx_utils_strcmp0(getenv("XDG_CURRENT_DESKTOP"), "Unity") == 0 || ++ strncmp(pim->uniqueName, "fcitx-keyboard-", strlen("fcitx-keyboard-")) != 0) { + icon = pim->strIconName; + } + boolean result = CheckAddPrefix(&icon);