After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 676102 - XKB keyboard layouts and IBus integration
XKB keyboard layouts and IBus integration
Status: RESOLVED FIXED
Product: gnome-settings-daemon
Classification: Core
Component: general
unspecified
Other All
: Normal normal
: ---
Assigned To: gnome-settings-daemon-maint
gnome-settings-daemon-maint
Depends on: 674948 676101 676583
Blocks:
 
 
Reported: 2012-05-15 14:41 UTC by Rui Matos
Modified: 2012-11-08 19:27 UTC
See Also:
GNOME target: 3.6
GNOME version: ---


Attachments
keyboard: Apply XKB layouts ourselves and stop relying on libgnomekbd (33.18 KB, patch)
2012-05-15 14:41 UTC, Rui Matos
needs-work Details | Review
keyboard: Add the IBus engine setting code (6.65 KB, patch)
2012-05-15 14:41 UTC, Rui Matos
needs-work Details | Review
keyboard: Always add a latin and a UI language XKB layouts (23.76 KB, patch)
2012-05-15 14:41 UTC, Rui Matos
needs-work Details | Review
keyboard: Apply XKB layouts ourselves and stop relying on libgnomekbd (34.20 KB, patch)
2012-05-22 18:29 UTC, Rui Matos
none Details | Review
keyboard: Add the capability to set IBus engines from input sources (8.63 KB, patch)
2012-05-22 18:33 UTC, Rui Matos
none Details | Review
keyboard: Apply XKB layouts ourselves and stop relying on libgnomekbd (35.00 KB, patch)
2012-05-24 20:56 UTC, Rui Matos
needs-work Details | Review
keyboard: Add the capability to set IBus engines from input sources (8.69 KB, patch)
2012-05-24 20:56 UTC, Rui Matos
reviewed Details | Review
media-keys: Add key bindings to switch input sources (4.72 KB, patch)
2012-05-29 13:45 UTC, Rui Matos
needs-work Details | Review
keyboard: Apply XKB layouts ourselves and stop relying on libgnomekbd (35.54 KB, patch)
2012-05-31 13:33 UTC, Rui Matos
none Details | Review
keyboard: Add the capability to set IBus engines from input sources (8.46 KB, patch)
2012-05-31 13:34 UTC, Rui Matos
none Details | Review
media-keys: Add key bindings to switch input sources (4.78 KB, patch)
2012-05-31 13:45 UTC, Rui Matos
none Details | Review
keyboard: Apply XKB layouts ourselves and stop relying on libgnomekbd (35.79 KB, patch)
2012-06-01 00:25 UTC, Rui Matos
committed Details | Review
media-keys: Add key bindings to switch input sources (4.78 KB, patch)
2012-06-01 00:25 UTC, Rui Matos
committed Details | Review
keyboard: Add the capability to set IBus engines from input sources (8.85 KB, patch)
2012-06-01 00:26 UTC, Rui Matos
reviewed Details | Review
keyboard: Add the capability to set IBus engines from input sources (16.96 KB, patch)
2012-06-21 14:45 UTC, Rui Matos
rejected Details | Review
keyboard: Add the capability to set IBus engines from input sources (15.64 KB, patch)
2012-06-22 13:26 UTC, Rui Matos
reviewed Details | Review
keyboard: Add the capability to set IBus engines from input sources (15.73 KB, patch)
2012-06-24 18:14 UTC, Rui Matos
none Details | Review
keyboard: Add the capability to set IBus engines from input sources (14.59 KB, patch)
2012-06-27 14:09 UTC, Rui Matos
needs-work Details | Review
keyboard: Add the capability to set IBus engines from input sources (14.69 KB, patch)
2012-06-29 16:52 UTC, Rui Matos
none Details | Review
keyboard: Add the capability to set IBus engines from input sources (12.99 KB, patch)
2012-07-10 16:08 UTC, Rui Matos
needs-work Details | Review
keyboard: Add functionality to set IBus engines from input sources (12.58 KB, patch)
2012-07-10 21:36 UTC, Rui Matos
reviewed Details | Review
keyboard: Use GSettings::change-event to cut on needless work (4.02 KB, patch)
2012-07-10 21:38 UTC, Rui Matos
committed Details | Review
keyboard: Add functionality to set IBus engines from input sources (13.36 KB, patch)
2012-07-12 03:38 UTC, Rui Matos
reviewed Details | Review
keyboard: Add functionality to set IBus engines from input sources (14.43 KB, patch)
2012-07-12 13:06 UTC, Rui Matos
needs-work Details | Review
keyboard: Add functionality to set IBus engines from input sources (14.74 KB, patch)
2012-07-12 23:48 UTC, Rui Matos
committed Details | Review

Description Rui Matos 2012-05-15 14:41:29 UTC
These patches go on top of the clean-ups in bug 674948.
Comment 1 Rui Matos 2012-05-15 14:41:33 UTC
Created attachment 214105 [details] [review]
keyboard: Apply XKB layouts ourselves and stop relying on libgnomekbd

libgnomekbd/xklavier aren't a good fit to have the keyboard input
story that we want since they rely on implementation details of the
XKB protocol to provide users with a means to switch keyboard layouts.

Of note here is a) their reliance on XKB groups, of which there can be
only up to 4, to specify the layouts the user is able to switch
between and b) their reliance on XKB options to specify the keybinding
to switch layouts which is a restricted set and falls outside the
regular GNOME desktop wide keybindings management as it's implemented
entirely on the X server side.

This commit introduces the use of a shared GSettings schema from
gsettings-desktop-schemas which will be the storage for our new
concept of "input sources". Input sources are basically a tuple of
keyboard layout and, if needed, an IBus input engine that work
together to provide the user with working keyboard input.

As a start we only handle the keyboard layout for now. We do it using
roughly the same method that setxkbmap(1) uses which should allow the
users that want to specify their own XKB features (except layout) to
still do so outside of GNOME (e.g. in a session startup script).
Comment 2 Rui Matos 2012-05-15 14:41:38 UTC
Created attachment 214106 [details] [review]
keyboard: Add the IBus engine setting code

We simply connect to IBus and tell it to switch engine when our
current input source setting is changed and an IBus engine is
specified there. The responsibility to make sure that this engine
actually exists on the IBus side is left to whoever writes the
setting.

At the same time, if an IBus engine is specified, we flip the setting
that backs the Gtk/IMModule XSETTING so that GTK+ applications get
notified to load the IBus input method when needed and go back to the
simple input method when IBus isn't required.
Comment 3 Rui Matos 2012-05-15 14:41:42 UTC
Created attachment 214107 [details] [review]
keyboard: Always add a latin and a UI language XKB layouts

Toolkits need to know about both a latin layout to handle
accelerators which are usually defined like Ctrl+C and a
layout with the symbols for the language used in UI strings
to handle mnemonics like Alt+Ф, so we try to find and add
them in XKB group slots after the layout which the user
actually intends to type with.
Comment 4 Bastien Nocera 2012-05-16 16:58:54 UTC
Review of attachment 214105 [details] [review]:

::: plugins/keyboard/Makefile.am
@@ +23,3 @@
 	$(NULL)
 
+XKBCONFIGROOT=@XKBCONFIGROOT@

Why do we need that?

