[metacity] Port preferences to GSettings



commit a228546d3cdf3364b82d76b374fb08aae202ab87
Author: Florian MÃllner <fmuellner gnome org>
Date:   Fri Nov 4 18:14:26 2011 +0100

    Port preferences to GSettings
    
    Move preferences to GSettings, using mainly shared schemas from
    gsettings-desktop-schemas.
    
    Unlike GConf, GSettings support is not optional, as Gio is already
    a hard dependency of GTK+.
    
    Based on an initial patch from Milan Bouchet-Valat.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=621204

 .gitignore                                         |    4 +-
 HACKING                                            |    8 +-
 README                                             |   32 +-
 configure.in                                       |   33 +-
 doc/compositor-control.txt                         |    6 +-
 doc/creating_themes/C/creating-metacity-themes.xml |    4 +-
 doc/man/metacity-message.1                         |    6 +-
 doc/man/metacity.1                                 |    2 +-
 po/POTFILES.in                                     |   10 +-
 src/50-metacity-launchers.xml.in                   |    8 -
 src/50-metacity-navigation.xml.in                  |  289 +--
 src/50-metacity-screenshot.xml.in                  |   11 -
 src/50-metacity-system.xml.in                      |   12 +-
 src/50-metacity-windows.xml.in                     |   58 +-
 src/Makefile.am                                    |   45 +-
 src/core/bell.c                                    |   13 +-
 src/core/core.c                                    |   42 +-
 src/core/display.c                                 |   10 +-
 src/core/keybindings.c                             |  173 +--
 src/core/prefs.c                                   | 2126 ++++++--------------
 src/core/schema-bindings.c                         |  195 --
 src/core/screen.c                                  |    2 +-
 src/core/window.c                                  |   12 +-
 src/core/workspace.c                               |   10 +-
 src/include/all-keybindings.h                      |  357 +---
 src/include/common.h                               |   31 +-
 src/include/prefs.h                                |   42 +-
 src/metacity-schemas.convert                       |    3 +
 src/metacity.schemas.in.in                         |  595 ------
 src/org.gnome.metacity.gschema.xml.in              |   27 +
 src/ui/frames.c                                    |   19 +-
 test/metacity-test                                 |    4 -
 32 files changed, 927 insertions(+), 3262 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index c32e43c..4fad7af 100644
--- a/.gitignore
+++ b/.gitignore
@@ -177,8 +177,8 @@ src/metacity
 src/metacity-theme-viewer
 src/metacity-wm.desktop
 src/metacity.desktop
-src/metacity.schemas
-src/metacity.schemas.in
+src/org.gnome.metacity.gschema.valid
+src/org.gnome.metacity.gschema.xml
 src/place.o
 src/prefs.o
 src/resizepopup.o
diff --git a/HACKING b/HACKING
index a6cbdf5..45bd8b4 100644
--- a/HACKING
+++ b/HACKING
@@ -42,10 +42,10 @@ Minimal Building/Testing Environment
   build a development version of Metacity -- odds are, you may be able
   to build metacity from CVS without building any other modules.
 
