[Usability] writeup of prefs storage plan
- From: Havoc Pennington <hp redhat com>
- To: gnomecc-list gnome org, usability gnome org, gnome-libs-devel gnome org
- Subject: [Usability] writeup of prefs storage plan
- Date: 24 Oct 2001 21:52:13 -0400
Hi,
I just found this in my home directory, I wrote it a while ago and
forgot to mail it off. This is taking into account comments I got last
time I posted on this topic.
I also forgot to implement gnome_client_get_global_id(). I think this
is just:
const char*
gnome_client_get_global_id (void)
{
return g_getenv ("GNOME_GLOBAL_SESSION_ID");
}
So, not a big deal. ;-) Well, there's also the matter of having
gnome-session set that env variable, but also not a big deal.
Send more comments. Where should we post the final writeup?
Havoc
Proposal for handling the storage of preferences and session state
using the GNOME platform.
Definitions:
- application session ID: a globally-unique string identifying an
application instance. Applications receive their ID from the
session manager; to get your ID, call gnome_client_get_id(). The
ID is in Latin-1 encoding. The ID may be NULL, if the app isn't
connected to a session manager yet. This is specified by the
XSMP protocol.
- session: a collection of application instances, possibly under
some user-provided name. For example, user might have "Home"
and "Work" sessions. The set of application instances can
be saved to disk, and then later restored. That is, each
application provides the session manager with a command line
to restart the app; the session manager records this information,
and uses it to restart apps next time you log in.
- global session ID: a unique string identifying a _session_. The
global session ID is a GNOME extension, and may not be supported by
all session managers. Retrieve it using
gnome_client_get_global_id(). The global session ID is a string
that all applications in the current session will know about, but
no applications outside the current session will know about.
Think of the global session ID as a session ID for the current
instance of the desktop considered as a whole. i.e. pretend GNOME
is an application, the global ID is its session ID.
For robustness, the global session ID for the default session will
be simply "Default" or the like, and never change. This ensures
that users who never use named sessions will never lose settings,
and ensures that users can safely kill off their session files
without losing settings.
- profile: a named set of application settings, as in the "terminal
class" of gnome-terminal. This makes sense when an app may
be used in multiple contexts by the same user, and that user
may want different settings in each context.
How to save data:
Data can be namespaced in the following ways:
- by including the application session ID in the data key,
the saved data will only apply to one copy of an app
- by including the global session ID in the data key, the saved
data will only apply to app instances that are in the session
with that ID
- by including no session ID in a data key, the saved data will
apply to all app instances in all sessions
To create a GConf key including a session ID, use the normal prefix
you would use (according to the key-naming conventions in the GConf
manual), but append "sessions/SESSIONID" to that prefix. For
example, Galeon stores preferences in the /apps/galeon/ directory. It
would store session state in /apps/galeon/sessions/SESSIONID/
instead. GNOME stores GNOME-wide preferences in /desktop/gnome/; it
would store GNOME-wide per-session preferences in
/desktop/gnome/sessions/GLOBALSESSIONID. Note that SESSIONID must be
escaped with gconf_escape_key() prior to using it in a GConf key.
Use a similar rule when storing data in files. For example, you might
have a file ~/.myappname/sessions/SESSIONID with per-session
information.
What data to put where:
. Only settings related to application _instance_ state should be
stored under the application's session ID. Examples are the
currently-open windows, what documents are opened in the windows,
where the cursor is located. Most settings are global preferences,
not session state.
. The window manager stores window positions. Apps need not bother
to do so.
. Important or critical data, including preferences that take effort
to set up, should never be stored per-session. If a user spends a
lot of time setting up their panel or terminal, they don't want to
lose that data when changing sessions, or if something goes wrong
with the session system. (See implementation notes on this
topic.) Data such as documents should NEVER go in the
instance-specific location.
. User preferences should almost always apply globally to all app
instances in all sessions. With GConf this can happen without
even restarting the app instances.
. Settings that are per-session, but not associated with a
particular application instance, should go under the global
session ID. For example, we might make the desktop background
per-session.
. In no case should the same setting be stored both per-instance and
globally. This simply makes no sense, and results in a UI that
makes no sense, and implementation code that makes no sense. For
example, if I have a setting "open directories in a new window,"
that setting cannot be saved per-session sometimes and globally
some other times. Pick one.
. Per-session settings should not appear in any prefs dialogs,
because it's confusing. Prefs dialogs should affect the global
state of the app.
Implementation notes:
. There is no real reason why app-instance-specific data needs to be
in GConf, though it may be convenient and there is nothing wrong
with it. Storing app-instance-specific data in files is fine,
because the features of GConf just aren't required.
. Often you want to allow per-session setups, but setting up an
application involves noticeable user effort. One suggested
solution to this problem is to have a "named profile" feature in
the application. Make the list of profiles, and the contents of
each profile, a global preference. Make the currently-active
profile a per-session or per-instance setting. This means that
only the easy-to-restore "active profile" can be lost if the user
switches sessions, but the user can still trivially return to the
previous setup, i.e. no data is lost.
A "Default" profile should always exist, for robustness; all
preferences are stored in the "Default" profile if the user never
uses the named profile feature.
Opening a new app instance should always create an instance with
the Default profile. i.e. don't do something like open new
instances with the most-recently-used profile. This leads to
a situation where users can't predict which profile a new app
instance will have.
An app with profiles should have a "Preferences" dialog that edits
whichever profile is active, if the profile includes all
preferences. However, the prefs dialog should not include an
option to change the current profile, because that fails to
emphasize the per-instance nature of the active profile; instead,
the profile should be chosen from a menu or the like. This also
allows naive users to ignore the profiles feature, and simply use
the preferences dialog without seeing it.
If an app only includes some of its settings in the profile, and
makes other settings apply to all copies of the app, then the
settings that always apply should be in the Preferences dialog,
and the settings that are per-profile should be in a separate
dialog called something like "Edit Profile." That is, the prefs
dialog should not be a mixture of a profile editor and
profile-spanning prefs, because then the user can't tell which
settings are per-profile.
Profiles are sort of inherently complicated, so apps that don't
need them (i.e. most apps) should not have them.
. We may also have a desktop-wide "profile" feature; this is
"location management," basically. (As I understand it.) For
desktop-wide profiles, the name of the currently-active profile
(location) would be stored under the global session ID, but the
list of profiles to choose from would be available in all
sessions.
. As mentioned earlier, session IDs are in Latin-1; to display them,
convert to UTF-8; to use them as a GConf key, use
gconf_escape_key().
. gnome_client_get_id () returns the application instance ID
. gnome_client_get_global_id () returns the global session ID
. Applications MUST ALWAYS open the same number of windows they
had open at session save time. If you haven't implemented this,
DO NOT connect to the session manager, because you will confuse
the window manager out of its mind. Call
gnome_disable_master_client() prior to initializing libgnomeui,
until you've implemented SM correctly.
. When setting the RestartCommand for your app, use
the standard --sm-client-id option to pass the current session ID
to the restarted app.
. For plain GTK apps, there's a start on a standalone SM library
in msm/gsmclient, in CVS; also, twm, metacity, and xclock
are examples of apps containing SM client code you could look
at.
. If you store session state in GConf, the DiscardCommand should
use "gconftool-2" explicitly (not "gconftool") because
only gconftool-2 supports the --recursive-delete option
for blowing away an entire directory.
How this looks to users:
Users need not use named sessions, and need not use named
profiles. Both features will be semi-hidden in the UI. If the
features are not activated (by creating names other than "Default"),
then all preferences appear to be global, and when the user saves
session they can expect the same set of apps to be opened in the same
positions next time they log in. If the user never saves their
session, they always get the default apps in the default
positions. That's all that happens, the user model is very simple (in
fact no user model is required, stuff just works as expected).
If named sessions are used, users see this as the ability to save a
set of currently open apps under some name, to be reopened later.
If named profiles are used, users see this as a way to "bookmark"
certain groups of preferences to be restored. Named profiles should
only be used in a few apps where it really makes sense, for example
for gnome-terminal.
Issues/Discussion:
What terminology and organization do we use when presenting things to
users? Profiles are the most interesting thing from this standpoint.
One UI for panel profiles might be a "Name this configuration..."
menu item to create a new profile with the current state, and a
"Configuration" menu listing all the configurations. This
could come pre-stocked with "Windows", "CDE", and "Ximian" style
configs, for example.
Name This Configuration...
Current Configuration ->
Windows
CDE
Ximian
gnome-terminal could work just the same way:
Name This Configuration...
Current Configuration ->
Linux console
Black-on-white
37337 E
xterm
For panel, there are global prefs that affect panels in all profiles;
e.g. the global keybindings. Suggestion: put these in the
Preferences... dialog, and have all per-panel settings in the
Properties... dialog for a particular panel. Then a profile contains
the list of current panels, and the properties of those panels. The
active profile gets saved with the session.
For gnome-terminal, the Preferences... dialog could just edit the
current profile, and all settings are stored per-profile.
For the panel, nearly everything in the current "Global prefs" dialog
could actually be per-panel, the line between global and per-panel
seems pretty random at the moment. If profiles only include per-panel
state, perhaps some of those global prefs should be moved into the
per-panel properties dialog.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]