summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfujiwarat <takao.fujiwara1@gmail.com>2015-06-19 13:57:35 +0900
committerfujiwarat <takao.fujiwara1@gmail.com>2015-06-19 13:57:35 +0900
commit23c45b970b195008a54884a1a9d810e7f8b22c5c (patch)
treeca76b44f3f7e115a1e311bb77fd81b6e61c0b5f6
parent7fd6077f19a5a39cdcd9c7fde0d9c8234ae5592e (diff)
downloadibus-23c45b970b195008a54884a1a9d810e7f8b22c5c.tar.gz
Enable to show a property on ibus panel icon
If an engine sets the value of icon-prop-key of IBusEngineDesc to a property name of IBusProperty.key, the panel will show the engine property in the icon with a delayed time. This way can show both the engine icon and the engine mode in one icon. Review URL: https://codereview.appspot.com/248950043
-rw-r--r--data/ibus.schemas.in16
-rw-r--r--src/ibusenginedesc.c38
-rw-r--r--src/ibusenginedesc.h16
-rw-r--r--ui/gtk3/panel.vala75
4 files changed, 140 insertions, 5 deletions
diff --git a/data/ibus.schemas.in b/data/ibus.schemas.in
index 1fc64f94..b034133f 100644
--- a/data/ibus.schemas.in
+++ b/data/ibus.schemas.in
@@ -305,6 +305,22 @@
</locale>
</schema>
<schema>
+ <key>/schemas/desktop/ibus/panel/property-icon-delay-time</key>
+ <applyto>/desktop/ibus/panel/property-icon-delay-time</applyto>
+ <owner>ibus</owner>
+ <type>int</type>
+ <default>500</default>
+ <locale name="C">
+ <short>The milliseconds to show the panel icon for a property</short>
+ <long>The milliseconds to show the panel icon from the
+ engine icon to a property icon whenever engines are
+ switched if the property is specified by the value of
+ icon-prop-key in IBusEngineDesc.
+ If the value is 0, no delay time and the property icon
+ is shown immediately.</long>
+ </locale>
+ </schema>
+ <schema>
<key>/schemas/desktop/ibus/general/use_system_keyboard_layout</key>
<applyto>/desktop/ibus/general/use_system_keyboard_layout</applyto>
<owner>ibus</owner>
diff --git a/src/ibusenginedesc.c b/src/ibusenginedesc.c
index f1a04a09..22622865 100644
--- a/src/ibusenginedesc.c
+++ b/src/ibusenginedesc.c
@@ -1,8 +1,8 @@
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/* vim:set et sts=4: */
/* bus - The Input Bus
- * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
- * Copyright (C) 2008-2010 Red Hat, Inc.
+ * Copyright (C) 2008-2015 Peng Huang <shawn.p.huang@gmail.com>
+ * Copyright (C) 2008-2015 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
@@ -46,6 +46,7 @@ enum {
PROP_SETUP,
PROP_VERSION,
PROP_TEXTDOMAIN,
+ PROP_ICON_PROP_KEY
};
@@ -67,6 +68,7 @@ struct _IBusEngineDescPrivate {
gchar *setup;
gchar *version;
gchar *textdomain;
+ gchar *icon_prop_key;
};
#define IBUS_ENGINE_DESC_GET_PRIVATE(o) \
@@ -323,6 +325,19 @@ ibus_engine_desc_class_init (IBusEngineDescClass *class)
"The textdomain of engine description",
"",
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ /**
+ * IBusEngineDesc:icon-prop-key:
+ *
+ * The key of IBusProperty to change panel icon dynamically.
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_ICON_PROP_KEY,
+ g_param_spec_string ("icon-prop-key",
+ "icon property key",
+ "The key of IBusProperty for the dynamic panel icon",
+ "",
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
}
static void
@@ -346,6 +361,7 @@ ibus_engine_desc_init (IBusEngineDesc *desc)
desc->priv->setup = NULL;
desc->priv->version = NULL;
desc->priv->textdomain = NULL;
+ desc->priv->icon_prop_key = NULL;
}
static void
@@ -366,6 +382,7 @@ ibus_engine_desc_destroy (IBusEngineDesc *desc)
g_free (desc->priv->setup);
g_free (desc->priv->version);
g_free (desc->priv->textdomain);
+ g_free (desc->priv->icon_prop_key);
IBUS_OBJECT_CLASS (ibus_engine_desc_parent_class)->destroy (IBUS_OBJECT (desc));
}
@@ -440,6 +457,10 @@ ibus_engine_desc_set_property (IBusEngineDesc *desc,
g_assert (desc->priv->textdomain == NULL);
desc->priv->textdomain = g_value_dup_string (value);
break;
+ case PROP_ICON_PROP_KEY:
+ g_assert (desc->priv->icon_prop_key == NULL);
+ desc->priv->icon_prop_key = g_value_dup_string (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (desc, prop_id, pspec);
}
@@ -500,6 +521,9 @@ ibus_engine_desc_get_property (IBusEngineDesc *desc,
case PROP_TEXTDOMAIN:
g_value_set_string (value, ibus_engine_desc_get_textdomain (desc));
break;
+ case PROP_ICON_PROP_KEY:
+ g_value_set_string (value, ibus_engine_desc_get_icon_prop_key (desc));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (desc, prop_id, pspec);
}
@@ -537,6 +561,7 @@ ibus_engine_desc_serialize (IBusEngineDesc *desc,
g_variant_builder_add (builder, "s", NOTNULL (desc->priv->layout_option));
g_variant_builder_add (builder, "s", NOTNULL (desc->priv->version));
g_variant_builder_add (builder, "s", NOTNULL (desc->priv->textdomain));
+ g_variant_builder_add (builder, "s", NOTNULL (desc->priv->icon_prop_key));
#undef NOTNULL
return TRUE;
@@ -593,6 +618,10 @@ ibus_engine_desc_deserialize (IBusEngineDesc *desc,
return retval;
ibus_g_variant_get_child_string (variant, retval++,
&desc->priv->textdomain);
+ if (g_variant_n_children (variant) < retval + 1)
+ return retval;
+ ibus_g_variant_get_child_string (variant, retval++,
+ &desc->priv->icon_prop_key);
return retval;
}
@@ -623,6 +652,7 @@ ibus_engine_desc_copy (IBusEngineDesc *dest,
dest->priv->setup = g_strdup (src->priv->setup);
dest->priv->version = g_strdup (src->priv->version);
dest->priv->textdomain = g_strdup (src->priv->textdomain);
+ dest->priv->icon_prop_key = g_strdup (src->priv->icon_prop_key);
return TRUE;
}
@@ -666,6 +696,7 @@ ibus_engine_desc_output (IBusEngineDesc *desc,
OUTPUT_ENTRY_1(setup);
OUTPUT_ENTRY_1(version);
OUTPUT_ENTRY_1(textdomain);
+ OUTPUT_ENTRY_1(icon_prop_key);
g_string_append_indent (output, indent + 1);
g_string_append_printf (output, "<rank>%u</rank>\n", desc->priv->rank);
#undef OUTPUT_ENTRY
@@ -705,6 +736,7 @@ ibus_engine_desc_parse_xml_node (IBusEngineDesc *desc,
PARSE_ENTRY_1(setup);
PARSE_ENTRY_1(version);
PARSE_ENTRY_1(textdomain);
+ PARSE_ENTRY_1(icon_prop_key);
#undef PARSE_ENTRY
#undef PARSE_ENTRY_1
if (g_strcmp0 (sub_node->name , "rank") == 0) {
@@ -739,6 +771,7 @@ IBUS_ENGINE_DESC_GET_PROPERTY (symbol, const gchar *)
IBUS_ENGINE_DESC_GET_PROPERTY (setup, const gchar *)
IBUS_ENGINE_DESC_GET_PROPERTY (version, const gchar *)
IBUS_ENGINE_DESC_GET_PROPERTY (textdomain, const gchar *)
+IBUS_ENGINE_DESC_GET_PROPERTY (icon_prop_key, const gchar *)
#undef IBUS_ENGINE_DESC_GET_PROPERTY
IBusEngineDesc *
@@ -792,6 +825,7 @@ ibus_engine_desc_new_varargs (const gchar *first_property_name, ...)
g_assert (desc->priv->setup);
g_assert (desc->priv->version);
g_assert (desc->priv->textdomain);
+ g_assert (desc->priv->icon_prop_key);
return desc;
}
diff --git a/src/ibusenginedesc.h b/src/ibusenginedesc.h
index 63eb99e7..cafc4cae 100644
--- a/src/ibusenginedesc.h
+++ b/src/ibusenginedesc.h
@@ -1,8 +1,8 @@
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/* vim:set et sts=4: */
/* bus - The Input Bus
- * Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
- * Copyright (C) 2008-2013 Red Hat, Inc.
+ * Copyright (C) 2008-2015 Peng Huang <shawn.p.huang@gmail.com>
+ * Copyright (C) 2008-2015 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
@@ -95,6 +95,7 @@ typedef struct _IBusEngineDescClass IBusEngineDescClass;
* setup: Exec lists of the engine setup command.
* version: Version number of the input method engine.
* textdomain: Domain name for dgettext()
+ * icon_prop_key: Key of IBusProperty to change panel icon dynamically.
*/
struct _IBusEngineDesc {
IBusSerializable parent;
@@ -311,6 +312,17 @@ const gchar *ibus_engine_desc_get_textdomain
(IBusEngineDesc *info);
/**
+ * ibus_engine_desc_get_icon_prop_key:
+ * @info: An IBusEngineDesc
+ * @returns: IBusProperty.key for dynamic panel icon in IBusEngineDesc
+ *
+ * Return the key of IBusProperty to load the panel icon dynamically
+ in IBusEngineDesc. It should not be freed.
+ */
+const gchar *ibus_engine_desc_get_icon_prop_key
+ (IBusEngineDesc *info);
+
+/**
* ibus_engine_desc_output:
* @info: An IBusEngineDesc
* @output: XML-formatted Input method engine description.
diff --git a/ui/gtk3/panel.vala b/ui/gtk3/panel.vala
index e2bd99d7..af98e40b 100644
--- a/ui/gtk3/panel.vala
+++ b/ui/gtk3/panel.vala
@@ -81,6 +81,9 @@ class Panel : IBus.PanelService {
private bool inited_engines_order = true;
private uint m_preload_engines_id;
private const uint PRELOAD_ENGINES_DELAY_TIME = 30000;
+ private string m_icon_prop_key = "";
+ private int m_property_icon_delay_time = 500;
+ private uint m_property_icon_delay_time_id;
private GLib.List<Keybinding> m_keybindings = new GLib.List<Keybinding>();
@@ -205,6 +208,10 @@ class Panel : IBus.PanelService {
m_settings_panel.changed["xkb-icon-rgba"].connect((key) => {
set_xkb_icon_rgba();
});
+
+ m_settings_panel.changed["property-icon-delay-time"].connect((key) => {
+ set_property_icon_delay_time();
+ });
}
#if INDICATOR
@@ -669,6 +676,11 @@ class Panel : IBus.PanelService {
}
}
+ private void set_property_icon_delay_time() {
+ m_property_icon_delay_time =
+ m_settings_panel.get_int("property-icon-delay-time");
+ }
+
private int compare_versions(string version1, string version2) {
string[] version1_list = version1.split(".");
string[] version2_list = version2.split(".");
@@ -780,6 +792,7 @@ class Panel : IBus.PanelService {
set_timeout_property_panel();
set_follow_input_cursor_when_always_shown_property_panel();
set_xkb_icon_rgba();
+ set_property_icon_delay_time();
}
private void engine_contexts_insert(IBus.EngineDesc engine) {
@@ -805,6 +818,11 @@ class Panel : IBus.PanelService {
m_xkblayout.set_layout(engine);
engine_contexts_insert(engine);
+
+ if (m_property_icon_delay_time_id > 0) {
+ GLib.Source.remove(m_property_icon_delay_time_id);
+ m_property_icon_delay_time_id = 0;
+ }
}
private void switch_engine(int i, bool force = false) {
@@ -1147,6 +1165,55 @@ class Panel : IBus.PanelService {
return m_ime_menu;
}
+ private void set_properties(IBus.PropList props) {
+ int i = 0;
+ while (true) {
+ IBus.Property prop = props.get(i);
+ if (prop == null)
+ break;
+ set_property(props.get(i), true);
+ i++;
+ }
+ }
+
+ private new void set_property(IBus.Property prop, bool all_update) {
+ string symbol = prop.get_symbol().get_text();
+
+ if (m_icon_prop_key != "" && prop.get_key() == m_icon_prop_key
+ && symbol != "")
+ animate_icon(symbol, all_update);
+ }
+
+ private void animate_icon(string symbol, bool all_update) {
+ if (m_property_icon_delay_time < 0)
+ return;
+
+ uint timeout = 0;
+ if (all_update)
+ timeout = (uint) m_property_icon_delay_time;
+
+ if (m_property_icon_delay_time_id > 0) {
+ GLib.Source.remove(m_property_icon_delay_time_id);
+ m_property_icon_delay_time_id = 0;
+ }
+
+ m_property_icon_delay_time_id = GLib.Timeout.add(timeout, () => {
+ m_property_icon_delay_time_id = 0;
+
+ if (m_icon_type == IconType.STATUS_ICON) {
+ Gdk.Pixbuf pixbuf = create_icon_pixbuf_with_string(symbol);
+ m_status_icon.set_from_pixbuf(pixbuf);
+ }
+ else if (m_icon_type == IconType.INDICATOR) {
+ Cairo.ImageSurface image =
+ create_cairo_image_surface_with_string(symbol, true);
+ m_indicator.set_cairo_image_surface_full(image, "");
+ }
+
+ return false;
+ });
+ }
+
/* override virtual functions */
public override void set_cursor_location(int x, int y,
int width, int height) {
@@ -1224,11 +1291,13 @@ class Panel : IBus.PanelService {
public override void register_properties(IBus.PropList props) {
m_property_manager.set_properties(props);
m_property_panel.set_properties(props);
+ set_properties(props);
}
public override void update_property(IBus.Property prop) {
m_property_manager.update_property(prop);
m_property_panel.update_property(prop);
+ set_property(prop, false);
}
public override void update_preedit_text(IBus.Text text,
@@ -1285,8 +1354,12 @@ class Panel : IBus.PanelService {
var icon_name = "ibus-keyboard";
var engine = m_bus.get_global_engine();
- if (engine != null)
+ if (engine != null) {
icon_name = engine.get_icon();
+ m_icon_prop_key = engine.get_icon_prop_key();
+ } else {
+ m_icon_prop_key = "";
+ }
if (icon_name[0] == '/') {
if (m_icon_type == IconType.STATUS_ICON) {