-  As long as you have gtk+ >= 2.10 and GConf with your distro (gtk+ >=
-  2.6 if you manually revert the change from bug 348633), you should
-  be able to install your distro's development packages
-  (e.g. gtk2-devel, GConf2-devel, startup-notification-devel on
+  As long as you have gtk+ >= 2.10 and GIO >= 2.25.10 with your distro
+  (gtk+ >= 2.6 if you manually revert the change from bug 348633), you
+  should be able to install your distro's development packages
+  (e.g. gtk2-devel, glib-devel, startup-notification-devel on
   Fedora; also, remember to install the gnome-common package which is
   needed for building cvs versions of Gnome modules like Metacity) as
   well as the standard development tools (gcc, autoconf, automake,
diff --git a/README b/README
index 9da1ef5..9b00692 100644
--- a/README
+++ b/README
@@ -18,8 +18,7 @@ COMPILING METACITY
 You need GTK+ 2.2.  For startup notification to work you need
 libstartup-notification at
 http://www.freedesktop.org/software/startup-notification/ or on the
-GNOME ftp site. You also need GConf 1.2 (unless building a funky
-extra-small embedded metacity with --disable-gconf, see below).
+GNOME ftp site.
 
 REPORTING BUGS AND SUBMITTING PATCHES
 ===
@@ -48,7 +47,6 @@ the theme engine.
 You can strip about 70K from the metacity binary by compiling with 
 options such as:
 
- --disable-gconf
  --disable-sm
  --disable-verbose-mode
  --disable-startup-notification
@@ -94,25 +92,24 @@ METACITY FEATURES
    and should work with KWin, fvwm2, and other EWMH-compliant WMs.)
 
  - Has a simple theme system and a couple of extra themes come with it.
-   Change themes via gconf-editor or gconftool or GNOME themes control
-   panel:
-     gconftool-2 --type=string --set /apps/metacity/general/theme Crux
-     gconftool-2 --type=string --set /apps/metacity/general/theme Gorilla
-     gconftool-2 --type=string --set /apps/metacity/general/theme Atlanta
-     gconftool-2 --type=string --set /apps/metacity/general/theme Bright
+   Change themes via gsettings:
+     gsettings set org.gnome.desktop.wm.preferences theme Crux
+     gsettings set org.gnome.desktop.wm.preferences theme Gorilla
+     gsettings set org.gnome.desktop.wm.preferences theme Atlanta
+     gsettings set org.gnome.desktop.wm.preferences theme Bright
 
    See theme-format.txt for docs on the theme format. Use 
    metacity-theme-viewer to preview themes.
 
- - Change number of workspaces via gconf-editor or gconftool:
-     gconftool-2 --type=int --set /apps/metacity/general/num_workspaces 5
+ - Change number of workspaces via gsettings:
+     gsettings set org.gnome.desktop.wm.preferences num-workspaces 5
 
    Can also change workspaces from GNOME 2 pager.
 
  - Change focus mode:
-     gconftool-2 --type=string --set /apps/metacity/general/focus_mode mouse
-     gconftool-2 --type=string --set /apps/metacity/general/focus_mode sloppy
-     gconftool-2 --type=string --set /apps/metacity/general/focus_mode click
+     gsettings set org.gnome.desktop.wm.preferences focus-mode mouse
+     gsettings set org.gnome.desktop.wm.preferences focus-mode sloppy
+     gsettings set org.gnome.desktop.wm.preferences focus-mode click
 
  - Global keybinding defaults include:   
 
@@ -127,12 +124,9 @@ METACITY FEATURES
 
    Change keybindings for example:
 
-     unst gconftool-2 --type=string --set /apps/metacity/global_keybindings/switch_to_workspace_1 '<Alt>F1'
+     gsettings set org.gnome.desktop.wm.keybindings switch_to_workspace_1 '<Alt>F1'
    
-   Also try the GNOME keyboard shortcuts control panel, or
-   gconf-editor.
-
-   See metacity.schemas for all available bindings.
+   Also try the GNOME keyboard shortcuts control panel.
 
  - Window keybindings:
 
diff --git a/configure.in b/configure.in
index eb646c0..dbf956e 100644
--- a/configure.in
+++ b/configure.in
@@ -113,20 +113,13 @@ dnl work; see https://bugzilla.gnome.org/show_bug.cgi?id=650513
 with_gtk=2.0
 GTK_API_VERSION=2.0
 GTK_MIN_VERSION=2.20.0
+GIO_MIN_VERSION=2.25.10
 CANBERRA_GTK=libcanberra-gtk
 
-METACITY_PC_MODULES="gtk+-$GTK_API_VERSION >= $GTK_MIN_VERSION pango >= 1.2.0"
+METACITY_PC_MODULES="gtk+-$GTK_API_VERSION >= $GTK_MIN_VERSION gio-2.0 >= $GIO_MIN_VERSION pango >= 1.2.0 gsettings-desktop-schemas"
 AC_SUBST(GTK_API_VERSION)
 
-AC_ARG_ENABLE(gconf,
-  AC_HELP_STRING([--disable-gconf],
-                 [disable gconf usage, for embedded/size-sensitive non-GNOME builds]),,
-  enable_gconf=yes)
-
-if test x$enable_gconf = xyes; then
-    AC_DEFINE(HAVE_GCONF,1,[Build with gconf support])
-    METACITY_PC_MODULES="$METACITY_PC_MODULES gconf-2.0 >= 1.2.0"
-fi
+GLIB_GSETTINGS
 
 AC_ARG_ENABLE(canberra,
   AC_HELP_STRING([--disable-canberra],
@@ -492,18 +485,6 @@ fi
 
 AC_SUBST(GDK_PIXBUF_CSOURCE)
 
-if test x$enable_gconf = xyes; then 
-   AC_PATH_PROG(GCONFTOOL, gconftool-2, no)
-   if test x"$GCONFTOOL" = xno; then
-     AC_MSG_ERROR([gconftool-2 executable not found in your path - should be installed with GConf])
-   fi
-
-   AM_GCONF_SOURCE_2
-else
-  GCONF_SCHEMAS_INSTALL_TRUE='#'
-  GCONF_SCHEMAS_INSTALL_FALSE=
-fi
-
 AC_PATH_PROG(ZENITY, zenity, no)
 if test x"$ZENITY" = xno; then
   AC_MSG_ERROR([zenity not found in your path - needed for dialogs])
@@ -539,13 +520,6 @@ po/Makefile.in
 
 AC_OUTPUT
 
-if test x$enable_gconf = xno; then
-        echo "*** WARNING WARNING WARNING WARNING WARNING"
-        echo "*** Building without GConf.  This means there's no"
-        echo "*** way to change prefs except hacking source code."
-        echo "*** This is intended for embedded systems etc., not for normal use."
-fi
-
 if test x$enable_verbose_mode = xno; then
         echo "*** WARNING WARNING WARNING WARNING WARNING"
         echo "*** Building without verbose mode"
@@ -562,7 +536,6 @@ metacity-$VERSION (using gtk+-${GTK_API_VERSION}):
 	source code location:	  ${srcdir}
 	compiler:		  ${CC}
 
-	GConf:                    ${enable_gconf}
 	Canberra:                 ${enable_canberra}
 	XFree86 Xinerama:         ${use_xfree_xinerama}
 	Solaris Xinerama:         ${use_solaris_xinerama}
diff --git a/doc/compositor-control.txt b/doc/compositor-control.txt
index e2e04bd..ae0f598 100644
--- a/doc/compositor-control.txt
+++ b/doc/compositor-control.txt
@@ -7,14 +7,14 @@ To turn the compositor on initially, you need to pass --enable-compositor to
 the configure script. This will introduce a dependence on libcm, which you
 can get from <URL:http://ftp.gnome.org/pub/GNOME/sources/libcm/>.
 
-When Metacity is compiled, you will need to turn the compositor on in gconf
+When Metacity is compiled, you will need to turn the compositor on in gsettings
 for it to have any effect. You will find the boolean switch at
 
-   /apps/metacity/general/compositing_manager
+   org.gnome.metacity compositing-manager
 
 When that's done, you can set some environment variables before you launch
 Metacity to influence how the compositor works. These will eventually become
-configuration options or gconf options when they grow up. Define them to any
+configuration options or gsettings options when they grow up. Define them to any
 value to turn them on; leave them undefined to turn them off. Currently the
 options you can set are:
 
diff --git a/doc/creating_themes/C/creating-metacity-themes.xml b/doc/creating_themes/C/creating-metacity-themes.xml
index ea5f040..045cae2 100644
--- a/doc/creating_themes/C/creating-metacity-themes.xml
+++ b/doc/creating_themes/C/creating-metacity-themes.xml
@@ -266,9 +266,9 @@ for a theme installed for all users.</para></listitem>
 <para>When you're editing a theme, you can view it without using it on the whole desktop using
 <command>metacity-theme-viewer YourThemeName</command></para>
 <para>and view it on the whole desktop using
-<command>gconftool -<!-- x -->-type=string -<!-- x -->-set /apps/metacity/general/theme YourThemeName</command></para>
+<command>gsettings set org.gnome.desktop.wm.preferences theme YourThemeName</command></para>
 
-<para>Whenever you change the selected theme in GConf, Metacity will load the newly-chosen theme.  This is how control-center does it.  But when you change a theme, as you're working on it, you might want to ask Metacity to reload the theme which is currently used on the whole desktop to reflect your changes.  You can do this using the little-known <command>metacity-message</command> program, with the command <literal>metacity-message reload-theme</literal>.  This works by sending the ClientMessage <literal>_METACITY_RELOAD_THEME_MESSAGE</literal> to the root window, in case you're interested.</para>
+<para>Whenever you change the selected theme in GSettings, Metacity will load the newly-chosen theme.  This is how control-center does it.  But when you change a theme, as you're working on it, you might want to ask Metacity to reload the theme which is currently used on the whole desktop to reflect your changes.  You can do this using the little-known <command>metacity-message</command> program, with the command <literal>metacity-message reload-theme</literal>.  This works by sending the ClientMessage <literal>_METACITY_RELOAD_THEME_MESSAGE</literal> to the root window, in case you're interested.</para>
 
 <para>Once you're done with your theme, consider submitting it to <ulink url="http://art.gnome.org/themes/metacity/";>the art.gnome.org site</ulink>, or <ulink url="http://www.gnome-look.org/index.php?xcontentmode=101";>the gnome-look site</ulink>.</para>
 
diff --git a/doc/man/metacity-message.1 b/doc/man/metacity-message.1
index 7ee62cd..80041f5 100644
--- a/doc/man/metacity-message.1
+++ b/doc/man/metacity-message.1
@@ -46,13 +46,13 @@ because the original program does not have a manual page.
 Restart \fBmetacity\fP(1) which is running.
 .TP
 .B reload-theme
-Reload a theme which is specified on gconf database.
+Reload a theme which is specified on gsettings database.
 .TP
 .B enable-keybindings
-Enable all of keybindings which is specified on gconf database.
+Enable all of keybindings which is specified on gsettings database.
 .TP
 .B disable-keybindings
-Disable all of keybindings which is specified on gconf database.
+Disable all of keybindings which is specified on gsettings database.
 .SH SEE ALSO
 .BR metacity (1)
 .SH AUTHOR
diff --git a/doc/man/metacity.1 b/doc/man/metacity.1
index 3232ade..0a4c347 100644
--- a/doc/man/metacity.1
+++ b/doc/man/metacity.1
@@ -51,7 +51,7 @@ Print the version number.
 .B \-?, \-\-help
 Show summary of options.
 .SH CONFIGURATION
-\fBmetacity\fP configuration can be found under \fIPreferences\fP->\fIWindows\fP and \fIPreferences\fP->\fIKeyboard Shortcuts\fP on the menu-panel. Advanced configuration can be achieved directly through gconf editing (gconf-editor or gconftool-2).
+\fBmetacity\fP configuration can be found under \fIPreferences\fP->\fIWindows\fP and \fIPreferences\fP->\fIKeyboard Shortcuts\fP on the menu-panel. Advanced configuration can be achieved directly through gsettings.
 .SH SEE ALSO
 .BR metacity-message (1)
 .SH AUTHOR
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 16ec2f8..2d68a85 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -14,22 +14,20 @@ src/core/keybindings.c
 src/core/main.c
 src/core/prefs.c
 src/core/screen.c
-src/core/schema-bindings.c
 src/core/session.c
 src/core/util.c
-src/core/window.c
 src/core/window-props.c
+src/core/window.c
 src/core/xprops.c
-src/include/all-keybindings.h
-src/metacity.desktop.in
-src/metacity.schemas.in.in
 src/metacity-wm.desktop.in
+src/metacity.desktop.in
+src/org.gnome.metacity.gschema.xml.in
 src/tools/metacity-message.c
 src/ui/frames.c
 src/ui/menu.c
 src/ui/metaaccellabel.c
 src/ui/resizepopup.c
-src/ui/theme.c
 src/ui/theme-parser.c
 src/ui/theme-viewer.c
+src/ui/theme.c
 
diff --git a/src/50-metacity-navigation.xml.in b/src/50-metacity-navigation.xml.in
index f2b0ea6..992b15d 100644
--- a/src/50-metacity-navigation.xml.in
+++ b/src/50-metacity-navigation.xml.in
@@ -1,218 +1,77 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<KeyListEntries group="system" _name="Navigation" wm_name="Metacity" package="metacity">
-
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/move_to_workspace_1"
-	value="1"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/move_to_workspace_2"
-	value="1"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/move_to_workspace_3"
-	value="2"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/move_to_workspace_4"
-	value="3"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/move_to_workspace_5"
-	value="4"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/move_to_workspace_6"
-	value="5"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/move_to_workspace_7"
-	value="6"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/move_to_workspace_8"
-	value="7"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/move_to_workspace_9"
-	value="8"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/move_to_workspace_10"
-	value="9"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/move_to_workspace_11"
-	value="10"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/move_to_workspace_12"
-	value="11"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/move_to_workspace_left"
-	value="1"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/move_to_workspace_right"
-	value="1"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/move_to_workspace_up"
-	value="1"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/move_to_workspace_down"
-	value="1"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/global_keybindings/switch_windows" />
-
-	<KeyListEntry
-	name="/apps/metacity/global_keybindings/switch_group" />
-
-	<KeyListEntry
-	name="/apps/metacity/global_keybindings/switch_panels" />
-
-	<KeyListEntry
-	name="/apps/metacity/global_keybindings/cycle_windows" />
-
-	<KeyListEntry
-	name="/apps/metacity/global_keybindings/cycle_group" />
-
-	<KeyListEntry
-	name="/apps/metacity/global_keybindings/cycle_panels" />
-
-	<KeyListEntry
-	name="/apps/metacity/global_keybindings/show_desktop" />
-
-	<KeyListEntry
-	name="/apps/metacity/global_keybindings/switch_to_workspace_1"
-	value="1"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/global_keybindings/switch_to_workspace_2"
-	value="1"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/global_keybindings/switch_to_workspace_3"
-	value="2"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/global_keybindings/switch_to_workspace_4"
-	value="3"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/global_keybindings/switch_to_workspace_5"
-	value="4"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/global_keybindings/switch_to_workspace_6"
-	value="5"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/global_keybindings/switch_to_workspace_7"
-	value="6"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/global_keybindings/switch_to_workspace_8"
-	value="7"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/global_keybindings/switch_to_workspace_9"
-	value="8"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/global_keybindings/switch_to_workspace_10"
-	value="9"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/global_keybindings/switch_to_workspace_11"
-	value="10"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/global_keybindings/switch_to_workspace_12"
-	value="11"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/global_keybindings/switch_to_workspace_left"
-	value="1"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/global_keybindings/switch_to_workspace_right"
-	value="1"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/global_keybindings/switch_to_workspace_up"
-	value="1"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
-
-	<KeyListEntry
-	name="/apps/metacity/global_keybindings/switch_to_workspace_down"
-	value="1"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
+<KeyListEntries schema="org.gnome.desktop.wm.keybindings"
+                group="system"
+                _name="Navigation"
+                wm_name="Metacity"
+                package="gsettings-desktop-schemas">
 
-</KeyListEntries>
+	<KeyListEntry name="move-to-workspace-1"
+	              _description="Move window to workspace 1" />
+
+	<KeyListEntry name="move-to-workspace-2"
+	              _description="Move window to workspace 2" />
+
+	<KeyListEntry name="move-to-workspace-3"
+	              _description="Move window to workspace 3" />
+
+	<KeyListEntry name="move-to-workspace-4"
+	              _description="Move window to workspace 4" />
+
+	<KeyListEntry name="move-to-workspace-left"
+	              _description="Move window one workspace to the left" />
+
+	<KeyListEntry name="move-to-workspace-right"
+	              _description="Move window one workspace to the right" />
+
+	<KeyListEntry name="move-to-workspace-up"
+	              _description="Move window one workspace up" />
+
+	<KeyListEntry name="move-to-workspace-down"
+	              _description="Move window one workspace down" />
+
+	<KeyListEntry name="switch-windows"
+	              _description="Switch applications"/>
+
+	<KeyListEntry name="switch-group"
+	              _description="Switch windows of an application"/>
+
+	<KeyListEntry name="switch-panels"
+	              _description="Switch system controls"/>
+
+	<KeyListEntry name="cycle-windows"
+	              _description="Switch windows directly"/>
 
+	<KeyListEntry name="cycle-group"
+	              _description="Switch windows of an app directly"/>
+
+	<KeyListEntry name="cycle-panels"
+	              _description="Switch system controls directly"/>
+
+	<KeyListEntry name="show-desktop"
+	              _description="Hide all normal windows"/>
+
+	<KeyListEntry name="switch-to-workspace-1"
+	              _description="Switch to workspace 1" />
+
+	<KeyListEntry name="switch-to-workspace-2"
+	              _description="Switch to workspace 2" />
+
+	<KeyListEntry name="switch-to-workspace-3"
+	              _description="Switch to workspace 3" />
+
+	<KeyListEntry name="switch-to-workspace-4"
+	              _description="Switch to workspace 4" />
+
+	<KeyListEntry name="switch-to-workspace-left"
+	              _description="Move to workspace left" />
+
+	<KeyListEntry name="switch-to-workspace-right"
+	              _description="Move to workspace right" />
+
+	<KeyListEntry name="switch-to-workspace-up"
+	              _description="Move to workspace above" />
+
+	<KeyListEntry name="switch-to-workspace-down"
+	              _description="Move to workspace below" />
+
+</KeyListEntries>
diff --git a/src/50-metacity-system.xml.in b/src/50-metacity-system.xml.in
index 0356bb9..a3deaaa 100644
--- a/src/50-metacity-system.xml.in
+++ b/src/50-metacity-system.xml.in
@@ -1,11 +1,13 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<KeyListEntries group="system" _name="System" wm_name="Metacity" package="metacity">
+<KeyListEntries schema="org.gnome.desktop.wm.keybindings"
+                group="system"
+                _name="System"
+                wm_name="Metacity"
+                package="gsettings-desktop-schemas">
 
-	<KeyListEntry
-	name="/apps/metacity/global_keybindings/panel_run_dialog" />
+	<KeyListEntry name="panel-run-dialog" _description="Show the run command prompt"/>
 
-	<KeyListEntry
-	name="/apps/metacity/global_keybindings/panel_main_menu" />
+	<KeyListEntry name="panel-main-menu" _description="Show the activities overview"/>
 
 </KeyListEntries>
 
diff --git a/src/50-metacity-windows.xml.in b/src/50-metacity-windows.xml.in
index c0dd3f6..23843c5 100644
--- a/src/50-metacity-windows.xml.in
+++ b/src/50-metacity-windows.xml.in
@@ -1,56 +1,42 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<KeyListEntries group="system" _name="Windows" wm_name="Metacity" package="metacity">
+<KeyListEntries schema="org.gnome.desktop.wm.keybindings"
+                group="system"
+                _name="Windows"
+                wm_name="Metacity"
+                package="gsettings-desktop-schemas">
 
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/activate_window_menu" />
+	<KeyListEntry name="activate-window-menu" _description="Activate the window menu"/>
 
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/toggle_fullscreen" />
+	<KeyListEntry name="toggle-fullscreen" _description="Toggle fullscreen mode"/>
 
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/toggle_maximized" />
+	<KeyListEntry name="toggle-maximized" _description="Toggle maximization state"/>
 
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/maximize" />
+	<KeyListEntry name="maximize" _description="Maximize window"/>
 
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/unmaximize" />
+	<KeyListEntry name="unmaximize" _description="Restore window"/>
 
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/toggle_shaded" />
+	<KeyListEntry name="toggle-shaded" _description="Toggle shaded state"/>
 
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/close" />
+	<KeyListEntry name="close" _description="Close window"/>
 
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/minimize" />
+	<KeyListEntry name="minimize" _description="Minimize window"/>
 
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/begin_move" />
+	<KeyListEntry name="begin-move" _description="Move window"/>
 
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/begin_resize" />
+	<KeyListEntry name="begin-resize" _description="Resize window"/>
 
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/toggle_on_all_workspaces"
-	value="1"
-	key="/apps/metacity/general/num_workspaces"
-	comparison="gt" />
+	<KeyListEntry name="toggle-on-all-workspaces"
+	              _description="Toggle window on all workspaces or one"/>
 
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/raise_or_lower" />
+	<KeyListEntry name="raise-or-lower" _description="Raise window if covered, otherwise lower it"/>
 
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/raise" />
+	<KeyListEntry name="raise" _description="Raise window above other windows"/>
 
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/lower" />
+	<KeyListEntry name="lower" _description="Lower window below other windows"/>
 
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/maximize_vertically" />
+	<KeyListEntry name="maximize-vertically" _description="Maximize window vertically"/>
 
-	<KeyListEntry
-	name="/apps/metacity/window_keybindings/maximize_horizontally" />
+	<KeyListEntry name="maximize-horizontally" _description="Maximize window horizontally"/>
 
 </KeyListEntries>
 
diff --git a/src/Makefile.am b/src/Makefile.am
index ea7fa48..1f39db2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -136,14 +136,12 @@ libmetacityinclude_HEADERS =			\
 metacity_theme_viewer_SOURCES=  \
 	ui/theme-viewer.c
 
-schema_bindings_SOURCES =       \
-        core/schema-bindings.c			\
-	metacity.schemas.in.in
+gsettings_SCHEMAS = org.gnome.metacity.gschema.xml
+ INTLTOOL_XML_NOMERGE_RULE@
+ GSETTINGS_RULES@
 
-schema_bindings_LDADD = @METACITY_LIBS@
-metacity.schemas.in: schema_bindings ${srcdir}/metacity.schemas.in.in
-	@echo Generating keybinding schemas... ${srcdir}/metacity.schemas.in.in
-	$(AM_V_GEN)${builddir}/schema_bindings ${srcdir}/metacity.schemas.in.in ${builddir}/metacity.schemas.in
+convertdir = $(datadir)/GConf/gsettings/
+convert_DATA = $(srcdir)/metacity-schemas.convert
 
 bin_PROGRAMS=metacity metacity-theme-viewer
 
@@ -155,7 +153,7 @@ testboxes_SOURCES=include/util.h core/util.c include/boxes.h core/boxes.c core/t
 testgradient_SOURCES=ui/gradient.h ui/gradient.c ui/testgradient.c
 testasyncgetprop_SOURCES=core/async-getprop.h core/async-getprop.c core/testasyncgetprop.c
 
-noinst_PROGRAMS=testboxes testgradient testasyncgetprop schema_bindings
+noinst_PROGRAMS=testboxes testgradient testasyncgetprop
 
 testboxes_LDADD= @METACITY_LIBS@
 testgradient_LDADD= @METACITY_LIBS@
@@ -173,17 +171,9 @@ wmproperties_in_files=metacity-wm.desktop.in
 wmproperties_files=$(wmproperties_in_files:.desktop.in=.desktop)
 wmproperties_DATA = $(wmproperties_files)
 
-schemadir   = @GCONF_SCHEMA_FILE_DIR@
-schema_in_files = metacity.schemas.in
-schema_DATA = $(schema_in_files:.schemas.in=.schemas)
-
- INTLTOOL_XML_NOMERGE_RULE@
-
 xmldir       = @GNOME_KEYBINDINGS_KEYSDIR@
 xml_in_files = \
-	50-metacity-launchers.xml.in	\
 	50-metacity-navigation.xml.in	\
-	50-metacity-screenshot.xml.in	\
 	50-metacity-system.xml.in	\
 	50-metacity-windows.xml.in
 
@@ -191,20 +181,13 @@ xml_DATA     = $(xml_in_files:.xml.in=.xml)
 
 @INTLTOOL_SCHEMAS_RULE@
 
-if GCONF_SCHEMAS_INSTALL
-install-data-local:
-	GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) $(GCONFTOOL) --makefile-install-rule $(schema_DATA)
-else
-install-data-local:
-endif
-
 IMAGES=stock_maximize.png stock_minimize.png stock_delete.png
 VARIABLES=stock_maximize_data $(srcdir)/stock_maximize.png \
           stock_minimize_data $(srcdir)/stock_minimize.png \
           stock_delete_data $(srcdir)/stock_delete.png
 
 BUILT_SOURCES = inlinepixbufs.h
-CLEANFILES = inlinepixbufs.h metacity.desktop metacity-wm.desktop metacity.schemas metacity.schemas.in 50-metacity-launchers.xml 50-metacity-navigation.xml 50-metacity-screenshot.xml 50-metacity-system.xml 50-metacity-windows.xml
+CLEANFILES = inlinepixbufs.h metacity.desktop metacity-wm.desktop org.gnome.metacity.gschema.xml 50-metacity-launchers.xml 50-metacity-navigation.xml 50-metacity-screenshot.xml 50-metacity-system.xml 50-metacity-windows.xml
 
 inlinepixbufs.h: $(IMAGES)
 	$(AM_V_GEN)$(GDK_PIXBUF_CSOURCE) --raw --build-list $(VARIABLES) >$(srcdir)/inlinepixbufs.h
@@ -213,12 +196,12 @@ pkgconfigdir = $(libdir)/pkgconfig
 
 pkgconfig_DATA = libmetacity-private.pc
 
-EXTRA_DIST=$(desktopfiles_files) 	\
-	$(wmproperties_files)         \
-	$(IMAGES) $(schema_DATA) 	\
-	$(desktopfiles_in_files)	\
-	$(wmproperties_in_files)	\
-	$(schema_in_files)		\
-	$(xml_in_files)			\
+EXTRA_DIST=$(desktopfiles_files)	 	\
+	$(wmproperties_files)			\
+	$(IMAGES)		 		\
+	$(desktopfiles_in_files)		\
+	$(wmproperties_in_files)		\
+	org.gnome.metacity.gschema.xml.in	\
+	$(xml_in_files)				\
 	libmetacity-private.pc.in
 
diff --git a/src/core/bell.c b/src/core/bell.c
index e54de74..a414519 100644
--- a/src/core/bell.c
+++ b/src/core/bell.c
@@ -131,7 +131,7 @@ bell_flash_screen (MetaDisplay *display,
       XFreeGC (display->xdisplay, gc);
     }
 
-  if (meta_prefs_get_focus_mode () != META_FOCUS_MODE_CLICK &&
+  if (meta_prefs_get_focus_mode () != G_DESKTOP_FOCUS_MODE_CLICK &&
       !display->mouse_mode)
     meta_display_increment_focus_sentinel (display);
   XFlush (display->xdisplay);
@@ -265,13 +265,13 @@ bell_visual_notify (MetaDisplay *display,
 {
   switch (meta_prefs_get_visual_bell_type ()) 
     {
-    case META_VISUAL_BELL_FULLSCREEN_FLASH:
+    case G_DESKTOP_VISUAL_BELL_FULLSCREEN_FLASH:
       bell_flash_fullscreen (display, xkb_ev);
       break;
-    case META_VISUAL_BELL_FRAME_FLASH:
+    case G_DESKTOP_VISUAL_BELL_FRAME_FLASH:
       bell_flash_frame (display, xkb_ev); /* does nothing yet */
       break;
-    case META_VISUAL_BELL_INVALID:
+    case G_DESKTOP_VISUAL_BELL_NONE:
       /* do nothing */
       break;
     }
@@ -281,9 +281,8 @@ void
 meta_bell_notify (MetaDisplay *display, 
 		  XkbAnyEvent *xkb_ev)
 {
-  /* flash something */
-  if (meta_prefs_get_visual_bell ()) 
-    bell_visual_notify (display, xkb_ev);
+  /* flash something if appropriate */
+  bell_visual_notify (display, xkb_ev);
 
   if (meta_prefs_bell_is_audible ()) 
     {
diff --git a/src/core/core.c b/src/core/core.c
index 347579b..a2fd1e8 100644
--- a/src/core/core.c
+++ b/src/core/core.c
@@ -262,7 +262,7 @@ meta_core_user_lower_and_unfocus (Display *xdisplay,
   
   meta_window_lower (window);
 
-  if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK &&
+  if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK &&
       meta_prefs_get_raise_on_click ())
     {
       /* Move window to the back of the focusing workspace's MRU list.
@@ -540,70 +540,70 @@ meta_core_get_menu_accelerator (MetaMenuOp           menu_op,
       break;
     case META_MENU_OP_UNSTICK:
     case META_MENU_OP_STICK:
-      name = "toggle_on_all_workspaces";
+      name = "toggle-on-all-workspaces";
       break;
     case META_MENU_OP_ABOVE:
     case META_MENU_OP_UNABOVE:
-      name = "toggle_above";
+      name = "toggle-above";
       break;
     case META_MENU_OP_WORKSPACES:
       switch (workspace)
         {
         case 1:
-          name = "move_to_workspace_1";
+          name = "move-to-workspace-1";
           break;
         case 2:
-          name = "move_to_workspace_2";
+          name = "move-to-workspace-2";
           break;
         case 3:
-          name = "move_to_workspace_3";
+          name = "move-to-workspace-3";
           break; 
         case 4:
-          name = "move_to_workspace_4";
+          name = "move-to-workspace-4";
           break; 
         case 5:
-          name = "move_to_workspace_5";
+          name = "move-to-workspace-5";
           break; 
         case 6:
-          name = "move_to_workspace_6";
+          name = "move-to-workspace-6";
           break; 
         case 7:
-          name = "move_to_workspace_7";
+          name = "move-to-workspace-7";
           break; 
         case 8:
-          name = "move_to_workspace_8";
+          name = "move-to-workspace-8";
           break; 
         case 9:
-          name = "move_to_workspace_9";
+          name = "move-to-workspace-9";
           break; 
         case 10:
-          name = "move_to_workspace_10";
+          name = "move-to-workspace-10";
           break;
         case 11:
-          name = "move_to_workspace_11";
+          name = "move-to-workspace-11";
           break;
         case 12:
-          name = "move_to_workspace_12";
+          name = "move-to-workspace-12";
           break;
         }
       break;
     case META_MENU_OP_MOVE:
-      name = "begin_move";
+      name = "begin-move";
       break;
     case META_MENU_OP_RESIZE:
-      name = "begin_resize";
+      name = "begin-resize";
       break;
     case META_MENU_OP_MOVE_LEFT:
-      name = "move_to_workspace_left";
+      name = "move-to-workspace-left";
       break;
     case META_MENU_OP_MOVE_RIGHT:
-      name = "move_to_workspace_right";
+      name = "move-to-workspace-right";
       break;
     case META_MENU_OP_MOVE_UP:
-      name = "move_to_workspace_up";
+      name = "move-to-workspace-up";
       break;
     case META_MENU_OP_MOVE_DOWN:
-      name = "move_to_workspace_down";
+      name = "move-to-workspace-down";
       break;
     case META_MENU_OP_RECOVER:
       /* No keybinding for this one */
diff --git a/src/core/display.c b/src/core/display.c
index 3143e0c..caae7ff 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -1704,7 +1704,7 @@ event_callback (XEvent   *event,
                * in application-based mode, and the different
                * app is not a dock or desktop, eat the focus click.
                */
-              if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK &&
+              if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK &&
                   meta_prefs_get_application_based () &&
                   !window->has_focus &&
                   window->type != META_WINDOW_DOCK &&
@@ -1783,8 +1783,8 @@ event_callback (XEvent   *event,
         {
           switch (meta_prefs_get_focus_mode ())
             {
-            case META_FOCUS_MODE_SLOPPY:
-            case META_FOCUS_MODE_MOUSE:
+            case G_DESKTOP_FOCUS_MODE_SLOPPY:
+            case G_DESKTOP_FOCUS_MODE_MOUSE:
               display->mouse_mode = TRUE;
               if (window->type != META_WINDOW_DOCK &&
                   window->type != META_WINDOW_DESKTOP)
@@ -1822,7 +1822,7 @@ event_callback (XEvent   *event,
                * alternative mechanism works great.
                */
               if (window->type == META_WINDOW_DESKTOP &&
-                  meta_prefs_get_focus_mode() == META_FOCUS_MODE_MOUSE &&
+                  meta_prefs_get_focus_mode() == G_DESKTOP_FOCUS_MODE_MOUSE &&
                   display->expected_focus_window != NULL)
                 {
                   meta_topic (META_DEBUG_FOCUS,
@@ -1834,7 +1834,7 @@ event_callback (XEvent   *event,
                                                           event->xcrossing.time);
                 }
               break;
-            case META_FOCUS_MODE_CLICK:
+            case G_DESKTOP_FOCUS_MODE_CLICK:
               break;
             }
           
diff --git a/src/core/keybindings.c b/src/core/keybindings.c
index da274e0..08d861e 100644
--- a/src/core/keybindings.c
+++ b/src/core/keybindings.c
@@ -56,7 +56,7 @@ typedef void (* MetaKeyHandlerFunc) (MetaDisplay    *display,
                                      MetaKeyBinding *binding);
 
 /* Prototypes for handlers */
-#define keybind(name, handler, param, flags, stroke, description) \
+#define keybind(name, handler, param, flags) \
 static void \
 handler (MetaDisplay    *display,\
          MetaScreen     *screen,\
@@ -124,7 +124,7 @@ struct _MetaKeyBinding
   const MetaKeyHandler *handler;
 };
 
-#define keybind(name, handler, param, flags, stroke, description) \
+#define keybind(name, handler, param, flags) \
    { #name, handler, param, flags },
 static const MetaKeyHandler key_handlers[] = {
 #include "all-keybindings.h"
@@ -2322,138 +2322,6 @@ handle_switch_to_workspace (MetaDisplay    *display,
 }
 
 static void
-error_on_command (int         command_index,
-                  const char *command,
-                  const char *message,
-                  int         screen_number,
-                  guint32     timestamp)
-{
-  if (command_index < 0)
-    meta_warning ("Error on terminal command \"%s\": %s\n", command, message);  
-  else
-    meta_warning ("Error on command %d \"%s\": %s\n",
-                  command_index, command, message);  
-
-  /*
-    metacity-dialog said:
-        
-    FIXME offer to change the value of the command's gconf key
-  */
-
-  if (command && strcmp(command, "")!=0)
-    {
-      char *text = g_strdup_printf (
-                                    /* Displayed when a keybinding which is
-                                     * supposed to launch a program fails.
-                                     */
-                                    _("There was an error running "
-                                      "<tt>%s</tt>:\n\n%s"),
-                                    command,
-                                    message);
-
-      meta_show_dialog ("--error",
-                        text,
-                        NULL,
-                        screen_number,
-                        NULL, NULL, 0,
-                        NULL, NULL);
-
-      g_free (text);
-
-    }
-  else
-    {
-      meta_show_dialog ("--error",
-                        message,
-                        NULL,
-                        screen_number,
-                        NULL, NULL, 0,
-                        NULL, NULL);
-    }
-}
-
-static void
-set_display_setup_func (void *data)
-{
-  const char *screen_name = data;
-  char *full;
-
-  full = g_strdup_printf ("DISPLAY=%s", screen_name);
-
-  putenv (full);
-
-  /* do not free full, because putenv is lame */
-} 
-
-static gboolean
-meta_spawn_command_line_async_on_screen (const gchar *command_line,
-                                         MetaScreen  *screen,
-                                         GError     **error)
-{
-  gboolean retval;
-  gchar **argv = NULL;
-
-  g_return_val_if_fail (command_line != NULL, FALSE);
-
-  if (!g_shell_parse_argv (command_line,
-                           NULL, &argv,
-                           error))
-    return FALSE;
-  
-  retval = g_spawn_async (NULL,
-                          argv,
-                          NULL,
-                          G_SPAWN_SEARCH_PATH,
-                          set_display_setup_func,
-                          screen->screen_name,
-                          NULL,
-                          error);
-  g_strfreev (argv);
-
-  return retval;
-}
-
-
-static void
-handle_run_command (MetaDisplay    *display,
-                    MetaScreen     *screen,
-                    MetaWindow     *window,
-                    XEvent         *event,
-                    MetaKeyBinding *binding)
-{
-  gint which = binding->handler->data;
-  const char *command;
-  GError *err;
-  
-  command = meta_prefs_get_command (which);
-
-  if (command == NULL)
-    {
-      char *s;
-
-      meta_topic (META_DEBUG_KEYBINDINGS,
-                  "No command %d to run in response to keybinding press\n",
-                  which);
-      
-      s = g_strdup_printf (_("No command %d has been defined.\n"),
-                           which + 1);
-      error_on_command (which, NULL, s, screen->number, event->xkey.time);
-      g_free (s);
-      
-      return;
-    }
-
-  err = NULL;
-  if (!meta_spawn_command_line_async_on_screen (command, screen, &err))
-    {
-      error_on_command (which, command, err->message, screen->number, event->xkey.time);
-      
-      g_error_free (err);
-    }
-}
-
-
-static void
 handle_maximize_vertically (MetaDisplay    *display,
                       MetaScreen     *screen,
                       MetaWindow     *window,
@@ -3370,40 +3238,3 @@ meta_set_keybindings_disabled (MetaDisplay *display,
   meta_topic (META_DEBUG_KEYBINDINGS,
               "Keybindings %s\n", all_bindings_disabled ? "disabled" : "enabled");
 }
-
-static void
-handle_run_terminal (MetaDisplay    *display,
-                     MetaScreen     *screen,
-                     MetaWindow     *window,
-                     XEvent         *event,
-                     MetaKeyBinding *binding)
-{
-  const char *command;
-  GError *err;
-  
-  command = meta_prefs_get_terminal_command ();
-
-  if (command == NULL)
-    {
-      char *s;
-
-      meta_topic (META_DEBUG_KEYBINDINGS,
-                  "No terminal command to run in response to "
-		  "keybinding press\n");
-      
-      s = g_strdup_printf (_("No terminal command has been defined.\n"));
-      error_on_command (-1, NULL, s, screen->number, event->xkey.time);
-      g_free (s);
-      
-      return;
-    }
-
-  err = NULL;
-  if (!meta_spawn_command_line_async_on_screen (command, screen, &err))
-    {
-      error_on_command (-1, command, err->message, screen->number,
-                        event->xkey.time);
-      
-      g_error_free (err);
-    }
-}
diff --git a/src/core/prefs.c b/src/core/prefs.c
index fdedef4..1fcb567 100644
--- a/src/core/prefs.c
+++ b/src/core/prefs.c
@@ -6,7 +6,8 @@
  * Copyright (C) 2001 Havoc Pennington, Copyright (C) 2002 Red Hat Inc.
  * Copyright (C) 2006 Elijah Newren
  * Copyright (C) 2008 Thomas Thurman
- * 
+ * Copyright (C) 2010 Milan Bouchet-Valat, Copyright (C) 2011 Red Hat Inc.
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
  * published by the Free Software Foundation; either version 2 of the
@@ -27,68 +28,58 @@
 #include "prefs.h"
 #include "ui.h"
 #include "util.h"
-#ifdef HAVE_GCONF
-#include <gconf/gconf-client.h>
-#endif
+#include <glib.h>
+#include <gio/gio.h>
 #include <string.h>
 #include <stdlib.h>
 
-#define MAX_REASONABLE_WORKSPACES 36
-
-#define MAX_COMMANDS (32 + NUM_EXTRA_COMMANDS)
-#define NUM_EXTRA_COMMANDS 2
-#define SCREENSHOT_COMMAND_IDX (MAX_COMMANDS - 2)
-#define WIN_SCREENSHOT_COMMAND_IDX (MAX_COMMANDS - 1)
-
-/* If you add a key, it needs updating in init() and in the gconf
+/* If you add a key, it needs updating in init() and in the gsettings
  * notify listener and of course in the .schemas file.
  *
  * Keys which are handled by one of the unified handlers below are
  * not given a name here, because the purpose of the unified handlers
  * is that keys should be referred to exactly once.
  */
-#define KEY_TITLEBAR_FONT "/apps/metacity/general/titlebar_font"
-#define KEY_NUM_WORKSPACES "/apps/metacity/general/num_workspaces"
-#define KEY_COMPOSITOR "/apps/metacity/general/compositing_manager"
-#define KEY_GNOME_ACCESSIBILITY "/desktop/gnome/interface/accessibility"
-
-#define KEY_COMMAND_DIRECTORY "/apps/metacity/keybinding_commands"
-#define KEY_COMMAND_PREFIX "/apps/metacity/keybinding_commands/command_"
-
-#define KEY_TERMINAL_DIR "/desktop/gnome/applications/terminal"
-#define KEY_TERMINAL_COMMAND KEY_TERMINAL_DIR "/exec"
-
-#define KEY_SCREEN_BINDINGS_PREFIX "/apps/metacity/global_keybindings"
-#define KEY_WINDOW_BINDINGS_PREFIX "/apps/metacity/window_keybindings"
-#define KEY_LIST_BINDINGS_SUFFIX "_list"
-
-#define KEY_WORKSPACE_NAME_DIRECTORY "/apps/metacity/workspace_names"
-#define KEY_WORKSPACE_NAME_PREFIX "/apps/metacity/workspace_names/name_"
+#define KEY_TITLEBAR_FONT "titlebar-font"
+#define KEY_NUM_WORKSPACES "num-workspaces"
+#define KEY_WORKSPACE_NAMES "workspace-names"
+#define KEY_COMPOSITOR "compositing-manager"
+
+/* Keys from "foreign" schemas */
+#define KEY_GNOME_ACCESSIBILITY "toolkit-accessibility"
+#define KEY_GNOME_ANIMATIONS "enable-animations"
+#define KEY_GNOME_CURSOR_THEME "cursor-theme"
+#define KEY_GNOME_CURSOR_SIZE "cursor-size"
+
+/* These are the different schemas we are keeping
+ * a GSettings instance for */
+#define SCHEMA_GENERAL         "org.gnome.desktop.wm.preferences"
+#define SCHEMA_METACITY        "org.gnome.metacity"
+#define SCHEMA_INTERFACE       "org.gnome.desktop.interface"
+#define SCHEMA_BINDINGS        "org.gnome.wm.keybindings"
+
+#define SETTINGS(s) g_hash_table_lookup (settings_schemas, (s))
 
-
-#ifdef HAVE_GCONF
-static GConfClient *default_client = NULL;
 static GList *changes = NULL;
 static guint changed_idle;
 static GList *listeners = NULL;
-#endif
+static GHashTable *settings_schemas;
 
 static gboolean use_system_font = FALSE;
 static PangoFontDescription *titlebar_font = NULL;
 static MetaVirtualModifier mouse_button_mods = Mod1Mask;
-static MetaFocusMode focus_mode = META_FOCUS_MODE_CLICK;
-static MetaFocusNewWindows focus_new_windows = META_FOCUS_NEW_WINDOWS_SMART;
+static GDesktopFocusMode focus_mode = G_DESKTOP_FOCUS_MODE_CLICK;
+static GDesktopFocusNewWindows focus_new_windows = G_DESKTOP_FOCUS_NEW_WINDOWS_SMART;
 static gboolean raise_on_click = TRUE;
 static char* current_theme = NULL;
 static int num_workspaces = 4;
-static MetaActionTitlebar action_double_click_titlebar = META_ACTION_TITLEBAR_TOGGLE_MAXIMIZE;
-static MetaActionTitlebar action_middle_click_titlebar = META_ACTION_TITLEBAR_LOWER;
-static MetaActionTitlebar action_right_click_titlebar = META_ACTION_TITLEBAR_MENU;
+static GDesktopTitlebarAction action_double_click_titlebar = G_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE;
+static GDesktopTitlebarAction action_middle_click_titlebar = G_DESKTOP_TITLEBAR_ACTION_LOWER;
+static GDesktopTitlebarAction action_right_click_titlebar = G_DESKTOP_TITLEBAR_ACTION_MENU;
 static gboolean application_based = FALSE;
 static gboolean disable_workarounds = FALSE;
 static gboolean auto_raise = FALSE;
 static gboolean auto_raise_delay = 500;
-static gboolean provide_visual_bell = FALSE;
 static gboolean bell_is_audible = TRUE;
 static gboolean reduced_resources = FALSE;
 static gboolean gnome_accessibility = FALSE;
@@ -99,73 +90,41 @@ static gboolean compositing_manager = FALSE;
 static gboolean resize_with_right_button = FALSE;
 static gboolean force_fullscreen = TRUE;
 
-static MetaVisualBellType visual_bell_type = META_VISUAL_BELL_FULLSCREEN_FLASH;
+static GDesktopVisualBellType visual_bell_type = G_DESKTOP_VISUAL_BELL_FULLSCREEN_FLASH;
 static MetaButtonLayout button_layout;
 
-/* The screenshot commands are at the end */
-static char *commands[MAX_COMMANDS] = { NULL, };
-
-static char *terminal_command = NULL;
+/* NULL-terminated array */
+static char **workspace_names = NULL;
 
-static char *workspace_names[MAX_REASONABLE_WORKSPACES] = { NULL, };
+static void handle_preference_update_enum (GSettings *settings,
+                                           gchar     *key);
 
-#ifdef HAVE_GCONF
-static gboolean handle_preference_update_enum (const gchar *key, GConfValue *value);
+static gboolean update_binding         (MetaKeyPref *binding,
+                                        gchar      **strokes);
+static gboolean update_key_binding     (const char  *key,
+                                        gchar      **strokes);
+static gboolean update_workspace_names (void);
 
-static gboolean update_key_binding     (const char *name,
-                                        const char *value);
-static gboolean find_and_update_list_binding (MetaKeyPref *bindings,
-                                              const char  *name,
-                                              GSList      *value);
-static gboolean update_key_list_binding (const char *name,
-                                         GSList      *value);
-static gboolean update_command            (const char  *name,
-                                           const char  *value);
-static gboolean update_workspace_name     (const char  *name,
-                                           const char  *value);
+static void settings_changed (GSettings      *settings,
+                              gchar          *key,
+                              gpointer        data);
+static void bindings_changed (GSettings      *settings,
+                              gchar          *key,
+                              gpointer        data);
 
-static void change_notify (GConfClient    *client,
-                           guint           cnxn_id,
-                           GConfEntry     *entry,
-                           gpointer        user_data);
-
-static char* gconf_key_for_workspace_name (int i);
 
 static void queue_changed (MetaPreference  pref);
 
-typedef enum
-  {
-    META_LIST_OF_STRINGS,
-    META_LIST_OF_GCONFVALUE_STRINGS
-  } MetaStringListType;
-
-static gboolean update_list_binding       (MetaKeyPref *binding,
-                                           GSList      *value,
-                                           MetaStringListType type_of_value);
-
-static void     cleanup_error             (GError **error);
-static gboolean get_bool                  (const char *key, gboolean *val);
 static void maybe_give_disable_workarounds_warning (void);
 
-static void titlebar_handler (MetaPreference, const gchar*, gboolean*);
-static void theme_name_handler (MetaPreference, const gchar*, gboolean*);
-static void mouse_button_mods_handler (MetaPreference, const gchar*, gboolean*);
-static void button_layout_handler (MetaPreference, const gchar*, gboolean*);
-
-#endif /* HAVE_GCONF */
-
-static gboolean update_binding            (MetaKeyPref *binding,
-                                           const char  *value);
+static gboolean titlebar_handler (GVariant*, gpointer*, gpointer);
+static gboolean theme_name_handler (GVariant*, gpointer*, gpointer);
+static gboolean mouse_button_mods_handler (GVariant*, gpointer*, gpointer);
+static gboolean button_layout_handler (GVariant*, gpointer*, gpointer);
 
 static void     init_bindings             (void);
-static void     init_commands             (void);
 static void     init_workspace_names      (void);
 
-#ifndef HAVE_GCONF
-static void     init_button_layout        (void);
-#endif /* !HAVE_GCONF */
-
-#ifdef HAVE_GCONF
 
 typedef struct
 {
@@ -173,112 +132,49 @@ typedef struct
   gpointer data;
 } MetaPrefsListener;
 
-static GConfEnumStringPair symtab_focus_mode[] =
-  {
-    { META_FOCUS_MODE_CLICK,  "click" },
-    { META_FOCUS_MODE_SLOPPY, "sloppy" },
-    { META_FOCUS_MODE_MOUSE,  "mouse" },
-    { 0, NULL },
-  };
-
-static GConfEnumStringPair symtab_focus_new_windows[] =
-  {
-    { META_FOCUS_NEW_WINDOWS_SMART,  "smart" },
-    { META_FOCUS_NEW_WINDOWS_STRICT, "strict" },
-    { 0, NULL },
-  };
-
-static GConfEnumStringPair symtab_visual_bell_type[] =
-  {
-    /* Note to the reader: 0 is an invalid value; these start at 1. */
-    { META_VISUAL_BELL_FULLSCREEN_FLASH, "fullscreen" },
-    { META_VISUAL_BELL_FRAME_FLASH,      "frame_flash" },
-    { 0, NULL },
-  };
-
-static GConfEnumStringPair symtab_titlebar_action[] =
-  {
-    { META_ACTION_TITLEBAR_TOGGLE_SHADE,    "toggle_shade" },
-    { META_ACTION_TITLEBAR_TOGGLE_MAXIMIZE, "toggle_maximize" },
-    { META_ACTION_TITLEBAR_TOGGLE_MAXIMIZE_HORIZONTALLY,
-                                "toggle_maximize_horizontally" },
-    { META_ACTION_TITLEBAR_TOGGLE_MAXIMIZE_VERTICALLY,
-                                "toggle_maximize_vertically" },
-    { META_ACTION_TITLEBAR_MINIMIZE,        "minimize" },
-    { META_ACTION_TITLEBAR_NONE,            "none" },
-    { META_ACTION_TITLEBAR_LOWER,           "lower" },
-    { META_ACTION_TITLEBAR_MENU,            "menu" },
-    { META_ACTION_TITLEBAR_TOGGLE_SHADE,    "toggle_shade" },
-    { 0, NULL },
-  };
 
-/**
- * The details of one preference which is constrained to be
- * one of a small number of string values-- in other words,
- * an enumeration.
- *
- * We could have done this other ways.  One particularly attractive
- * possibility would have been to represent the entire symbol table
- * as a space-separated string literal in the list of symtabs, so
- * the focus mode enums could have been represented simply by
- * "click sloppy mouse".  However, the simplicity gained would have
- * been outweighed by the bugs caused when the ordering of the enum
- * strings got out of sync with the actual enum statement.  Also,
- * there is existing library code to use this kind of symbol tables.
- *
- * Other things we might consider doing to clean this up in the
- * future include:
- *
- *   - most of the keys begin with the same prefix, and perhaps we
- *     could assume it if they don't start with a slash
- *
- *   - there are several cases where a single identifier could be used
- *     to generate an entire entry, and perhaps this could be done
- *     with a macro.  (This would reduce clarity, however, and is
- *     probably a bad thing.)
- *
- *   - these types all begin with a gchar* (and contain a MetaPreference)
- *     and we can factor out the repeated code in the handlers by taking
- *     advantage of this using some kind of union arrangement.
- */
 typedef struct
 {
   gchar *key;
+  gchar *schema;
   MetaPreference pref;
-  GConfEnumStringPair *symtab;
+} MetaBasePreference;
+
+
+typedef struct
+{
+  MetaBasePreference base;
   gpointer target;
 } MetaEnumPreference;
 
 typedef struct
 {
-  gchar *key;
-  MetaPreference pref;
+  MetaBasePreference base;
   gboolean *target;
   gboolean becomes_true_on_destruction;
 } MetaBoolPreference;
 
 typedef struct
 {
-  gchar *key;
-  MetaPreference pref;
+  MetaBasePreference base;
 
   /**
    * A handler.  Many of the string preferences aren't stored as
    * strings and need parsing; others of them have default values
    * which can't be solved in the general case.  If you include a
-   * function pointer here, it will be called before the string
-   * value is written out to the target variable.
+   * function pointer here, it will be called instead of writing
+   * the string value out to the target variable.
    *
-   * The function is passed two arguments: the preference, and
-   * the new string as a gchar*.  It returns a gboolean;
-   * only if this is true, the listeners will be informed that
-   * the preference has changed.
+   * The function will be passed to g_settings_get_mapped() and should
+   * return %TRUE if the mapping was successful and %FALSE otherwise.
+   * In the former case the function is expected to handle the result
+   * of the conversion itself and call queue_changed() appropriately;
+   * in particular the @result (out) parameter as returned by
+   * g_settings_get_mapped() will be ignored in all cases.
    *
    * This may be NULL.  If it is, see "target", below.
    */
-  void (*handler) (MetaPreference pref,
-                     const gchar *string_value,
-                     gboolean *inform_listeners);
+  GSettingsGetMapping handler;
 
   /**
    * Where to write the incoming string.
@@ -290,189 +186,228 @@ typedef struct
 
 } MetaStringPreference;
 
-#define METAINTPREFERENCE_NO_CHANGE_ON_DESTROY G_MININT
-
 typedef struct
 {
-  gchar *key;
-  MetaPreference pref;
+  MetaBasePreference base;
   gint *target;
-  /**
-   * Minimum and maximum values of the integer.
-   * If the new value is out of bounds, it will be discarded with a warning.
-   */
-  gint minimum, maximum;
-  /**
-   * Value to use if the key is destroyed.
-   * If this is METAINTPREFERENCE_NO_CHANGE_ON_DESTROY, it will
-   * not be changed when the key is destroyed.
-   */
-  gint value_if_destroyed;
 } MetaIntPreference;
 
+
+/* All preferences that are not keybindings must be listed here,
+ * plus in the GSettings schemas and the MetaPreference enum.
+ */
+
 /* FIXMEs: */
 /* @@@ Don't use NULL lines at the end; glib can tell you how big it is */
-/* @@@ /apps/metacity/general should be assumed if first char is not / */
-/* @@@ Will it ever be possible to merge init and update? If not, why not? */
-
 static MetaEnumPreference preferences_enum[] =
   {
-    { "/apps/metacity/general/focus_new_windows",
-      META_PREF_FOCUS_NEW_WINDOWS,
-      symtab_focus_new_windows,
+    {
+      { "focus-new-windows",
+        SCHEMA_GENERAL,
+        META_PREF_FOCUS_NEW_WINDOWS,
+      },
       &focus_new_windows,
     },
-    { "/apps/metacity/general/focus_mode",
-      META_PREF_FOCUS_MODE,
-      symtab_focus_mode,
+    {
+      { "focus-mode",
+        SCHEMA_GENERAL,
+        META_PREF_FOCUS_MODE,
+      },
       &focus_mode,
     },
-    { "/apps/metacity/general/visual_bell_type",
-      META_PREF_VISUAL_BELL_TYPE,
-      symtab_visual_bell_type,
+    {
+      { "visual-bell-type",
+        SCHEMA_GENERAL,
+        META_PREF_VISUAL_BELL_TYPE,
+      },
       &visual_bell_type,
     },
-    { "/apps/metacity/general/action_double_click_titlebar",
-      META_PREF_ACTION_DOUBLE_CLICK_TITLEBAR,
-      symtab_titlebar_action,
+    {
+      { "action-double-click-titlebar",
+        SCHEMA_GENERAL,
+        META_PREF_ACTION_DOUBLE_CLICK_TITLEBAR,
+      },
       &action_double_click_titlebar,
     },
-    { "/apps/metacity/general/action_middle_click_titlebar",
-      META_PREF_ACTION_MIDDLE_CLICK_TITLEBAR,
-      symtab_titlebar_action,
+    {
+      { "action-middle-click-titlebar",
+        SCHEMA_GENERAL,
+        META_PREF_ACTION_MIDDLE_CLICK_TITLEBAR,
+      },
       &action_middle_click_titlebar,
     },
-    { "/apps/metacity/general/action_right_click_titlebar",
-      META_PREF_ACTION_RIGHT_CLICK_TITLEBAR,
-      symtab_titlebar_action,
+    {
+      { "action-right-click-titlebar",
+        SCHEMA_GENERAL,
+        META_PREF_ACTION_RIGHT_CLICK_TITLEBAR,
+      },
       &action_right_click_titlebar,
     },
-    { NULL, 0, NULL, NULL },
+    { { NULL, 0, 0 }, NULL },
   };
 
 static MetaBoolPreference preferences_bool[] =
   {
-    { "/apps/metacity/general/raise_on_click",
-      META_PREF_RAISE_ON_CLICK,
+    {
+      { "raise-on-click",
+        SCHEMA_GENERAL,
+        META_PREF_RAISE_ON_CLICK,
+      },
       &raise_on_click,
       TRUE,
     },
-    { "/apps/metacity/general/titlebar_uses_system_font",
-      META_PREF_TITLEBAR_FONT, /* note! shares a pref */
+    {
+      { "titlebar-uses-system-font",
+        SCHEMA_GENERAL,
+        META_PREF_TITLEBAR_FONT, /* note! shares a pref */
+      },
       &use_system_font,
       TRUE,
     },
-    { "/apps/metacity/general/application_based",
-      META_PREF_APPLICATION_BASED,
+    {
+      { "application-based",
+        SCHEMA_GENERAL,
+        META_PREF_APPLICATION_BASED,
+      },
       NULL, /* feature is known but disabled */
       FALSE,
     },
-    { "/apps/metacity/general/disable_workarounds",
-      META_PREF_DISABLE_WORKAROUNDS,
+    {
+      { "disable-workarounds",
+        SCHEMA_GENERAL,
+        META_PREF_DISABLE_WORKAROUNDS,
+      },
       &disable_workarounds,
       FALSE,
     },
-    { "/apps/metacity/general/auto_raise",
-      META_PREF_AUTO_RAISE,
+    {
+      { "auto-raise",
+        SCHEMA_GENERAL,
+        META_PREF_AUTO_RAISE,
+      },
       &auto_raise,
       FALSE,
     },
-    { "/apps/metacity/general/visual_bell",
-      META_PREF_VISUAL_BELL,
-      &provide_visual_bell, /* FIXME: change the name: it's confusing */
-      FALSE,
-    },
-    { "/apps/metacity/general/audible_bell",
-      META_PREF_AUDIBLE_BELL,
+    {
+      { "audible-bell",
+        SCHEMA_GENERAL,
+        META_PREF_AUDIBLE_BELL,
+      },
       &bell_is_audible, /* FIXME: change the name: it's confusing */
       FALSE,
     },
-    { "/apps/metacity/general/reduced_resources",
-      META_PREF_REDUCED_RESOURCES,
+    {
+      { "reduced-resources",
+        SCHEMA_METACITY,
+        META_PREF_REDUCED_RESOURCES,
+      },
       &reduced_resources,
       FALSE,
     },
-    { "/desktop/gnome/interface/accessibility",
-      META_PREF_GNOME_ACCESSIBILITY,
+    {
+      { KEY_GNOME_ACCESSIBILITY,
+        SCHEMA_INTERFACE,
+        META_PREF_GNOME_ACCESSIBILITY,
+      },
       &gnome_accessibility,
       FALSE,
     },
-    { "/desktop/gnome/interface/enable_animations",
-      META_PREF_GNOME_ANIMATIONS,
+    {
+      { KEY_GNOME_ANIMATIONS,
+        SCHEMA_INTERFACE,
+        META_PREF_GNOME_ANIMATIONS,
+      },
       &gnome_animations,
       TRUE,
     },
-    { "/apps/metacity/general/compositing_manager",
-      META_PREF_COMPOSITING_MANAGER,
+    {
+      { "compositing-manager",
+        SCHEMA_METACITY,
+        META_PREF_COMPOSITING_MANAGER,
+      },
       &compositing_manager,
       FALSE,
     },
-    { "/apps/metacity/general/resize_with_right_button",
-      META_PREF_RESIZE_WITH_RIGHT_BUTTON,
+    {
+      { "resize-with-right-button",
+        SCHEMA_GENERAL,
+        META_PREF_RESIZE_WITH_RIGHT_BUTTON,
+      },
       &resize_with_right_button,
       FALSE,
     },
-    { NULL, 0, NULL, FALSE },
+    { { NULL, 0, 0 }, NULL, FALSE },
   };
 
 static MetaStringPreference preferences_string[] =
   {
-    { "/apps/metacity/general/mouse_button_modifier",
-      META_PREF_MOUSE_BUTTON_MODS,
+    {
+      { "mouse-button-modifier",
+        SCHEMA_GENERAL,
+        META_PREF_MOUSE_BUTTON_MODS,
+      },
       mouse_button_mods_handler,
       NULL,
     },
-    { "/apps/metacity/general/theme",
-      META_PREF_THEME,
+    {
+      { "theme",
+        SCHEMA_GENERAL,
+        META_PREF_THEME,
+      },
       theme_name_handler,
       NULL,
     },
-    { KEY_TITLEBAR_FONT,
-      META_PREF_TITLEBAR_FONT,
+    {
+      { KEY_TITLEBAR_FONT,
+        SCHEMA_GENERAL,
+        META_PREF_TITLEBAR_FONT,
+      },
       titlebar_handler,
       NULL,
     },
-    { KEY_TERMINAL_COMMAND,
-      META_PREF_TERMINAL_COMMAND,
-      NULL,
-      &terminal_command,
-    },
-    { "/apps/metacity/general/button_layout",
-      META_PREF_BUTTON_LAYOUT,
+    {
+      { "button-layout",
+        SCHEMA_GENERAL,
+        META_PREF_BUTTON_LAYOUT,
+      },
       button_layout_handler,
       NULL,
     },
-    { "/desktop/gnome/peripherals/mouse/cursor_theme",
-      META_PREF_CURSOR_THEME,
+    {
+      { KEY_GNOME_CURSOR_THEME,
+        SCHEMA_INTERFACE,
+        META_PREF_CURSOR_THEME,
+      },
       NULL,
       &cursor_theme,
     },
-    { NULL, 0, NULL, NULL },
+    { { NULL, 0, 0 }, NULL },
   };
 
 static MetaIntPreference preferences_int[] =
   {
-    { "/apps/metacity/general/num_workspaces",
-      META_PREF_NUM_WORKSPACES,
-      &num_workspaces,
-      /* I would actually recommend we change the destroy value to 4
-       * and get rid of METAINTPREFERENCE_NO_CHANGE_ON_DESTROY entirely.
-       *  -- tthurman
-       */
-      1, MAX_REASONABLE_WORKSPACES, METAINTPREFERENCE_NO_CHANGE_ON_DESTROY,
+    {
+      { "num-workspaces",
+        SCHEMA_GENERAL,
+        META_PREF_NUM_WORKSPACES,
+      },
+      &num_workspaces
     },
-    { "/apps/metacity/general/auto_raise_delay",
-      META_PREF_AUTO_RAISE_DELAY,
-      &auto_raise_delay,
-      0, 10000, 0,
-      /* @@@ Get rid of MAX_REASONABLE_AUTO_RAISE_DELAY */
+    {
+      { "auto-raise-delay",
+        SCHEMA_GENERAL,
+        META_PREF_AUTO_RAISE_DELAY,
+      },
+      &auto_raise_delay
     },
-    { "/desktop/gnome/peripherals/mouse/cursor_size",
-      META_PREF_CURSOR_SIZE,
-      &cursor_size,
-      1, 128, 24,
+    {
+      { KEY_GNOME_CURSOR_SIZE,
+        SCHEMA_INTERFACE,
+        META_PREF_CURSOR_SIZE,
+      },
+      &cursor_size
     },
-    { NULL, 0, NULL, 0, 0, 0, },
+    { { NULL, 0, 0 }, NULL },
   };
 
 static void
@@ -480,35 +415,13 @@ handle_preference_init_enum (void)
 {
   MetaEnumPreference *cursor = preferences_enum;
 
-  while (cursor->key!=NULL)
+  while (cursor->base.key != NULL)
     {
-      char *value;
-      GError *error = NULL;
-
       if (cursor->target==NULL)
-        {
-          ++cursor;
-          continue;
-        }
-
-      value = gconf_client_get_string (default_client,
-                                       cursor->key,
-                                       &error);
-      cleanup_error (&error);
-
-      if (value==NULL)
-        {
-          ++cursor;
           continue;
-        }
-
-      if (!gconf_string_to_enum (cursor->symtab,
-                                 value,
-                                 (gint *) cursor->target))
-        meta_warning (_("GConf key '%s' is set to an invalid value\n"),
-                      cursor->key);
 
-      g_free (value);
+      *((gint *) cursor->target) =
+        g_settings_get_enum (SETTINGS (cursor->base.schema), cursor->base.key);
 
       ++cursor;
     }
@@ -519,10 +432,12 @@ handle_preference_init_bool (void)
 {
   MetaBoolPreference *cursor = preferences_bool;
 
-  while (cursor->key!=NULL)
+  while (cursor->base.key != NULL)
     {
       if (cursor->target!=NULL)
-        get_bool (cursor->key, cursor->target);
+        *cursor->target =
+          g_settings_get_boolean (SETTINGS (cursor->base.schema),
+                                  cursor->base.key);
 
       ++cursor;
     }
@@ -535,32 +450,30 @@ handle_preference_init_string (void)
 {
   MetaStringPreference *cursor = preferences_string;
 
-  while (cursor->key!=NULL)
+  while (cursor->base.key != NULL)
     {
       char *value;
-      GError *error = NULL;
-      gboolean dummy = TRUE;
-
-      /* the string "value" will be newly allocated */
-      value = gconf_client_get_string (default_client,
-                                       cursor->key,
-                                       &error);
-      cleanup_error (&error);
 
+      /* Complex keys have a mapping function to check validity */
       if (cursor->handler)
         {
           if (cursor->target)
-            meta_bug ("%s has both a target and a handler\n", cursor->key);
-
-          cursor->handler (cursor->pref, value, &dummy);
+            meta_bug ("%s has both a target and a handler\n", cursor->base.key);
 
-          g_free (value);
+          g_settings_get_mapped (SETTINGS (cursor->base.schema),
+                                 cursor->base.key, cursor->handler, NULL);
         }
-      else if (cursor->target)
+      else
         {
+          if (!cursor->target)
+            meta_bug ("%s must have handler or target\n", cursor->base.key);
+
           if (*(cursor->target))
             g_free (*(cursor->target));
 
+          value = g_settings_get_string (SETTINGS (cursor->base.schema),
+                                         cursor->base.key);
+
           *(cursor->target) = value;
         }
 
@@ -574,277 +487,136 @@ handle_preference_init_int (void)
   MetaIntPreference *cursor = preferences_int;
 
   
-  while (cursor->key!=NULL)
+  while (cursor->base.key != NULL)
     {
-      gint value;
-      GError *error = NULL;
-
-      value = gconf_client_get_int (default_client,
-                                    cursor->key,
-                                    &error);
-      cleanup_error (&error);
-
-      if (value < cursor->minimum || value > cursor->maximum)
-        {
-          meta_warning (_("%d stored in GConf key %s is out of range %d to %d\n"),
-                        value, cursor->key,  cursor->minimum, cursor->maximum);
-          /* Former behaviour for out-of-range values was:
-           *   - number of workspaces was clamped;
-           *   - auto raise delay was always reset to zero even if too high!;
-           *   - cursor size was ignored.
-           *
-           * These seem to be meaningless variations.  If they did
-           * have meaning we could have put them into MetaIntPreference.
-           * The last of these is the closest to how we behave for
-           * other types, so I think we should standardise on that.
-           */
-        }
-      else if (cursor->target)
-        *cursor->target = value;
+      if (cursor->target)
+        *cursor->target = g_settings_get_int (SETTINGS (cursor->base.schema),
+                                              cursor->base.key);
 
       ++cursor;
     }
 }
 
-static gboolean
-handle_preference_update_enum (const gchar *key, GConfValue *value)
+static void
+handle_preference_update_enum (GSettings *settings,
+                               gchar *key)
 {
   MetaEnumPreference *cursor = preferences_enum;
   gint old_value;
 
-  while (cursor->key!=NULL && strcmp (key, cursor->key)!=0)
+  while (cursor->base.key != NULL && strcmp (key, cursor->base.key) != 0)
     ++cursor;
 
-  if (cursor->key==NULL)
+  if (cursor->base.key==NULL)
     /* Didn't recognise that key. */
-    return FALSE;
-      
-  /* Setting it to null (that is, removing it) always means
-   * "don't change".
-   */
-
-  if (value==NULL)
-    return TRUE;
-
-  /* Check the type.  Enums are always strings. */
-
-  if (value->type != GCONF_VALUE_STRING)
-    {
-      meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
-                    key);
-      /* But we did recognise it. */
-      return TRUE;
-    }
+    return;
 
   /* We need to know whether the value changes, so
-   * store the current value away.
-   */
-
+   * store the current value away. */
   old_value = * ((gint *) cursor->target);
-  
-  /* Now look it up... */
-
-  if (!gconf_string_to_enum (cursor->symtab,
-                             gconf_value_get_string (value),
-                             (gint *) cursor->target))
-    {
-      /*
-       * We found it, but it was invalid.  Complain.
-       *
-       * FIXME: This replicates the original behaviour, but in the future
-       * we might consider reverting invalid keys to their original values.
-       * (We know the old value, so we can look up a suitable string in
-       * the symtab.)
-       *
-       * (Empty comment follows so the translators don't see this.)
-       */
 
-      /*  */      
-      meta_warning (_("GConf key '%s' is set to an invalid value\n"),
-                    key);
-      return TRUE;
-    }
+  *((gint *) cursor->target) =
+    g_settings_get_enum (SETTINGS (cursor->base.schema), key);
 
   /* Did it change?  If so, tell the listeners about it. */
-
   if (old_value != *((gint *) cursor->target))
-    queue_changed (cursor->pref);
-
-  return TRUE;
+    queue_changed (cursor->base.pref);
 }
 
-static gboolean
-handle_preference_update_bool (const gchar *key, GConfValue *value)
+static void
+handle_preference_update_bool (GSettings *settings,
+                               gchar *key)
 {
   MetaBoolPreference *cursor = preferences_bool;
   gboolean old_value;
 
-  while (cursor->key!=NULL && strcmp (key, cursor->key)!=0)
+  while (cursor->base.key != NULL && strcmp (key, cursor->base.key) != 0)
     ++cursor;
 
-  if (cursor->key==NULL)
-    /* Didn't recognise that key. */
-    return FALSE;
-
-  if (cursor->target==NULL)
-    /* No work for us to do. */
-    return TRUE;
-      
-  if (value==NULL)
-    {
-      /* Value was destroyed; let's get out of here. */
-
-      if (cursor->becomes_true_on_destruction)
-        /* This preserves the behaviour of the old system, but
-         * for all I know that might have been an oversight.
-         */
-        *((gboolean *)cursor->target) = TRUE;
-
-      return TRUE;
-    }
-
-  /* Check the type. */
-
-  if (value->type != GCONF_VALUE_BOOL)
-    {
-      meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
-                    key);
-      /* But we did recognise it. */
-      return TRUE;
-    }
+  if (cursor->base.key==NULL || cursor->target==NULL)
+    /* Unknown key or no work for us to do. */
+    return;
 
   /* We need to know whether the value changes, so
-   * store the current value away.
-   */
+   * store the current value away. */
+  old_value = *((gboolean *) cursor->target);
 
-  old_value = * ((gboolean *) cursor->target);
-  
-  /* Now look it up... */
-
-  *((gboolean *) cursor->target) = gconf_value_get_bool (value);
+  *((gboolean *) cursor->target) =
+    g_settings_get_boolean (SETTINGS (cursor->base.schema), key);
 
   /* Did it change?  If so, tell the listeners about it. */
-
   if (old_value != *((gboolean *) cursor->target))
-    queue_changed (cursor->pref);
+    queue_changed (cursor->base.pref);
 
-  if (cursor->pref==META_PREF_DISABLE_WORKAROUNDS)
+  if (cursor->base.pref==META_PREF_DISABLE_WORKAROUNDS)
     maybe_give_disable_workarounds_warning ();
-
-  return TRUE;
 }
 
-static gboolean
-handle_preference_update_string (const gchar *key, GConfValue *value)
+static void
+handle_preference_update_string (GSettings *settings,
+                                 gchar *key)
 {
   MetaStringPreference *cursor = preferences_string;
-  const gchar *value_as_string;
-  gboolean inform_listeners = TRUE;
+  char *value;
+  gboolean inform_listeners = FALSE;
 
-  while (cursor->key!=NULL && strcmp (key, cursor->key)!=0)
+  while (cursor->base.key != NULL && strcmp (key, cursor->base.key) != 0)
     ++cursor;
 
-  if (cursor->key==NULL)
+  if (cursor->base.key==NULL)
     /* Didn't recognise that key. */
-    return FALSE;
-
-  if (value==NULL)
-    return TRUE;
-
-  /* Check the type. */
+    return;
 
-  if (value->type != GCONF_VALUE_STRING)
+  /* Complex keys have a mapping function to check validity */
+  if (cursor->handler)
     {
-      meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
-                    key);
-      /* But we did recognise it. */
-      return TRUE;
+      if (cursor->target)
+        meta_bug ("%s has both a target and a handler\n", cursor->base.key);
+
+      g_settings_get_mapped (SETTINGS (cursor->base.schema),
+                             cursor->base.key, cursor->handler, NULL);
     }
+  else
+    {
+      if (!cursor->target)
+        meta_bug ("%s must have handler or target\n", cursor->base.key);
 
-  /* Docs: "The returned string is not a copy, don't try to free it." */
-  value_as_string = gconf_value_get_string (value);
+      value = g_settings_get_string (SETTINGS (cursor->base.schema),
+                                     cursor->base.key);
+      inform_listeners = (g_strcmp0 (value, *(cursor->target)) != 0);
 
-  if (cursor->handler)
-    cursor->handler (cursor->pref, value_as_string, &inform_listeners);
-  else if (cursor->target)
-    {
       if (*(cursor->target))
-        g_free(*(cursor->target));
-
-      if (value_as_string!=NULL)
-        *(cursor->target) = g_strdup (value_as_string);
-      else
-        *(cursor->target) = NULL;
+        g_free (*(cursor->target));
 
-      inform_listeners =
-        (value_as_string==NULL && *(cursor->target)==NULL) ||
-        (value_as_string!=NULL && *(cursor->target)!=NULL &&
-         strcmp (value_as_string, *(cursor->target))==0);
+      *(cursor->target) = value;
     }
 
   if (inform_listeners)
-    queue_changed (cursor->pref);
-
-  return TRUE;
+    queue_changed (cursor->base.pref);
 }
 
-static gboolean
-handle_preference_update_int (const gchar *key, GConfValue *value)
+static void
+handle_preference_update_int (GSettings *settings,
+                              gchar *key)
 {
   MetaIntPreference *cursor = preferences_int;
   gint new_value;
 
-  while (cursor->key!=NULL && strcmp (key, cursor->key)!=0)
+  while (cursor->base.key != NULL && strcmp (key, cursor->base.key) != 0)
     ++cursor;
 
-  if (cursor->key==NULL)
-    /* Didn't recognise that key. */
-    return FALSE;
-
-  if (cursor->target==NULL)
-    /* No work for us to do. */
-    return TRUE;
-      
-  if (value==NULL)
-    {
-      /* Value was destroyed. */
-
-      if (cursor->value_if_destroyed != METAINTPREFERENCE_NO_CHANGE_ON_DESTROY)
-        *((gint *)cursor->target) = cursor->value_if_destroyed;
-
-      return TRUE;
-    }
-
-  /* Check the type. */
-
-  if (value->type != GCONF_VALUE_INT)
-    {
-      meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
-                    key);
-      /* But we did recognise it. */
-      return TRUE;
-    }
-
-  new_value = gconf_value_get_int (value);
+  if (cursor->base.key==NULL || cursor->target==NULL)
+    /* Unknown key or no work for us to do. */
+    return;
 
-  if (new_value < cursor->minimum || new_value > cursor->maximum)
-    {
-      meta_warning (_("%d stored in GConf key %s is out of range %d to %d\n"),
-                    new_value, cursor->key,
-                    cursor->minimum, cursor->maximum);
-      return TRUE;
-    }
+  new_value = g_settings_get_int (SETTINGS (cursor->base.schema), key);
 
   /* Did it change?  If so, tell the listeners about it. */
-
   if (*cursor->target != new_value)
     {
       *cursor->target = new_value;
-      queue_changed (cursor->pref);
+      queue_changed (cursor->base.pref);
     }
-
-  return TRUE;
-  
 }
 
 
@@ -956,70 +728,50 @@ queue_changed (MetaPreference pref)
     meta_topic (META_DEBUG_PREFS, "Change of pref %s was already pending\n",
                 meta_preference_to_string (pref));
 
-  /* add idle at priority below the gconf notify idle */
   if (changed_idle == 0)
     changed_idle = g_idle_add_full (META_PRIORITY_PREFS_NOTIFY,
                                     changed_idle_handler, NULL, NULL);
 }
 
-#else /* HAVE_GCONF */
-
-void
-meta_prefs_add_listener (MetaPrefsChangedFunc func,
-                         gpointer             data)
-{
-  /* Nothing, because they have gconf turned off */
-}
-
-void
-meta_prefs_remove_listener (MetaPrefsChangedFunc func,
-                            gpointer             data)
-{
-  /* Nothing, because they have gconf turned off */
-}
-
-#endif /* HAVE_GCONF */
-
 
 /****************************************************************************/
 /* Initialisation.                                                          */
 /****************************************************************************/
 
-#ifdef HAVE_GCONF
-/* @@@ again, use glib's ability to tell you the size of the array */
-static gchar *gconf_dirs_we_are_interested_in[] = {
-  "/apps/metacity",
-  KEY_TERMINAL_DIR,
-  KEY_GNOME_ACCESSIBILITY,
-  "/desktop/gnome/peripherals/mouse",
-  "/desktop/gnome/interface",
-  NULL,
-};
-#endif
-
 void
 meta_prefs_init (void)
 {
-#ifdef HAVE_GCONF
-  GError *err = NULL;
-  gchar **gconf_dir_cursor;
-  
-  if (default_client != NULL)
-    return;
-  
-  /* returns a reference which we hold forever */
-  default_client = gconf_client_get_default ();
+  GSettings *settings;
+
+  settings_schemas = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                            NULL, g_object_unref);
+
+  settings = g_settings_new (SCHEMA_GENERAL);
+  g_signal_connect (settings, "changed", G_CALLBACK (settings_changed), NULL);
+  g_hash_table_insert (settings_schemas, SCHEMA_GENERAL, settings);
+
+  settings = g_settings_new (SCHEMA_METACITY);
+  g_signal_connect (settings, "changed", G_CALLBACK (settings_changed), NULL);
+  g_hash_table_insert (settings_schemas, SCHEMA_METACITY, settings);
+
+  /* Individual keys we watch outside of our schemas */
+  settings = g_settings_new (SCHEMA_INTERFACE);
+  g_signal_connect (settings, "changed::" KEY_GNOME_ACCESSIBILITY,
+                    G_CALLBACK (settings_changed), NULL);
+  g_signal_connect (settings, "changed::" KEY_GNOME_ANIMATIONS,
+                    G_CALLBACK (settings_changed), NULL);
+  g_signal_connect (settings, "changed::" KEY_GNOME_CURSOR_THEME,
+                    G_CALLBACK (settings_changed), NULL);
+  g_signal_connect (settings, "changed::" KEY_GNOME_CURSOR_SIZE,
+                    G_CALLBACK (settings_changed), NULL);
+  g_hash_table_insert (settings_schemas, SCHEMA_INTERFACE, settings);
+
+  /* Bindings have a separate handler, since they are in separate schemas
+   * and work differently */
+  settings = g_settings_new (SCHEMA_BINDINGS);
+  g_signal_connect (settings, "changed", G_CALLBACK (bindings_changed), NULL);
+  g_hash_table_insert (settings_schemas, SCHEMA_BINDINGS, settings);
 
-  for (gconf_dir_cursor=gconf_dirs_we_are_interested_in;
-       *gconf_dir_cursor!=NULL;
-       gconf_dir_cursor++)
-    {
-      gconf_client_add_dir (default_client,
-                            *gconf_dir_cursor,
-                            GCONF_CLIENT_PRELOAD_RECURSIVE,
-                            &err);
-      cleanup_error (&err);
-    }
 
   /* Pick up initial values. */
 
@@ -1028,35 +780,7 @@ meta_prefs_init (void)
   handle_preference_init_string ();
   handle_preference_init_int ();
 
-  /* @@@ Is there any reason we don't do the add_dir here? */
-  for (gconf_dir_cursor=gconf_dirs_we_are_interested_in;
-       *gconf_dir_cursor!=NULL;
-       gconf_dir_cursor++)
-    {
-      gconf_client_notify_add (default_client,
-                               *gconf_dir_cursor,
-                               change_notify,
-                               NULL,
-                               NULL,
-                               &err);
-      cleanup_error (&err);
-    }
-
-#else  /* HAVE_GCONF */
-
-  /* Set defaults for some values that can't be set at initialization time of
-   * the static globals.  In the case of the theme, note that there is code
-   * elsewhere that will do everything possible to fallback to an existing theme
-   * if the one here does not exist.
-   */
-  titlebar_font = pango_font_description_from_string ("Sans Bold 10");
-  current_theme = g_strdup ("Atlanta");
-  
-  init_button_layout();
-#endif /* HAVE_GCONF */
-  
   init_bindings ();
-  init_commands ();
   init_workspace_names ();
 }
 
@@ -1065,157 +789,70 @@ meta_prefs_init (void)
 /* Updates.                                                                 */
 /****************************************************************************/
 
-#ifdef HAVE_GCONF
-
-gboolean (*preference_update_handler[]) (const gchar*, GConfValue*) = {
-  handle_preference_update_enum,
-  handle_preference_update_bool,
-  handle_preference_update_string,
-  handle_preference_update_int,
-  NULL
-};
-
 static void
-change_notify (GConfClient    *client,
-               guint           cnxn_id,
-               GConfEntry     *entry,
-               gpointer        user_data)
-{
-  const char *key;
-  GConfValue *value;
-  gint i=0;
-  
-  key = gconf_entry_get_key (entry);
-  value = gconf_entry_get_value (entry);
-
-  /* First, search for a handler that might know what to do. */
-
-  /* FIXME: When this is all working, since the first item in every
-   * array is the gchar* of the key, there's no reason we can't
-   * find the correct record for that key here and save code duplication.
-   */
+settings_changed (GSettings *settings,
+                  gchar *key,
+                  gpointer data)
+{
+  GVariant *value;
+  const GVariantType *type;
+  MetaEnumPreference *cursor;
+  gboolean found_enum;
 
-  while (preference_update_handler[i]!=NULL)
+  /* String array, handled separately */
+  if (strcmp (key, KEY_WORKSPACE_NAMES) == 0)
     {
-      if (preference_update_handler[i] (key, value))
-        goto out; /* Get rid of this eventually */
+      if (update_workspace_names ());
+        queue_changed (META_PREF_WORKSPACE_NAMES);
 
-      i++;
+      return;
     }
-  
-  if (g_str_has_prefix (key, KEY_WINDOW_BINDINGS_PREFIX) ||
-      g_str_has_prefix (key, KEY_SCREEN_BINDINGS_PREFIX))
-    {
-      if (g_str_has_suffix (key, KEY_LIST_BINDINGS_SUFFIX))
-        {
-          GSList *list;
-
-          if (value && value->type != GCONF_VALUE_LIST)
-            {
-              meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
-                            key);
-              goto out;
-            }
-
-          list = value ? gconf_value_get_list (value) : NULL;
-
-          if (update_key_list_binding (key, list))
-            queue_changed (META_PREF_KEYBINDINGS);
-        }
-      else
-        {
-          const char *str;
-
-          if (value && value->type != GCONF_VALUE_STRING)
-            {
-              meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
-                            key);
-              goto out;
-            }
 
-          str = value ? gconf_value_get_string (value) : NULL;
+  value = g_settings_get_value (settings, key);
+  type = g_variant_get_type (value);
 
-          if (update_key_binding (key, str))
-            queue_changed (META_PREF_KEYBINDINGS);
-        }
-    }
-  else if (g_str_has_prefix (key, KEY_COMMAND_PREFIX))
+  if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
+    handle_preference_update_bool (settings, key);
+  else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
+    handle_preference_update_int (settings, key);
+  else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
     {
-      const char *str;
+      cursor = preferences_enum;
+      found_enum = FALSE;
 
-      if (value && value->type != GCONF_VALUE_STRING)
+      while (cursor->base.key != NULL)
         {
-          meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
-                        key);
-          goto out;
-        }
-
-      str = value ? gconf_value_get_string (value) : NULL;
-
-      if (update_command (key, str))
-        queue_changed (META_PREF_COMMANDS);
-    }
-  else if (g_str_has_prefix (key, KEY_WORKSPACE_NAME_PREFIX))
-    {
-      const char *str;
+          if (strcmp (key, cursor->base.key) == 0)
+            found_enum = TRUE;
 
-      if (value && value->type != GCONF_VALUE_STRING)
-        {
-          meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
-                        key);
-          goto out;
+          cursor++;
         }
 
-      str = value ? gconf_value_get_string (value) : NULL;
-
-      if (update_workspace_name (key, str))
-        queue_changed (META_PREF_WORKSPACE_NAMES);
+      if (found_enum)
+        handle_preference_update_enum (settings, key);
+      else
+        handle_preference_update_string (settings, key);
     }
   else
-    {
-      meta_topic (META_DEBUG_PREFS, "Key %s doesn't mean anything to Metacity\n",
-                  key);
-    }
-  
- out:
-  /* nothing */
-  return; /* AIX compiler wants something after a label like out: */
+    /* Someone added a preference of an unhandled type */
+    g_assert_not_reached ();
+
+  g_variant_unref (value);
 }
 
 static void
-cleanup_error (GError **error)
+bindings_changed (GSettings *settings,
+                  gchar *key,
+                  gpointer data)
 {
-  if (*error)
-    {
-      meta_warning ("%s\n", (*error)->message);
-      
-      g_error_free (*error);
-      *error = NULL;
-    }
-}
+  gchar **strokes;
 
-/* get_bool returns TRUE if *val is filled in, FALSE otherwise */
-/* @@@ probably worth moving this inline; only used once */
-static gboolean
-get_bool (const char *key, gboolean *val)
-{
-  GError     *err = NULL;
-  GConfValue *value;
-  gboolean    filled_in = FALSE;
+  strokes = g_settings_get_strv (settings, key);
 
-  value = gconf_client_get (default_client, key, &err);
-  cleanup_error (&err);
-  if (value)
-    {
-      if (value->type == GCONF_VALUE_BOOL)
-        {
-          *val = gconf_value_get_bool (value);
-          filled_in = TRUE;
-        }
-      gconf_value_free (value);
-    }
+   if (update_key_binding (key, strokes))
+     queue_changed (META_PREF_KEYBINDINGS);
 
-  return filled_in;
+  g_strfreev (strokes);
 }
 
 /**
@@ -1236,21 +873,19 @@ maybe_give_disable_workarounds_warning (void)
     }
 }
 
-#endif /* HAVE_GCONF */
-
 MetaVirtualModifier
 meta_prefs_get_mouse_button_mods  (void)
 {
   return mouse_button_mods;
 }
 
-MetaFocusMode
+GDesktopFocusMode
 meta_prefs_get_focus_mode (void)
 {
   return focus_mode;
 }
 
-MetaFocusNewWindows
+GDesktopFocusNewWindows
 meta_prefs_get_focus_new_windows (void)
 {
   return focus_new_windows;
@@ -1262,7 +897,7 @@ meta_prefs_get_raise_on_click (void)
   /* Force raise_on_click on for click-to-focus, as requested by Havoc
    * in #326156.
    */
-  return raise_on_click || focus_mode == META_FOCUS_MODE_CLICK;
+  return raise_on_click || focus_mode == G_DESKTOP_FOCUS_MODE_CLICK;
 }
 
 const char*
@@ -1288,88 +923,104 @@ meta_prefs_get_cursor_size (void)
 /* Handlers for string preferences.                                         */
 /****************************************************************************/
 
-#ifdef HAVE_GCONF
-
-static void
-titlebar_handler (MetaPreference pref,
-                  const gchar    *string_value,
-                  gboolean       *inform_listeners)
+static gboolean
+titlebar_handler (GVariant *value,
+                  gpointer *result,
+                  gpointer  data)
 {
-  PangoFontDescription *new_desc = NULL;
+  PangoFontDescription *desc;
+  const gchar *string_value;
 
-  if (string_value)
-    new_desc = pango_font_description_from_string (string_value);
+  *result = NULL; /* ignored */
+  string_value = g_variant_get_string (value, NULL);
+  desc = pango_font_description_from_string (string_value);
 
-  if (new_desc == NULL)
+  if (desc == NULL)
     {
       meta_warning (_("Could not parse font description "
-                      "\"%s\" from GConf key %s\n"),
+                      "\"%s\" from GSettings key %s\n"),
                     string_value ? string_value : "(null)",
                     KEY_TITLEBAR_FONT);
 
-      *inform_listeners = FALSE;
-
-      return;
+      return FALSE;
     }
 
   /* Is the new description the same as the old? */
-
   if (titlebar_font &&
-      pango_font_description_equal (new_desc, titlebar_font))
+      pango_font_description_equal (desc, titlebar_font))
     {
-      pango_font_description_free (new_desc);
-      *inform_listeners = FALSE;
-      return;
+      pango_font_description_free (desc);
     }
+  else
+    {
+      if (titlebar_font)
+        pango_font_description_free (titlebar_font);
 
-  /* No, so free the old one and put ours in instead. */
-
-  if (titlebar_font)
-    pango_font_description_free (titlebar_font);
-
-  titlebar_font = new_desc;
+      titlebar_font = desc;
+      queue_changed (META_PREF_TITLEBAR_FONT);
+    }
 
+  return TRUE;
 }
 
-static void
-theme_name_handler (MetaPreference pref,
-                    const gchar *string_value,
-                    gboolean *inform_listeners)
+static gboolean
+theme_name_handler (GVariant *value,
+                    gpointer *result,
+                    gpointer  data)
 {
-  g_free (current_theme);
+  const gchar *string_value;
 
-  /* Fallback crackrock */
-  if (string_value == NULL)
-    current_theme = g_strdup ("Atlanta");
-  else
-    current_theme = g_strdup (string_value);
+  *result = NULL; /* ignored */
+  string_value = g_variant_get_string (value, NULL);
+
+  if (!string_value || !*string_value)
+    return FALSE;
+
+  if (g_strcmp0 (current_theme, string_value) != 0)
+    {
+      if (current_theme)
+        g_free (current_theme);
+
+      current_theme = g_strdup (string_value);
+      queue_changed (META_PREF_THEME);
+    }
+
+  return TRUE;
 }
 
-static void
-mouse_button_mods_handler (MetaPreference pref,
-                           const gchar *string_value,
-                           gboolean *inform_listeners)
+static gboolean
+mouse_button_mods_handler (GVariant *value,
+                           gpointer *result,
+                           gpointer  data)
 {
   MetaVirtualModifier mods;
+  const gchar *string_value;
 
-  meta_topic (META_DEBUG_KEYBINDINGS,
-              "Mouse button modifier has new gconf value \"%s\"\n",
-              string_value);
-  if (string_value && meta_ui_parse_modifier (string_value, &mods))
-    {
-      mouse_button_mods = mods;
-    }
-  else
+  string_value = g_variant_get_string (value, NULL);
+
+  if (!string_value || !meta_ui_parse_modifier (string_value, &mods))
     {
       meta_topic (META_DEBUG_KEYBINDINGS,
-                  "Failed to parse new gconf value\n");
+                  "Failed to parse new GSettings value\n");
           
       meta_warning (_("\"%s\" found in configuration database is "
                       "not a valid value for mouse button modifier\n"),
                     string_value);
 
-      *inform_listeners = FALSE;
+      return FALSE;
     }
+
+  meta_topic (META_DEBUG_KEYBINDINGS,
+              "Mouse button modifier has new GSettings value \"%s\"\n",
+              string_value);
+
+  if (mods != mouse_button_mods)
+    {
+      mouse_button_mods = mods;
+      queue_changed (META_PREF_MOUSE_BUTTON_MODS);
+    }
+
+  return TRUE;
 }
 
 static gboolean
@@ -1389,17 +1040,19 @@ button_layout_equal (const MetaButtonLayout *a,
         return FALSE;
       if (a->right_buttons_has_spacer[i] != b->right_buttons_has_spacer[i])
         return FALSE;
-      ++i;
+      i++;
     }
 
   return TRUE;
 }
 
+/*
+ * This conversion cannot be handled by GSettings since
+ * several values are stored in the same key (as a string).
+ */
 static MetaButtonFunction
 button_function_from_string (const char *str)
 {
-  /* FIXME: gconf_string_to_enum is the obvious way to do this */
-
   if (strcmp (str, "menu") == 0)
     return META_BUTTON_FUNCTION_MENU;
   else if (strcmp (str, "minimize") == 0)
@@ -1444,36 +1097,41 @@ button_opposite_function (MetaButtonFunction ofwhat)
     }
 }
 
-static void
-button_layout_handler (MetaPreference pref,
-                         const gchar *string_value,
-                         gboolean *inform_listeners)
+static gboolean
+button_layout_handler (GVariant *value,
+                       gpointer *result,
+                       gpointer  data)
 {
   MetaButtonLayout new_layout;
+  const gchar *string_value;
   char **sides = NULL;
   int i;
-  
+
   /* We need to ignore unknown button functions, for
    * compat with future versions
    */
-  
+
+  *result = NULL; /* ignored */
+  string_value = g_variant_get_string (value, NULL);
+
   if (string_value)
     sides = g_strsplit (string_value, ":", 2);
 
+  i = 0;
+
   if (sides != NULL && sides[0] != NULL)
     {
       char **buttons;
       int b;
       gboolean used[META_BUTTON_FUNCTION_LAST];
 
-      i = 0;
       while (i < META_BUTTON_FUNCTION_LAST)
         {
           used[i] = FALSE;
           new_layout.left_buttons_has_spacer[i] = FALSE;
-          ++i;
+          i++;
         }
-      
+
       buttons = g_strsplit (sides[0], ",", -1);
       i = 0;
       b = 0;
@@ -1496,7 +1154,7 @@ button_layout_handler (MetaPreference pref,
                 {
                   new_layout.left_buttons[i] = f;
                   used[f] = TRUE;
-                  ++i;
+                  i++;
 
                   f = button_opposite_function (f);
 
@@ -1510,28 +1168,31 @@ button_layout_handler (MetaPreference pref,
                               buttons[b]);
                 }
             }
-          
+
           ++b;
         }
 
-      new_layout.left_buttons[i] = META_BUTTON_FUNCTION_LAST;
-      new_layout.left_buttons_has_spacer[i] = FALSE;
-      
       g_strfreev (buttons);
     }
 
+  /* Close the buttons list even if it's empty */
+  new_layout.left_buttons[i] = META_BUTTON_FUNCTION_LAST;
+  new_layout.left_buttons_has_spacer[i] = FALSE;
+
+
+  i = 0;
+
   if (sides != NULL && sides[0] != NULL && sides[1] != NULL)
     {
       char **buttons;
       int b;
       gboolean used[META_BUTTON_FUNCTION_LAST];
 
-      i = 0;
       while (i < META_BUTTON_FUNCTION_LAST)
         {
           used[i] = FALSE;
           new_layout.right_buttons_has_spacer[i] = FALSE;
-          ++i;
+          i++;
         }
       
       buttons = g_strsplit (sides[1], ",", -1);
@@ -1555,7 +1216,7 @@ button_layout_handler (MetaPreference pref,
                 {
                   new_layout.right_buttons[i] = f;
                   used[f] = TRUE;
-                  ++i;
+                  i++;
 
                   f = button_opposite_function (f);
 
@@ -1573,14 +1234,16 @@ button_layout_handler (MetaPreference pref,
           ++b;
         }
 
-      new_layout.right_buttons[i] = META_BUTTON_FUNCTION_LAST;
-      new_layout.right_buttons_has_spacer[i] = FALSE;
-      
       g_strfreev (buttons);
     }
 
-  g_strfreev (sides);
-  
+  /* Close the buttons list even if it's empty */
+  new_layout.right_buttons[i] = META_BUTTON_FUNCTION_LAST;
+  new_layout.right_buttons_has_spacer[i] = FALSE;
+
+  if (sides)
+    g_strfreev (sides);
+
   /* Invert the button layout for RTL languages */
   if (meta_ui_get_direction() == META_UI_DIRECTION_RTL)
   {
@@ -1613,19 +1276,15 @@ button_layout_handler (MetaPreference pref,
 
     new_layout = rtl_layout;
   }
-  
-  if (button_layout_equal (&button_layout, &new_layout))
-    {
-      /* Same as before, so duck out */
-      *inform_listeners = FALSE;
-    }
-  else
+
+  if (!button_layout_equal (&button_layout, &new_layout))
     {
       button_layout = new_layout;
+      emit_changed (META_PREF_BUTTON_LAYOUT);
     }
-}
 
-#endif /* HAVE_GCONF */
+  return TRUE;
+}
 
 const PangoFontDescription*
 meta_prefs_get_titlebar_font (void)
@@ -1656,16 +1315,11 @@ meta_prefs_get_disable_workarounds (void)
   return disable_workarounds;
 }
 
-#ifdef HAVE_GCONF
-#define MAX_REASONABLE_AUTO_RAISE_DELAY 10000
-  
-#endif /* HAVE_GCONF */
-
 #ifdef WITH_VERBOSE_MODE
 const char*
 meta_preference_to_string (MetaPreference pref)
 {
-  /* FIXME: another case for gconf_string_to_enum */
+  /* TODO: better handled via GLib enum nicknames */
   switch (pref)
     {
     case META_PREF_MOUSE_BUTTON_MODS:
@@ -1713,12 +1367,6 @@ meta_preference_to_string (MetaPreference pref)
     case META_PREF_AUTO_RAISE_DELAY:
       return "AUTO_RAISE_DELAY";
 
-    case META_PREF_COMMANDS:
-      return "COMMANDS";
-
-    case META_PREF_TERMINAL_COMMAND:
-      return "TERMINAL_COMMAND";
-
     case META_PREF_BUTTON_LAYOUT:
       return "BUTTON_LAYOUT";
 
@@ -1766,34 +1414,12 @@ meta_preference_to_string (MetaPreference pref)
 void
 meta_prefs_set_num_workspaces (int n_workspaces)
 {
-#ifdef HAVE_GCONF
-  GError *err;
-  
-  if (default_client == NULL)
-    return;
-
-  if (n_workspaces < 1)
-    n_workspaces = 1;
-  if (n_workspaces > MAX_REASONABLE_WORKSPACES)
-    n_workspaces = MAX_REASONABLE_WORKSPACES;
-  
-  err = NULL;
-  gconf_client_set_int (default_client,
-                        KEY_NUM_WORKSPACES,
-                        n_workspaces,
-                        &err);
-
-  if (err)
-    {
-      meta_warning (_("Error setting number of workspaces to %d: %s\n"),
-                    num_workspaces,
-                    err->message);
-      g_error_free (err);
-    }
-#endif /* HAVE_GCONF */
+  g_settings_set_int (SETTINGS (SCHEMA_GENERAL),
+                      KEY_NUM_WORKSPACES,
+                      n_workspaces);
 }
 
-#define keybind(name, handler, param, flags, stroke, description) \
+#define keybind(name, handler, param, flags) \
   { #name, NULL, !!(flags & BINDING_REVERSES), !!(flags & BINDING_PER_WINDOW) },
 static MetaKeyPref key_bindings[] = {
 #include "all-keybindings.h"
@@ -1801,373 +1427,66 @@ static MetaKeyPref key_bindings[] = {
 };
 #undef keybind
 
-#ifndef HAVE_GCONF
-
-/**
- * A type to map names of keybindings (such as "switch_windows")
- * to the binding strings themselves (such as "<Alt>Tab").
- * It exists only when GConf is turned off in ./configure and
- * functions as a sort of ersatz GConf.
- */
-typedef struct
-{
-  const char *name;
-  const char *keybinding;
-} MetaSimpleKeyMapping;
-
-/* FIXME: This would be neater if the array only contained entries whose
- * default keystroke was non-null.  You COULD do this by defining
- * ONLY_BOUND_BY_DEFAULT around various blocks at the cost of making
- * the bindings file way more complicated.  However, we could stop this being
- * data and move it into code.  Then the compiler would optimise away
- * the problem lines.
- */
-
-#define keybind(name, handler, param, flags, stroke, description) \
-  { #name, stroke },
-
-static MetaSimpleKeyMapping key_string_bindings[] = {
-#include "all-keybindings.h"
-  { NULL, NULL }
-};
-#undef keybind
-
-#endif /* NOT HAVE_GCONF */
 
 static void
 init_bindings (void)
 {
-#ifdef HAVE_GCONF
-  const char *prefix[] = {
-    KEY_WINDOW_BINDINGS_PREFIX,
-    KEY_SCREEN_BINDINGS_PREFIX,
-    NULL
-  };
   int i;
-  GSList *list, *l, *list_val;
-  const char *str_val;
-  const char *key;
-  GConfEntry *entry;
-  GConfValue *value;
+  gchar **strokes;
 
-  for (i = 0; prefix[i]; i++)
+  for (i = 0; key_bindings[i].name; i++)
     {
-      list = gconf_client_all_entries (default_client, prefix[i], NULL);
-      for (l = list; l; l = l->next)
-        {
-          entry = l->data;
-          key = gconf_entry_get_key (entry);
-          value = gconf_entry_get_value (entry);
-          if (g_str_has_suffix (key, KEY_LIST_BINDINGS_SUFFIX))
-            {
-              list_val = gconf_client_get_list (default_client, key, GCONF_VALUE_STRING, NULL);
- 
-              update_key_list_binding (key, list_val);
-              g_slist_foreach (list_val, (GFunc)g_free, NULL);
-              g_slist_free (list_val);
-            }
-          else
-            {
-              str_val = gconf_value_get_string (value);
-              update_key_binding (key, str_val);
-            }
-          gconf_entry_free (entry);
-        }
-      g_slist_free (list);
-    }
-#else /* HAVE_GCONF */
-  int i = 0;
-  int which = 0;
-  while (key_string_bindings[i].name)
-    {
-      if (key_string_bindings[i].keybinding == NULL) {
-        ++i;
-        continue;
-      }
-    
-      while (strcmp(key_bindings[which].name, 
-                    key_string_bindings[i].name) != 0)
-        which++;
-
-      /* Set the binding */
-      update_binding (&key_bindings[which], 
-                      key_string_bindings[i].keybinding);
+      strokes = g_settings_get_strv (SETTINGS (SCHEMA_BINDINGS),
+                                     key_bindings[i].name);
+      update_key_binding (key_bindings[i].name, strokes);
 
-      ++i;
+      g_strfreev (strokes);
     }
-#endif /* HAVE_GCONF */
-}
-
-static void
-init_commands (void)
-{
-#ifdef HAVE_GCONF
-  GSList *list, *l;
-  const char *str_val;
-  const char *key;
-  GConfEntry *entry;
-  GConfValue *value;
-
-  list = gconf_client_all_entries (default_client, KEY_COMMAND_DIRECTORY, NULL);
-  for (l = list; l; l = l->next)
-    {
-      entry = l->data;
-      key = gconf_entry_get_key (entry);
-      value = gconf_entry_get_value (entry);
-      str_val = gconf_value_get_string (value);
-      update_command (key, str_val);
-      gconf_entry_free (entry);
-    }
-  g_slist_free (list);
-#else
-  int i;
-  for (i = 0; i < MAX_COMMANDS; i++)
-    commands[i] = NULL;
-#endif /* HAVE_GCONF */
 }
 
 static void
 init_workspace_names (void)
 {
-  int i;
-  for (i = 0; i < MAX_REASONABLE_WORKSPACES; i++)
-    workspace_names[i] = NULL;
-
-#ifdef HAVE_GCONF
-  GSList *list, *l;
-  const char *str_val;
-  const char *key;
-  GConfEntry *entry;
-  GConfValue *value;
-
-  list = gconf_client_all_entries (default_client, KEY_WORKSPACE_NAME_DIRECTORY, NULL);
-  for (l = list; l; l = l->next)
-    {
-      entry = l->data;
-      key = gconf_entry_get_key (entry);
-      value = gconf_entry_get_value (entry);
-      str_val = gconf_value_get_string (value);
-      update_workspace_name (key, str_val);
-      gconf_entry_free (entry);
-    }
-  g_slist_free (list);
-#endif /* HAVE_GCONF */
-
-  /* initialise any we didn't see */
-  for (i = 0; i < MAX_REASONABLE_WORKSPACES; i++)
-    if (workspace_names[i]==NULL)
-      workspace_names[i] = g_strdup_printf (_("Workspace %d"), i + 1);
-
-  meta_topic (META_DEBUG_PREFS,
-              "Initialized workspace names\n");
+  update_workspace_names ();
 }
 
 static gboolean
 update_binding (MetaKeyPref *binding,
-                const char  *value)
-{
-  unsigned int keysym;
-  unsigned int keycode;
-  MetaVirtualModifier mods;
-  MetaKeyCombo *combo;
-  gboolean changed;
-
-  meta_topic (META_DEBUG_KEYBINDINGS,
-              "Binding \"%s\" has new gconf value \"%s\"\n",
-              binding->name, value ? value : "none");
-  
-  keysym = 0;
-  keycode = 0;
-  mods = 0;
-  if (value)
-    {
-      if (!meta_ui_parse_accelerator (value, &keysym, &keycode, &mods))
-        {
-          meta_topic (META_DEBUG_KEYBINDINGS,
-                      "Failed to parse new gconf value\n");
-          meta_warning (_("\"%s\" found in configuration database is not a valid value for keybinding \"%s\"\n"),
-                        value, binding->name);
-
-          return FALSE;
-        }
-    }
-
-  /* If there isn't already a first element, make one. */
-  if (!binding->bindings)
-    {
-      MetaKeyCombo *blank = g_malloc0 (sizeof (MetaKeyCombo));
-      binding->bindings = g_slist_alloc();
-      binding->bindings->data = blank;
-    }
-  
-   combo = binding->bindings->data;
-
-#ifdef HAVE_GCONF
-   /* Bug 329676: Bindings which can be shifted must not have no modifiers,
-    * nor only SHIFT as a modifier.
-    */
-
-  if (binding->add_shift &&
-      0 != keysym &&
-      (META_VIRTUAL_SHIFT_MASK == mods || 0 == mods))
-    {
-      gchar *old_setting;
-      gchar *key;
-      GError *err = NULL;
-      
-      meta_warning ("Cannot bind \"%s\" to %s: it needs a modifier "
-                    "such as Ctrl or Alt.\n",
-                    binding->name,
-                    value);
-
-      old_setting = meta_ui_accelerator_name (combo->keysym,
-                                              combo->modifiers);
-
-      if (!strcmp(old_setting, value))
-        {
-          /* We were about to set it to the same value
-           * that it had originally! This must be caused
-           * by getting an invalid string back from
-           * meta_ui_accelerator_name. Bail out now
-           * so we don't get into an infinite loop.
-           */
-           g_free (old_setting);
-           return TRUE;
-        }
-
-      meta_warning ("Reverting \"%s\" to %s.\n",
-                    binding->name,
-                    old_setting);
-
-      /* FIXME: add_shift is currently screen_bindings only, but
-       * there's no really good reason it should always be.
-       * So we shouldn't blindly add KEY_SCREEN_BINDINGS_PREFIX
-       * onto here.
-       */
-      key = g_strconcat (KEY_SCREEN_BINDINGS_PREFIX, "/",
-                         binding->name, NULL);
-      
-      gconf_client_set_string (gconf_client_get_default (),
-                               key, old_setting, &err);
-
-      if (err)
-        {
-          meta_warning ("Error while reverting keybinding: %s\n",
-                        err->message);
-          g_error_free (err);
-          err = NULL;
-        }
-      
-      g_free (old_setting);
-      g_free (key);
-
-      /* The call to gconf_client_set_string() will cause this function
-       * to be called again with the new value, so there's no need to
-       * carry on.
-       */
-      return TRUE;
-    }
-#endif
-  
-  changed = FALSE;
-  if (keysym != combo->keysym ||
-      keycode != combo->keycode ||
-      mods != combo->modifiers)
-    {
-      changed = TRUE;
-      
-      combo->keysym = keysym;
-      combo->keycode = keycode;
-      combo->modifiers = mods;
-      
-      meta_topic (META_DEBUG_KEYBINDINGS,
-                  "New keybinding for \"%s\" is keysym = 0x%x keycode = 0x%x mods = 0x%x\n",
-                  binding->name, combo->keysym, combo->keycode,
-                  combo->modifiers);
-    }
-  else
-    {
-      meta_topic (META_DEBUG_KEYBINDINGS,
-                  "Keybinding for \"%s\" is unchanged\n", binding->name);
-    }
-  
-  return changed;
-}
-
-#ifdef HAVE_GCONF
-static gboolean
-update_list_binding (MetaKeyPref *binding,
-                     GSList      *value,
-                     MetaStringListType type_of_value)
+                gchar      **strokes)
 {
   unsigned int keysym;
   unsigned int keycode;
   MetaVirtualModifier mods;
   gboolean changed = FALSE;
-  const gchar *pref_string;
-  GSList *pref_iterator = value, *tmp;
   MetaKeyCombo *combo;
+  int i;
 
   meta_topic (META_DEBUG_KEYBINDINGS,
-              "Binding \"%s\" has new gconf value\n",
+              "Binding \"%s\" has new GSettings value\n",
               binding->name);
-  
-  if (binding->bindings == NULL)
-    {
-      /* We need to insert a dummy element into the list, because the first
-       * element is the one governed by update_binding. We only handle the
-       * subsequent elements.
-       */
-      MetaKeyCombo *blank = g_malloc0 (sizeof (MetaKeyCombo));
-      binding->bindings = g_slist_alloc();
-      binding->bindings->data = blank;
-    }
-       
+
   /* Okay, so, we're about to provide a new list of key combos for this
    * action. Delete any pre-existing list.
    */
-  tmp = binding->bindings->next;
-  while (tmp)
-    {
-      g_free (tmp->data);
-      tmp = tmp->next;
-    }
-  g_slist_free (binding->bindings->next);
-  binding->bindings->next = NULL;
+  g_slist_foreach (binding->bindings, (GFunc) g_free, NULL);
+  g_slist_free (binding->bindings);
+  binding->bindings = NULL;
   
-  while (pref_iterator)
+  for (i = 0; strokes && strokes[i]; i++)
     {
       keysym = 0;
       keycode = 0;
       mods = 0;
 
-      if (!pref_iterator->data)
-        {
-          pref_iterator = pref_iterator->next;
-          continue;
-        }
-
-      switch (type_of_value)
-        {
-        case META_LIST_OF_STRINGS:
-          pref_string = pref_iterator->data;
-          break;
-        case META_LIST_OF_GCONFVALUE_STRINGS:
-          pref_string = gconf_value_get_string (pref_iterator->data);
-          break;
-        default:
-          g_assert_not_reached ();
-        }
-      
-      if (!meta_ui_parse_accelerator (pref_string, &keysym, &keycode, &mods))
+      if (!meta_ui_parse_accelerator (strokes[i], &keysym, &keycode, &mods))
         {
           meta_topic (META_DEBUG_KEYBINDINGS,
-                      "Failed to parse new gconf value\n");
+                      "Failed to parse new GSettings value\n");
           meta_warning (_("\"%s\" found in configuration database is not a valid value for keybinding \"%s\"\n"),
-                        pref_string, binding->name);
+                        strokes[i], binding->name);
 
-          /* Should we remove this value from the list in gconf? */
-          pref_iterator = pref_iterator->next;
+          /* Value is kept and will thus be removed next time we save the key.
+           * Changing the key in response to a modification could lead to cyclic calls. */
           continue;
         }
 
@@ -2182,387 +1501,153 @@ update_list_binding (MetaKeyPref *binding,
           meta_warning ("Cannot bind \"%s\" to %s: it needs a modifier "
                         "such as Ctrl or Alt.\n",
                         binding->name,
-                        pref_string);
-
-          /* Should we remove this value from the list in gconf? */
+                        strokes[i]);
 
-          pref_iterator = pref_iterator->next;
+          /* Value is kept and will thus be removed next time we save the key.
+           * Changing the key in response to a modification could lead to cyclic calls. */
           continue;
         }
-  
+
       changed = TRUE;
 
       combo = g_malloc0 (sizeof (MetaKeyCombo));
       combo->keysym = keysym;
       combo->keycode = keycode;
       combo->modifiers = mods;
-      binding->bindings->next = g_slist_prepend (binding->bindings->next, combo);
+      binding->bindings = g_slist_prepend (binding->bindings, combo);
 
       meta_topic (META_DEBUG_KEYBINDINGS,
                       "New keybinding for \"%s\" is keysym = 0x%x keycode = 0x%x mods = 0x%x\n",
                       binding->name, keysym, keycode, mods);
+    }
 
-      pref_iterator = pref_iterator->next;
-    }  
   return changed;
 }
 
-static const gchar*
-relative_key (const gchar* key)
-{
-  const gchar* end;
-  
-  end = strrchr (key, '/');
-
-  ++end;
-
-  return end;
-}
-
-/* Return value is TRUE if a preference changed and we need to
- * notify
- */
 static gboolean
-find_and_update_binding (MetaKeyPref *bindings, 
-                         const char  *name,
-                         const char  *value)
+update_key_binding (const char *key,
+                    gchar     **strokes)
 {
-  const char *key;
   int i;
-  
-  if (*name == '/')
-    key = relative_key (name);
-  else
-    key = name;
 
   i = 0;
-  while (bindings[i].name &&
-         strcmp (key, bindings[i].name) != 0)
-    ++i;
+  while (key_bindings[i].name &&
+         strcmp (key, key_bindings[i].name) != 0)
+    i++;
 
-  if (bindings[i].name)
-    return update_binding (&bindings[i], value);
+  if (key_bindings[i].name)
+    return update_binding (&key_bindings[i], strokes);
   else
     return FALSE;
 }
 
 static gboolean
-update_key_binding (const char *name,
-                       const char *value)
+update_workspace_names (void)
 {
-  return find_and_update_binding (key_bindings, name, value);
-}
-
-static gboolean
-find_and_update_list_binding (MetaKeyPref *bindings,
-                              const char  *name,
-                              GSList      *value)
-{
-  const char *key;
   int i;
-  gchar *name_without_suffix = g_strdup(name);
-
-  name_without_suffix[strlen(name_without_suffix) - strlen(KEY_LIST_BINDINGS_SUFFIX)] = 0;
-
-  if (*name_without_suffix == '/')
-    key = relative_key (name_without_suffix);
-  else
-    key = name_without_suffix;
-
-  i = 0;
-  while (bindings[i].name &&
-         strcmp (key, bindings[i].name) != 0)
-    ++i;
-
-  g_free (name_without_suffix);
+  char **names;
+  int n_workspace_names, n_names;
+  gboolean changed = FALSE;
 
-  if (bindings[i].name)
-    return update_list_binding (&bindings[i], value, META_LIST_OF_GCONFVALUE_STRINGS);
-  else
-    return FALSE;
-}
+  names = g_settings_get_strv (SETTINGS (SCHEMA_GENERAL), KEY_WORKSPACE_NAMES);
+  n_names = g_strv_length (names);
+  n_workspace_names = workspace_names ? g_strv_length (workspace_names) : 0;
 
-static gboolean
-update_key_list_binding (const char *name,
-                            GSList *value)
-{
-  return find_and_update_list_binding (key_bindings, name, value);
-}
+  for (i = 0; i < n_names; i++)
+    if (n_workspace_names < i + 1 || !workspace_names[i] ||
+        g_strcmp0 (names[i], workspace_names[i]) != 0)
+      {
+        changed = TRUE;
+        break;
+      }
 
-static gboolean
-update_command (const char  *name,
-                const char  *value)
-{
-  char *p;
-  int i;
-  
-  p = strrchr (name, '_');
-  if (p == NULL)
-    {
-      meta_topic (META_DEBUG_KEYBINDINGS,
-                  "Command %s has no underscore?\n", name);
-      return FALSE;
-    }
-  
-  ++p;
+  if (n_workspace_names != n_names)
+    changed = TRUE;
 
-  if (g_ascii_isdigit (*p))
+  if (changed)
     {
-      i = atoi (p);
-      i -= 1; /* count from 0 not 1 */
+      if (workspace_names)
+        g_strfreev (workspace_names);
+      workspace_names = names;
     }
   else
     {
-      p = strrchr (name, '/');
-      ++p;
-
-      if (strcmp (p, "command_screenshot") == 0)
-        {
-          i = SCREENSHOT_COMMAND_IDX;
-        }
-      else if (strcmp (p, "command_window_screenshot") == 0)
-        {
-          i = WIN_SCREENSHOT_COMMAND_IDX;
-        }
-      else
-        {
-          meta_topic (META_DEBUG_KEYBINDINGS,
-                      "Command %s doesn't end in number?\n", name);
-          return FALSE;
-        }
-    }
-  
-  if (i >= MAX_COMMANDS)
-    {
-      meta_topic (META_DEBUG_KEYBINDINGS,
-                  "Command %d is too highly numbered, ignoring\n", i);
-      return FALSE;
-    }
-
-  if ((commands[i] == NULL && value == NULL) ||
-      (commands[i] && value && strcmp (commands[i], value) == 0))
-    {
-      meta_topic (META_DEBUG_KEYBINDINGS,
-                  "Command %d is unchanged\n", i);
-      return FALSE;
-    }
-  
-  g_free (commands[i]);
-  commands[i] = g_strdup (value);
-
-  meta_topic (META_DEBUG_KEYBINDINGS,
-              "Updated command %d to \"%s\"\n",
-              i, commands[i] ? commands[i] : "none");
-  
-  return TRUE;
-}
-
-#endif /* HAVE_GCONF */
-
-const char*
-meta_prefs_get_command (int i)
-{
-  g_return_val_if_fail (i >= 0 && i < MAX_COMMANDS, NULL);
-  
-  return commands[i];
-}
-
-char*
-meta_prefs_get_gconf_key_for_command (int i)
-{
-  char *key;
-
-  switch (i)
-    {
-    case SCREENSHOT_COMMAND_IDX:
-      key = g_strdup (KEY_COMMAND_PREFIX "screenshot");
-      break;
-    case WIN_SCREENSHOT_COMMAND_IDX:
-      key = g_strdup (KEY_COMMAND_PREFIX "window_screenshot");
-      break;
-    default:
-      key = g_strdup_printf (KEY_COMMAND_PREFIX"%d", i + 1);
-      break;
+      g_strfreev (names);
     }
-  
-  return key;
-}
 
-const char*
-meta_prefs_get_terminal_command (void)
-{
-  return terminal_command;
+  return changed;
 }
 
 const char*
-meta_prefs_get_gconf_key_for_terminal_command (void)
-{
-  return KEY_TERMINAL_COMMAND;
-}
-
-#ifdef HAVE_GCONF
-static gboolean
-update_workspace_name (const char  *name,
-                       const char  *value)
+meta_prefs_get_workspace_name (int i)
 {
-  char *p;
-  int i;
-  
-  p = strrchr (name, '_');
-  if (p == NULL)
-    {
-      meta_topic (META_DEBUG_PREFS,
-                  "Workspace name %s has no underscore?\n", name);
-      return FALSE;
-    }
-  
-  ++p;
+  const char *name;
 
-  if (!g_ascii_isdigit (*p))
-    {
-      meta_topic (META_DEBUG_PREFS,
-                  "Workspace name %s doesn't end in number?\n", name);
-      return FALSE;
-    }
-  
-  i = atoi (p);
-  i -= 1; /* count from 0 not 1 */
-  
-  if (i >= MAX_REASONABLE_WORKSPACES)
-    {
-      meta_topic (META_DEBUG_PREFS,
-                  "Workspace name %d is too highly numbered, ignoring\n", i);
-      return FALSE;
-    }
+  g_return_val_if_fail (i >= 0, NULL);
 
-  if (workspace_names[i] && value && strcmp (workspace_names[i], value) == 0)
+  if (!workspace_names ||
+      g_strv_length (workspace_names) < (guint)i + 1 ||
+      !*workspace_names[i])
     {
-      meta_topic (META_DEBUG_PREFS,
-                  "Workspace name %d is unchanged\n", i);
-      return FALSE;
-    }  
-
-  /* This is a bad hack. We have to treat empty string as
-   * "unset" because the root window property can't contain
-   * null. So it gets empty string instead and we don't want
-   * that to result in setting the empty string as a value that
-   * overrides "unset".
-   */
-  if (value != NULL && *value != '\0')
-    {
-      g_free (workspace_names[i]);
-      workspace_names[i] = g_strdup (value);
+      char *generated_name = g_strdup_printf (_("Workspace %d"), i + 1);
+      name = g_intern_string (generated_name);
+      g_free (generated_name);
     }
   else
-    {
-      /* use a default name */
-      char *d;
+    name = workspace_names[i];
 
-      d = g_strdup_printf (_("Workspace %d"), i + 1);
-      if (workspace_names[i] && strcmp (workspace_names[i], d) == 0)
-        {
-          g_free (d);
-          return FALSE;
-        }
-      else
-        {
-          g_free (workspace_names[i]);
-          workspace_names[i] = d;
-        }
-    }
-  
   meta_topic (META_DEBUG_PREFS,
-              "Updated workspace name %d to \"%s\"\n",
-              i, workspace_names[i] ? workspace_names[i] : "none");
-  
-  return TRUE;
-}
-#endif /* HAVE_GCONF */
-
-const char*
-meta_prefs_get_workspace_name (int i)
-{
-  g_return_val_if_fail (i >= 0 && i < MAX_REASONABLE_WORKSPACES, NULL);
-
-  g_assert (workspace_names[i] != NULL);
+              "Getting name of workspace %d: \"%s\"\n", i, name);
 
-  meta_topic (META_DEBUG_PREFS,
-              "Getting workspace name for %d: \"%s\"\n",
-              i, workspace_names[i]);
-  
-  return workspace_names[i];
+  return name;
 }
 
 void
-meta_prefs_change_workspace_name (int         i,
+meta_prefs_change_workspace_name (int         num,
                                   const char *name)
 {
-#ifdef HAVE_GCONF
-  char *key;
-  GError *err;
+  GVariantBuilder builder;
+  int n_workspace_names, i;
   
-  g_return_if_fail (i >= 0 && i < MAX_REASONABLE_WORKSPACES);
+  g_return_if_fail (num >= 0);
 
   meta_topic (META_DEBUG_PREFS,
               "Changing name of workspace %d to %s\n",
-              i, name ? name : "none");
+              num, name ? name : "none");
 
-  /* This is a bad hack. We have to treat empty string as
-   * "unset" because the root window property can't contain
-   * null. So it gets empty string instead and we don't want
-   * that to result in setting the empty string as a value that
-   * overrides "unset".
-   */
-  if (name && *name == '\0')
-    name = NULL;
-  
-  if ((name == NULL && workspace_names[i] == NULL) ||
-      (name && workspace_names[i] && strcmp (name, workspace_names[i]) == 0))
+  /* NULL and empty string both mean "default" here,
+   * and we also need to match the name against its default value
+   * to avoid saving it literally. */
+  if (g_strcmp0 (name, meta_prefs_get_workspace_name (num)) == 0)
     {
-      meta_topic (META_DEBUG_PREFS,
-                  "Workspace %d already has name %s\n",
-                  i, name ? name : "none");
+      if (!name || !*name)
+        meta_topic (META_DEBUG_PREFS,
+                    "Workspace %d already uses default name\n", num);
+      else
+        meta_topic (META_DEBUG_PREFS,
+                    "Workspace %d already has name %s\n", num, name);
       return;
     }
-  
-  key = gconf_key_for_workspace_name (i);
 
-  err = NULL;
-  if (name != NULL)
-    gconf_client_set_string (default_client,
-                             key, name,
-                             &err);
-  else
-    gconf_client_unset (default_client,
-                        key, &err);
+  g_variant_builder_init (&builder, G_VARIANT_TYPE_STRING_ARRAY);
+  n_workspace_names = workspace_names ? g_strv_length (workspace_names) : 0;
 
-  
-  if (err)
+  for (i = 0; i < MAX (num + 1, n_workspace_names); i++)
     {
-      meta_warning (_("Error setting name for workspace %d to \"%s\": %s\n"),
-                    i, name ? name : "none",
-                    err->message);
-      g_error_free (err);
-    }
-  
-  g_free (key);
-#else
-  g_free (workspace_names[i]);
-  workspace_names[i] = g_strdup (name);
-#endif /* HAVE_GCONF */
-}
+      const char *value;
 
-#ifdef HAVE_GCONF
-static char*
-gconf_key_for_workspace_name (int i)
-{
-  char *key;
-  
-  key = g_strdup_printf (KEY_WORKSPACE_NAME_PREFIX"%d", i + 1);
-  
-  return key;
+      if (i == num)
+        value = name ? name : "";
+      else if (i < n_workspace_names)
+        value = workspace_names[i] ? workspace_names[i] : "";
+      else
+        value = "";
+
+      g_variant_builder_add (&builder, "s", value);
+    }
+  g_settings_set_value (SETTINGS (SCHEMA_GENERAL), KEY_WORKSPACE_NAMES,
+                        g_variant_builder_end (&builder));
 }
-#endif /* HAVE_GCONF */
 
 void
 meta_prefs_get_button_layout (MetaButtonLayout *button_layout_p)
@@ -2571,18 +1656,12 @@ meta_prefs_get_button_layout (MetaButtonLayout *button_layout_p)
 }
 
 gboolean
-meta_prefs_get_visual_bell (void)
-{
-  return provide_visual_bell;
-}
-
-gboolean
 meta_prefs_bell_is_audible (void)
 {
   return bell_is_audible;
 }
 
-MetaVisualBellType
+GDesktopVisualBellType
 meta_prefs_get_visual_bell_type (void)
 {
   return visual_bell_type;
@@ -2597,19 +1676,19 @@ meta_prefs_get_key_bindings (const MetaKeyPref **bindings,
   *n_bindings = (int) G_N_ELEMENTS (key_bindings) - 1;
 }
 
-MetaActionTitlebar
+GDesktopTitlebarAction
 meta_prefs_get_action_double_click_titlebar (void)
 {
   return action_double_click_titlebar;
 }
 
-MetaActionTitlebar
+GDesktopTitlebarAction
 meta_prefs_get_action_middle_click_titlebar (void)
 {
   return action_middle_click_titlebar;
 }
 
-MetaActionTitlebar
+GDesktopTitlebarAction
 meta_prefs_get_action_right_click_titlebar (void)
 {
   return action_right_click_titlebar;
@@ -2733,64 +1812,9 @@ meta_prefs_get_force_fullscreen (void)
 void
 meta_prefs_set_compositing_manager (gboolean whether)
 {
-#ifdef HAVE_GCONF
-  GError *err = NULL;
-
-  gconf_client_set_bool (default_client,
-                         KEY_COMPOSITOR,
-                         whether,
-                         &err);
-
-  if (err)
-    {
-      meta_warning (_("Error setting compositor status: %s\n"),
-                    err->message);
-      g_error_free (err);
-    }
-#else
-  compositing_manager = whether;
-#endif
+  g_settings_set_boolean (SETTINGS (SCHEMA_METACITY), KEY_COMPOSITOR, whether);
 }
 
-#ifndef HAVE_GCONF
-static void
-init_button_layout(void)
-{
-  MetaButtonLayout button_layout_ltr = {
-    {    
-      /* buttons in the group on the left side */
-      META_BUTTON_FUNCTION_MENU,
-      META_BUTTON_FUNCTION_LAST
-    },
-    {
-      /* buttons in the group on the right side */
-      META_BUTTON_FUNCTION_MINIMIZE,
-      META_BUTTON_FUNCTION_MAXIMIZE,
-      META_BUTTON_FUNCTION_CLOSE,
-      META_BUTTON_FUNCTION_LAST
-    }
-  };
-  MetaButtonLayout button_layout_rtl = {
-    {    
-      /* buttons in the group on the left side */
-      META_BUTTON_FUNCTION_CLOSE,
-      META_BUTTON_FUNCTION_MAXIMIZE,
-      META_BUTTON_FUNCTION_MINIMIZE,
-      META_BUTTON_FUNCTION_LAST
-    },
-    {
-      /* buttons in the group on the right side */
-      META_BUTTON_FUNCTION_MENU,
-      META_BUTTON_FUNCTION_LAST
-    }
-  };
-
-  button_layout = meta_ui_get_direction() == META_UI_DIRECTION_LTR ?
-    button_layout_ltr : button_layout_rtl;
-};
-
-#endif
-
 void
 meta_prefs_set_force_fullscreen (gboolean whether)
 {
diff --git a/src/core/screen.c b/src/core/screen.c
index f202947..34dcdc3 100644
--- a/src/core/screen.c
+++ b/src/core/screen.c
@@ -848,7 +848,7 @@ prefs_changed_callback (MetaPreference pref,
   
   if (pref == META_PREF_NUM_WORKSPACES)
     {
-      /* GConf doesn't provide timestamps, but luckily update_num_workspaces
+      /* GSettings doesn't provide timestamps, but luckily update_num_workspaces
        * often doesn't need it...
        */
       guint32 timestamp = 
diff --git a/src/core/window.c b/src/core/window.c
index 7e3d33e..2f2f800 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -1667,7 +1667,7 @@ idle_calc_showing (gpointer data)
       tmp = tmp->next;
     }
 
-  if (meta_prefs_get_focus_mode () != META_FOCUS_MODE_CLICK)
+  if (meta_prefs_get_focus_mode () != G_DESKTOP_FOCUS_MODE_CLICK)
     {
       /* When display->mouse_mode is false, we want to ignore
        * EnterNotify events unless they come from mouse motion.  To do
@@ -2004,7 +2004,7 @@ window_state_on_map (MetaWindow *window,
    * approximation to enforce so we do that.
    */
   if (*takes_focus &&
-      meta_prefs_get_focus_new_windows () == META_FOCUS_NEW_WINDOWS_STRICT &&
+      meta_prefs_get_focus_new_windows () == G_DESKTOP_FOCUS_NEW_WINDOWS_STRICT &&
       !window->display->allow_terminal_deactivation &&
       __window_is_terminal (window->display->focus_window) &&
       !meta_window_is_ancestor_of_transient (window->display->focus_window,
@@ -2221,7 +2221,7 @@ meta_window_show (MetaWindow *window)
        * that new window below a lot of other windows.
        */
       if (overlap || 
-          (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK &&
+          (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK &&
            meta_prefs_get_raise_on_click ()))
         meta_window_stack_just_below (window, focus_window);
 
@@ -5447,7 +5447,7 @@ meta_window_notify_focus (MetaWindow *window,
            *
            * There is dicussion in bugs 102209, 115072, and 461577
            */
-          if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK ||
+          if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK ||
               !meta_prefs_get_raise_on_click())
             meta_display_ungrab_focus_window_button (window->display, window);
         }
@@ -5491,7 +5491,7 @@ meta_window_notify_focus (MetaWindow *window,
           meta_window_update_layer (window);
 
           /* Re-grab for click to focus and raise-on-click, if necessary */
-          if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK ||
+          if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK ||
               !meta_prefs_get_raise_on_click ())
             meta_display_grab_focus_window_button (window->display, window);
        }
@@ -8138,7 +8138,7 @@ meta_window_set_user_time (MetaWindow *window,
        * doesn't want to have focus transferred for now due to new windows.
        */
       if (meta_prefs_get_focus_new_windows () ==
-               META_FOCUS_NEW_WINDOWS_STRICT &&
+               G_DESKTOP_FOCUS_NEW_WINDOWS_STRICT &&
           __window_is_terminal (window))
         window->display->allow_terminal_deactivation = FALSE;
     }
diff --git a/src/core/workspace.c b/src/core/workspace.c
index 12798a5..e877b19 100644
--- a/src/core/workspace.c
+++ b/src/core/workspace.c
@@ -888,7 +888,7 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace,
     }
 
 
-  if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK ||
+  if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK ||
       !workspace->screen->display->mouse_mode)
     focus_ancestor_or_mru_window (workspace, not_this_one, timestamp);
   else
@@ -926,9 +926,9 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace,
                                                      window);
             }
         }
-      else if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_SLOPPY)
+      else if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_SLOPPY)
         focus_ancestor_or_mru_window (workspace, not_this_one, timestamp);
-      else if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_MOUSE)
+      else if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_MOUSE)
         {
           meta_topic (META_DEBUG_FOCUS,
                       "Setting focus to no_focus_window, since no valid "
@@ -984,7 +984,7 @@ focus_ancestor_or_mru_window (MetaWorkspace *workspace,
           meta_window_focus (ancestor, timestamp);
 
           /* Also raise the window if in click-to-focus */
-          if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK)
+          if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
             meta_window_raise (ancestor);
 
           return;
@@ -1030,7 +1030,7 @@ focus_ancestor_or_mru_window (MetaWorkspace *workspace,
       meta_window_focus (window, timestamp);
 
       /* Also raise the window if in click-to-focus */
-      if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK)
+      if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
         meta_window_raise (window);
     }
   else
diff --git a/src/include/all-keybindings.h b/src/include/all-keybindings.h
index 9d3540a..f1aa02d 100644
--- a/src/include/all-keybindings.h
+++ b/src/include/all-keybindings.h
@@ -55,12 +55,6 @@
  *                             explain this better)
  *      or 0 if no flag applies.
  *
- *   5) a string representing the default binding.
- *          If this is NULL, the action is unbound by default.
- *          Please use NULL and not "disabled".
- *   6) a short description.
- *          It must be marked translatable (i.e. inside "_(...)").
- *
  * Don't try to do XML entity escaping anywhere in the strings.
  */
 
@@ -84,30 +78,18 @@
 /* convenience, since in this file they must always be set together */
 #define REVERSES_AND_REVERSED (BINDING_REVERSES | BINDING_IS_REVERSED)
 
-keybind (switch_to_workspace_1,  handle_switch_to_workspace, 0, 0, NULL,
-        _("Switch to workspace 1"))
-keybind (switch_to_workspace_2,  handle_switch_to_workspace, 1, 0, NULL,
-        _("Switch to workspace 2"))
-keybind (switch_to_workspace_3,  handle_switch_to_workspace, 2, 0, NULL,
-        _("Switch to workspace 3"))
-keybind (switch_to_workspace_4,  handle_switch_to_workspace, 3, 0, NULL,
-        _("Switch to workspace 4"))
-keybind (switch_to_workspace_5,  handle_switch_to_workspace, 4, 0, NULL,
-        _("Switch to workspace 5"))
-keybind (switch_to_workspace_6,  handle_switch_to_workspace, 5, 0, NULL,
-        _("Switch to workspace 6"))
-keybind (switch_to_workspace_7,  handle_switch_to_workspace, 6, 0, NULL,
-        _("Switch to workspace 7"))
-keybind (switch_to_workspace_8,  handle_switch_to_workspace, 7, 0, NULL,
-        _("Switch to workspace 8"))
-keybind (switch_to_workspace_9,  handle_switch_to_workspace, 8, 0, NULL,
-        _("Switch to workspace 9"))
-keybind (switch_to_workspace_10, handle_switch_to_workspace, 9, 0, NULL,
-        _("Switch to workspace 10"))
-keybind (switch_to_workspace_11, handle_switch_to_workspace, 10, 0, NULL,
-        _("Switch to workspace 11"))
-keybind (switch_to_workspace_12, handle_switch_to_workspace, 11, 0, NULL,
-        _("Switch to workspace 12"))
+keybind (switch-to-workspace-1,  handle_switch_to_workspace, 0, 0)
+keybind (switch-to-workspace-2,  handle_switch_to_workspace, 1, 0)
+keybind (switch-to-workspace-3,  handle_switch_to_workspace, 2, 0)
+keybind (switch-to-workspace-4,  handle_switch_to_workspace, 3, 0)
+keybind (switch-to-workspace-5,  handle_switch_to_workspace, 4, 0)
+keybind (switch-to-workspace-6,  handle_switch_to_workspace, 5, 0)
+keybind (switch-to-workspace-7,  handle_switch_to_workspace, 6, 0)
+keybind (switch-to-workspace-8,  handle_switch_to_workspace, 7, 0)
+keybind (switch-to-workspace-9,  handle_switch_to_workspace, 8, 0)
+keybind (switch-to-workspace-10, handle_switch_to_workspace, 9, 0)
+keybind (switch-to-workspace-11, handle_switch_to_workspace, 10, 0)
+keybind (switch-to-workspace-12, handle_switch_to_workspace, 11, 0)
 
 /* META_MOTION_* are negative, and so distinct from workspace numbers,
  * which are always zero or positive.
@@ -117,21 +99,17 @@ keybind (switch_to_workspace_12, handle_switch_to_workspace, 11, 0, NULL,
  * workspace.h, of course.
  */
 
-keybind (switch_to_workspace_left, handle_switch_to_workspace,
-         META_MOTION_LEFT, 0, "<Control><Alt>Left",
-        _("Move to workspace left"))
+keybind (switch-to-workspace-left, handle_switch_to_workspace,
+         META_MOTION_LEFT, 0)
 
-keybind (switch_to_workspace_right, handle_switch_to_workspace,
-         META_MOTION_RIGHT, 0, "<Control><Alt>Right",
-        _("Move to workspace right"))
+keybind (switch-to-workspace-right, handle_switch_to_workspace,
+         META_MOTION_RIGHT, 0)
 
-keybind (switch_to_workspace_up, handle_switch_to_workspace,
-         META_MOTION_UP, 0, "<Control><Alt>Up",
-        _("Move to workspace above"))
+keybind (switch-to-workspace-up, handle_switch_to_workspace,
+         META_MOTION_UP, 0)
 
-keybind (switch_to_workspace_down, handle_switch_to_workspace,
-         META_MOTION_DOWN, 0, "<Control><Alt>Down",
-        _("Move to workspace below"))
+keybind (switch-to-workspace-down, handle_switch_to_workspace,
+         META_MOTION_DOWN, 0)
 
 /***********************************/
 
@@ -145,102 +123,36 @@ keybind (switch_to_workspace_down, handle_switch_to_workspace,
  * same function checking a bit in the parameter for difference.
  */
 
-keybind (switch_group,              handle_switch,        META_TAB_LIST_GROUP,
-         BINDING_REVERSES,       "<Alt>Above_Tab",
-        _("Switch windows of an application"))
-keybind (switch_group_backward,    handle_switch,        META_TAB_LIST_GROUP,
-         REVERSES_AND_REVERSED,  NULL,
-         _("Reverse switch windows of an application"))
-keybind (switch_windows,            handle_switch,        META_TAB_LIST_NORMAL,
-         BINDING_REVERSES,       "<Alt>Tab",
-        _("Switch applications"))
-keybind (switch_windows_backward,  handle_switch,        META_TAB_LIST_NORMAL,
-         REVERSES_AND_REVERSED,  NULL,
-        _("Reverse switch applications"))
-keybind (switch_panels,             handle_switch,        META_TAB_LIST_DOCKS,
-         BINDING_REVERSES,       "<Control><Alt>Tab",
-        _("Switch system controls"))
-keybind (switch_panels_backward,   handle_switch,        META_TAB_LIST_DOCKS,
-         REVERSES_AND_REVERSED,  NULL,
-         _("Reverse switch system controls"))
-
-keybind (cycle_group,               handle_cycle,         META_TAB_LIST_GROUP,
-        BINDING_REVERSES,        "<Alt>F6",
-        _("Switch windows of an app directly"))
-keybind (cycle_group_backward,     handle_cycle,         META_TAB_LIST_GROUP,
-        REVERSES_AND_REVERSED,   NULL,
-        _("Reverse switch windows of an app directly"))
-keybind (cycle_windows,             handle_cycle,         META_TAB_LIST_NORMAL,
-        BINDING_REVERSES,        "<Alt>Escape",
-        _("Switch windows directly"))
-keybind (cycle_windows_backward,   handle_cycle,         META_TAB_LIST_NORMAL,
-        REVERSES_AND_REVERSED,   NULL,
-        _("Reverse switch windows directly"))
-keybind (cycle_panels,              handle_cycle,         META_TAB_LIST_DOCKS,
-        BINDING_REVERSES,        "<Control><Alt>Escape",
-        _("Switch system controls directly"))
-keybind (cycle_panels_backward,    handle_cycle,         META_TAB_LIST_DOCKS,
-        REVERSES_AND_REVERSED,   NULL,
-        _("Reverse switch system controls directly"))
+keybind (switch-group, handle_switch, META_TAB_LIST_GROUP, BINDING_REVERSES)
+keybind (switch-group-backward, handle_switch, META_TAB_LIST_GROUP,
+         REVERSES_AND_REVERSED)
+keybind (switch-windows, handle_switch, META_TAB_LIST_NORMAL, BINDING_REVERSES)
+keybind (switch-windows-backward, handle_switch, META_TAB_LIST_NORMAL,
+         REVERSES_AND_REVERSED)
+keybind (switch-panels, handle_switch, META_TAB_LIST_DOCKS, BINDING_REVERSES)
+keybind (switch-panels-backward, handle_switch, META_TAB_LIST_DOCKS,
+         REVERSES_AND_REVERSED)
+
+keybind (cycle-group, handle_cycle, META_TAB_LIST_GROUP, BINDING_REVERSES)
+keybind (cycle-group-backward, handle_cycle, META_TAB_LIST_GROUP,
+        REVERSES_AND_REVERSED)
+keybind (cycle-windows, handle_cycle, META_TAB_LIST_NORMAL, BINDING_REVERSES)
+keybind (cycle-windows-backward, handle_cycle, META_TAB_LIST_NORMAL,
+        REVERSES_AND_REVERSED)
+keybind (cycle-panels, handle_cycle, META_TAB_LIST_DOCKS, BINDING_REVERSES)
+keybind (cycle-panels-backward, handle_cycle, META_TAB_LIST_DOCKS,
+        REVERSES_AND_REVERSED)
 
 /***********************************/
 
-keybind (show_desktop, handle_show_desktop, 0, 0, NULL,
-      _("Hide all normal windows"))
-keybind (panel_main_menu, handle_panel,
-       META_KEYBINDING_ACTION_PANEL_MAIN_MENU, 0, "<Alt>F1",
-      _("Show the activities overview"))
-keybind (panel_run_dialog, handle_panel,
-       META_KEYBINDING_ACTION_PANEL_RUN_DIALOG, 0, "<Alt>F2",
-      _("Show the run command prompt"))
-
-/* Yes, the param is offset by one.  Historical reasons.  (Maybe worth fixing
- * at some point.)  The description is NULL here because the stanza is
- * irregularly shaped in metacity.schemas.in.  This will probably be fixed
- * as well.
- */
-keybind (run_command_1,  handle_run_command,  0, 0, NULL, NULL)
-keybind (run_command_2,  handle_run_command,  1, 0, NULL, NULL)
-keybind (run_command_3,  handle_run_command,  2, 0, NULL, NULL)
-keybind (run_command_4,  handle_run_command,  3, 0, NULL, NULL)
-keybind (run_command_5,  handle_run_command,  4, 0, NULL, NULL)
-keybind (run_command_6,  handle_run_command,  5, 0, NULL, NULL)
-keybind (run_command_7,  handle_run_command,  6, 0, NULL, NULL)
-keybind (run_command_8,  handle_run_command,  7, 0, NULL, NULL)
-keybind (run_command_9,  handle_run_command,  8, 0, NULL, NULL)
-keybind (run_command_10, handle_run_command,  9, 0, NULL, NULL)
-keybind (run_command_11, handle_run_command, 10, 0, NULL, NULL)
-keybind (run_command_12, handle_run_command, 11, 0, NULL, NULL)
-keybind (run_command_13, handle_run_command, 12, 0, NULL, NULL)
-keybind (run_command_14, handle_run_command, 13, 0, NULL, NULL)
-keybind (run_command_15, handle_run_command, 14, 0, NULL, NULL)
-keybind (run_command_16, handle_run_command, 15, 0, NULL, NULL)
-keybind (run_command_17, handle_run_command, 16, 0, NULL, NULL)
-keybind (run_command_18, handle_run_command, 17, 0, NULL, NULL)
-keybind (run_command_19, handle_run_command, 18, 0, NULL, NULL)
-keybind (run_command_20, handle_run_command, 19, 0, NULL, NULL)
-keybind (run_command_21, handle_run_command, 20, 0, NULL, NULL)
-keybind (run_command_22, handle_run_command, 21, 0, NULL, NULL)
-keybind (run_command_23, handle_run_command, 22, 0, NULL, NULL)
-keybind (run_command_24, handle_run_command, 23, 0, NULL, NULL)
-keybind (run_command_25, handle_run_command, 24, 0, NULL, NULL)
-keybind (run_command_26, handle_run_command, 25, 0, NULL, NULL)
-keybind (run_command_27, handle_run_command, 26, 0, NULL, NULL)
-keybind (run_command_28, handle_run_command, 27, 0, NULL, NULL)
-keybind (run_command_29, handle_run_command, 28, 0, NULL, NULL)
-keybind (run_command_30, handle_run_command, 29, 0, NULL, NULL)
-keybind (run_command_31, handle_run_command, 30, 0, NULL, NULL)
-keybind (run_command_32, handle_run_command, 31, 0, NULL, NULL)
-
-keybind (run_command_screenshot, handle_run_command, 32, 0, "Print",
-      _("Take a screenshot"))
-keybind (run_command_window_screenshot, handle_run_command, 33, 0,"<Alt>Print",
-      _("Take a screenshot of a window"))
-
-keybind (run_command_terminal, handle_run_terminal, 0, 0, NULL, _("Launch Terminal"))
-
-/* No description because this is undocumented */
-keybind (set_spew_mark, handle_set_spew_mark, 0, 0, NULL, NULL)
+keybind (show-desktop, handle_show_desktop, 0, 0)
+keybind (panel-main-menu, handle_panel,
+       META_KEYBINDING_ACTION_PANEL_MAIN_MENU, 0)
+keybind (panel-run-dialog, handle_panel,
+       META_KEYBINDING_ACTION_PANEL_RUN_DIALOG, 0)
+
+/* FIXME: No description because this is undocumented */
+keybind (set-spew-mark, handle_set_spew_mark, 0, 0)
 
 #undef REVERSES_AND_REVERSED
 
@@ -250,70 +162,33 @@ keybind (set_spew_mark, handle_set_spew_mark, 0, 0, NULL, NULL)
  * if no window is active.
  */
 
-keybind (activate_window_menu, handle_activate_window_menu, 0,
-        BINDING_PER_WINDOW, "<Alt>space",
-        _("Activate the window menu"))
-keybind (toggle_fullscreen, handle_toggle_fullscreen, 0, BINDING_PER_WINDOW,
-        NULL,
-        _("Toggle fullscreen mode"))
-keybind (toggle_maximized, handle_toggle_maximized, 0, BINDING_PER_WINDOW, "<Alt>F10",
-        _("Toggle maximization state"))
-keybind (toggle_above, handle_toggle_above, 0, BINDING_PER_WINDOW, NULL,
-        _("Toggle window always appearing on top"))
-keybind (maximize, handle_maximize, 0, BINDING_PER_WINDOW, NULL,
-        _("Maximize window"))
-keybind (unmaximize, handle_unmaximize, 0, BINDING_PER_WINDOW, "<Alt>F5",
-        _("Restore window"))
-keybind (toggle_shaded, handle_toggle_shaded, 0, BINDING_PER_WINDOW, NULL,
-        _("Toggle shaded state"))
-keybind (minimize, handle_minimize, 0, BINDING_PER_WINDOW, NULL,
-        _("Minimize window"))
-keybind (close, handle_close, 0, BINDING_PER_WINDOW, "<Alt>F4",
-        _("Close window"))
-keybind (begin_move, handle_begin_move, 0, BINDING_PER_WINDOW, "<Alt>F7",
-        _("Move window"))
-keybind (begin_resize, handle_begin_resize, 0, BINDING_PER_WINDOW, "<Alt>F8",
-        _("Resize window"))
-keybind (toggle_on_all_workspaces, handle_toggle_on_all_workspaces, 0,
-         BINDING_PER_WINDOW, NULL,
-        _("Toggle window on all workspaces or one"))
-
-keybind (move_to_workspace_1, handle_move_to_workspace, 0, BINDING_PER_WINDOW,
-        NULL,
-        _("Move window to workspace 1"))
-keybind (move_to_workspace_2, handle_move_to_workspace, 1, BINDING_PER_WINDOW,
-        NULL,
-        _("Move window to workspace 2"))
-keybind (move_to_workspace_3, handle_move_to_workspace, 2, BINDING_PER_WINDOW,
-        NULL,
-        _("Move window to workspace 3"))
-keybind (move_to_workspace_4, handle_move_to_workspace, 3, BINDING_PER_WINDOW,
-        NULL,
-        _("Move window to workspace 4"))
-keybind (move_to_workspace_5, handle_move_to_workspace, 4, BINDING_PER_WINDOW,
-        NULL,
-        _("Move window to workspace 5"))
-keybind (move_to_workspace_6, handle_move_to_workspace, 5, BINDING_PER_WINDOW,
-        NULL,
-        _("Move window to workspace 6"))
-keybind (move_to_workspace_7, handle_move_to_workspace, 6, BINDING_PER_WINDOW,
-        NULL,
-        _("Move window to workspace 7"))
-keybind (move_to_workspace_8, handle_move_to_workspace, 7, BINDING_PER_WINDOW,
-        NULL,
-        _("Move window to workspace 8"))
-keybind (move_to_workspace_9, handle_move_to_workspace, 8, BINDING_PER_WINDOW,
-        NULL,
-        _("Move window to workspace 9"))
-keybind (move_to_workspace_10, handle_move_to_workspace, 9, BINDING_PER_WINDOW,
-        NULL,
-        _("Move window to workspace 10"))
-keybind (move_to_workspace_11, handle_move_to_workspace, 10, BINDING_PER_WINDOW,
-        NULL,
-        _("Move window to workspace 11"))
-keybind (move_to_workspace_12, handle_move_to_workspace, 11, BINDING_PER_WINDOW,
-        NULL,
-        _("Move window to workspace 12"))
+keybind (activate-window-menu, handle_activate_window_menu, 0,
+        BINDING_PER_WINDOW)
+keybind (toggle-fullscreen, handle_toggle_fullscreen, 0, BINDING_PER_WINDOW)
+keybind (toggle-maximized, handle_toggle_maximized, 0, BINDING_PER_WINDOW)
+keybind (toggle-above, handle_toggle_above, 0, BINDING_PER_WINDOW)
+keybind (maximize, handle_maximize, 0, BINDING_PER_WINDOW)
+keybind (unmaximize, handle_unmaximize, 0, BINDING_PER_WINDOW)
+keybind (toggle-shaded, handle_toggle_shaded, 0, BINDING_PER_WINDOW)
+keybind (minimize, handle_minimize, 0, BINDING_PER_WINDOW)
+keybind (close, handle_close, 0, BINDING_PER_WINDOW)
+keybind (begin-move, handle_begin_move, 0, BINDING_PER_WINDOW)
+keybind (begin-resize, handle_begin_resize, 0, BINDING_PER_WINDOW)
+keybind (toggle-on-all-workspaces, handle_toggle_on_all_workspaces, 0,
+         BINDING_PER_WINDOW)
+
+keybind (move-to-workspace-1, handle_move_to_workspace, 0, BINDING_PER_WINDOW)
+keybind (move-to-workspace-2, handle_move_to_workspace, 1, BINDING_PER_WINDOW)
+keybind (move-to-workspace-3, handle_move_to_workspace, 2, BINDING_PER_WINDOW)
+keybind (move-to-workspace-4, handle_move_to_workspace, 3, BINDING_PER_WINDOW)
+keybind (move-to-workspace-5, handle_move_to_workspace, 4, BINDING_PER_WINDOW)
+keybind (move-to-workspace-6, handle_move_to_workspace, 5, BINDING_PER_WINDOW)
+keybind (move-to-workspace-7, handle_move_to_workspace, 6, BINDING_PER_WINDOW)
+keybind (move-to-workspace-8, handle_move_to_workspace, 7, BINDING_PER_WINDOW)
+keybind (move-to-workspace-9, handle_move_to_workspace, 8, BINDING_PER_WINDOW)
+keybind (move-to-workspace-10, handle_move_to_workspace, 9, BINDING_PER_WINDOW)
+keybind (move-to-workspace-11, handle_move_to_workspace, 10, BINDING_PER_WINDOW)
+keybind (move-to-workspace-12, handle_move_to_workspace, 11, BINDING_PER_WINDOW)
 
 /* META_MOTION_* are negative, and so distinct from workspace numbers,
  * which are always zero or positive.
@@ -323,62 +198,34 @@ keybind (move_to_workspace_12, handle_move_to_workspace, 11, BINDING_PER_WINDOW,
  * workspace.h, of course.
  */
 
-keybind (move_to_workspace_left, handle_move_to_workspace,
-         META_MOTION_LEFT, BINDING_PER_WINDOW, "<Control><Shift><Alt>Left",
-        _("Move window one workspace to the left"))
-keybind (move_to_workspace_right, handle_move_to_workspace,
-         META_MOTION_RIGHT, BINDING_PER_WINDOW, "<Control><Shift><Alt>Right",
-        _("Move window one workspace to the right"))
-keybind (move_to_workspace_up, handle_move_to_workspace,
-         META_MOTION_UP, BINDING_PER_WINDOW, "<Control><Shift><Alt>Up",
-        _("Move window one workspace up"))
-keybind (move_to_workspace_down, handle_move_to_workspace,
-         META_MOTION_DOWN, BINDING_PER_WINDOW, "<Control><Shift><Alt>Down",
-        _("Move window one workspace down"))
-
-keybind (raise_or_lower, handle_raise_or_lower, 0, BINDING_PER_WINDOW, NULL,
-        _("Raise window if covered, otherwise lower it"))
-keybind (raise, handle_raise, 0, BINDING_PER_WINDOW, NULL,
-        _("Raise window above other windows"))
-keybind (lower, handle_lower, 0, BINDING_PER_WINDOW, NULL,
-        _("Lower window below other windows"))
-
-keybind (maximize_vertically, handle_maximize_vertically, 0,
-        BINDING_PER_WINDOW, NULL,
-        _("Maximize window vertically"))
-
-keybind (maximize_horizontally, handle_maximize_horizontally, 0,
-        BINDING_PER_WINDOW, NULL,
-        _("Maximize window horizontally"))
-
-keybind (move_to_corner_nw, handle_move_to_corner_nw, 0,
-        BINDING_PER_WINDOW, NULL,
-        _("Move window to top left corner"))
-keybind (move_to_corner_ne, handle_move_to_corner_ne, 0,
-        BINDING_PER_WINDOW, NULL,
-        _("Move window to top right corner"))
-keybind (move_to_corner_sw, handle_move_to_corner_sw, 0,
-        BINDING_PER_WINDOW, NULL,
-        _("Move window to bottom left corner"))
-keybind (move_to_corner_se, handle_move_to_corner_se, 0,
-        BINDING_PER_WINDOW, NULL,
-        _("Move window to bottom right corner"))
-
-keybind (move_to_side_n, handle_move_to_side_n, 0,
-        BINDING_PER_WINDOW, NULL,
-        _("Move window to top edge of screen"))
-keybind (move_to_side_s, handle_move_to_side_s, 0,
-        BINDING_PER_WINDOW, NULL,
-        _("Move window to bottom edge of screen"))
-keybind (move_to_side_e, handle_move_to_side_e, 0,
-        BINDING_PER_WINDOW, NULL,
-        _("Move window to right side of screen"))
-keybind (move_to_side_w, handle_move_to_side_w, 0,
-        BINDING_PER_WINDOW, NULL,
-        _("Move window to left side of screen"))
-keybind (move_to_center, handle_move_to_center, 0,
-        BINDING_PER_WINDOW, NULL,
-        _("Move window to center of screen"))
+keybind (move-to-workspace-left, handle_move_to_workspace,
+         META_MOTION_LEFT, BINDING_PER_WINDOW)
+keybind (move-to-workspace-right, handle_move_to_workspace,
+         META_MOTION_RIGHT, BINDING_PER_WINDOW)
+keybind (move-to-workspace-up, handle_move_to_workspace,
+         META_MOTION_UP, BINDING_PER_WINDOW)
+keybind (move-to-workspace-down, handle_move_to_workspace,
+         META_MOTION_DOWN, BINDING_PER_WINDOW)
+
+keybind (raise-or-lower, handle_raise_or_lower, 0, BINDING_PER_WINDOW)
+keybind (raise, handle_raise, 0, BINDING_PER_WINDOW)
+keybind (lower, handle_lower, 0, BINDING_PER_WINDOW)
+
+keybind (maximize-vertically, handle_maximize_vertically, 0, BINDING_PER_WINDOW)
+
+keybind (maximize-horizontally, handle_maximize_horizontally, 0,
+        BINDING_PER_WINDOW)
+
+keybind (move-to-corner-nw, handle_move_to_corner_nw, 0, BINDING_PER_WINDOW)
+keybind (move-to-corner-ne, handle_move_to_corner_ne, 0, BINDING_PER_WINDOW)
+keybind (move-to-corner-sw, handle_move_to_corner_sw, 0, BINDING_PER_WINDOW)
+keybind (move-to-corner-se, handle_move_to_corner_se, 0, BINDING_PER_WINDOW)
+
+keybind (move-to-side-n, handle_move_to_side_n, 0, BINDING_PER_WINDOW)
+keybind (move-to-side-s, handle_move_to_side_s, 0, BINDING_PER_WINDOW)
+keybind (move-to-side-e, handle_move_to_side_e, 0, BINDING_PER_WINDOW)
+keybind (move-to-side-w, handle_move_to_side_w, 0, BINDING_PER_WINDOW)
+keybind (move-to-center, handle_move_to_center, 0, BINDING_PER_WINDOW)
 
 /* eof all-keybindings.h */
 
diff --git a/src/include/common.h b/src/include/common.h
index de2dfff..4ce800b 100644
--- a/src/include/common.h
+++ b/src/include/common.h
@@ -1,6 +1,9 @@
 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 
-/* Metacity common types shared by core.h and ui.h */
+/* Metacity common types shared by core.h and ui.h
+ *
+ * PLEASE KEEP IN SYNC WITH GSETTINGS SCHEMAS!
+ */
 
 /* 
  * Copyright (C) 2001 Havoc Pennington
@@ -160,32 +163,6 @@ typedef enum
 
 typedef enum
 {
-  META_FOCUS_MODE_CLICK,
-  META_FOCUS_MODE_SLOPPY,
-  META_FOCUS_MODE_MOUSE
-} MetaFocusMode;
-
-typedef enum
-{
-  META_FOCUS_NEW_WINDOWS_SMART,
-  META_FOCUS_NEW_WINDOWS_STRICT
-} MetaFocusNewWindows;
-
-typedef enum
-{
-  META_ACTION_TITLEBAR_TOGGLE_SHADE,
-  META_ACTION_TITLEBAR_TOGGLE_MAXIMIZE,
-  META_ACTION_TITLEBAR_TOGGLE_MAXIMIZE_HORIZONTALLY,
-  META_ACTION_TITLEBAR_TOGGLE_MAXIMIZE_VERTICALLY,
-  META_ACTION_TITLEBAR_MINIMIZE,
-  META_ACTION_TITLEBAR_NONE,
-  META_ACTION_TITLEBAR_LOWER,
-  META_ACTION_TITLEBAR_MENU,
-  META_ACTION_TITLEBAR_LAST
-} MetaActionTitlebar;
-
-typedef enum
-{
   META_FRAME_TYPE_NORMAL,
   META_FRAME_TYPE_DIALOG,
   META_FRAME_TYPE_MODAL_DIALOG,
diff --git a/src/include/prefs.h b/src/include/prefs.h
index a4193ff..c9f31ec 100644
--- a/src/include/prefs.h
+++ b/src/include/prefs.h
@@ -28,7 +28,9 @@
 /* This header is a "common" one between the UI and core side */
 #include "common.h"
 #include <pango/pango-font.h>
+#include <gdesktop-enums.h>
 
+/* Keep in sync with GSettings schemas! */
 typedef enum
 {
   META_PREF_MOUSE_BUTTON_MODS,
@@ -46,8 +48,6 @@ typedef enum
   META_PREF_APPLICATION_BASED,
   META_PREF_KEYBINDINGS,
   META_PREF_DISABLE_WORKAROUNDS,
-  META_PREF_COMMANDS,
-  META_PREF_TERMINAL_COMMAND,
   META_PREF_BUTTON_LAYOUT,
   META_PREF_WORKSPACE_NAMES,
   META_PREF_VISUAL_BELL,
@@ -77,8 +77,8 @@ const char* meta_preference_to_string (MetaPreference pref);
 MetaVirtualModifier         meta_prefs_get_mouse_button_mods  (void);
 guint                       meta_prefs_get_mouse_button_resize (void);
 guint                       meta_prefs_get_mouse_button_menu  (void);
-MetaFocusMode               meta_prefs_get_focus_mode         (void);
-MetaFocusNewWindows         meta_prefs_get_focus_new_windows  (void);
+GDesktopFocusMode           meta_prefs_get_focus_mode         (void);
+GDesktopFocusNewWindows     meta_prefs_get_focus_new_windows  (void);
 gboolean                    meta_prefs_get_raise_on_click     (void);
 const char*                 meta_prefs_get_theme              (void);
 /* returns NULL if GTK default should be used */
@@ -92,19 +92,18 @@ gboolean                    meta_prefs_get_reduced_resources  (void);
 gboolean                    meta_prefs_get_gnome_accessibility (void);
 gboolean                    meta_prefs_get_gnome_animations   (void);
 
-const char*                 meta_prefs_get_command            (int i);
+const char*                 meta_prefs_get_screenshot_command (void);
 
-char*                       meta_prefs_get_gconf_key_for_command (int i);
+const char*                 meta_prefs_get_window_screenshot_command (void);
 
 const char*                 meta_prefs_get_terminal_command   (void);
-const char*                 meta_prefs_get_gconf_key_for_terminal_command (void);
 
 void                        meta_prefs_get_button_layout (MetaButtonLayout *button_layout);
 
 /* Double, right, middle click can be configured to any titlebar meta-action */
-MetaActionTitlebar          meta_prefs_get_action_double_click_titlebar (void);
-MetaActionTitlebar          meta_prefs_get_action_middle_click_titlebar (void);
-MetaActionTitlebar          meta_prefs_get_action_right_click_titlebar (void);
+GDesktopTitlebarAction       meta_prefs_get_action_double_click_titlebar (void);
+GDesktopTitlebarAction       meta_prefs_get_action_middle_click_titlebar (void);
+GDesktopTitlebarAction       meta_prefs_get_action_right_click_titlebar (void);
 
 void meta_prefs_set_num_workspaces (int n_workspaces);
 
@@ -165,18 +164,6 @@ typedef enum _MetaKeyBindingAction
   META_KEYBINDING_ACTION_SHOW_DESKTOP,
   META_KEYBINDING_ACTION_PANEL_MAIN_MENU,
   META_KEYBINDING_ACTION_PANEL_RUN_DIALOG,
-  META_KEYBINDING_ACTION_COMMAND_1,
-  META_KEYBINDING_ACTION_COMMAND_2,
-  META_KEYBINDING_ACTION_COMMAND_3,
-  META_KEYBINDING_ACTION_COMMAND_4,
-  META_KEYBINDING_ACTION_COMMAND_5,
-  META_KEYBINDING_ACTION_COMMAND_6,
-  META_KEYBINDING_ACTION_COMMAND_7,
-  META_KEYBINDING_ACTION_COMMAND_8,
-  META_KEYBINDING_ACTION_COMMAND_9,
-  META_KEYBINDING_ACTION_COMMAND_10,
-  META_KEYBINDING_ACTION_COMMAND_11,
-  META_KEYBINDING_ACTION_COMMAND_12
 } MetaKeyBindingAction;
 
 typedef struct
@@ -214,17 +201,8 @@ void meta_prefs_get_window_binding (const char          *name,
                                     unsigned int        *keysym,
                                     MetaVirtualModifier *modifiers);
 
-typedef enum
-{
-  META_VISUAL_BELL_INVALID = 0,
-  META_VISUAL_BELL_FULLSCREEN_FLASH,
-  META_VISUAL_BELL_FRAME_FLASH
-
-} MetaVisualBellType;
-
-gboolean           meta_prefs_get_visual_bell      (void);
 gboolean           meta_prefs_bell_is_audible      (void);
-MetaVisualBellType meta_prefs_get_visual_bell_type (void);
+GDesktopVisualBellType meta_prefs_get_visual_bell_type (void);
 
 #endif
 
diff --git a/src/metacity-schemas.convert b/src/metacity-schemas.convert
new file mode 100644
index 0000000..46f3104
--- /dev/null
+++ b/src/metacity-schemas.convert
@@ -0,0 +1,3 @@
+[org.gnome.metacity]
+compositing-manager = /apps/metacity/general/compositing_manager
+reduced-resources = /apps/metacity/general/reduced_resources
diff --git a/src/org.gnome.metacity.gschema.xml.in b/src/org.gnome.metacity.gschema.xml.in
new file mode 100644
index 0000000..8fcdd7c
--- /dev/null
+++ b/src/org.gnome.metacity.gschema.xml.in
@@ -0,0 +1,27 @@
+<schemalist>
+
+  <schema id="org.gnome.metacity" path="/org/gnome/metacity/"
+          gettext-domain="@GETTEXT_PACKAGE@">
+    <key name="compositing-manager" type="b">
+      <default>false</default>
+      <_summary>Compositing Manager</_summary>
+      <_description>
+        Determines whether Metacity is a compositing manager.
+      </_description>
+    </key>
+    <key name="reduced-resources" type="b">
+      <default>false</default>
+      <_summary>If true, trade off usability for less resource usage</_summary>
+      <_description>
+        If true, metacity will give the user less feedback by using wireframes,
+        avoiding animations, or other means.  This is a significant reduction
+        in usability for many users, but may allow legacy applications to
+        continue working, and may also be a useful tradeoff
+        for terminal servers.
+
+        However, the wireframe feature is disabled when accessibility is on.
+      </_description>
+    </key>
+  </schema>
+
+</schemalist>
diff --git a/src/ui/frames.c b/src/ui/frames.c
index a56fc8f..232994b 100644
--- a/src/ui/frames.c
+++ b/src/ui/frames.c
@@ -1259,7 +1259,7 @@ meta_frame_titlebar_event (MetaUIFrame    *frame,
   
   switch (action)
     {
-    case META_ACTION_TITLEBAR_TOGGLE_SHADE:
+    case G_DESKTOP_TITLEBAR_ACTION_TOGGLE_SHADE:
       {
         meta_core_get (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow,
                        META_CORE_GET_FRAME_FLAGS, &flags,
@@ -1279,7 +1279,7 @@ meta_frame_titlebar_event (MetaUIFrame    *frame,
       }
       break;          
       
-    case META_ACTION_TITLEBAR_TOGGLE_MAXIMIZE:
+    case G_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE:
       {
         meta_core_get (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow,
                        META_CORE_GET_FRAME_FLAGS, &flags,
@@ -1292,7 +1292,7 @@ meta_frame_titlebar_event (MetaUIFrame    *frame,
       }
       break;
 
-    case META_ACTION_TITLEBAR_TOGGLE_MAXIMIZE_HORIZONTALLY:
+    case G_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE_HORIZONTALLY:
       {
         meta_core_get (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow,
                        META_CORE_GET_FRAME_FLAGS, &flags,
@@ -1305,7 +1305,7 @@ meta_frame_titlebar_event (MetaUIFrame    *frame,
       }
       break;
 
-    case META_ACTION_TITLEBAR_TOGGLE_MAXIMIZE_VERTICALLY:
+    case G_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE_VERTICALLY:
       {
         meta_core_get (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow,
                        META_CORE_GET_FRAME_FLAGS, &flags,
@@ -1318,7 +1318,7 @@ meta_frame_titlebar_event (MetaUIFrame    *frame,
       }
       break;
 
-    case META_ACTION_TITLEBAR_MINIMIZE:
+    case G_DESKTOP_TITLEBAR_ACTION_MINIMIZE:
       {
         meta_core_get (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow,
                        META_CORE_GET_FRAME_FLAGS, &flags,
@@ -1331,17 +1331,17 @@ meta_frame_titlebar_event (MetaUIFrame    *frame,
       }
       break;
 
-    case META_ACTION_TITLEBAR_NONE:
+    case G_DESKTOP_TITLEBAR_ACTION_NONE:
       /* Yaay, a sane user that doesn't use that other weird crap! */
       break;
     
-    case META_ACTION_TITLEBAR_LOWER:
+    case G_DESKTOP_TITLEBAR_ACTION_LOWER:
       meta_core_user_lower_and_unfocus (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
                                         frame->xwindow,
                                         event->time);
       break;
 
-    case META_ACTION_TITLEBAR_MENU:
+    case G_DESKTOP_TITLEBAR_ACTION_MENU:
       meta_core_show_window_menu (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
                                   frame->xwindow,
                                   event->x_root,
@@ -1349,9 +1349,6 @@ meta_frame_titlebar_event (MetaUIFrame    *frame,
                                   event->button,
                                   event->time);
       break;
-
-    case META_ACTION_TITLEBAR_LAST:
-      break;
     }
   
   return TRUE;
diff --git a/test/metacity-test b/test/metacity-test
index de46d66..99a2356 100644
--- a/test/metacity-test
+++ b/test/metacity-test
@@ -195,10 +195,6 @@ class test_ansi(BuildTest):
     def run(self):
         return self.run_build(c='ansi')
 
-class test_gconfoff(BuildTest):
-    def run(self):
-        return self.run_build(autogen='--disable-gconf')
-
 class test_compositoroff(BuildTest):
     def run(self):
         return self.run_build(autogen='--disable-compositor')



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]