::: plugins/keyboard/gsd-keyboard-manager.c
@@ +66,3 @@
+#define GNOME_DESKTOP_INPUT_SOURCES_DIR "org.gnome.desktop.input-sources"
+
+#define KEY_CURRENT_IS     "current"

KEY_CURRENT_INPUT_SOURCE isn't that long.

@@ +69,3 @@
+#define KEY_INPUT_SOURCES  "sources"
+
+#ifndef DFLT_XKB_CONFIG_ROOT

Why do we need all that? Can't we require a new enough version of xkb to have those defined?

@@ +87,3 @@
         GSettings *settings;
+        GSettings *is_settings;
+        gulong     ignore_serial;

The "ignore_serial" stuff all across this file look like magic to me, and not the good kind of magic. Please document it.

@@ +217,3 @@
+        if (!XkbRF_GetNamesProp (display, rules, var_defs) || !*rules) {
+                *rules = strdup (DFLT_XKB_RULES_FILE);
+                var_defs->model = strdup (DFLT_XKB_MODEL);

can't you use g_strdup() and thus get rid of all the "if (foo) free (foo)" code?

@@ +279,3 @@
+
+        if (!XkbRF_SetNamesProp (display, rules_file, var_defs))
+                g_warning ("Couldn't update the XKB root window property");

Are you sure this doesn't generate X errors? Do we need push_error() pop_error() around here?

@@ +299,3 @@
+                rules_path = g_strdup (rules_file);
+        else
+                rules_path = g_strdup_printf ("%s/rules/%s",

That's not how you create file paths, see g_build_filename() for example.
Comment 5 Bastien Nocera 2012-05-16 17:03:37 UTC
Review of attachment 214106 [details] [review]:

::: plugins/keyboard/gsd-keyboard-manager.c
@@ +352,3 @@
+{
+        IBusEngineDesc *desc = NULL;
+        IBusBus *ibus = ibus_bus_new ();

Don't assign in the declaration, especially instantiating new objects.

@@ +355,3 @@
+
+        if (!ibus_bus_set_global_engine (ibus, engine) ||
+            !(desc = ibus_bus_get_global_engine (ibus)))

Split this up so the error paths aren't as messy as they are now.

@@ +356,3 @@
+        if (!ibus_bus_set_global_engine (ibus, engine) ||
+            !(desc = ibus_bus_get_global_engine (ibus)))
+                g_warning ("Couldn't set IBus engine");

Better error reporting?

@@ +362,3 @@
+                                       GTK_IM_MODULE_IBUS);
+
+        g_object_unref (ibus);

Do we need to keep the ibus object around?

@@ +519,3 @@
 
+#ifdef HAVE_IBUS
+        ibus_init ();

Error reporting?
Comment 6 Bastien Nocera 2012-05-16 17:14:54 UTC
Review of attachment 214107 [details] [review]:

The code addedin gsd-keyboard-manager.c should be split out, a test application written, and automatically launched. See this for example:
http://git.gnome.org/browse/gnome-control-center/tree/panels/info/test-hostname.c

Need a test application for the xkb-rules-db code as well, and it needs to be valgrinded clean.
Where's the code to clean up the database's allocated memory? Could you use a database object instead, which would make checking the lifetime of the various allocated bits of memory much simpler?

::: plugins/keyboard/xkb-rules-db.c
@@ +34,3 @@
+
+#ifndef DFLT_XKB_CONFIG_ROOT
+#define DFLT_XKB_CONFIG_ROOT "/usr/share/X11/xkb"

Isn't this the same defines I was saying we shouldn't need? We probably really don't want them in 2 files...
Comment 7 Rui Matos 2012-05-22 18:29:44 UTC
Created attachment 214685 [details] [review]
keyboard: Apply XKB layouts ourselves and stop relying on libgnomekbd

--
(In reply to comment #4)
> +XKBCONFIGROOT=@XKBCONFIGROOT@
>
> Why do we need that?

[ this moved to a gnome-desktop patch ]

Removed.

> KEY_CURRENT_INPUT_SOURCE isn't that long.

Agree.

> +#ifndef DFLT_XKB_CONFIG_ROOT
>
> Why do we need all that? Can't we require a new enough version of xkb to have
> those defined?

[ this moved to a gnome-desktop patch ]

Yup, it seems that xkeyboard-config.pc defines this one.

> The "ignore_serial" stuff all across this file look like magic to me, and not
> the good kind of magic. Please document it.

This was a just a leftover from previous experiments. Removed.

> +        if (!XkbRF_GetNamesProp (display, rules, var_defs) || !*rules) {
> +                *rules = strdup (DFLT_XKB_RULES_FILE);
> +                var_defs->model = strdup (DFLT_XKB_MODEL);
>
> can't you use g_strdup() and thus get rid of all the "if (foo) free (foo)"
> code?

[ this moved to a gnome-desktop patch ]

Seem like we can yes. Even though the XkbRF* functions allocate it
internally with malloc and friends.

> +        if (!XkbRF_SetNamesProp (display, rules_file, var_defs))
> +                g_warning ("Couldn't update the XKB root window property");
>
> Are you sure this doesn't generate X errors? Do we need push_error()
> pop_error() around here?

[ this moved to a gnome-desktop patch ]

Added.

> +                rules_path = g_strdup_printf ("%s/rules/%s",
>
> That's not how you create file paths, see g_build_filename() for example.

[ this moved to a gnome-desktop patch ]

Done.

Thanks for the review.
Comment 8 Rui Matos 2012-05-22 18:33:11 UTC
Created attachment 214686 [details] [review]
keyboard: Add the capability to set IBus engines from input sources

--
I re-worked things a bit. Now I'm keeping the IBus connection always
opened. I'm still missing code to re-connect if IBus crashes or
otherwise goes away but I think that can go in another patch and this
can be review as is.
Comment 9 Bastien Nocera 2012-05-22 18:47:48 UTC
(In reply to comment #7)
> [ this moved to a gnome-desktop patch ]

Where's the bug? Can you please add the blockers as appropriate.

> > +        if (!XkbRF_GetNamesProp (display, rules, var_defs) || !*rules) {
> > +                *rules = strdup (DFLT_XKB_RULES_FILE);
> > +                var_defs->model = strdup (DFLT_XKB_MODEL);
> >
> > can't you use g_strdup() and thus get rid of all the "if (foo) free (foo)"
> > code?
> 
> [ this moved to a gnome-desktop patch ]
> 
> Seem like we can yes. Even though the XkbRF* functions allocate it
> internally with malloc and friends.

If the XkbRF* functions do allocation, then you need to use the corresponding free function. So, in fact, you can't stop using all that "if (foo) free (foo)".
Comment 10 Ray Strode [halfline] 2012-05-24 19:51:15 UTC
free(NULL); is perfectly valid C (it's a no-op).
Comment 11 Rui Matos 2012-05-24 20:56:01 UTC
Created attachment 214897 [details] [review]
keyboard: Apply XKB layouts ourselves and stop relying on libgnomekbd
Comment 12 Rui Matos 2012-05-24 20:56:12 UTC
Created attachment 214898 [details] [review]
keyboard: Add the capability to set IBus engines from input sources
Comment 13 Rui Matos 2012-05-29 13:45:38 UTC
Created attachment 215174 [details] [review]
media-keys: Add key bindings to switch input sources
Comment 14 Matthias Clasen 2012-05-29 23:11:58 UTC
Review of attachment 214898 [details] [review]:

::: plugins/keyboard/gsd-keyboard-manager.c
@@ +671,3 @@
+                g_object_unref (p->interface_settings);
+                p->interface_settings = NULL;
+        }

Could just g_clear_object() here

@@ +676,3 @@
+                g_object_unref (p->ibus);
+                p->ibus = NULL;
+        }

And here
Comment 15 Bastien Nocera 2012-05-30 11:00:37 UTC
Review of attachment 214897 [details] [review]:

::: plugins/keyboard/gsd-keyboard-manager.c
@@ +201,3 @@
+        g_return_if_fail (p != NULL);
+
+        if (p->keymap)

What halfline said actually, the ifs aren't needed.

@@ +227,3 @@
+
+        /* Upload it to the X server using the same method as setxkbmap */
+        xkb_desc = XkbGetKeyboardByName (display,

I think this need gdk_error_trap_push()/gdk_error_trap_pop() to catch BadMatch.

@@ +293,3 @@
+        if ((g_strcmp0 (latin_layout, locale_layout) == 0 &&
+             g_strcmp0 (latin_variant, locale_variant) == 0)
+            ||

This section is unreadable.

@@ +309,3 @@
+                free (xkb_var_defs->layout);
+
+        xkb_var_defs->layout =

This is unreadable.

@@ +321,3 @@
+                free (xkb_var_defs->variant);
+
+        xkb_var_defs->variant =

This is unreadable.

@@ +360,3 @@
+        }
+
+        gdk_error_trap_pop_ignored ();

Why do you ignore the error here, but print out a warning if you get an error from the function? Both are returns from the function, just one is async.

@@ +387,3 @@
+        }
+        if (current >= g_variant_n_children (sources)) {
+                g_warning ("Current input source index out of bounds, resetting");

There's no need for a warning.
I'm also not sure that you want to reset the index when removing the last item from the list for example.

@@ +583,3 @@
+
+        if (p->input_sources_settings != NULL) {
+                g_object_unref (p->input_sources_settings);

g_clear_object()

@@ +588,3 @@
+
+        if (p->xkb_info != NULL) {
+                g_object_unref (p->xkb_info);

g_clear_object()
Comment 16 Bastien Nocera 2012-05-30 11:06:40 UTC
Review of attachment 215174 [details] [review]:

::: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in
@@ +177,3 @@
     </key>
+    <key name="switch-input-source" type="s">
+      <default>''</default>

What's the default keybinding to do that currently?

::: plugins/media-keys/gsd-media-keys-manager.c
@@ +1790,3 @@
+        settings = g_settings_new (GNOME_DESKTOP_INPUT_SOURCES_DIR);
+        sources = g_settings_get_value (settings, KEY_INPUT_SOURCES);
+        n = g_variant_n_children (sources);

int new_index;

new_index = n + (type == SWITCH_INPUT_SOURCE_KEY ? +1 : -1);
if (new_index < 0)
  new_index = n;
else if (new_index > n)
  new_index = 0;

@@ +1791,3 @@
+        sources = g_settings_get_value (settings, KEY_INPUT_SOURCES);
+        n = g_variant_n_children (sources);
+        if (n > 0) {

if (n == 0)
  goto out;
(and do this before any of the calculations)
Comment 17 Rui Matos 2012-05-31 13:33:45 UTC
Created attachment 215330 [details] [review]
keyboard: Apply XKB layouts ourselves and stop relying on libgnomekbd

--
(In reply to comment #15)
> +        if (p->keymap)
>
> What halfline said actually, the ifs aren't needed.

Sure.

> @@ +227,3 @@
> +
> +        /* Upload it to the X server using the same method as setxkbmap */
> +        xkb_desc = XkbGetKeyboardByName (display,
>
> I think this need gdk_error_trap_push()/gdk_error_trap_pop() to catch BadMatch.

There's already a trap_push/pop on the outer function.

> @@ +293,3 @@
> +        if ((g_strcmp0 (latin_layout, locale_layout) == 0 &&
> +             g_strcmp0 (latin_variant, locale_variant) == 0)
> +            ||
>
> This section is unreadable.

Yeah, I hope it's clearer now.

> @@ +360,3 @@
> +        }
> +
> +        gdk_error_trap_pop_ignored ();
>
> Why do you ignore the error here, but print out a warning if you get an error
> from the function? Both are returns from the function, just one is async.

Fixed.

> @@ +387,3 @@
> +        }
> +        if (current >= g_variant_n_children (sources)) {
> +                g_warning ("Current input source index out of bounds,
> resetting");
>
> There's no need for a warning.

Agree.

> I'm also not sure that you want to reset the index when removing the last item
> from the list for example.

Changed it to cap the value to N - 1.

> g_clear_object()

Ok.
Comment 18 Rui Matos 2012-05-31 13:34:04 UTC
Created attachment 215331 [details] [review]
keyboard: Add the capability to set IBus engines from input sources
Comment 19 Rui Matos 2012-05-31 13:45:57 UTC
Created attachment 215332 [details] [review]
media-keys: Add key bindings to switch input sources

--
(In reply to comment #16)
> What's the default keybinding to do that currently?

I don't think there's a default currently. I guess people add one in
"Region and Language" > Layouts > Options... > "Key(s) to change
layout". Should I add one?

BTW, with the current key binding infrastructure we have in g-s-d we
can't use the kinds of key bindings that were available in those XKB
options like Shift+CapsLock or Alt+Shift. I looked a bit into how we
could do that and it seems that it's possible to do it with something
like the gsd-locate-pointer code that checks when Ctrl is released and
there were no other key presses in between the press and release.

> ::: plugins/media-keys/gsd-media-keys-manager.c
> @@ +1790,3 @@
> +        settings = g_settings_new (GNOME_DESKTOP_INPUT_SOURCES_DIR);
> +        sources = g_settings_get_value (settings, KEY_INPUT_SOURCES);
> +        n = g_variant_n_children (sources);
>
> int new_index;
>
> new_index = n + (type == SWITCH_INPUT_SOURCE_KEY ? +1 : -1);
> if (new_index < 0)
>   new_index = n;
> else if (new_index > n)
>   new_index = 0;
>
> @@ +1791,3 @@
> +        sources = g_settings_get_value (settings, KEY_INPUT_SOURCES);
> +        n = g_variant_n_children (sources);
> +        if (n > 0) {
>
> if (n == 0)
>   goto out;
> (and do this before any of the calculations)

OK, I think it's clearer now.
Comment 20 Rui Matos 2012-06-01 00:25:21 UTC
Created attachment 215369 [details] [review]
keyboard: Apply XKB layouts ourselves and stop relying on libgnomekbd

--
Updated for schema changes.
Comment 21 Rui Matos 2012-06-01 00:25:39 UTC
Created attachment 215370 [details] [review]
media-keys: Add key bindings to switch input sources

--
Updated for schema changes.
Comment 22 Rui Matos 2012-06-01 00:26:03 UTC
Created attachment 215371 [details] [review]
keyboard: Add the capability to set IBus engines from input sources

--
Updated for schema changes.
Comment 23 Bastien Nocera 2012-06-01 17:40:39 UTC
Can you please make sure that you get a replacement status icon made?
Also, did you run test-keyboard stand-alone under valgrind to make sure that there aren't any leaks?
Comment 24 Takao Fujiwara 2012-06-08 10:08:38 UTC
Currently switch-input-source and switch-input-source-backward in org.gnome.settings-daemon.plugins.media-keys.gschema.xml has the string type but not array type.
I think multiple shortcut keys are needed to switch IMEs.
E.g. Korean users use Alt_R and Hangul keys to switch Korean keyboard layout and ibus-hangul.
Probably I think the default shortcut key is Control+space and it could be customized by users to add other shortcut keys.

apply_input_sources_settings() always calls apply_xkb_layout() but I think some input method engines don't change the XKB but use the current XKB. So if ibus_engine_desc_get_layout() returns 'default', I'd like to cancel apply_xkb_layout().
Comment 25 Rui Matos 2012-06-12 08:48:28 UTC
(In reply to comment #24)
> Currently switch-input-source and switch-input-source-backward in
> org.gnome.settings-daemon.plugins.media-keys.gschema.xml has the string type
> but not array type.
> I think multiple shortcut keys are needed to switch IMEs.
> E.g. Korean users use Alt_R and Hangul keys to switch Korean keyboard layout
> and ibus-hangul.

That's bug 677427.

> Probably I think the default shortcut key is Control+space and it could be
> customized by users to add other shortcut keys.

I'm a bit wary of assigning that specific shortcut by default for all the clashes that it will probably cause with applications. We could assign it only when more than 1 input source is configured and there's nothing configured yet?

Some design input here would be nice. FWIW, Windows 8 uses Windows+Space to switch input sources.

> apply_input_sources_settings() always calls apply_xkb_layout() but I think some
> input method engines don't change the XKB but use the current XKB. So if
> ibus_engine_desc_get_layout() returns 'default', I'd like to cancel
> apply_xkb_layout().

Like I told you on IRC, I don't think this is a good idea. Even if technically IBUS engines can cope with an arbitrary XKB layout, I think it's very confusing for users that some keys would input different symbols depending on the previously selected input source. It's just too obscure.

I think IBUS engines must specify a XKB layout or otherwise we should default to the US layout.
Comment 26 Takao Fujiwara 2012-06-13 10:35:22 UTC
(In reply to comment #25)
> > Probably I think the default shortcut key is Control+space and it could be
> > customized by users to add other shortcut keys.
> 
> I'm a bit wary of assigning that specific shortcut by default for all the
> clashes that it will probably cause with applications. We could assign it only
> when more than 1 input source is configured and there's nothing configured yet?

If one XKB layout only is configured, I think the shortcut key is not needed.
If one XKB layout and one input method are configured, I think the default shortcut key is needed and Asian IM users use Control+space for ten years.
If there is no input methods but some XKB layouts, different shortcut keys might be better.

> Some design input here would be nice. FWIW, Windows 8 uses Windows+Space to
> switch input sources.

I know it however my concern is Windows key does not exist in non-Win keyboards.

> > apply_input_sources_settings() always calls apply_xkb_layout() but I think some
> > input method engines don't change the XKB but use the current XKB. So if
> > ibus_engine_desc_get_layout() returns 'default', I'd like to cancel
> > apply_xkb_layout().
> 
> Like I told you on IRC, I don't think this is a good idea. Even if technically
> IBUS engines can cope with an arbitrary XKB layout, I think it's very confusing
> for users that some keys would input different symbols depending on the
> previously selected input source. It's just too obscure.
> 
> I think IBUS engines must specify a XKB layout or otherwise we should default
> to the US layout.

If the 'default' is not implemented, I think it's very confusing users and probably I need to enable gtk ibus panel and ibus-gjs against gnome-settings-daemon.
I think input method should not have the keyboard layouts. As I noted, ibus-m17n engines need to have 'us' layout because it works likes keyboard layouts rather than input methods. But pure input method could work for any keyboard layouts and input methods convert the single byte chars (e.g. 'a') to the multi byte chars (e.g. 'a') according to the current keyboard layout.
Comment 27 Takao Fujiwara 2012-06-13 10:56:11 UTC
I have another problem in the current patches.
Fedora 17 ibus uses ibus 1.5 and now it provides the new Control+space key which can switch ibus engines by pressing space key till Control key is released. The new Control+space key works likes metacity Alt+tab and I think this would need a GUI of the switcher dialog to select the engine.

The previous ibus provides toggle shortcut keys and prev/next shortcut keys.
ibus 1.5 migrated the toggle shortcut keys and prev/next shortcut keys to the new Control+space.

Currently switch-input-source and switch-input-source-backward are implemented
in org.gnome.settings-daemon.plugins.media-keys.gschema.xml. The switch-input-source/switch-input-source-backward are almost same with ibus prev/next shorcut keys.

If the switcher dialog is not implemented, I think the toggle shortcut keys are required to switch a XKB layout and an input method.

E.g. in case of the ibus engine list is, us, anthy, jp:
toggle shortcut key swaps the first engine and the second engine, us <-> anthy.
next shortcut key switches us -> anthy -> jp -> us...
prev shortcut key switches us -> jp -> anthy -> us...

The new Control+space in ibus 1.5 swaps the engine when Control key is released.
If Control key is released when anthy is selected, the order is anthy, us, jp.
If Control key is released when jp is selected, the order is jp, us, anthy.
This satisfies both toggle shortcut keys and prev/next shortcut keys in the previous ibus.
Comment 28 Matthias Clasen 2012-06-20 02:56:39 UTC
Review of attachment 215371 [details] [review]:

::: plugins/keyboard/gsd-keyboard-manager.c
@@ +454,3 @@
+                g_settings_set_string (priv->interface_settings,
+                                       KEY_GTK_IM_MODULE,
+                                       GTK_IM_MODULE_SIMPLE);

I wonder if this is being shortcut anywhere for the common case where all input sources are xkb - we don't want to constantly reload immodules in all running applications...

@@ +634,3 @@
+#ifdef HAVE_IBUS
+        manager->priv->interface_settings = g_settings_new (GNOME_DESKTOP_INTERFACE_DIR);
+        ibus_init ();

Can ibus_init() be called more than once ?

@@ +639,3 @@
+                g_warning ("Couldn't connect to ibus-daemon");
+                g_object_unref (manager->priv->ibus);
+                manager->priv->ibus = NULL;

Could use g_clear_object here

@@ +641,3 @@
+                manager->priv->ibus = NULL;
+        }
+        if (manager->priv->ibus)

Could just be an 'else' here ?
Comment 29 Rui Matos 2012-06-21 14:45:01 UTC
Created attachment 216931 [details] [review]
keyboard: Add the capability to set IBus engines from input sources

--
Here's a new version which tries to handle the ibus-daemon
lifecycle. If you agree with this approach I'll do a request on ibus
upstream to never start ibus on a gnome session from their
initialization scripts.

(In reply to comment #28)
> ::: plugins/keyboard/gsd-keyboard-manager.c
> @@ +454,3 @@
> +                g_settings_set_string (priv->interface_settings,
> +                                       KEY_GTK_IM_MODULE,
> +                                       GTK_IM_MODULE_SIMPLE);
>
> I wonder if this is being shortcut anywhere for the common case where all input
> sources are xkb - we don't want to constantly reload immodules in all running
> applications...

Oh yes, good catch. I'm handling this now.

> @@ +634,3 @@
> +#ifdef HAVE_IBUS
> +        manager->priv->interface_settings = g_settings_new
> (GNOME_DESKTOP_INTERFACE_DIR);
> +        ibus_init ();
>
> Can ibus_init() be called more than once ?

I tested and it works. It just calls g_type_init() and a handful of
*_get_type() for its types. Anyway g-s-d plugins are only initialized
once, right?
Comment 30 Takao Fujiwara 2012-06-22 01:32:29 UTC
I think it's good to run a .desktop file or another configuration file instead of running ibus-daemon direclty.
The arguments of ibus-daemon will be provided by ibus package.
Currently imsettings loads /etc/X11/xinit/xinputrc .
Running ibus-daemon is not handled by ibus but imsettings so I think you need to ask imsettings instead.
Comment 31 Matthias Clasen 2012-06-22 11:52:39 UTC
(In reply to comment #29)

> > @@ +634,3 @@
> > +#ifdef HAVE_IBUS
> > +        manager->priv->interface_settings = g_settings_new
> > (GNOME_DESKTOP_INTERFACE_DIR);
> > +        ibus_init ();
> >
> > Can ibus_init() be called more than once ?
> 
> I tested and it works. It just calls g_type_init() and a handful of
> *_get_type() for its types. Anyway g-s-d plugins are only initialized
> once, right?

I think you can toggle the 'active' setting to have them stopped or started at will. I was just commenting on the general principle that stop should undo what start has done. If the init function is idempotent, there's no problem.
Comment 32 Matthias Clasen 2012-06-22 12:07:46 UTC
Review of attachment 216931 [details] [review]:

::: plugins/keyboard/gsd-keyboard-manager.c
@@ +155,3 @@
+
+        g_clear_object (&priv->ibus);
+        g_clear_object (&priv->ibus_cancellable);

Do you want to cancel the cancellable here, if it is non-NULL ?  Not sure it makes a big difference, just wondering.

@@ +256,3 @@
+        g_warning ("Couldn't activate and connect to the IBus daemon");
+
+        set_ibus_state_off (manager); /* give up */

Do you forget to clear priv->ibus_connection_timeout_id here ?

@@ +258,3 @@
+        set_ibus_state_off (manager); /* give up */
+
+        return FALSE;

I'd prefer G_SOURCE_REMOVE here.

@@ +290,3 @@
+        char *args[] = {
+                "ibus-daemon",
+                "--daemonize",

Why daemonize ? I think daemonizing in the user session is basically always a mistake.

@@ +324,3 @@
+        g_clear_object (&priv->ibus);
+
+        spawn_ibus (manager);

This looks to me like we have a forced 2-second timeout before we even try spawning ibus ? Thats not great...

Shouldn't we optimize for the case where ibus is not running yet, and just spawn it  ? If it was already starting up anyway, at worst, we'll have an extra process that dies when it can't get its bus name.

@@ +326,3 @@
+        spawn_ibus (manager);
+
+        return FALSE;

I really prefer to return G_SOURCE_REMOVE nowadays, it is just much more obvious.
Not sure what the policy in gnome-control-center is, though.
Comment 33 Rui Matos 2012-06-22 13:02:31 UTC
Review of attachment 216931 [details] [review]:

Thanks for the comments.

::: plugins/keyboard/gsd-keyboard-manager.c
@@ +155,3 @@
+
+        g_clear_object (&priv->ibus);
+        g_clear_object (&priv->ibus_cancellable);

Yes, I always want to cancel any in-flight async op on this cancellable. Actually, right now, it can only be the initial engine description fetch.

Also, when the cancellable is NULL, g_cancellable_cancel() is a nop so I can always call it unconditionally to keep the logic simpler.

@@ +256,3 @@
+        g_warning ("Couldn't activate and connect to the IBus daemon");
+
+        set_ibus_state_off (manager); /* give up */

set_ibus_state_off() always clears it.

@@ +258,3 @@
+        set_ibus_state_off (manager); /* give up */
+
+        return FALSE;

Sure, I had forgotten that we now have this. Will fix.

@@ +290,3 @@
+        char *args[] = {
+                "ibus-daemon",
+                "--daemonize",

OK.

@@ +324,3 @@
+        g_clear_object (&priv->ibus);
+
+        spawn_ibus (manager);

Yes you're right. I'll just remove the first connection attempt. I had simpler version before which was hitting some race conditions but now I think I over-did it.
Comment 34 Rui Matos 2012-06-22 13:26:18 UTC
Created attachment 217025 [details] [review]
keyboard: Add the capability to set IBus engines from input sources

--

Now I'm just spawning ibus imediately. Unfortunately I can't get rid
of the timeout between spawning and connecting because of the race
there. And since ibus doesn't show up on the session bus I can't watch
that to properly handle this.
Comment 35 Matthias Clasen 2012-06-22 23:17:04 UTC
Review of attachment 217025 [details] [review]:

The code looks like it will handle ibus-daemon crashing or going away for some other reason. Have you tested such scenarios ?

::: plugins/keyboard/gsd-keyboard-manager.c
@@ +170,3 @@
+        GError *error;
+
+        g_return_if_fail (priv->ibus_state == IBUS_STATE_INITIALIZING);

I wonder if you can actually assert this - couldn't you get a ::disconnected signal before the list_engines_async call returns (probably with an error) ? In that case,
the state would already be OFF again.

@@ +297,3 @@
+        g_spawn_async (NULL, args, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error);
+
+        if (error) {

I wonder if this works in the case where ibus-daemon is already running, though ?

When trying to launch ibus-daemon a second time here:

$ ibus-daemon
current session already has an ibus-daemon.
[mclasen@localhost ibus-1.4.0]$ echo $?
255

Unfortunately, it return 255 for every possible error condition, so you'd have to parse the error message to find out whats going on.

Another alternative might be to just pass --replace
Comment 36 Rui Matos 2012-06-24 18:14:07 UTC
Created attachment 217134 [details] [review]
keyboard: Add the capability to set IBus engines from input sources

--
(In reply to comment #35)
> The code looks like it will handle ibus-daemon crashing or going away for some
> other reason. Have you tested such scenarios ?

Yes, I've been running with it and killing ibus-daemon now and then to
make sure it's working.

> ::: plugins/keyboard/gsd-keyboard-manager.c
> @@ +170,3 @@
> +        GError *error;
> +
> +        g_return_if_fail (priv->ibus_state == IBUS_STATE_INITIALIZING);
>
> I wonder if you can actually assert this - couldn't you get a ::disconnected
> signal before the list_engines_async call returns (probably with an error) ? In
> that case,
> the state would already be OFF again.

Ups, you're right, on disconnection we cancel the cancellable and the
result function will still be called for the cancellation. It's
expected so I'm just adding the OFF state to the assertion.

> @@ +297,3 @@
> +        g_spawn_async (NULL, args, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL,
> NULL, &error);
> +
> +        if (error) {
>
> I wonder if this works in the case where ibus-daemon is already running, though
> ?

The spawn call will succeed and the newly spawned daemon will just
exit.

> When trying to launch ibus-daemon a second time here:
>
> $ ibus-daemon
> current session already has an ibus-daemon.
> [mclasen@localhost ibus-1.4.0]$ echo $?
> 255
>
> Unfortunately, it return 255 for every possible error condition, so you'd have
> to parse the error message to find out whats going on.
>
> Another alternative might be to just pass --replace

I actually had this before and it's what was causing a race because
with --replace you end up often connecting to the older instance which
will exit just after we connect. Anyway, it seems to be working here
both with ibus-daemon already running before g-s-d starts or not.


More problematic is the race at session init time because gnome-shell
will try to connect to ibus but it might not be ready yet since all
this is async. At this point I think the only option is making
ibus-daemon have a presence in the session bus.
Comment 37 Takao Fujiwara 2012-06-25 03:09:40 UTC
It seems "default" layout is not handled yet. 
If the 'default' layout is applied in ibus engine, apply_xkb_layout() could be ignored or g-s-d could take the first layout of the XKB layout engines.

If it's not implemented, I'm thinking a possibility to disconnect g-s-d or ibus engine could provide many instances per layout in case that the parent is g-s-d but probably the appearance would not be good.
Also I think IME switcher dialog or IME toggle trigger key is needed.

> +                if (engine_desc) {
> +                        layout = ibus_engine_desc_get_layout (engine_desc);
> +                        variant = "";

I think this needs to handle variant. E.g. layout == 'en(dvorak)', the layout is 'en' and variant is 'dvorak'.

(In reply to comment #36)
> More problematic is the race at session init time because gnome-shell
> will try to connect to ibus but it might not be ready yet since all
> this is async. At this point I think the only option is making
> ibus-daemon have a presence in the session bus.

Probably I think you could check 'connect' signal in js/ui/status/ibus/indicator.js
Comment 38 Matthias Clasen 2012-06-25 13:50:33 UTC
(In reply to comment #36)
> > Have you tested such scenarios ?
> 
> Yes, I've been running with it and killing ibus-daemon now and then to
> make sure it's working.

Ah, good.


> > Another alternative might be to just pass --replace
> 
> I actually had this before and it's what was causing a race because
> with --replace you end up often connecting to the older instance which
> will exit just after we connect. Anyway, it seems to be working here
> both with ibus-daemon already running before g-s-d starts or not.

I see. Ok then.
 
> More problematic is the race at session init time because gnome-shell
> will try to connect to ibus but it might not be ready yet since all
> this is async. At this point I think the only option is making
> ibus-daemon have a presence in the session bus.

Doesn't the shell have to somehow retry anyway, in order to be robust against ibus-daemon crashing ? I guess a bus name would make that easier too
Comment 39 Rui Matos 2012-06-27 14:09:36 UTC
Created attachment 217407 [details] [review]
keyboard: Add the capability to set IBus engines from input sources

--
After talking with Takao on IRC we reached the conclusion that it's
better to just add the ibus-daemon to the session bus. See

http://code.google.com/p/ibus/issues/detail?id=1476

I changed this patch accordingly: it now relies on dbus activation to
spawn ibus-daemon and watches a well known name there to track its
life cylce.
Comment 40 Matthias Clasen 2012-06-27 22:59:08 UTC
Review of attachment 217407 [details] [review]:

Looks good to me now - will we get the ibus bus name into rawhide soon ?
Comment 41 Bastien Nocera 2012-06-29 14:03:29 UTC
Review of attachment 217407 [details] [review]:

::: plugins/keyboard/gsd-keyboard-manager.c
@@ +236,3 @@
+                stop_ibus_name_watch (manager);
+                start_ibus_name_watch (manager);
+                priv->ibus_reactivated = TRUE;

I don't like this "reactivated" business. Can't we just bail out if one of the calls to the ibus-daemon fails? Why would we enter a loop?

@@ +619,3 @@
+                        goto exit;
+                }
+#ifdef HAVE_IBUS

I really don't like having an ifdef opening and closing in different blocks.

@@ +627,3 @@
+                                               GTK_IM_MODULE_SIMPLE);
+                g_free (module);
+        } else if (g_str_equal (type, INPUT_SOURCE_TYPE_IBUS)) {

And you should warn here if you have an ibus engine configured and g-s-d is built without ibus support.

@@ +646,3 @@
+                        module = g_settings_get_string (priv->interface_settings,
+                                                        KEY_GTK_IM_MODULE);
+                        if (!g_str_equal (module, GTK_IM_MODULE_IBUS))

You have that construct twice in this code. Can't you monitor which im module is in use and do this checking in a separate function?
Comment 42 Rui Matos 2012-06-29 16:52:59 UTC
Created attachment 217639 [details] [review]
keyboard: Add the capability to set IBus engines from input sources

--
(In reply to comment #41)
> ::: plugins/keyboard/gsd-keyboard-manager.c
> @@ +236,3 @@
> +                stop_ibus_name_watch (manager);
> +                start_ibus_name_watch (manager);
> +                priv->ibus_reactivated = TRUE;
>
> I don't like this "reactivated" business. Can't we just bail out if one of the
> calls to the ibus-daemon fails? Why would we enter a loop?

The loop happens if we stop the name watch and start it again with the
AUTO_START flag and dbus-daemon fails to bring ibus up for some
reason. Then the vanished callback is called and... we are in a
loop. I actually tried "chmod a-x `which ibus-daemon`" to see what
would happen and that's why I added that flag.

Now, we can just not care when ibus disappears and not try to bring it
up again. It's not supposed to crash anyway and it's actually
architected with engines running in separate processes to lower that
likelihood.

> @@ +619,3 @@
> +                        goto exit;
> +                }
> +#ifdef HAVE_IBUS
>
> I really don't like having an ifdef opening and closing in different blocks.

Ok I moved things around now.

> @@ +627,3 @@
> +                                               GTK_IM_MODULE_SIMPLE);
> +                g_free (module);
> +        } else if (g_str_equal (type, INPUT_SOURCE_TYPE_IBUS)) {
>
> And you should warn here if you have an ibus engine configured and g-s-d is
> built without ibus support.

Done.

> @@ +646,3 @@
> +                        module = g_settings_get_string
> (priv->interface_settings,
> +                                                        KEY_GTK_IM_MODULE);
> +                        if (!g_str_equal (module, GTK_IM_MODULE_IBUS))
>
> You have that construct twice in this code. Can't you monitor which im module
> is in use and do this checking in a separate function?

Also done.
Comment 43 Bastien Nocera 2012-06-29 17:04:59 UTC
(In reply to comment #42)
> Created an attachment (id=217639) [details] [review]
> keyboard: Add the capability to set IBus engines from input sources
> 
> --
> (In reply to comment #41)
> > ::: plugins/keyboard/gsd-keyboard-manager.c
> > @@ +236,3 @@
> > +                stop_ibus_name_watch (manager);
> > +                start_ibus_name_watch (manager);
> > +                priv->ibus_reactivated = TRUE;
> >
> > I don't like this "reactivated" business. Can't we just bail out if one of the
> > calls to the ibus-daemon fails? Why would we enter a loop?
> 
> The loop happens if we stop the name watch and start it again with the
> AUTO_START flag and dbus-daemon fails to bring ibus up for some
> reason. Then the vanished callback is called and... we are in a
> loop. I actually tried "chmod a-x `which ibus-daemon`" to see what
> would happen and that's why I added that flag.
> 
> Now, we can just not care when ibus disappears and not try to bring it
> up again. It's not supposed to crash anyway and it's actually
> architected with engines running in separate processes to lower that
> likelihood.

How about removing the auto_start flag, and making sure we use async function to poke it. That way, the daemon would autostart when we need poke it, and that's all. Would probably stop those loops, and get us errors in code paths where we can get to the errors.
Comment 44 Rui Matos 2012-07-01 17:26:52 UTC
(In reply to comment #43)
> How about removing the auto_start flag, and making sure we use async function
> to poke it. That way, the daemon would autostart when we need poke it, and
> that's all. Would probably stop those loops, and get us errors in code paths
> where we can get to the errors.

Hmm, I'm afraid you might be overlooking something here. We don't do any calls on ibus-daemon through the session bus. The DBus calls that libibus does in the background for us use a connection directly to ibus-daemon. ibus-daemon didn't have any presence at all in the session DBus daemon and the only thing it's going to have there going forward is owning a well known name which just allows us to watch it and thus have a race-free way of keeping track of its life-cycle.
Comment 45 Bastien Nocera 2012-07-09 10:19:28 UTC
The problem is that you're not only keeping track of its lifecycle, but also taking care of launching it in a way that's not race-free. Let the session D-Bus launch it automatically when libibus pokes at it.
Comment 46 Rui Matos 2012-07-09 11:41:39 UTC
(In reply to comment #45)
> The problem is that you're not only keeping track of its lifecycle, but also
> taking care of launching it in a way that's not race-free.

I fail to see where's the race with the current patch. It *was* racy with the previous patch that was g_spawning ibus-daemon, but now there's no race as far as I can tell.

> Let the session
> D-Bus launch it automatically when libibus pokes at it.

Yeah, that would probably be better but it implies more ibus patching, which I can certainly do, but will probably delay us even more in having an upstream release that we can use?
Comment 47 Matthias Clasen 2012-07-09 12:30:40 UTC
Bastien, ok to land this as-is now, and work on moving the activation into libibus afterwards ? We really should land this before guadec, so we can gather some feedback.
Comment 48 Rui Matos 2012-07-10 16:08:04 UTC
Created attachment 218443 [details] [review]
keyboard: Add the capability to set IBus engines from input sources

--

This implements Bastien's suggestion. I added a new patch in the IBus
bug report which tries to dbus activate the ibus daemon when connecting
asynchronously.

I've also modified things slightly here and am only connecting to ibus
(and thus activating it) when there's actually a configured input
source which needs it. This requires some changes to the control
center patch which I'll update shortly.
Comment 49 Bastien Nocera 2012-07-10 17:17:22 UTC
Review of attachment 218443 [details] [review]:

::: plugins/keyboard/gsd-keyboard-manager.c
@@ +76,3 @@
+#define GTK_IM_MODULE_SIMPLE "gtk-im-context-simple"
+#ifdef HAVE_IBUS
+#define GTK_IM_MODULE_IBUS   "ibus"

No need to optionally define that, it's just a string.

@@ +139,3 @@
+{
+        GsdKeyboardManagerPrivate *priv = manager->priv;
+        GList *list, *iter;

Call iter, "l" instead.

@@ +158,3 @@
+        priv->ibus_engines = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
+
+        for (iter = list; iter; iter = iter->next)

add braces here, for the multi-line block.

@@ +175,3 @@
+
+        ibus_bus_list_engines_async (priv->ibus,
+                                     -1, /* default gdbus timeout */

No need for that comment.

@@ +193,3 @@
+
+        g_signal_connect_swapped (priv->ibus, "disconnected",
+                                  G_CALLBACK (on_ibus_disconnected), manager);

As mentioned in IRC:
<hadess> rtcm, i don't think we care it's been disconnected
<hadess>  rtcm, when it's disconnected, it's either because we don't need it (and we've destroyed the ibus object), or because it crashed, in which case it should restart the first time we poke at it

@@ +227,3 @@
+                                  G_CALLBACK (on_ibus_connected), manager);
+}
+#endif

#endif /* HAVE_IBUS */
The start of the condition is pretty far away.
Comment 50 Rui Matos 2012-07-10 21:36:08 UTC
Created attachment 218480 [details] [review]
keyboard: Add functionality to set IBus engines from input sources

--
Addressed all the points. Thanks
Comment 51 Rui Matos 2012-07-10 21:38:01 UTC
Created attachment 218481 [details] [review]
keyboard: Use GSettings::change-event to cut on needless work

Since we end up always doing the same amount of work for in input
sources settings we might as well save some when several keys change
in bulk.

--
Noticed that we could do an optimization here while playing with
changing the input sources order in control center. I can squash this
with the previous patch if you prefer.
Comment 52 Bastien Nocera 2012-07-11 15:47:49 UTC
Review of attachment 218480 [details] [review]:

Looks good to commit.

::: plugins/keyboard/gsd-keyboard-manager.c
@@ +145,3 @@
+        g_clear_object (&priv->ibus_cancellable);
+
+        if (error) {

if (list == NULL && error != NULL)

@@ +155,3 @@
+        priv->ibus_engines = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
+
+        for (l = list; l; l = l->next) {

IBusEngineDesc *engine = l->data;
and use engine in the function.

@@ +200,3 @@
+                }
+
+        if (!need_ibus)

Why don't you call clear_ibus() before?
Surely, it should be stopped if it's not needed anymore.
Comment 53 Bastien Nocera 2012-07-11 15:50:34 UTC
Review of attachment 218481 [details] [review]:

Looks good. As it's an optimisation, it can live outside the main patch.
Comment 54 Rui Matos 2012-07-12 03:38:04 UTC
Created attachment 218602 [details] [review]
keyboard: Add functionality to set IBus engines from input sources

--

Since IBus upstream doesn't want to ship a dbus service file to make
it activatable but agreed to add a patch to own a well known name we
concluded, on IRC, that we will ship the dbus service file for IBus.

I've modified the patch to do that and activate the service by
watching the well known name with the AUTO_START flag. I immediately
unwatch it since we don't need to track it.

I've also addressed Bastien's comments and re-worked the autoconf foo.
Comment 55 Takao Fujiwara 2012-07-12 07:31:56 UTC
(In reply to comment #54)
> Created an attachment (id=218602) [details] [review]
> keyboard: Add functionality to set IBus engines from input sources

I wish ibus package provides org.freedesktop.IBus.service to determine the arguments in ibus side while I don't mind if it's upstreamed or not.
Comment 56 Bastien Nocera 2012-07-12 10:09:38 UTC
Review of attachment 218602 [details] [review]:

::: data/Makefile.am
@@ +90,3 @@
+	             echo 'Name=org.freedesktop.IBus'; \
+	             echo 'Exec=${bindir}/ibus-daemon --replace --xim --panel disable') > $@.tmp && \
+	            mv $@.tmp $@

Use a .in file instead please.
Comment 57 Rui Matos 2012-07-12 13:06:06 UTC
Created attachment 218619 [details] [review]
keyboard: Add functionality to set IBus engines from input sources

--

Using a .in file now.

(In reply to comment #55)
> I wish ibus package provides org.freedesktop.IBus.service to determine the
> arguments in ibus side while I don't mind if it's upstreamed or not.

I think that's not a good idea. I've added the rationale for this to
the commit message:

The ibus-daemon claims a well known name in the session bus but
doesn't ship a .service file to make it activatable so we ship one
ourselves which will spawn it in a convenient way for us. In
particular, we disable its 'panel' component since that functionality
is provided by gnome-shell and would conflict at run time. We also
tell it to replace an existing ibus-daemon since traditionally it
would be spawned at session init time before even DBus was up and out
of control of gnome-session so, in case that happens, our own spawned
version will take place which is what we intend since the
traditionally launched ibus-daemon is highly likely to be running with
its 'panel' component enabled.
Comment 58 Bastien Nocera 2012-07-12 13:19:14 UTC
Review of attachment 218619 [details] [review]:

::: configure.ac
@@ +182,3 @@
+        enable_ibus=yes)
+
+if test "x$enable_ibus" = "xyes" ; then

Doesn't that fail with "auto" as the enable_ibus value?
You'll still need to check for presence of ibus-1.0 in that case.

Or make it a hard requirement that can be disabled with --disable-ibus.

::: data/Makefile.am
@@ +90,3 @@
+	$(AM_V_GEN) sed -e "s|\@bindir\@|$(bindir)|" $< > $@.tmp && mv $@.tmp $@
+
+EXTRA_DIST += $(dbusservice_in_files)

If you add the EXTRA_DIST within the if, you'll break dist'ing without ibus support.

::: data/org.freedesktop.IBus.service.in
@@ +1,3 @@
+[D-BUS Service]
+Name=org.freedesktop.IBus
+Exec=@bindir@/ibus-daemon --replace --xim --panel disable

Will the fallback session still get its ibus notification area icon?
Comment 59 Rui Matos 2012-07-12 23:48:24 UTC
Created attachment 218667 [details] [review]
keyboard: Add functionality to set IBus engines from input sources

--
(In reply to comment #58)
> ::: configure.ac
> @@ +182,3 @@
> +        enable_ibus=yes)
> +
> +if test "x$enable_ibus" = "xyes" ; then
>
> Doesn't that fail with "auto" as the enable_ibus value?
> You'll still need to check for presence of ibus-1.0 in that case.

There's no auto.

> Or make it a hard requirement that can be disabled with --disable-ibus.

That's how it behaves as is.

> ::: data/Makefile.am
> @@ +90,3 @@
> +    $(AM_V_GEN) sed -e "s|\@bindir\@|$(bindir)|" $< > $@.tmp && mv $@.tmp $@
> +
> +EXTRA_DIST += $(dbusservice_in_files)
>
> If you add the EXTRA_DIST within the if, you'll break dist'ing without ibus
> support.

Fixed.

> ::: data/org.freedesktop.IBus.service.in
> @@ +1,3 @@
> +[D-BUS Service]
> +Name=org.freedesktop.IBus
> +Exec=@bindir@/ibus-daemon --replace --xim --panel disable
>
> Will the fallback session still get its ibus notification area icon?

Hmmm, I guess it won't, no. TBH, I'm inclined to just do XKB for
fallback as I'm not inclined to re-implement all the gnome-shell part
in gtk+ (on which module would that live, g-s-d?) and sort of keep the
status quo there for IM users.
Comment 60 Matthias Clasen 2012-07-13 11:53:21 UTC
(In reply to comment #59)
 
> Hmmm, I guess it won't, no. TBH, I'm inclined to just do XKB for
> fallback as I'm not inclined to re-implement all the gnome-shell part
> in gtk+ (on which module would that live, g-s-d?) and sort of keep the
> status quo there for IM users.

I agree with that.
Comment 61 Bastien Nocera 2012-07-13 12:54:04 UTC
Review of attachment 218667 [details] [review]:

::: .gitignore
@@ -40,3 @@
 data/gnome-settings-daemon.desktop.in
 data/50-accessibility.xml
-data/org.gnome.SettingsDaemon.service

Remove that line in a separate patch please.

::: configure.ac
@@ +177,3 @@
 
+AC_ARG_ENABLE(ibus,
+        AS_HELP_STRING([--enable-ibus],

> That's how it behaves as is.
Why is it called --enable-ibus then?

@@ +188,3 @@
+fi
+
+PKG_CHECK_MODULES(KEYBOARD, xkbfile $IBUS_MODULE gnome-desktop-3.0 >= $GNOME_DESKTOP_REQUIRED_VERSION)

Move that below the ibus checks.

::: data/Makefile.am
@@ +92,3 @@
+	$(AM_V_GEN) sed -e "s|\@bindir\@|$(bindir)|" $< > $@.tmp && mv $@.tmp $@
+
+DISTCLEANFILES += $(dbusservice_DATA)

CLEANFILES instead.

::: plugins/keyboard/gsd-keyboard-manager.c
@@ +197,3 @@
+
+        /* DBus activate it if the well known name isn't there. */
+        g_bus_unwatch_name (g_bus_watch_name (G_BUS_TYPE_SESSION,

This is awful. The whole point of using a well-known name with a .service file is to make the daemon autostart when the first function on that object is poked at. You shouldn't have to do ugliness like that.
Comment 62 Rui Matos 2012-07-13 14:07:41 UTC
(In reply to comment #61)
> +AC_ARG_ENABLE(ibus,
> +        AS_HELP_STRING([--enable-ibus],
>
> > That's how it behaves as is.
> Why is it called --enable-ibus then?

Changed to --disable-ibus and fixed the help string.

> @@ +188,3 @@
> +PKG_CHECK_MODULES(KEYBOARD, xkbfile $IBUS_MODULE gnome-desktop-3.0 >=
> $GNOME_DESKTOP_REQUIRED_VERSION)
>
> Move that below the ibus checks.

Done.

> ::: data/Makefile.am
> @@ +92,3 @@
> +DISTCLEANFILES += $(dbusservice_DATA)
>
> CLEANFILES instead.

Done.

> ::: plugins/keyboard/gsd-keyboard-manager.c
> @@ +197,3 @@
> +
> +        /* DBus activate it if the well known name isn't there. */
> +        g_bus_unwatch_name (g_bus_watch_name (G_BUS_TYPE_SESSION,
>
> This is awful. The whole point of using a well-known name with a .service file
> is to make the daemon autostart when the first function on that object is poked
> at. You shouldn't have to do ugliness like that.

Right. IBus is being sui generis here. I expanded the comment
explaining this.

Thanks for the review.

Attachment 218481 [details] pushed as 207d0ef - keyboard: Use GSettings::change-event to cut on needless work
Attachment 218667 [details] pushed as 557bfce - keyboard: Add functionality to set IBus engines from input sources
Comment 63 mads 2012-11-08 18:58:48 UTC
Other applications used to be able to use XKB to
1. get a list of the currently available layouts (or at least 4 of them)
2. select one of them

That was used by for instance other keyboard layout switchers, for instance in cinnamon. Such applications that rely on the XKB API do now behave very strangely.

What should applications now do to cooperate with gnome-settings-daemon?
Comment 64 Rui Matos 2012-11-08 19:08:19 UTC
(In reply to comment #63)
> Other applications used to be able to use XKB to
> 1. get a list of the currently available layouts (or at least 4 of them)
> 2. select one of them
> 
> That was used by for instance other keyboard layout switchers, for instance in
> cinnamon. Such applications that rely on the XKB API do now behave very
> strangely.
> 
> What should applications now do to cooperate with gnome-settings-daemon?

Undefined at this point. If you have specific requests or use cases that you'd like addressed please file a new bug and explain your rationale there.
Comment 65 mads 2012-11-08 19:27:17 UTC
Filed Bug 687935 - Need for some "official" API for interacting with new 3.6 keyboard layout mechanism