diff options
author | fujiwarat <takao.fujiwara1@gmail.com> | 2015-06-19 13:57:35 +0900 |
---|---|---|
committer | fujiwarat <takao.fujiwara1@gmail.com> | 2015-06-19 13:57:35 +0900 |
commit | 23c45b970b195008a54884a1a9d810e7f8b22c5c (patch) | |
tree | ca76b44f3f7e115a1e311bb77fd81b6e61c0b5f6 | |
parent | 7fd6077f19a5a39cdcd9c7fde0d9c8234ae5592e (diff) | |
download | ibus-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.in | 16 | ||||
-rw-r--r-- | src/ibusenginedesc.c | 38 | ||||
-rw-r--r-- | src/ibusenginedesc.h | 16 | ||||
-rw-r--r-- | ui/gtk3/panel.vala | 75 |
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) { |