Blueprint:DesktopAgnosticConfig
From AWN Wiki
Contents |
[edit] Launchpad Blueprint: Desktop-Agnostic Configuration for Avant Window Navigator
The proposed configuration API wraps the GConf and GKeyFile APIs so that either one can be used to maintain the configuration of AWN. The API implementation is configurable at compile-time with the ./configure switch --with-gconf/--without-gconf.
Note: usage of MUST, SHOULD, MAY conform to RFC 2119.
[edit] API
All public API calls that require a GConf key MUST use the supplied GKeyFile key to GConf key conversion function (also supplied in the (private) API) in order for the GConf-specific code to function.
For the GKeyFile-specific code, gconf notification functions will be supported in that when the set_* functions are called, the notify function(s) will also be called upon completion of the set_* function. There are no plans on monitoring each configuration file for changes, as there would be too much overhead. That is, in this scenario, on each change detected, the configuration file would have to be re-read and re-parsed.
libawn/awn-config.h will be used to supplement libawn/awn-gconf.h and AwnSettings, instead of pure GConf code.
[edit] C Function Prototypes
[edit] libawn/awn-config-client.h
typedef union {
gboolean bool_val;
gfloat float_val;
gint int_val;
gchar *str_val;
GSList *list_val;
} AwnConfigClientNotifyValue;
typedef struct {
AwnConfigClient *client;
gchar *group;
gchar *key;
AwnConfigClientNotifyValue value;
} AwnConfigClientNotifyEntry;
typedef void (*AwnConfigClientNotifyFunc) (AwnConfigClientNotifyEntry *entry, gpointer data);
typedef struct {
AwnConfigClientNotifyFunc callback;
gpointer data;
} AwnConfigClientNotifyData;
#define AWN_CONFIG_CLIENT_DEFAULT_GROUP "DEFAULT"
typedef enum {
AWN_CONFIG_CLIENT_LIST_TYPE_BOOL,
AWN_CONFIG_CLIENT_LIST_TYPE_FLOAT,
AWN_CONFIG_CLIENT_LIST_TYPE_INT,
AWN_CONFIG_CLIENT_LIST_TYPE_STRING
} AwnConfigListType;
AwnConfigClient *awn_config_client_new (); /* used with Awn core */
/* name is a UNIX-style name that will be used as part of the filename with the GKeyFile mode, and as part of the key for the GConf mode.
* If uid is NULL, it is assumed that the applet is a singleton.
*/
AwnConfigClient *awn_config_client_new_for_applet (gchar *name, gchar *uid);
void awn_config_client_clear (AwnConfigClient *client, GError **err);
void awn_config_client_ensure_group (AwnConfigClient *client, const gchar *group);
void awn_config_client_notify_add (AwnConfigClient *client, const gchar *group,
const gchar *key, AwnConfigClientNotifyFunc callback,
gpointer data);
gboolean awn_config_client_entry_exists (AwnConfigClient *client, const gchar *group,
const gchar *key);
gboolean awn_config_client_get_bool (AwnConfigClient *client, const gchar *group,
const gchar *key, GError **err);
void awn_config_client_set_bool (AwnConfigClient *client, const gchar *group,
const gchar *key, gboolean value, GError **err);
gfloat awn_config_client_get_float (AwnConfigClient *client, const gchar *group,
const gchar *key, GError **err);
void awn_config_client_set_float (AwnConfigClient *client, const gchar *group,
const gchar *key, gfloat value, GError **err);
gint awn_config_client_get_int (AwnConfigClient *client, const gchar *group,
const gchar *key, GError **err);
void awn_config_client_set_int (AwnConfigClient *client, const gchar *group,
const gchar *key, gint value, GError **err);
gchar *awn_config_client_get_string (AwnConfigClient *client, const gchar *group,
const gchar *key, GError **err);
void awn_config_client_set_string (AwnConfigClient *client, const gchar *group,
const gchar *key, gchar *value, GError **err);
GSList *awn_config_client_get_list (AwnConfigClient *client, const gchar *group,
const gchar *key, AwnConfigListType list_type,
GError **err);
void awn_config_client_set_list (AwnConfigClient *client, const gchar *group,
const gchar *key, AwnConfigListType list_type,
GSList *value, GError **err);
void awn_config_client_unref (AwnConfigClient *client);
[edit] Python Bindings
[edit] awn.Config
awn.CONFIG_LIST_BOOL, awn.CONFIG_LIST_FLOAT, awn.CONFIG_LIST_INT, awn.CONFIG_LIST_STRING = range(4) awn.CONFIG_DEFAULT_GROUP = 'DEFAULT'
cfg = awn.Config() # constructor for Awn core cfg = awn.Config(str_name, str_uid) # constructor for applets cfg.clear() # raises gobject.GError cfg.ensure_group(str_group) cfg.notify_add(str_group, str_key, callback_notify) cfg.notify_add(str_group, str_key, callback_notify, obj_user_data) ret_bool = cfg.exists(str_group, str_key) ret_bool = cfg.get_bool(str_group, str_key) # raises gobject.GError cfg.set_bool(str_group, str_key, bool_value) # raises gobject.GError ret_float = cfg.get_float(str_group, str_key) # raises gobject.GError cfg.set_float(str_group, str_key, float_value) # raises gobject.GError ret_int = cfg.get_int(str_group, str_key) # raises gobject.GError cfg.set_int(str_group, str_key, int_value) # raises gobject.GError ret_str = cfg.get_string(str_group, str_key) # raises gobject.GError cfg.set_string(str_group, str_key, str_value) # raises gobject.GError ret_seq = cfg.get_list(str_group, str_key) # raises gobject.GError cfg.set_list(str_group, str_key, list_type, seq_value) # raises gobject.GError
[edit] GConf Key / Directory Structure
This section describes the schema that GConf keys and GKeyFile configuration files' directory structures MUST adhere to.
[edit] GConf
All GConf keys SHOULD reside under the prefix /apps/avant-window-navigator. All applet-specific GConf keys SHOULD reside under the prefix /apps/avant-window-navigator/applets.
[edit] GKeyFile
All configuration files SHOULD reside in the folder $XDG_CONFIG_HOME/awn/ or a subdirectory thereof [FDO-BASEDIR]. The configuration file that handles the core AWN options resides at $XDG_CONFIG_HOME/awn/awn.ini. All applet configuration files SHOULD reside in the folder $XDG_CONFIG_HOME/awn/applets/.
[edit] Schema
The GKeyFile API doesn't have a mechanism to dynamically determine the value type of the key that it stores, so we have to create a schema format to do it ourselves. A Python script to convert the GKeyFile schema to a GConf schema will be provided, as well as a sample Makefile.am that uses the script to generate a GConf schema if the user uses the GConf backend.
[edit] File Type
- MIME Type: application/x-awn-config-schema
- File extension: .schema-ini
[edit] Location
The code will look in the following location(s) for these files: $AWN_DATADIR/awn/schemas for AWN proper's schema file, named awn.schema-ini, and $AWN_DATADIR/awn/schemas and $XDG_DATA_HOME/awn/schemas for applet schema files [FDO-BASEDIR]. $AWN_DATADIR is the data directory configured at compile-time by ./configure, using the --datadir=[PATH] switch.
[edit] File Format
In the example below, values which look like uppercased variables in PHP or PERL (i.e., prefixed with a $) are values which can have a number of different values.
[$GROUP/$KEY] type = $TYPE default = $DEFAULT description = $DESC description[$LOCALE] = $DESC_LOCALE
- $GROUP: The group to which the key belongs.
- $KEY: The key being described.
- $TYPE: This entry MUST be in the group. Value MUST be one of the following case-sensitive values:
- bool
- float
- int
- string
- list-bool
- list-float
- list-int
- list-string
- $DEFAULT: The default value of the key. MUST be the same type as the type specified in the type entry. This entry SHOULD be in the group.
- $DESC: The description of the key. It SHOULD be in United States English (en_US). This entry MUST be in the group.
- $LOCALE: The locale in which you want to write an alternate description [IEEE STD 1003.1 CH. 7]
- $DESC_LOCALE: The alternate description written in the locale specified. This entry MAY be in the group.
[edit] Examples
Hypothetically, I added a new feature called "bling" that makes all of the widgets on the dock sparkly. This can be turned on or off in awn-manager with a checkbox under "effects". The GConf key for this option would be /apps/avant-window-navigator/effects/bling (boolean). The equivalent option in a GKeyFile would reside in /home/bob/.config/awn/awn.ini, and look something like the following:
... [effects] ... bling = True ...
The schema for this would reside in /usr/share/awn/schemas/awn.schema-ini, and would look something like the following:
... [effects/bling] type = bool default = False description = Makes all of the widgets on the dock sparkly ...
To get and set that configuration option via the C API:
AwnConfigClient *client = awn_config_new (); gboolean do_bling = awn_config_get_bool (client, "effects", "bling"); awn_config_set_bool (client, "effects, "bling", FALSE);
Here's the equivalent code using the Python API:
import awn
client = awn.Config()
do_bling = client.get_bool('effects', 'bling')
client.set_bool("effects", "bling", False)
Now I've decided to write an applet that shows a random thumbnail from my pictures folder. The applet name is "thumb-slide". It uses the following configuration options:
- show_time - the amount of time (in seconds) that the thumbnail stays on the screen before a new one is picked. (int)
- picture_folders - the list of folders where the pictures to be chosen reside. (string list)
In GConf mode, the options would reside in /apps/avant-window-navigator/applets/thumb-slide. In GKeyFile mode, the options would reside in /home/bob/.config/awn/applets/thumb-slide.ini.
The schema file would reside in /usr/share/awn/schemas/thumb-slide.schema-ini, and look like this:
[DEFAULT/show_time] type = int default = 10 description = the amount of time (in seconds) that the thumbnail stays on the screen before a new one is picked [DEFAULT/picture_folders] type = list-string default = ; # this is an empty list description = the list of folders where the pictures to be chosen reside
In the applet, the way to manipulate the configuration options using the C API is as follows:
AwnConfigClient *aclient = awn_config_new_for_applet ("thumb-slide", NULL);
GSList *folders = awn_config_get_list (aclient, AWN_CONFIG_DEFAULT_GROUP, "picture_folders", AWN_CONFIG_LIST_TYPE_STRING);
GSList *iter;
for (iter = folders; iter != NULL; iter = g_slist_next(iter)) { /* ... */ }
gint show_time = awn_config_get_int(aclient, AWN_CONFIG_DEFAULT_GROUP, "show_time");
Here's the equivalent code using the Python API:
import awn
aclient = awn.Config('thumb-slide', None)
folders = aclient.get_list(awn.CONFIG_DEFAULT_GROUP, "picture_folders", awn.CONFIG_TYPE_STRING)
for folder in folders:
do_stuff(folder)
show_time = aclient.get_int(awn.CONFIG_DEFAULT_GROUP, "show_time")
[edit] References
- FDO-BASEDIR: freedesktop.org base directory specification
- IEEE STD 1003.1 CH. 7: The Open Group Base Specifications Issue 6: IEEE Std 1003.1, 2004 Edition, Chapter 7 - Locale

