Move input configuration to accountsservice
Submitted by Allison (desrt)
Link to original bug (#709213)
Description
We currently store the list of input configurations in GSettings.
So that the information is available at the login screen (to allow the user to enter their password with their own layout) we want to move the settings to accountsservice. At the same time, this will give us a chance to expand the format to be based on dictionaries rather than tuples (which will fix the current situation whereby it's not possible to specify the layout to use a given input method with).
Since we're storing the information in accountsservice, we need to stop storing it in GSettings (since syncing those two things up would not be fun). It is also my opinion that the current-selected layout should be treated as transient state, and not stored anywhere persistent.
I particularly believe this to be the case because it is very important that the layout at the login screen (where the user is typing their password) be set in a predictable way, not affected by what happened to be the last-selected layout the last time the user was logged in.
This will impact at least the following modules:
-
accountsservice: see https://bugs.freedesktop.org/show_bug.cgi?id=63086
-
gnome-control-center: will have to update accountsservice instead of gsettings
-
gnome-settings-daemon: will have to get values out of accountsservice instead of gsettings
-
gnome-shell: can no longer use gsettings to query/set the layout
-
gdm: will want to display the layout options to the user and set them up in the X server.
Aside from simply moving the data from GSettings to accountsservice, two interesting problems will need to be solved. The first is that, if the user changes their layout at the login screen, we should expect that that changed layout will be the active one once the session is logged in. We therefore need a way to get that information from accountsservice into the session.
I think the easiest way to do this would be via an X property that stores the current layout. We discussed just now on IRC storing an index into the list from accountsservice, but maybe it would be better if we GVariant-text-serialised the current layout (dictionary) and stored that, in order to avoid possible races whereby the list of layouts changes out-of-sync with the index pointer.
Second is that although it is a bit weird, but OK for gnome-shell to be looking at gsettings in order to compute the list of possible layouts for display and switching, we probably don't want gnome-shell talking to accountsservice for the same purpose. It would be much better, in my opinion, if we put a D-Bus interface for this on gnome-settings-daemon and made the code in the shell as dumb as possible. The interface could be as simple as telling the shell which user-visible strings to display in the menu and which is the active one.
Maybe we could even use GMenuModel and GActionGroup and leverage the existing code for these that's already in the shell. ;)
Another interesting question is about what will happen when the user is changing the list of input sources in the control center. Obviously, we need to update the accounts service and also notify g-s-d (somehow) so that it can make changes to the current session in realtime. Maybe we should just have, as part of our input sources API on g-s-d, an interface for adding and removing configurations. That would allow the code in g-c-c to be very simple, grouping all of the "smarts" of how this works into a single place. That would also mean that g-s-d is the sole keeper of the "current layout" state in the session, which is nice for everyone.
Assuming we go along with all of the above, I guess we'd see an interface on gnome-settings-daemon along the lines of the following:
org.gnome.InputSources { properties; aa{sv} sources; /* read-only / int32 active_source; / read-only */
methods: .Add (int32 before_index, a{sv} input_source_info);
.Remove (int32 index);
.SetActive (int32 index);
signals:
.ActiveChanged (int32 index);
.ListChanged (int32 position, int32 removed, aa{sv} inserted); /* NB: similar to GMenuModel */ };
or another more brute-force approach:
org.gnome.InputSources { properties: aa{sv} sources; /* read/write / int32 active_source; / read/write */ }
gnome-settings-daemon would make sure each a{sv} contained a "display-name" property for the benefit of simplicity of implementation in the shell. Adding or removing sources would cause gnome-settings-daemon to take care of the legwork in dealing with accountsservice and handling setup of X/ibus/etc.
I'm implicitly assuming here that the user will be permitted to modify their own keyboard layout. If the admin were to want to restrict that (using polkit) then we may need some way for g-s-d to notify g-c-c that changes are not permitted, because although the user would be making changes in g-c-c, the actual write to the backend would be done from g-s-d. Maybe that is reason enough to make the g-s-d interface only useful for the shell (ie: viewing the currently-setup layouts and changing between them) and having g-c-c itself modify the accountsservice.
Implicitly, the first item in the list would be the default one.